pppc/pppc.c

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

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