Revision 1.9 2009/02/18 12:18:58 olereinhardt 2009-02-18 Ole Reinhardt <ole.reinhardt@thermotemp.de>
Fixed compilier warnings. Especialy signedness of char buffers as well as unused code on arm platform and main functions without return value
Revision 1.8 2008/01/31 09:38:15 haraldkipp Added return statement in main to avoid warnings with latest GCC.
Revision 1.7 2006/07/21 09:08:19 haraldkipp Use devAhdlc0 instead of devUart0. The latter will not work.
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 00089 #include <cfg/arch.h> 00090 00091 /* 00092 * PPP user and password. 00093 */ 00094 #define PPPUSER "me" 00095 #define PPPPASS "secret" 00096 00097 /* 00098 * The Nut/OS modem chat utility works similar to the the UNIX 00099 * chat script. This one is used to connect to a Windows PC 00100 * using a direct cable. 00101 */ 00102 #define PPPCHAT "TIMEOUT 2 '' CLIENT\\c CLIENTSERVER" 00103 00104 /* 00105 * A very simple modem script. 00106 */ 00107 //#define PPPCHAT "'' AT OK ATD555 CONNECT" 00108 00109 00110 /* 00111 * PPP device settings. 00112 */ 00113 #if defined(__AVR__) 00114 #define PPPDEV devAhdlc0 /* Use HDLC driver. */ 00115 //#define PPPDEV devUart0 /* Use standard UART driver. */ 00116 #else 00117 #warning "Works on ATmega128 only." 00118 #endif 00119 #define PPPCOM "uart0" /* Physical device name. */ 00120 #define PPPSPEED 115200 /* Baudrate. */ 00121 #define PPPRXTO 1000 /* Character receive timeout. */ 00122 00123 00124 /* 00125 * Server input buffer size. 00126 */ 00127 #define RXBUFFSIZE 256 00128 00129 #include <cfg/os.h> 00130 #include <dev/debug.h> 00131 //#include <dev/hd44780.h> 00132 #include <dev/ahdlcavr.h> 00133 //#include <dev/uartavr.h> 00134 #include <dev/ppp.h> 00135 #include <dev/chat.h> 00136 00137 #include <sys/version.h> 00138 #include <sys/heap.h> 00139 #include <sys/thread.h> 00140 #include <sys/socket.h> 00141 00142 #include <sys/timer.h> 00143 00144 #include <arpa/inet.h> 00145 #include <netdb.h> 00146 #include <net/if_var.h> 00147 #include <net/route.h> 00148 00149 #ifdef NUTDEBUG 00150 #include <net/netdebug.h> 00151 #endif 00152 00153 #include <stdlib.h> 00154 #include <string.h> 00155 #include <stdio.h> 00156 #include <io.h> 00157 #include <fcntl.h> 00158 00159 #if defined(__IMAGECRAFT__) 00160 #define CC_STRING "ICCAVR" 00161 #elif defined(__GNUC__) 00162 #define CC_STRING "AVRGCC" 00163 #else 00164 #define CC_STRING "Compiler unknown" 00165 #endif 00166 00167 /* 00168 * Debug output device settings. 00169 */ 00170 #ifdef __AVR_ENHANCED__ 00171 #define DBGDEV devDebug1 /* Use debug driver. */ 00172 //#define DBGDEV devUart1 /* Use standard UART driver. */ 00173 #define DBGCOM "uart1" /* Device name. */ 00174 #define DBGSPEED 115200 /* Baudrate. */ 00175 #endif 00176 00177 prog_char vbanner_P[] = "\n\nPPP Client Sample - Nut/OS %s - " CC_STRING "\n"; 00178 prog_char banner_P[] = "200 Welcome to tcps. Type help to get help.\r\n"; 00179 prog_char help_P[] = "400 List of commands follows\r\n" 00180 "m[emory]\tQueries number of RAM bytes free.\r\n" 00181 "t[hreads]\tLists all created threads.\r\n" 00182 "ti[mers]\tLists all running timers.\r\n" "q[uit]\t\tTerminates connection.\r\n" ".\r\n"; 00183 prog_char thread_intro_P[] = "220 List of threads with name,state,prio,stack,mem,timeout follows\r\n"; 00184 prog_char timer_intro_P[] = "221 List of timers with ticks left and interval follows\r\n"; 00185 prog_char mem_fmt_P[] = "210 %lu bytes RAM free\r\n"; 00186 00187 00188 /* 00189 * Process client requests. 00190 */ 00191 void ProcessRequests(FILE * stream) 00192 { 00193 int got; 00194 char *cp; 00195 char *buff; 00196 00197 /* 00198 * We allocate the input buffer from heap memory. 00199 */ 00200 buff = malloc(RXBUFFSIZE); 00201 00202 /* 00203 * Send a welcome banner. 00204 */ 00205 fputs_P(banner_P, stream); 00206 for (;;) { 00207 00208 /* 00209 * Flush output and read a line. 00210 */ 00211 fflush(stream); 00212 if (fgets(buff, RXBUFFSIZE, stream) == 0) 00213 break; 00214 00215 /* 00216 * Chop off EOL. 00217 */ 00218 if ((cp = strchr(buff, '\r')) != 0) 00219 *cp = 0; 00220 if ((cp = strchr(buff, '\n')) != 0) 00221 *cp = 0; 00222 00223 /* 00224 * Ignore blank lines. 00225 */ 00226 got = strlen(buff); 00227 if (got == 0) 00228 continue; 00229 00230 /* 00231 * Memory info. 00232 */ 00233 if (strncmp(buff, "memory", got) == 0) { 00234 fprintf_P(stream, mem_fmt_P, NutHeapAvailable()); 00235 continue; 00236 } 00237 00238 /* 00239 * List threads. 00240 */ 00241 if (strncmp(buff, "threads", got) == 0) { 00242 NUTTHREADINFO *tdp; 00243 NUTTIMERINFO *tnp; 00244 00245 fputs_P(thread_intro_P, stream); 00246 for (tdp = nutThreadList; tdp; tdp = tdp->td_next) { 00247 fputs(tdp->td_name, stream); 00248 switch (tdp->td_state) { 00249 case TDS_TERM: 00250 fputs("\tTerm\t", stream); 00251 break; 00252 case TDS_RUNNING: 00253 fputs("\tRun\t", stream); 00254 break; 00255 case TDS_READY: 00256 fputs("\tReady\t", stream); 00257 break; 00258 case TDS_SLEEP: 00259 fputs("\tSleep\t", stream); 00260 break; 00261 } 00262 fprintf(stream, "%u\t%u", tdp->td_priority, (u_short) tdp->td_sp - (u_short) tdp->td_memory); 00263 if (*((u_long *) tdp->td_memory) != DEADBEEF) 00264 fputs("\tCorrupted\t", stream); 00265 else 00266 fputs("\tOK\t", stream); 00267 00268 if ((tnp = (NUTTIMERINFO *) tdp->td_timer) != 0) 00269 fprintf(stream, "%lu\r\n", tnp->tn_ticks_left); 00270 else 00271 fputs("None\r\n", stream); 00272 } 00273 fputs(".\r\n", stream); 00274 continue; 00275 } 00276 00277 /* 00278 * List timers. 00279 */ 00280 if (strncmp("timers", buff, got) == 0) { 00281 NUTTIMERINFO *tnp; 00282 00283 fputs_P(timer_intro_P, stream); 00284 for (tnp = nutTimerList; tnp; tnp = tnp->tn_next) { 00285 fprintf(stream, "%lu\t", tnp->tn_ticks_left); 00286 if (tnp->tn_ticks) 00287 fprintf(stream, "%lu\r\n", tnp->tn_ticks); 00288 else 00289 fputs("Oneshot\r\n", stream); 00290 } 00291 fputs(".\r\n", stream); 00292 continue; 00293 } 00294 00295 /* 00296 * Quit connection. 00297 */ 00298 if (strncmp("quit", buff, got) == 0) { 00299 break; 00300 } 00301 00302 /* 00303 * Display help text on any unknown command. 00304 */ 00305 fputs_P(help_P, stream); 00306 } 00307 } 00308 00309 /* 00310 * PPP client application entry. 00311 */ 00312 int main(void) 00313 { 00314 int pppcom; 00315 u_long lctl; 00316 #ifdef PPPDEV 00317 PPPDCB *dcb; 00318 int rc; 00319 #endif 00320 /* 00321 * Register our devices. 00322 */ 00323 #ifdef __AVR_ENHANCED__ 00324 NutRegisterDevice(&DBGDEV, 0, 0); 00325 #endif 00326 #ifdef PPPDEV 00327 NutRegisterDevice(&PPPDEV, 0, 0); 00328 NutRegisterDevice(&devPpp, 0, 0); 00329 #endif 00330 00331 /* 00332 * Open debug device for standard output. 00333 */ 00334 if(freopen("uart1", "w", stdout) == 0) { 00335 for(;;); 00336 } 00337 00338 /* 00339 * Set debug output speed. 00340 */ 00341 #ifdef __AVR_ENHANCED__ 00342 lctl = DBGSPEED; 00343 _ioctl(_fileno(stdout), UART_SETSPEED, &lctl); 00344 #endif 00345 00346 /* 00347 * Display banner including compiler info and Nut/OS version. 00348 */ 00349 printf_P(vbanner_P, NutVersionString()); 00350 00351 /* 00352 * Open PPP device. Specify physical device, user and password. 00353 */ 00354 printf("Open uart..."); 00355 if ((pppcom = _open("ppp:" PPPCOM "/" PPPUSER "/" PPPPASS, _O_RDWR | _O_BINARY)) == -1) { 00356 printf("Failed to open " PPPCOM "\n"); 00357 for (;;); 00358 } 00359 puts("done"); 00360 00361 #ifdef PPPDEV 00362 /* 00363 * Set PPP line speed. 00364 */ 00365 lctl = PPPSPEED; 00366 _ioctl(pppcom, UART_SETSPEED, &lctl); 00367 00368 /* 00369 * The PPP driver doesn't set any receive timeout, but 00370 * may require it. 00371 */ 00372 lctl = PPPRXTO; 00373 _ioctl(pppcom, UART_SETREADTIMEOUT, &lctl); 00374 00375 #ifdef NUTDEBUG 00376 /* 00377 * Optionally enable PPP trace. 00378 */ 00379 NutTracePPP(stdout, 1); 00380 #endif 00381 00382 /* 00383 * This delay may be removed. It is quite helpful during development. 00384 */ 00385 NutSleep(5000); 00386 00387 /* 00388 * PPP connection loop. 00389 */ 00390 for (;;) { 00391 /* 00392 * Connect using a chat script. We may also set any 00393 * required hardware handshake line at this stage. 00394 */ 00395 printf("Connecting..."); 00396 if ((rc = NutChat(pppcom, PPPCHAT)) != 0) { 00397 printf("no connect, reason = %d\n", rc); 00398 continue; 00399 } 00400 puts("done"); 00401 00402 /* 00403 * We are connected, configure our PPP network interface. 00404 * This will initiate the PPP configuration negotiation 00405 * and authentication with the server. 00406 */ 00407 printf("Configure PPP..."); 00408 rc = NutNetIfConfig("ppp", 0, 0, 0); 00409 if (rc != 0) { 00410 puts("failed"); 00411 /* 00412 * Optionally toggle DTR to hang up the modem. 00413 */ 00414 continue; 00415 } 00416 puts("done"); 00417 00418 /* 00419 * Set name server and default route. Actually the PPP interface 00420 * should do this, but the current release doesn't. 00421 */ 00422 dcb = devPpp.dev_dcb; 00423 NutDnsConfig2(0, 0, dcb->dcb_ip_dns1, dcb->dcb_ip_dns2); 00424 NutIpRouteAdd(0, 0, dcb->dcb_remote_ip, &devPpp); 00425 00426 /* 00427 * Display our IP settings. 00428 */ 00429 printf(" Local IP: %s\n", inet_ntoa(dcb->dcb_local_ip)); 00430 printf(" Remote IP: %s\n", inet_ntoa(dcb->dcb_remote_ip)); 00431 printf(" Primary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns1)); 00432 printf("Secondary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns2)); 00433 00434 /* 00435 * Client connection loop. 00436 */ 00437 for (;;) { 00438 TCPSOCKET *sock; 00439 FILE *stream; 00440 00441 /* 00442 * Create a socket. 00443 */ 00444 if ((sock = NutTcpCreateSocket()) != 0) { 00445 00446 /* 00447 * Listen on port 23. If we return, we got a client. 00448 */ 00449 printf("Waiting for a client..."); 00450 if (NutTcpAccept(sock, 23) == 0) { 00451 puts("connected"); 00452 00453 /* 00454 * Open a stream and associate it with the socket, so 00455 * we can use standard I/O. Note, that socket streams 00456 * currently do support text mode. 00457 */ 00458 if ((stream = _fdopen((int) sock, "r+b")) != 0) { 00459 /* 00460 * Process client requests. 00461 */ 00462 ProcessRequests(stream); 00463 puts("\nDisconnected"); 00464 00465 /* 00466 * Close the stream. 00467 */ 00468 fclose(stream); 00469 } else { 00470 puts("Assigning a stream failed"); 00471 } 00472 } else { 00473 puts("failed"); 00474 } 00475 00476 /* 00477 * Close our socket. 00478 */ 00479 NutTcpCloseSocket(sock); 00480 } 00481 NutSleep(1000); 00482 printf("%u bytes free\n", NutHeapAvailable()); 00483 } 00484 } 00485 #endif /* PPPDEV */ 00486 return 0; 00487 }