This is the controlling application for the CDCS UltraLite basic ppp demonstration This demo is suited to the Call Direct UltraLite GM47 board rather than the regular Ethernut board and will need modification to run with ethernut or other boards. I don't have an original Ethernut so I cannot do this myself
To get started connect a terminal at 9600bps to uart0 and a modem to uart1
When the application starts it will try to turn on the GM47 phone module, if you're not using the Call Direct board you'll need to change this, you can probably remove the interface control thread, there is also a line in Nutmain that waits for the phone to turn on you'll need to remove this too.
The driver at the time of writing is only tested against the Sony Ericsson GSM/GPRS phone module, if you wish to use a different modem/ISP combination you will probably need to do some debuging and feature adding, the most obvious thing I can think of is that the driver does not fully support user authentication.
The application should now present an "RMU >" prompt hit ?<cr> to see a list of available commands. To start the PPP session type connect<cr>
ppp debug is activated in this application and the ppp driver should output something like the following on uart0 if :-
RMU> connect Resetting PPP link
RMU> Auto-Connecting to GPRS service s = OK r = at+cgqreq=1,1,1,4,4,12 g = 22 i = 18 s = OK r = g = 0 i = -79 s = OK r = OK g = 2 i = 0 s = OK r = at+cgqmin=1,0,0,0,0,0 g = 21 i = 18 s = OK r = g = 0 i = -79 s = OK r = OK g = 2 i = 0 s = OK r = at+cgdcont=1,"IP","telstra.internet",,0,0 g = 41 i = 18 s = OK r = g = 0 i = -79 s = OK r = OK g = 2 i = 0 s = CONNECT r = atd*99*0*1*1# g = 13 i = 30 s = CONNECT r = g = 0 i = -67 s = CONNECT r = CONNECT g = 7 i = 0 Calling IFConfig Enter PPPInit Waiting for connect Enter PPPReceive Enter LCP ACCM = 0 PFC =1 ACFC =1 AUTH = c023 Enter LCP LCP Options Negotiated Enter PAP PAP ACK Enter IPCP IPCP Request Enter IPCP IPCP Nack Enter IPCP IPCP Accept PPP State = UP PPP Configured IP Address = 10.224.0.175 IP Mask = 0.0.0.0 IP Remote = 10.224.0.174 PRI DNS = 139.130.4.4 SEC DNS = 203.50.2.71 Finished IFConfig
RMU>
To establish a PPP session I use CDNetPPPConnect() to dial the host and then call NutNetIfConfig() as in this example. CDNetPPPConnect(NUTDEVICE *dev, const char *scriptin) can run a very simple connect script to get you connected to your host device, to use it the dev parameter should point to the device to which the modem is attached, the scriptin string should contain the connection script in the format "command:expected response" this could be as simple as "atd <ISP Phone number>:CONNECT"
Unless you are using GPRS you will definatly need to change the connect script.
Once connected to your isp you can do some basic tests from the command line interface in the demo application.
The lookup command allows you to perform a DNS lookup eg:-
RMU> lookup mail.egnite.de Name: mail.egnite.de Address: 217.160.92.226
RMU>
The telnet command allows you to establish a simple TCP (not really telnet) session with some host eg:-
RMU> telnet mail.egnite.de 25 Connecting to 217.160.92.226 25 Use ^] to quit 220 p15095813.pureserver.info ESMTP Sendmail 8.11.3/8.11.3/SuSE Linux 8.11.1-0.5 ; Fri, 25 Oct 2002 03:17:06 +0200 500 5.5.1 Command unrecognized: "" 214-2.0.0 This is sendmail version 8.11.3 214-2.0.0 Topics: 214-2.0.0 HELO EHLO MAIL RCPT DATA 214-2.0.0 RSET NOOP QUIT HELP VRFY 214-2.0.0 EXPN VERB ETRN DSN AUTH 214-2.0.0 STARTTLS 214-2.0.0 For more info use "HELP <topic>". 214-2.0.0 To report bugs in the implementation send email to 214-2.0.0 sendmail-bugs@sendmail.org. 214-2.0.0 For local information send email to Postmaster at your site. 214 2.0.0 End of HELP info Done error = 0
RMU>
The PPP driver itself is stable for my configuration but will need work if it is going to be generally useful, as such it is being released as a pre-alpha driver at this stage Good Luck !!!
#include <string.h> #include <dev/uartavr.h> /* Reference to the uart0 device driver. */ #include <sys/thread.h> /* Contains the THREAD macro. */ #include <sys/print.h> /* Formatted output functions. */ #include <sys/ifstream.h> /* Stream IO functions */ #include <sys/timer.h> #include <net/if_var.h> #include <sys/heap.h> #include <dev/netbuf.h> #include <net/PPPif.h> #include <netinet/sostream.h> #include <arpa/inet.h> #include <dev/irqreg.h> #include "UltraLite_E47.h" #include "CDCS_MMI.h" #include "CDCS_Modem.h" #ifdef NUTDEBUG #include <sys/kprint.h> #include <sys/osdebug.h> #include <net/netdebug.h> #endif // Version Info #define banner PSTR("\r\nCDCS UltraLite Intelligent Terminal - PPP Demo") static const char verMJ = 0x01; static const char verMN = 0x00; // Globals int Flags; // Devices NUTDEVICE *uart0; NUTDEVICE *uart1; NUTDEVICE *PPP0; // Device to pass data to/from UART0 (external serial port) NUTDEVICE *dev_passthru; // Various define #define PASSTHRUBUFFSIZE 128 // This thread is responsible for ensuring that the phone module is turned on THREAD(InterfaceControl, arg) { int i; #ifdef NUTDEBUG NutPrintString_P (dev_debug,PSTR("Started Interface control\r\n")); #endif outp(inp(PORTD) | RED | GREEN, PORTD); // Both LEDS on during reset while (inp(PINE) & VCCL) // If Phone Module ON { i = inp(DDRE); outp((i|MODPWR),DDRE); // Set MODPWR low i = 150; // Wait up to 15s while ((inp(PINE) & VCCL) && i) // for power to turn off { NutSleep (100); i --; } i = inp(DDRE) ; outp(i & ~MODPWR,DDRE); // Set MODPWR Hi-Z Again } for(;;) { if (inp(PINE) & VCCL) // If Phone Module ON { i = inp(PORTD); if (inp(PINE) & SVC_LED) // If Service LED ON { i |= GREEN; // Led On i &= ~RED; } else { i &= ~(RED|GREEN); // Led Off } outp(i, PORTD); Flags |= Phone_ON; } else // If Phone Module OFF { // Internal modem lines low until module power up outp((RI), PORTG); // RI Negated Flags &= ~Phone_ON; NutSleep (100); i = inp(DDRE); outp((i|MODPWR),DDRE); // Set MODPWR low i = 50; // Wait up to 150s while (((inp(PINE) & VCCL) == 0) && i) // for power to turn on { NutSleep (100); i --; } NutSleep (500); i = inp(DDRE); i &= ~MODPWR; outp(i,DDRE); // Set MODPWR Hi-Z again NutSleep (500); } NutThreadYield(); } } // Run the MMI on uart 0 // Uart 0 is connected to the external serial port THREAD(MIIThread, arg) { for(;;) { DoMMI(uart0); } } THREAD(NutMain, arg) { u_long ltmp; u_char *resp = 0; // Setup IO Ports outp((DCD | CTS | RTS_P | DTR_P), DDRB); // DCD_P, DCD, CTS_P, CTS, RTS, RTS_P, DTR, DTR_P outp((DCD | CTS), PORTB); // External RS-232 lines High (negated) // Internal lines low until module power up outp((RESETE | DSR | RED | GREEN | TEST2| TEST1), DDRD); // RESETE, DSR, RED, GREEN, (TD_P,RD_P,SDA,SCL) outp((RESETE | RED | GREEN), PORTD); // Ethernet controler held in reset, DSR Asserted, BOTH LEDS ON outp(0x04, DDRE); // PFI, SVC_LED, MODDPWR, VCCL, PE3, PE2, (TD, RD) outp(0, PORTE); // MODPWR is normally Hi-Z outp(0, DDRF); // (TDI, TDO, TMS, TCK), outp(0x0F, PORTF); // Enable pull ups on unused pins outp(0x0, DDRG); // RI_P, RI, (ALE, MOE, MWE) outp((RI_P), PORTG); // Enable pull up on RI_P // Initialise Globals // Flags = Auto_GPRS_Attach; dev_passthru = NULL; Flags = 0; // Register all of our hardware devices NutRegisterDevice(&devUart0, 0, 0); NutRegisterDevice(&devUart1, 1, 0); NutRegisterDevice(&devPPP0, 0, 0); // Initialise the UARTS uart0 = NutDeviceOpen("uart0"); // External Serial Port ltmp = 9600; NutDeviceIOCtl(uart0, UART_SETSPEED, <mp); #ifdef NUTDEBUG dev_debug = uart0; // Enable buffered debug output #endif uart1 = NutDeviceOpen("uart1"); ltmp = 9600; NutDeviceIOCtl(uart1, UART_SETSPEED, <mp); // Phone starts at 9600 is reset to 57600 below // Display Banner and Version NutPrintString_P(uart0, banner); NutPrintFormat(uart0, " V%d.%d\r\n",verMJ, verMN); NutPrintFlush(uart0); NutPrintString_P (uart0,PSTR("Starting threads\r\n")); NutPrintFlush(uart0); NutThreadCreate("ifctrl", InterfaceControl, 0, 200); // Wait for phone to initialise while ((Flags & Phone_ON) == 0) NutSleep(100); NutPrintString_P (uart0,PSTR("Phone ON\r\n")); NutPrintFlush(uart0); NutThreadCreate("mmi", MIIThread, 0, 1024); Send_ATCommand(uart1, "AT+IPR=38400",&resp,1000); // Reset phone interface to 38400 ltmp = 38400; NutDeviceIOCtl(uart1, UART_SETSPEED, <mp); #ifdef NUTDEBUG //NutKOsTrace(1); //NutKHeapTrace(1); //NutKTcpTrace(1); NutKPPPTrace(1); #endif // // Nut/OS never expects a thread to return. // So we enter an endless loop here. // for(;;) { if ((Flags & Auto_GPRS_Attach) && (PPPGetState(&devPPP0) == DEAD)) { NutPrintString_P (uart0,PSTR("Auto-Connecting to GPRS service\r\n")); NutPrintFlush(uart0); if (CDNetPPPConnect(uart1, "at+cgqreq=1,1,1,4,4,12:OK:at+cgqmin=1,0,0,0,0,0:OK:at+cgdcont=1,\"IP\",\"telstra.internet\",,0,0:OK:atd*99*0*1*1#:CONNECT") != -1) //if (CDNetPPPConnect(vc_gprs, // "at+cgqreq=1,1,1,4,4,12:OK:at+cgqmin=1,2,1,4,2,3:OK:at+cgdcont=1,\"IP\",\"vfinternet.au\",,0,0:OK:atd*99*0*1*1#:CONNECT") // != -1) //if (CDNetPPPConnect(vc_gprs, // "at+cgqreq=1,1,1,4,4,12:OK:at+cgqmin=1,0,0,0,0,0:OK:at+cgdcont=1,\"IP\",\"yesintprv\",,0,0:OK:atd*99*0*1*1#:CONNECT") // != -1) // Min started at 1,3,3,5,1,1 // <Precedence> 3 = OK, 2 = OK, 1 = No Connect // <delay> 1 = OK, 3 = OK // <reliability> 2 = No Connect, 3 = No Connect, 4 = OK, 5 = OK // <peak> 1 = OK, 2 = OK, 3 = No Connect, 4 = No Connect // <mean> 1 = OK, 2 = OK, 3 = ??, 31 = OK(but no data) { NutPrintString_P (uart0,PSTR("Calling IFConfig\r\n")); NutPrintFlush(uart0); if (NutNetIfConfig("PPP0",uart1, 0,0)) { DisconnectCall(uart1); NutSleep(5000); } NutPrintString_P (uart0,PSTR("Finished IFConfig\r\n")); NutPrintFlush(uart0); } else { NutPrintString_P (uart0,PSTR("Could not configure phone\r\n")); NutPrintFlush(uart0); DisconnectCall(uart1); NutSleep(5000); } } NutThreadYield(); } }