Lab2_web / Mbed 2 deprecated webserverBlinky

Dependencies:   mbed

Fork of webserverBlinky by RealTimeCompLab2

Revision:
133:0f5b4085b6d3
Parent:
132:09b66cc5cf4a
Child:
134:af9d1f8d451d
--- a/main.cpp	Mon Aug 14 19:27:36 2017 +0000
+++ b/main.cpp	Wed Aug 16 11:08:43 2017 +0000
@@ -31,8 +31,10 @@
 // in the above command 172.10.10.1 is the adapter IP, and 172.10.10.2 is the IP of PPP-Blinky.
 // See also https://en.wikipedia.org/wiki/Point-to-Point_Protocol_daemon
 
-// To try the WebSocket, enter the following in your browser console:
-// var x = new WebSocket("ws://172.10.10.2"); x.onmessage=function(msg){console.log(msg.data);} ; x.send("Hello WebSocket World");
+// Special pages in PPP-Blinky
+// 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 brings up a simple websocket demo
 
 // Ok, enough talking, time to check out some code!!
 
@@ -43,7 +45,7 @@
 // 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.
 // Note - the LPC11U24 does NOT have a second serial port
-#define SERIAL_PORT_MONITOR_NO /* change to SERIAL_PORT_MONITOR_YES for debug messages */
+#define SERIAL_PORT_MONITOR_YES /* change to SERIAL_PORT_MONITOR_YES for debug messages */
 
 // here we define the OPTIONAL, second debug serial port for the various target boards
 // insert your target board's port here if it's not in yet - if it works, please send it to me - thanks!!!
@@ -81,6 +83,7 @@
 
 // this is the webpage we serve when we get an HTTP request to root (/)
 // keep size under ~900 bytes to fit into a single PPP packet
+
 const static char rootWebPage[] = "\
 <!DOCTYPE html>\
 <html>\
@@ -97,7 +100,44 @@
 <h1 id=\"w\" style=\"text-align:center;\">0</h1>\
 <h1><a href=\"http://bit.ly/pppBlink2\">Source on mbed</a></h1>\
 </body>\
-</html>"; // around 461 bytes long
+</html>"; // 460 characters plus 1 null byte = 461
+
+const static char webSocketPage[] = "\
+<!DOCTYPE html>\
+<html>\
+<head>\
+<title>mbed PPP-Blinky</title>\
+<script>\
+window.onload=function(){\
+ var url=\"ws://172.10.10.2\";\
+ var sts=document.getElementById(\"sts\");\
+ var btn=document.getElementById(\"btn\");\
+ var ctr=0;\
+ function show(text){sts.textContent=text;}\
+ btn.onclick=function(){\
+  if(btn.textContent==\"Connect\"){\
+   x=new WebSocket(url);\
+    x.onopen=function(){\
+    show(\"Connected to : \"+url);\
+    btn.textContent=\"Send \\\"\"+ctr+\"\\\"\";\
+   };\
+  x.onclose=function(){show(\"closed\");};\
+  x.onmessage=function(msg){show(\"PPP-Blinky Sent: \\\"\"+msg.data+\"\\\"\");};\
+  } else {\
+   x.send(ctr);\
+   ctr=ctr+1;\
+   btn.textContent=\"Send \\\"\"+ctr+\"\\\"\";\
+  }\
+ };\
+};\
+</script>\
+<body style=\"font-family: sans-serif; font-size:30px; color:#807070\">\
+<h4>PPP-Blinky WebSocket Test</h4>\
+<div id=\"sts\">Idle</div>\
+<button id=\"btn\" style=\"font-size: 100%; margin-top: 55px; margin-bottom: 55px;\">Connect</button>\
+<h4><a href=\"/\">PPP-Blinky home</a></h4>\
+</body>\
+</html>"; 
 
 // The serial port on your mbed hardware. Your PC should be configured to view this port as a standard dial-up networking modem.
 // On Windows the model type of the modem should be selected as "Communications cable between two computers"
@@ -331,12 +371,14 @@
 }
 
 void send_pppFrame()   // send a PPP frame in HDLC format
-{
+{   
     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)
     pcPutcWhileCheckingInput(0x7e); // hdlc start-of-frame "flag"
     for(int i=0; i<ppp.pkt.len; i++) {
+        wait_us(86); // wait one character time
+        fillbuf();
         hdlcPut( ppp.pkt.buf[i] ); // send a character
     }
     pcPutcWhileCheckingInput(0x7e); // hdlc end-of-frame "flag"
@@ -710,15 +752,17 @@
 
     int nHeader; // byte size of HTTP header
     int contentLengthStart; // index where HTML starts
-    int httpGetx, httpGetRoot; // temporary storage of strncmp results
+    int httpGet5,httpGet6,httpGetx, httpGetRoot; // temporary storage of strncmp results
 
     ppp.httpPageCount++; // 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
+    httpGet5    = dataStart[5]; // the first character in the path name, we use it for special functions later on
+    httpGet6    = dataStart[6]; // the second character in the path name, we use it for special functions later on
     // for example, you could try this using netcat (nc):    echo "GET /x" | nc 172.10.10.2
     if( (httpGetRoot==0) || (httpGetx==0) ) {
-        n=n+sprintf(n+dataStart,"HTTP/1.1 200 OK\r\nServer: mbed-PPP-Blinky\r\n"); // 200 OK header
+        n=n+sprintf(n+dataStart,"HTTP/1.1 200 OK\r\nServer: mbed-PPP-Blinky-v1\r\n"); // 200 OK header
     } else {
         n=n+sprintf(n+dataStart,"HTTP/1.1 404 Not Found\r\nServer: mbed-PPP-Blinky\r\n"); // 404 header
     }
@@ -731,7 +775,10 @@
     if( httpGetRoot == 0 ) {
         // this is where we insert our web page into the buffer
         memcpy(n+dataStart,rootWebPage,sizeof(rootWebPage));
-        n = n + sizeof(rootWebPage);
+        n = n + sizeof(rootWebPage)-1; // one less than sizeof because we don't count the null byte at the end
+    } else if ( (httpGet5 == 'w') && (httpGet6 == 's') ) { // "ws" is a special page for websocket demo
+        memcpy(n+dataStart,webSocketPage,sizeof(webSocketPage));
+        n = n + sizeof(webSocketPage)-1; // one less than size
     } else {
         if (httpGetx == 0) { // the page request started with "GET /x" - here we treat anything starting with /x special:
 
@@ -741,14 +788,11 @@
             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
 #else
-#define BENCHMARK_USING_BROWSER_NO /* set to _YES if you want to use your browser as a benchmark tool */
-#ifdef BENCHMARK_USING_BROWSER_YES
-            // semd a small browser script that will reload the page after 10 ms - handy for benchmarking with your web browser, use http://172.10.10.2/x
-            n=n+sprintf(n+dataStart, "<script>setTimeout(function(){location.reload();},10);</script><body>%d</body>",ppp.httpPageCount);
-#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 fast - most browsers and curl are ok with it
-#endif
+            n=n+sprintf(n+dataStart,"%d ",ppp.httpPageCount); // 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
@@ -896,11 +940,11 @@
     ppp.ip.ident++; // get next ident number for our packet
 
     // Now we recalculate all the header sizes
-    int newPacketSize = headerSizeIP + headerSizeTCP + dataLen; // calculate size of the outgoing packet
+    tcpSize = headerSizeTCP + dataLen; // tcp packet size
+    int newPacketSize = headerSizeIP + tcpSize; // calculate size of the outgoing packet
     pktLen[0] = (newPacketSize>>8);
     pktLen[1]=newPacketSize; // ip total packet size
-    ppp.pkt.len = newPacketSize+6; // ppp packet length
-    tcpSize = headerSizeTCP + dataLen; // tcp packet size
+    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
@@ -931,6 +975,7 @@
         wait_us(10); // wait less than 1 character duration at 115200
     }
     send_pppFrame(); // All preparation complete - send the TCP response
+    if(0) dumpPPPFrame(); // set to 1 to dump transmitted ppp frame
     memset(ppp.pkt.buf+44,0,500); // flush out traces of previous data that we may scan for
 }
 
@@ -1123,6 +1168,7 @@
     pc.baud(115200); // USB serial port to pc
     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
     while(1) {
         scanForConnectString(); // wait for connect from PC dial-up networking