Lab2_web / Mbed 2 deprecated webserverBlinky

Dependencies:   mbed

Fork of webserverBlinky by RealTimeCompLab2

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