Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of webserverBlinky by
Diff: PPP-Blinky/ppp-blinky.cpp
- Revision:
- 143:c5019f856a56
- Parent:
- 142:54d1543e23e5
- Child:
- 144:01d98cf7738e
--- a/PPP-Blinky/ppp-blinky.cpp Mon Aug 28 18:47:48 2017 +0000 +++ b/PPP-Blinky/ppp-blinky.cpp Tue Aug 29 17:26:42 2017 +0000 @@ -31,7 +31,7 @@ // Special pages when PPP-Blinky is running // 172.10.10.2 root page -// 172.10.10.2/x returns a number that increments every time you request a page - this is handy for testing +// 172.10.10.2/x returns a number that increments every time you request a page - this is handy for testing // 172.10.10.2/xb also returns a number, but issues a fast refresh command. This allows you to use your browser to benchmark page load speed // 172.10.10.2/ws a simple WebSocket demo // http://jsfiddle.net/d26cyuh2/ more complete WebSocket demo in JSFiddle @@ -156,6 +156,7 @@ /// a structure to keep all our ppp globals in struct pppType { int online; // we hunt for a PPP connection if this is zero + int hostIP; // ip address of host int crc; // for calculating IP and TCP CRCs int ledState; // state of LED1 int httpPageCount; @@ -208,7 +209,7 @@ void led1Toggle() { led1 = (ppp.ledState >> 1) & 1; // use second bit, in other words toggle LED only every second packet - ppp.ledState++; + ppp.ledState++; } @@ -216,9 +217,10 @@ int connected() { return ppp.online; -} +} -/// check for available characters from the PC and read them into our own circular serial receive buffer at ppp.rx.buf +/// Check for available characters from the PC and read them into our own circular serial receive buffer at ppp.rx.buf. +/// Also, if we are offline and a 0x7e frame start character is seen, we go online immediately void checkPc() { char ch; @@ -378,7 +380,7 @@ } /// do PPP HDLC-like handling of special (flag) characters -void hdlcPut(int ch) +void hdlcPut(int ch) { if ( (ch<0x20) || (ch==0x7d) || (ch==0x7e) ) { pcPutcWhileCheckingInput(0x7d); @@ -389,8 +391,8 @@ } /// send a PPP frame in HDLC format -void send_pppFrame() -{ +void send_pppFrame() +{ int crc = crcBuf(ppp.pkt.buf, ppp.pkt.len-2); // update crc ppp.pkt.buf[ ppp.pkt.len-2 ] = (~crc>>0); // fcs lo (crc) ppp.pkt.buf[ ppp.pkt.len-1 ] = (~crc>>8); // fcs hi (crc) @@ -403,10 +405,23 @@ pcPutcWhileCheckingInput(0x7e); // hdlc end-of-frame "flag" } +/// convert a network ip address in the buffer to an integer (IP adresses are big-endian, i.e most significant byte first) +int bufferToIP(char * buffer) +{ + int result=0; + for(int i=0; i<4; i++) result = (result<<8)|(*buffer++ & 0xff); + return result; +} + /// handle IPCP configuration requests void ipcpConfigRequestHandler() { debugPrintf("Their IPCP Config Req, Our Ack\n"); + if(ppp.pkt.buf[8]==3) { + ppp.hostIP = bufferToIP(ppp.pkt.buf+10); + debugPrintf("Host IP = %d.%d.%d.%d (%08x)\n", ppp.pkt.buf[10],ppp.pkt.buf[11],ppp.pkt.buf[12],ppp.pkt.buf[13],ppp.hostIP); + } + ppp.pkt.buf[4]=2; // change code to ack send_pppFrame(); // acknowledge everything they ask for - assume it's IP addresses @@ -423,13 +438,15 @@ debugPrintf("Their IPCP Grant\n"); } -/// handle IPCP NACK by sending our suggested IP address if there is an IP involved +/// Handle IPCP NACK by sending our suggested IP address if there is an IP involved. +/// This is how Linux responds to an IPCP request with no options - Windows assumes any IP address on the submnet is OK. void ipcpNackHandler() { - debugPrintf("Their IPCP Nack, Our ACK\n"); + debugPrintf("Their IPCP Nack"); if (ppp.pkt.buf[8]==3) { // check if the NACK contains an IP address parameter ppp.pkt.buf[4]=1; // assume the NACK contains our "suggested" IP address send_pppFrame(); // let's request this IP address as ours + debugPrintf("Our IPCP ACK (received an IP)\n"); } // if it's not an IP nack we ignore it } @@ -464,26 +481,22 @@ char * udpPkt = ppp.pkt.buf+4; // udp packet start int headerSizeIP = (( udpPkt[0]&0xf)*4); char * udpBlock = udpPkt + headerSizeIP; // udp info start + char * udpInf = udpBlock+8; // actual start of info #ifdef SERIAL_PORT_MONITOR_YES char * udpSrc = udpBlock; // source port char * udpDst = udpBlock+2; // destination port -#endif char * udpLen = udpBlock+4; // udp data length - char * udpInf = udpBlock+8; // actual start of info -#ifdef SERIAL_PORT_MONITOR_YES + char * srcIP = udpPkt+12; // udp src addr + char * dstIP = udpPkt+16; // udp dst addr int srcPort = (udpSrc[0]<<8) | udpSrc[1]; int dstPort = (udpDst[0]<<8) | udpDst[1]; - char * srcIP = udpPkt+12; // udp src addr - char * dstIP = udpPkt+16; // udp dst addr -#endif -#define UDP_HEADER_SIZE 8 - int udpLength = ((udpLen[0]<<8) | udpLen[1]) - UDP_HEADER_SIZE; // size of the actual udp data + int udpLength = ((udpLen[0]<<8) | udpLen[1]) - 8; // size of the actual udp data if(v0) debugPrintf("UDP %d.%d.%d.%d:%d ", srcIP[0],srcIP[1],srcIP[2],srcIP[3],srcPort); if(v0) debugPrintf("%d.%d.%d.%d:%d ", dstIP[0],dstIP[1],dstIP[2],dstIP[3],dstPort); if(v0) debugPrintf("Len %03d", udpLength); - int printSize = udpLength; - if (printSize > 20) printSize = 20; // print only first 20 characters if (v1) { + int printSize = udpLength; + if (printSize > 20) printSize = 20; // print only first 20 characters for (int i=0; i<printSize; i++) { char ch = udpInf[i]; if (ch>31 && ch<127) { @@ -494,6 +507,8 @@ } } if (v0) debugPrintf("\n"); +#endif + if (strncmp(udpInf,"echo ", 5) == 5) debugPrintf("echo found\n"); } /// perform a 16-bit checksum. if the byte count is odd, stuff in an extra zero byte. @@ -712,7 +727,7 @@ #endif } -/// +/// Encode a buffer in base-64 void enc64(char * in, char * out, int len) { const static char lut [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; @@ -1099,14 +1114,14 @@ debugPrintf("LCP Ack\n"); } -/// handle LCP end packets by acknowledging them and by setting ppp.online to false +/// handle LCP end (disconnect) packets by acknowledging them and by setting ppp.online to false void LCPend() { ppp.pkt.buf[4]=6; send_pppFrame(); // acknowledge ppp.online=0; // start hunting for connect string again pppInitStruct(); // flush the receive buffer - debugPrintf("LCP End\n"); + debugPrintf("LCP End (Disconnect from host)\n"); } /// respond to other LCP requests by ignoring them @@ -1173,7 +1188,7 @@ } /// scan the PPP serial input stream for frame start markers -void waitForPppFrame() +void waitForPppFrame() { while(1) { checkPc(); // handle received characters @@ -1206,7 +1221,7 @@ char * found1 = strstr( (char *)ppp.rx.buf, "CLIENT" ); if (found1 != NULL) { // respond with Windows Dialup networking expected "Direct Connection Between Two Computers" response string - if (v0) debugPrintf("Found connect string \"CLIENT\", sent \"CLIENTSERVER\"\n"); + if (v0) debugPrintf("Connected: Found connect string \"CLIENT\", sent \"CLIENTSERVER\"\n"); pc.puts("CLIENTSERVER"); ppp.online=1; // we are connected - set flag so we stop looking for the connect string checkPc(); @@ -1221,7 +1236,7 @@ debugBaudRate(115200); // baud rate for our (optional) debug port debugPrintf("\x1b[2J\x1b[H\x1b[30mmbed PPP-Blinky HTTP & WebSocket server ready :)\n"); // VT100 codes for clear_screen, home, black_text - Tera Term is a handy VT100 terminal pppInitStruct(); // initialize all the PPP properties -} +} /* /// initialize, wait for the connect message, then start processing PPP frames