Revision 1.6 2005/10/16 23:22:44 hwmaier Commented out unreferenced include statement hd44780.h
Revision 1.5 2005/04/30 16:42:41 chaac Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG is defined in NutConf, it will make effect where it is used.
Revision 1.4 2005/02/23 04:44:35 hwmaier Changes in order to support AT90CAN128
Revision 1.3 2004/01/28 14:24:47 drsung Bugfix for ICCAVR
Revision 1.2 2003/11/06 09:24:50 haraldkipp Added a note that debug output will hang ATmega103
Revision 1.1 2003/08/14 14:57:07 haraldkipp First release
PPP client. Similar to the TCP server sample, but uses PPP over RS232.
The default settings in this sample may be used to connect to a RAS server of a Windows PC. When adding a similar modem script, it will also work with a Linux PC nearly out of the box. At least you need to change the PPPUSER and PPPPASS.
00001 /* 00002 * Copyright (C) 2003-2006 by egnite Software GmbH. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions 00006 * are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holders nor the names of 00014 * contributors may be used to endorse or promote products derived 00015 * from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS 00018 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00019 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00020 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE 00021 * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00022 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00023 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00024 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00025 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00026 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00027 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * For additional information see http://www.ethernut.de/ 00031 * 00032 */ 00033 00076 #include <cfg/arch.h> 00077 00078 /* 00079 * PPP user and password. 00080 */ 00081 #define PPPUSER "me" 00082 #define PPPPASS "secret" 00083 00084 /* 00085 * The Nut/OS modem chat utility works similar to the the UNIX 00086 * chat script. This one is used to connect to a Windows PC 00087 * using a direct cable. 00088 */ 00089 #define PPPCHAT "TIMEOUT 2 '' CLIENT\\c CLIENTSERVER" 00090 00091 /* 00092 * A very simple modem script. 00093 */ 00094 //#define PPPCHAT "'' AT OK ATD555 CONNECT" 00095 00096 00097 /* 00098 * PPP device settings. 00099 */ 00100 #if defined(__AVR__) 00101 #define PPPDEV devAhdlc0 /* Use HDLC driver. */ 00102 //#define PPPDEV devUart0 /* Use standard UART driver. */ 00103 #else 00104 #warning "Works on ATmega128 only." 00105 #endif 00106 #define PPPCOM "uart0" /* Physical device name. */ 00107 #define PPPSPEED 115200 /* Baudrate. */ 00108 #define PPPRXTO 1000 /* Character receive timeout. */ 00109 00110 00111 /* 00112 * Server input buffer size. 00113 */ 00114 #define RXBUFFSIZE 256 00115 00116 #include <cfg/os.h> 00117 #include <dev/debug.h> 00118 //#include <dev/hd44780.h> 00119 #include <dev/ahdlcavr.h> 00120 //#include <dev/uartavr.h> 00121 #include <dev/ppp.h> 00122 #include <dev/chat.h> 00123 00124 #include <sys/version.h> 00125 #include <sys/heap.h> 00126 #include <sys/thread.h> 00127 #include <sys/socket.h> 00128 00129 #include <sys/timer.h> 00130 00131 #include <arpa/inet.h> 00132 #include <netdb.h> 00133 #include <net/if_var.h> 00134 #include <net/route.h> 00135 00136 #ifdef NUTDEBUG 00137 #include <net/netdebug.h> 00138 #endif 00139 00140 #include <stdlib.h> 00141 #include <string.h> 00142 #include <stdio.h> 00143 #include <io.h> 00144 #include <fcntl.h> 00145 00146 #if defined(__IMAGECRAFT__) 00147 #define CC_STRING "ICCAVR" 00148 #elif defined(__GNUC__) 00149 #define CC_STRING "AVRGCC" 00150 #else 00151 #define CC_STRING "Compiler unknown" 00152 #endif 00153 00154 /* 00155 * Debug output device settings. 00156 */ 00157 #ifdef __AVR_ENHANCED__ 00158 #define DBGDEV devDebug1 /* Use debug driver. */ 00159 //#define DBGDEV devUart1 /* Use standard UART driver. */ 00160 #define DBGCOM "uart1" /* Device name. */ 00161 #define DBGSPEED 115200 /* Baudrate. */ 00162 #endif 00163 00164 prog_char vbanner_P[] = "\n\nPPP Client Sample - Nut/OS %s - " CC_STRING "\n"; 00165 prog_char banner_P[] = "200 Welcome to tcps. Type help to get help.\r\n"; 00166 prog_char help_P[] = "400 List of commands follows\r\n" 00167 "m[emory]\tQueries number of RAM bytes free.\r\n" 00168 "t[hreads]\tLists all created threads.\r\n" 00169 "ti[mers]\tLists all running timers.\r\n" "q[uit]\t\tTerminates connection.\r\n" ".\r\n"; 00170 prog_char thread_intro_P[] = "220 List of threads with name,state,prio,stack,mem,timeout follows\r\n"; 00171 prog_char timer_intro_P[] = "221 List of timers with ticks left and interval follows\r\n"; 00172 prog_char mem_fmt_P[] = "210 %u bytes RAM free\r\n"; 00173 00174 00175 /* 00176 * Process client requests. 00177 */ 00178 void ProcessRequests(FILE * stream) 00179 { 00180 int got; 00181 char *cp; 00182 char *buff; 00183 00184 /* 00185 * We allocate the input buffer from heap memory. 00186 */ 00187 buff = malloc(RXBUFFSIZE); 00188 00189 /* 00190 * Send a welcome banner. 00191 */ 00192 fputs_P(banner_P, stream); 00193 for (;;) { 00194 00195 /* 00196 * Flush output and read a line. 00197 */ 00198 fflush(stream); 00199 if (fgets(buff, RXBUFFSIZE, stream) == 0) 00200 break; 00201 00202 /* 00203 * Chop off EOL. 00204 */ 00205 if ((cp = strchr(buff, '\r')) != 0) 00206 *cp = 0; 00207 if ((cp = strchr(buff, '\n')) != 0) 00208 *cp = 0; 00209 00210 /* 00211 * Ignore blank lines. 00212 */ 00213 got = strlen(buff); 00214 if (got == 0) 00215 continue; 00216 00217 /* 00218 * Memory info. 00219 */ 00220 if (strncmp(buff, "memory", got) == 0) { 00221 fprintf_P(stream, mem_fmt_P, NutHeapAvailable()); 00222 continue; 00223 } 00224 00225 /* 00226 * List threads. 00227 */ 00228 if (strncmp(buff, "threads", got) == 0) { 00229 NUTTHREADINFO *tdp; 00230 NUTTIMERINFO *tnp; 00231 00232 fputs_P(thread_intro_P, stream); 00233 for (tdp = nutThreadList; tdp; tdp = tdp->td_next) { 00234 fputs(tdp->td_name, stream); 00235 switch (tdp->td_state) { 00236 case TDS_TERM: 00237 fputs("\tTerm\t", stream); 00238 break; 00239 case TDS_RUNNING: 00240 fputs("\tRun\t", stream); 00241 break; 00242 case TDS_READY: 00243 fputs("\tReady\t", stream); 00244 break; 00245 case TDS_SLEEP: 00246 fputs("\tSleep\t", stream); 00247 break; 00248 } 00249 fprintf(stream, "%u\t%u", tdp->td_priority, (u_short) tdp->td_sp - (u_short) tdp->td_memory); 00250 if (*((u_long *) tdp->td_memory) != DEADBEEF) 00251 fputs("\tCorrupted\t", stream); 00252 else 00253 fputs("\tOK\t", stream); 00254 00255 if ((tnp = (NUTTIMERINFO *) tdp->td_timer) != 0) 00256 fprintf(stream, "%lu\r\n", tnp->tn_ticks_left); 00257 else 00258 fputs("None\r\n", stream); 00259 } 00260 fputs(".\r\n", stream); 00261 continue; 00262 } 00263 00264 /* 00265 * List timers. 00266 */ 00267 if (strncmp("timers", buff, got) == 0) { 00268 NUTTIMERINFO *tnp; 00269 00270 fputs_P(timer_intro_P, stream); 00271 for (tnp = nutTimerList; tnp; tnp = tnp->tn_next) { 00272 fprintf(stream, "%lu\t", tnp->tn_ticks_left); 00273 if (tnp->tn_ticks) 00274 fprintf(stream, "%lu\r\n", tnp->tn_ticks); 00275 else 00276 fputs("Oneshot\r\n", stream); 00277 } 00278 fputs(".\r\n", stream); 00279 continue; 00280 } 00281 00282 /* 00283 * Quit connection. 00284 */ 00285 if (strncmp("quit", buff, got) == 0) { 00286 break; 00287 } 00288 00289 /* 00290 * Display help text on any unknown command. 00291 */ 00292 fputs_P(help_P, stream); 00293 } 00294 } 00295 00296 /* 00297 * PPP client application entry. 00298 */ 00299 int main(void) 00300 { 00301 int pppcom; 00302 PPPDCB *dcb; 00303 u_long lctl; 00304 int rc; 00305 00306 /* 00307 * Register our devices. 00308 */ 00309 #ifdef __AVR_ENHANCED__ 00310 NutRegisterDevice(&DBGDEV, 0, 0); 00311 #endif 00312 #ifdef PPPDEV 00313 NutRegisterDevice(&PPPDEV, 0, 0); 00314 NutRegisterDevice(&devPpp, 0, 0); 00315 #endif 00316 00317 /* 00318 * Open debug device for standard output. 00319 */ 00320 if(freopen("uart1", "w", stdout) == 0) { 00321 for(;;); 00322 } 00323 00324 /* 00325 * Set debug output speed. 00326 */ 00327 #ifdef __AVR_ENHANCED__ 00328 lctl = DBGSPEED; 00329 _ioctl(_fileno(stdout), UART_SETSPEED, &lctl); 00330 #endif 00331 00332 /* 00333 * Display banner including compiler info and Nut/OS version. 00334 */ 00335 printf_P(vbanner_P, NutVersionString()); 00336 00337 /* 00338 * Open PPP device. Specify physical device, user and password. 00339 */ 00340 printf("Open uart..."); 00341 if ((pppcom = _open("ppp:" PPPCOM "/" PPPUSER "/" PPPPASS, _O_RDWR | _O_BINARY)) == -1) { 00342 printf("Failed to open " PPPCOM "\n"); 00343 for (;;); 00344 } 00345 puts("done"); 00346 00347 #ifdef PPPDEV 00348 /* 00349 * Set PPP line speed. 00350 */ 00351 lctl = PPPSPEED; 00352 _ioctl(pppcom, UART_SETSPEED, &lctl); 00353 00354 /* 00355 * The PPP driver doesn't set any receive timeout, but 00356 * may require it. 00357 */ 00358 lctl = PPPRXTO; 00359 _ioctl(pppcom, UART_SETREADTIMEOUT, &lctl); 00360 00361 #ifdef NUTDEBUG 00362 /* 00363 * Optionally enable PPP trace. 00364 */ 00365 NutTracePPP(stdout, 1); 00366 #endif 00367 00368 /* 00369 * This delay may be removed. It is quite helpful during development. 00370 */ 00371 NutSleep(5000); 00372 00373 /* 00374 * PPP connection loop. 00375 */ 00376 for (;;) { 00377 /* 00378 * Connect using a chat script. We may also set any 00379 * required hardware handshake line at this stage. 00380 */ 00381 printf("Connecting..."); 00382 if ((rc = NutChat(pppcom, PPPCHAT)) != 0) { 00383 printf("no connect, reason = %d\n", rc); 00384 continue; 00385 } 00386 puts("done"); 00387 00388 /* 00389 * We are connected, configure our PPP network interface. 00390 * This will initiate the PPP configuration negotiation 00391 * and authentication with the server. 00392 */ 00393 printf("Configure PPP..."); 00394 rc = NutNetIfConfig("ppp", 0, 0, 0); 00395 if (rc != 0) { 00396 puts("failed"); 00397 /* 00398 * Optionally toggle DTR to hang up the modem. 00399 */ 00400 continue; 00401 } 00402 puts("done"); 00403 00404 /* 00405 * Set name server and default route. Actually the PPP interface 00406 * should do this, but the current release doesn't. 00407 */ 00408 dcb = devPpp.dev_dcb; 00409 NutDnsConfig2(0, 0, dcb->dcb_ip_dns1, dcb->dcb_ip_dns2); 00410 NutIpRouteAdd(0, 0, dcb->dcb_remote_ip, &devPpp); 00411 00412 /* 00413 * Display our IP settings. 00414 */ 00415 printf(" Local IP: %s\n", inet_ntoa(dcb->dcb_local_ip)); 00416 printf(" Remote IP: %s\n", inet_ntoa(dcb->dcb_remote_ip)); 00417 printf(" Primary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns1)); 00418 printf("Secondary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns2)); 00419 00420 /* 00421 * Client connection loop. 00422 */ 00423 for (;;) { 00424 TCPSOCKET *sock; 00425 FILE *stream; 00426 00427 /* 00428 * Create a socket. 00429 */ 00430 if ((sock = NutTcpCreateSocket()) != 0) { 00431 00432 /* 00433 * Listen on port 23. If we return, we got a client. 00434 */ 00435 printf("Waiting for a client..."); 00436 if (NutTcpAccept(sock, 23) == 0) { 00437 puts("connected"); 00438 00439 /* 00440 * Open a stream and associate it with the socket, so 00441 * we can use standard I/O. Note, that socket streams 00442 * currently do support text mode. 00443 */ 00444 if ((stream = _fdopen((int) sock, "r+b")) != 0) { 00445 /* 00446 * Process client requests. 00447 */ 00448 ProcessRequests(stream); 00449 puts("\nDisconnected"); 00450 00451 /* 00452 * Close the stream. 00453 */ 00454 fclose(stream); 00455 } else { 00456 puts("Assigning a stream failed"); 00457 } 00458 } else { 00459 puts("failed"); 00460 } 00461 00462 /* 00463 * Close our socket. 00464 */ 00465 NutTcpCloseSocket(sock); 00466 } 00467 NutSleep(1000); 00468 printf("%u bytes free\n", NutHeapAvailable()); 00469 } 00470 } 00471 #endif /* PPPDEV */ 00472 }