Lab2_web / Mbed 2 deprecated webserverBlinky

Dependencies:   mbed

Fork of webserverBlinky by RealTimeCompLab2

Revision:
146:a45f49a2b29c
Parent:
145:098b6ed2f7f2
Child:
147:0f40005cbc5f
--- a/PPP-Blinky/ppp-blinky.cpp	Tue Aug 29 18:57:04 2017 +0000
+++ b/PPP-Blinky/ppp-blinky.cpp	Wed Aug 30 00:55:21 2017 +0000
@@ -32,7 +32,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/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/xb  also returns a number, but issues a fast refresh meta 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
 
@@ -41,9 +41,10 @@
 #include "ppp-blinky.h"
 
 // The #define below enables/disables a second (OPTIONAL) serial port that prints out interesting diagnostic messages.
-// Change to SERIAL_PORT_MONITOR_YES to enable diagnostics messages. You need to wire a second serial port to your mbed hardware to monitor this.
+// Change to SERIAL_PORT_MONITOR_YES to enable diagnostics messages. You need to wire a second serial port to your mbed hardware to monitor the debug output.
 // Using the second serial port will slow down packet response time
 // Note - the LPC11U24 does NOT have a second serial port
+
 #define SERIAL_PORT_MONITOR_NO /* change to SERIAL_PORT_MONITOR_YES for debug messages */
 
 // here we define the OPTIONAL, second debug serial port for various mbed target boards
@@ -86,12 +87,12 @@
 <!DOCTYPE html>\
 <html>\
 <head>\
-<title>mbed PPP-Blinky</title>\
-<script>\
+<title>mbed PPP-Blinky</title>\r\n\
+<script>\r\n\
 window.onload=function(){\
 setInterval(function(){function x(){return document.getElementById('w');};\
-x().textContent=parseInt(x().textContent)+1;},100);};\
-</script>\
+x().textContent=parseInt(x().textContent)+1;},100);};\r\n\
+</script>\r\n\
 </head>\
 <body style=\"font-family: sans-serif; font-size:20px; text-align:center; color:#807070\">\
 <h1>mbed PPP-Blinky Up and Running</h1>\
@@ -102,7 +103,7 @@
 <h1><a href=\"/xb\">Benchmark 2</a></h1>\
 <h1><a href=\"http://jsfiddle.net/d26cyuh2/\">JSFiddle Demo</a></h1>\
 </body>\
-</html>"; // size = 634 bytes plus 1 null byte = 635 bytes
+</html>\r\n"; // size = 644 bytes plus 1 null byte = 645 bytes
 
 const static char webSocketPage[] = "\
 <!DOCTYPE html>\
@@ -159,7 +160,7 @@
     int hostIP; // ip address of host
     int fcs; // PPP "frame check sequence" - a 16-bit HDLC-like checksum used in all PPP frames
     int ledState; // state of LED1
-    int httpPageCount;
+    int responseCounter;
     int firstFrame; // cleared after first frame
     struct {
 #define RXBUFLEN (1<<11)
@@ -201,7 +202,7 @@
     ppp.ip.ident=10000; // easy to recognize in ip packet dumps
     ppp.ledState=0;
     ppp.hdlc.frameStartIndex=0;
-    ppp.httpPageCount=0;
+    ppp.responseCounter=0;
     ppp.firstFrame=1;
 }
 
@@ -264,12 +265,6 @@
 #endif
 }
 
-/// a sniffer tool to assist in figuring out where in the code we are having characters in the input buffer
-void qq()
-{
-    if ( pc.readable() ) putsWhileCheckingInput( "Character available!\n" );
-}
-
 /// Initialize the PPP FCS (frame check sequence) total
 void fcsReset()
 {
@@ -442,12 +437,14 @@
 /// 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");
+    debugPrintf("Their IPCP Nack\n");
     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
         sendPppFrame(); // 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
+    } else { // if it's not an IP nack we ignore it
+        debugPrintf("IPCP Nack Ignored\n");
+    }
 }
 
 /// handle all other IPCP requests (by ignoring them)
@@ -475,55 +472,6 @@
     }
 }
 
-/// process an incoming UDP packet
-void UDPpacket()
-{
-    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
-    char * udpSrc = udpBlock; // source port
-    char * udpDst = udpBlock+2; // destination port
-    char * udpLen = udpBlock+4; // udp data length
-    char * udpCks = udpBlock+6; // udp checksum
-    char * srcIP = udpPkt+12; // udp src addr
-    char * dstIP = udpPkt+16; // udp dst addr
-    if (udpLen); // shut up compiler warning for unused udpLen
-#ifdef SERIAL_PORT_MONITOR_YES
-    int srcPort = (udpSrc[0]<<8) | udpSrc[1];
-    int dstPort = (udpDst[0]<<8) | udpDst[1];
-    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);
-    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) {
-                debugPrintf("%c", ch);
-            } else {
-                debugPrintf("_");
-            }
-        }
-    }
-    if (v0) debugPrintf("\n");
-#endif
-    if (strncmp(udpInf,"echo", 4)==0) { // if the UDP string starts with "echo" we echo it back
-        char tempHold[12]; // it's 12 long because we later reuse it when building the TCP pseudo-header
-        memcpy(tempHold, srcIP,4);
-        memcpy(srcIP, dstIP,4);
-        memcpy(dstIP, tempHold,4); // swap ip address source/dest
-        memcpy(tempHold, udpSrc,2);
-        memcpy(udpSrc, udpDst,2);
-        memcpy(udpDst, tempHold,2); // swap udp port source/dest
-        memcpy(udpInf,"Got:",4);
-        memset(udpCks,0,2); // we don't compute the checksum (it's optional), so have to zero it
-        sendPppFrame();
-    }
-}
-
 /// perform a 16-bit checksum. if the byte count is odd, stuff in an extra zero byte.
 unsigned int dataCheckSum(unsigned char * ptr, int len)
 {
@@ -550,12 +498,13 @@
 }
 
 /// perform the checksum on an IP header
-void headerCheckSum()
+void IpHeaderCheckSum()
 {
-    int len =(ppp.pkt.buf[4]&0xf)*4; // length of header in bytes
-    char * ptr = ppp.pkt.buf+4; // start of ip packet
+    ppp.pkt.buf[4+10]=0; // zero the checsum in the IP header
+    ppp.pkt.buf[4+11]=0; // zero the checksum in the IP header
+    int len =(ppp.pkt.buf[4]&0xf)*4; // length of IP header in bytes
+    char * ptr = ppp.pkt.buf+4; // start of IP packet
     int sum=0;
-
     for (int i=0; i<len/2; i++) {
         int hi = *ptr;
         ptr++;
@@ -567,8 +516,82 @@
     }
     sum = sum + (sum>>16);
     sum = ~sum;
-    ppp.pkt.buf[14]= (sum>>8);
-    ppp.pkt.buf[15]= (sum   );
+    ppp.pkt.buf[4+10]= (sum>>8);
+    ppp.pkt.buf[4+11]= (sum   );
+}
+
+/// Process an incoming UDP packet.
+/// If the packet starts with the string "echo " or "test" we echo back a special packet
+void UDPpacket()
+{
+    char * ipHeader     = ppp.pkt.buf+4; // udp packet start
+    char * ipSizeBuf    = ipHeader+2; // size of IP packet
+    char * srcIP        = ipHeader+12; // IP source
+    char * dstIP        = ipHeader+16; // IP destination
+    int headerSizeIP    = 4*(ipHeader[0]&0xf); // size of IP header
+    char * udpHeader    = ipHeader + headerSizeIP; // udp info start
+    char * udpSrcPort   = udpHeader+0; // source port
+    char * udpDstPort   = udpHeader+2; // destination port
+    char * udpLen       = udpHeader+4; // udp data length
+    char * udpCheckSum  = udpHeader+6; // udp checksum
+    char * udpData = udpHeader+8; // start of UDP data
+    int udpLength = ((udpLen[0]<<8) | udpLen[1]); // size of udp packet
+    int udpDataSize = udpLength - 8; // size of udp data
+    
+#ifdef SERIAL_PORT_MONITOR_YES
+    int udpSrc = (udpSrcPort[0]<<8)|udpSrcPort[1]; // integer of UDP source port
+    int udpDst = (udpDstPort[0]<<8)|udpDstPort[1]; // integer of UDP dest port
+    if(v0) debugPrintf("UDP %d.%d.%d.%d:%d ", srcIP[0],srcIP[1],srcIP[2],srcIP[3],udpSrc);
+    if(v0) debugPrintf("%d.%d.%d.%d:%d ",     dstIP[0],dstIP[1],dstIP[2],dstIP[3],udpDst);
+    if(v0) debugPrintf("Len %03d", udpLength);
+    if (v1) {
+        int printSize = udpLength-8;
+        if (printSize > 20) printSize = 20; // print only first 20 characters
+        for (int i=0; i<printSize; i++) {
+            char ch = udpData[i];
+            if (ch>31 && ch<127) {
+                debugPrintf("%c", ch);
+            } else {
+                debugPrintf("_");
+            }
+        }
+    }
+    if (v0) debugPrintf("\n");
+#endif
+    int echoFound = !strncmp(udpData,"echo ",5); // true if UDP message starts with "echo "
+    int testFound = !strncmp(udpData,"test" ,4); // true if UDP message starts with "test"
+    if ( (echoFound) || (testFound)) { // if the UDP message starts with "echo " or "test" we answer back
+        char tempHold[4];
+        memcpy(tempHold, srcIP,4);
+        memcpy(srcIP, dstIP,4);
+        memcpy(dstIP, tempHold,4); // swap ip address source/dest
+        memcpy(tempHold, udpSrcPort,2);
+        memcpy(udpSrcPort, udpDstPort,2);
+        memcpy(udpDstPort, tempHold,2); // swap udp port source/dest
+        if (echoFound) {
+            memcpy(udpData,"Got{",4); // in the UDP data modify "echo" to "Got:"
+            char endString[] = "} UDP Server: PPP-Blinky\n"; // an appendix
+            memcpy(udpData+udpLength-8,endString,sizeof(endString)-1); // add endstring size to the UDP message
+            udpDataSize = udpDataSize + sizeof(endString)-1; // update udp data size with the size of the appendix
+        }
+        if (testFound) {
+            char udpResponse[50];
+            int n = 0;
+            n = n+sprintf(udpResponse+n,"Response count %d\n",ppp.responseCounter++);
+            memcpy(udpData,udpResponse,n); // copy response to the UDP data area
+            udpDataSize = n; // new udp data size
+        }
+        udpLength = udpDataSize+8; // update udp packet length
+        int ipSize = headerSizeIP + udpLength; // update ip packet length
+        ppp.pkt.len = ipSize+2+4; // update ppp packet length
+        udpLen[0]    = udpLength>>8;
+        udpLen[1]    = udpLength; // update UDP length
+        ipSizeBuf[0] = ipSize>>8;
+        ipSizeBuf[1] = ipSize; // update IP length
+        IpHeaderCheckSum();  // update IP header checksum
+        memset(udpCheckSum,0,2); // we don't yet recompute the checksum (it's optional), so have to zero it
+        sendPppFrame(); // send the UDP message back
+    }
 }
 
 /// handle a PING ICMP (internet control message protocol) packet
@@ -606,10 +629,8 @@
         memcpy(dst, dstAdr,4);
         memcpy(srcAdr, dst,4);
         memcpy(dstAdr, src,4); // swap src & dest ip
-        char * chkSum = ipPkt+10;
-        chkSum[0]=0;
-        chkSum[1]=0;
-        headerCheckSum();  // new ip header checksum
+//        char * chkSum = ipPkt+10;
+        IpHeaderCheckSum();  // calculate new ip header checksum
 #define ICMP_TYPE_ECHO_REPLY 0
         icmpType[0]=ICMP_TYPE_ECHO_REPLY; // icmp echo reply
         icmpSum[0]=0;
@@ -816,7 +837,7 @@
     int contentLengthStart; // index where HTML starts
     int httpGet5,httpGet6,httpGetx, httpGetRoot; // temporary storage of strncmp results
 
-    ppp.httpPageCount++; // increment the number of frames we have made
+    ppp.responseCounter++; // increment the number of frames we have made
 
     httpGetRoot = strncmp(dataStart, "GET / HTTP/1.", 13);  // found a GET to the root directory
     httpGetx    = strncmp(dataStart, "GET /x", 6);          // found a GET to /x which we will treat special (anything starting with /x, e.g. /x, /xyz, /xABC?pqr=123
@@ -848,13 +869,13 @@
 // change the above to W3C_COMPLIANT_RESPONSE_YES if you want a W3C.org compliant HTTP response
 #ifdef W3C_COMPLIANT_RESPONSE_YES
             n=n+sprintf(n+dataStart,"<!DOCTYPE html><title>mbed PPP-Blinky</title>"); // html title (W3C.org required elements)
-            n=n+sprintf(n+dataStart,"<body>%d</body>",ppp.httpPageCount); // body = the http frame count
+            n=n+sprintf(n+dataStart,"<body>%d</body>",ppp.responseCounter); // body = the http frame count
 #else
             if( httpGet6 == 'b' ) { // if the fetched page is "xb" send a meta command to let the browser continuously reload
                 n=n+sprintf(n+dataStart, "<meta http-equiv=\"refresh\" content=\"0\">"); // reload loop - handy for benchmarking
             }
             // /x is a very short page, in fact, it is only a decimal number showing the http Page count
-            n=n+sprintf(n+dataStart,"%d ",ppp.httpPageCount); // not really valid html but most browsers and curl are ok with it
+            n=n+sprintf(n+dataStart,"%d ",ppp.responseCounter); // not really valid html but most browsers and curl are ok with it
 #endif
         } else {
             // all other requests get 404 Not Found response with a http frame count - nice for debugging
@@ -909,7 +930,7 @@
     char * pktLen =     ipPkt+2;  // 2 bytes
     char * ident =      ipPkt+4;  // 2 bytes
     char * protocol =   ipPkt+9;  // 1 byte
-    char * headercheck= ipPkt+10; // 2 bytes
+//    char * headercheck= ipPkt+10; // 2 bytes
     char * srcAdr =     ipPkt+12; // 4 bytes
     char * dstAdr =     ipPkt+16; // 4 bytes = total of 20 bytes
     int headerSizeIP = (ihl[0]&0xf)*4;
@@ -1012,9 +1033,7 @@
     ppp.pkt.len = newPacketSize+4+2; // ip packet length + 4-byte ppp prefix (ff 03 00 21) + 2 fcs (crc) bytes bytes at the end of the packet
 
     // the header is all set up, now do the IP and TCP checksums
-    headercheck[0]=0; // IP header checksum
-    headercheck[1]=0; // IP header checksum
-    headerCheckSum(); // calculate the IP header checksum
+    IpHeaderCheckSum(); // calculate new IP header checksum
 
     // now we have to build the so-called 12-byte TCP "pseudo-header" in front of the TCP header (containing some IP header values) in order to correctly calculate the TCP checksum
     // this header  contains the most important parts of the IP header, i.e. source and destination address, protocol number and data length.
@@ -1200,6 +1219,12 @@
     }
 }
 
+/// a sniffer tool to assist in figuring out where in the code we are having characters in the input buffer
+void sniff()
+{
+    if ( pc.readable() ) putsWhileCheckingInput( "Sniff - Char available!\n" ); // if this prints anything it means there is a character in the serial receive buffer
+}
+
 /// scan the PPP serial input stream for frame start markers
 void waitForPppFrame()
 {