/* * Copyright (C) 2011 by egnite GmbH * Copyright (C) 2003-2006 by egnite Software GmbH * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * For additional information see http://www.ethernut.de/ */ /*! * $Id: pppc.c 4640 2012-09-24 12:05:56Z u_bonnes $ */ /*! * \example pppc/pppc.c * * PPP client sample. * * This example demonstrates Nut/OS Point-To-Point protocol. Most likely * it will not run without modification. See the '#define' entries * below. * * The application will dial the provider via a modem, using the specified * chat script. When connected, it will establish a PPP session. Then DNS * is used to query the IP address of an NTP server, from which it queries * the current time. Finally the PPP session is terminated and the whole * procedure is repeated every hour. * * By default the application will use 2 serial ports. The first one is * used for debugging output on stdout and the second UART will be * connected to a modem. * * Note, that PPP is not available for all target boards. If this is the * case the program will use the local Ethernet network, where DHCP must * be available. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Conversational script with a modem. * * The Nut/OS modem chat utility works similar to the the UNIX chat * script. In general it consists of one or more expect-send pairs of * strings or optional keyword-parameter pairs. Keywords are * * - TIMEOUT to set the max. time in seconds to wait for expected string * - ABORT to specify up to 10 abort strings * - REPORT to specify up to 3 reported abort strings * * Adjust this script to the requirements of your modem equipment * and your GPRS provider. * * The following script had been tested with a Siemens GPRS modem * (S55 mobile phone), using a t-mobile pre-paid account. */ #define PPP_CHAT /* Wait up to 20 seconds for any response. */ \ "TIMEOUT 20" \ /* Expect nothing at the beginning. */ \ " ''" \ /* Send simple AT command to check the modem. */ \ " AT OK" \ /* Define PDP context, expecting 'OK'. */ \ " AT+CGDCONT=1,\"IP\",\"internet.t-mobile\" OK" \ /* Dial and wait for 'CONNECT'. */ \ " ATD*99***1# CONNECT" /* * PPP user and password. * * Often GPRS providers accept any login. */ #define PPP_USER "me" #define PPP_PASS "secret" /* * PPP device settings. */ #if defined(NUT_THREAD_AHDLCRXSTACK) #define PPP_DEV devAhdlc1 /* AHDLC driver */ #define PPP_DEV_NAME "uart1" /* Physical device name */ #define PPP_SPEED 115200 /* Baudrate */ #define PPP_RXTO 1000 /* Receive timeout (ms) */ #else #warning "PPP is not supported on your target" #endif /* * Open serial debug port for standard output. */ static void DebugPortOpen(void) { uint32_t baud = 115200; /* Register debug UART. */ NutRegisterDevice(&DEV_CONSOLE, 0, 0); /* Open debug device for standard output. */ freopen(DEV_CONSOLE.dev_name, "w", stdout); /* Set baud rate. */ _ioctl(_fileno(stdout), UART_SETSPEED, &baud); } /* * Initialize the protocol port. */ static void ProtocolPortInit(void) { #ifdef PPP_DEV /* Register PPP and UART device. */ NutRegisterDevice(&PPP_DEV, 0, 0); NutRegisterDevice(&devPpp, 0, 0); #else /* Use Ethernet. */ NutRegisterDevice(&DEV_ETHER, 0, 0); #endif } /* * Open the physical device. */ static int ProtocolPortOpen(void) { #ifdef PPP_DEV int pppcom; uint32_t lctl; /* Open PPP device. Specify physical device, user and password. */ printf("Open PPP interface at " PPP_DEV_NAME "..."); pppcom = _open("ppp:" PPP_DEV_NAME "/" PPP_USER "/" PPP_PASS, _O_RDWR | _O_BINARY); if (pppcom == -1) { puts("failed"); return -1; } /* * Set PPP line speed. */ lctl = PPP_SPEED; _ioctl(pppcom, UART_SETSPEED, &lctl); printf("%lu baud", lctl); /* * The PPP driver doesn't set any receive timeout, but * may require it. */ lctl = PPP_RXTO; _ioctl(pppcom, UART_SETREADTIMEOUT, &lctl); printf(", %lu ms timeout\n", lctl); return pppcom; #else /* Nothing to be done for Ethernet. */ return 0; #endif } /* * Establish a modem connection. */ static int ProtocolPortConnect(int pppcom) { #ifdef PPP_DEV int rc; /* * Connect using a chat script. We may also set any * required hardware handshake line at this stage. */ printf("Connecting..."); for (;;) { rc = NutChat(pppcom, PPP_CHAT); switch (rc) { case 0: puts("done"); /* A short pause is required here to let the driver initialize the receiver thread. */ NutSleep(100); break; case 1: puts("bad script"); break; case 2: puts("I/O error"); break; case 3: puts("no response"); break; default: printf("aborted (%d)\n", rc); break; } if (rc != 3) { break; } NutSleep(1000); } return rc; #else /* Nothing to be done for Ethernet. */ return 0; #endif } /* * Hang up. */ static void ProtocolPortClose(int pppcom) { #ifdef PPP_DEV /* Set the UART back to normal mode. */ _ioctl(pppcom, HDLC_SETIFNET, NULL); /* Close the physical port. This may or may not hang up. Please check the modem's documentation. */ _close(pppcom); #endif } static int ProtocolPortConfigure(void) { #ifdef PPP_DEV PPPDCB *dcb; /* * We are connected, configure our PPP network interface. * This will initiate the PPP configuration negotiation * and authentication with the server. */ printf("Configure network interface..."); if (NutNetIfConfig("ppp", 0, 0, 0)) { puts("failed"); return -1; } puts("done"); /* * Set name server and default route. Actually the PPP interface * should do this, but the current release doesn't. */ dcb = devPpp.dev_dcb; NutDnsConfig2(0, 0, dcb->dcb_ip_dns1, dcb->dcb_ip_dns2); NutIpRouteAdd(0, 0, dcb->dcb_remote_ip, &devPpp); /* * Display our IP settings. */ printf(" Local IP: %s\n", inet_ntoa(dcb->dcb_local_ip)); printf(" Remote IP: %s\n", inet_ntoa(dcb->dcb_remote_ip)); printf(" Primary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns1)); printf("Secondary DNS: %s\n", inet_ntoa(dcb->dcb_ip_dns2)); #else /* We use DHCP on Ethernet. */ printf("Configure network interface..."); if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) { puts("failed"); return -1; } puts("done"); #endif return 0; } /* * Connect any NTP-Pool server to query the current time. */ static void QueryDateAndTime(void) { uint32_t ip; time_t now; int i; /* First connect the DNS server to get the IP address. */ printf("Is There Anybody Out There? "); ip = NutDnsGetHostByName((uint8_t *) "pool.ntp.org"); if (ip == 0) { puts("No?"); } else { /* We do have an IP, now try to connect it. */ printf("Yes, found %s\n", inet_ntoa(ip)); for (i = 0; i < 3; i++) { printf("What's the time? "); if (NutSNTPGetTime(&ip, &now) == 0) { /* We got a valid response, display the result. */ printf("%s GMT\n", Rfc1123TimeString(gmtime(&now))); return; } else { /* It failed. May be the server is too busy. Try again in 5 seconds. */ puts("Sorry?"); NutSleep(5000); } } } /* We give up after 3 trials. */ puts("You missed the starting gun."); } /* * PPP client application entry. */ int main(void) { int pppcom; /* Initialize a debug port for standard output and display a banner. */ DebugPortOpen(); printf("\n\nPPP Client Sample - Nut/OS %s\n", NutVersionString()); /* Initialize the network interface. */ ProtocolPortInit(); /* This loop runs once per hour. */ for (;;) { /* Open the network interface. */ pppcom = ProtocolPortOpen(); if (pppcom == -1) { /* If this fails, we are busted. */ break; } /* Establish the modem connection. */ if (ProtocolPortConnect(pppcom) == 0) { /* Configure the network interface. */ if (ProtocolPortConfigure() == 0) { /* Talk to the Internet. */ QueryDateAndTime(); } } /* Hang up. */ ProtocolPortClose(pppcom); /* Sleep 1 hour. */ puts("I'll be back in 1 hour."); NutSleep(3600000); } /* Ouch... */ puts("Good bye cruel world"); return 0; }