pppc/pppc.c

$Log$ Revision 1.10 2009/03/08 20:17:51 haraldkipp AVR compile error fixed. lctl is required.

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.

Bug:
This sample works with ICCAVR (6.28 tested) only with debugging enabled.
Bug:
Not working with ATmega103. Debug output needs to be removed.
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 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/