Lab2_web / Mbed 2 deprecated webserverBlinky

Dependencies:   mbed

Fork of webserverBlinky by RealTimeCompLab2

Revision:
85:53e57ff1cf05
Parent:
84:456e73151f11
Child:
87:9f5ac1fabd95
diff -r 456e73151f11 -r 53e57ff1cf05 main.cpp
--- a/main.cpp	Tue Jul 18 01:01:10 2017 +0000
+++ b/main.cpp	Thu Jul 20 01:01:07 2017 +0000
@@ -32,7 +32,20 @@
 #define SERIAL_PORT_MONITOR_NO /* or change to SERIAL_PORT_MONITOR_YES */
 
 #ifndef SERIAL_PORT_MONITOR_NO
-Serial xx(PC_10, PC_11); // Not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO
+
+// here we define the debug serial port for the various target boards
+// add yours if it's not in here
+#if TARGET_LPC1768
+Serial xx(p9, p10); // Second serial port on LPC1768 - not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO
+#elif TARGET_NUCLEO_F446RE
+Serial xx(PC_10, PC_11); // Second serial port on NUCLEO boards - not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO
+#elif TARGET_NUCLEO_L152RE
+Serial xx(PC_10, PC_11); // Second serial port on NUCLEO boards - not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO
+#else
+#error Add your target board's second serial port here if you want to use debugging - or choose SERIAL_PORT_MONITOR_NO
+#endif
+
+
 #define debug(x...) xx.printf (x)
 #else
 #define debug(x...) {}
@@ -91,7 +104,7 @@
     int httpFrame;
     struct {
 #define RXBUFLEN (1<<14)
-        char buf[RXBUFLEN]; // RXBUFLEN MUST be a power of two because we use & operator for fast wrap-around in rxHandler
+        char buf[RXBUFLEN]; // RXBUFLEN MUST be a power of two because we use & operator for fast wrap-around in ring buffer
         //char * buf;
         volatile int head;
         volatile int tail;
@@ -118,10 +131,8 @@
 {
     memset( ppp.rx.buf, 0, RXBUFLEN);
     ppp.online=0;
-    __disable_irq();
     ppp.rx.tail=0;
     ppp.rx.head=0;
-    __enable_irq();
     ppp.rx.buflevel=0;
     ppp.pkt.len=0;
     ppp.ident=1000;
@@ -157,13 +168,15 @@
     return ppp.crc;
 }
 
-void rxHandler() // serial port receive interrupt handler
+
+// fill our own receive buffer with characters from the PPP serial port
+void fillbuf()
 {
-    while ( pc.readable() ) {
-        int hd = (ppp.rx.head+1)&(RXBUFLEN-1); // increment/wrap
+    if ( pc.readable() ) {
+        int hd = (ppp.rx.head+1)&(RXBUFLEN-1); // increment/wrap head index
         if ( hd == ppp.rx.tail ) {
-            debug("Receive buffer is full. ppp.rx.buflevel = %d\n",ppp.rx.buflevel);
-            break; // watch for buffer full
+            debug("\nReceive buffer full\n");
+            return;
         }
         ppp.rx.buf[ppp.rx.head]=pc.getc(); // insert in rx buffer
         ppp.rx.head = hd; // update head pointer
@@ -171,15 +184,13 @@
     }
 }
 
-int rxbufNotEmpty() // check if rx buffer has data
+int rxbufNotEmpty()   // check if rx buffer has data
 {
-    __disable_irq(); // critical section start
     int emptyStatus = (ppp.rx.head==ppp.rx.tail) ? 0 : 1 ;
-    __enable_irq(); // critical section end
     return emptyStatus;
 }
 
-int pc_getBuf() // get one character from the buffer
+int pc_getBuf()   // get one character from the buffer
 {
     int x = ppp.rx.buf[ ppp.rx.tail ];
     ppp.rx.tail=(ppp.rx.tail+1)&(RXBUFLEN-1);
@@ -222,7 +233,7 @@
         void determinePacketType(); // declaration only
         determinePacketType();
     } else if (v0) {
-        debug("PPP FCS(crc) Error CRC=%x Length = %d\n",ppp.pkt.crc,ppp.pkt.len); // ignore packets with CRC errors but print a debug line
+        // debug("PPP FCS(crc) Error CRC=%x Length = %d\n",ppp.pkt.crc,ppp.pkt.len); // ignore packets with CRC errors but print a debug line
     }
 }
 
@@ -245,7 +256,7 @@
     }
 }
 
-void sendFrame() // send a PPP frame in HDLC format
+void sendFrame()   // 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)
@@ -491,9 +502,12 @@
 
     char srcIP [16];
     snprintf(srcIP,16, "%d.%d.%d.%d", srcAdr[0],srcAdr[1],srcAdr[2],srcAdr[3]);
+    fillbuf();
     char dstIP [16];
     snprintf(dstIP,16, "%d.%d.%d.%d", dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]);
+    fillbuf();
     if (v0) debug("IP %s %s v%d h%d d%d e%d L%03d ",srcIP,dstIP,versionIP,headerSizeIP,dscpIP,ecnIP,packetLength);
+    fillbuf();
     if (v0) debug("i%04x f%d t%d p%d C%04x\n",identIP,flagsIP,ttlIP,protocolIP,checksumIP);
 }
 
@@ -536,9 +550,9 @@
     int n=0; // number of bytes we have printed so far
     int nHeader; // byte size of HTTP header
     int contentLengthStart; // index where HTML starts
-    
+
     ppp.httpFrame++; // increment count of response frames
-    
+
     int rootFetch = strncmp(dataStart, "GET / HTTP/1.1", 14);
 
     if( rootFetch == 0 ) {
@@ -546,7 +560,7 @@
     } else {
         n=n+sprintf(n+dataStart,"HTTP/1.1 404 Not Found\r\nServer: PPP-Blinky\r\n"); // http header
     }
-    
+
     n=n+sprintf(n+dataStart,"Content-Length: "); // http header
     contentLengthStart = n; // remember where Content-Length is in buffer
     n=n+sprintf(n+dataStart,"?????\r\n"); // leave five spaces for content length - will be updated later
@@ -557,12 +571,12 @@
     if( rootFetch == 0 ) {
         // this is where we insert our web page into the buffer
         n=n+sprintf(n+dataStart,"%s", ourWebPage);
-    } else { 
+    } else {
         // all other requests get 404 Not Found response a
         n=n+sprintf(n+dataStart,"<!DOCTYPE html>"); // html start
         n=n+sprintf(n+dataStart,"<title>%06d</title>",ppp.httpFrame); // shortest possible valid frame
     }
-    
+
     while( (n%4)!= 2)
         n=n+sprintf(n+dataStart," "); // insert spaces until n is exactly two away from a multiple of four
     n=n+sprintf(n+dataStart,"\r\n");  // add the last \r\n sequence - n is now an exact multiple of four
@@ -610,8 +624,11 @@
     char * dataStart = ppp.pkt.buf + 4 + headerSizeIP + headerSizeTCP; // start of data block after TCP header
     int tcpDataSize = tcpSize - headerSizeTCP; // size of data block after TCP header
 
-    unsigned int ack = (seqtcp[0]<<24)|(seqtcp[1]<<16)|(seqtcp[2]<<8)|(seqtcp[3]) + tcpDataSize;
-    unsigned int seq = (acktcp[0]<<24)|(acktcp[1]<<16)|(acktcp[2]<<8)|(acktcp[3]); // use their idea of our seq
+    unsigned int seq_in = (seqtcp[0]<<24)|(seqtcp[1]<<16)|(seqtcp[2]<<8)|(seqtcp[3]);
+    unsigned int ack_in = (acktcp[0]<<24)|(acktcp[1]<<16)|(acktcp[2]<<8)|(acktcp[3]);
+
+    unsigned int ack_out = seq_in + tcpDataSize;
+    unsigned int seq_out = ack_in; // ack_in is their calculation of our current sequence number
 
 
 #define TCP_FLAG_ACK (1<<4)
@@ -629,22 +646,17 @@
     // This strategy allows web browsers, netcat and curl to work ok while keeping the state machine simple
 
     switch ( flagsTCP ) {
-        case TCP_FLAG_ACK:
-            if ( tcpDataSize != 1 ) return;
-            ack++;
         case TCP_FLAG_SYN:
-            // ignore all TCP options by shortening packet to 40 bytes
-            pktLen[1] = 40; // shorten packet to 40 bytes
-            packetLength = 40; // shorten packet to 40 bytes
-            headerSizeTCP = 20; // shorten packet to 40 bytes
-            tcpSize = 20; // shorten packet to 40 bytes
-            headerSizeTCP = 20; // shorten packet to 40 bytes
-            offset[0] =  (headerSizeTCP/4)<<4; // shorten packet to 40 bytes
-
-            flagsOut = TCP_FLAG_SYN | TCP_FLAG_ACK; // something wants to connect - ack it
-            ppp.seq = ppp.seq + 10000; // create a new sequence number (normally random)
-            seq = ppp.seq; // create a new sequence number (normally random)
-            ack++; // for SYN flag we have to increase their sequence by 1
+            ack_out++; // for SYN flag we have to increase the sequence by 1
+            // ignore all TCP option requests by shortening the TCP header to 20 bytes
+            headerSizeTCP = 20; // shorten TCP header size 20 bytes
+            offset[0] =  (headerSizeTCP/4)<<4; // shorten tcp header size to 20 bytes
+            tcpSize = 20; // shorten total TCP packet size to 20 bytes (no data)
+            packetLength = 40; // shorten total packet size to 40 bytes (20 ip + 20 tcp)
+            pktLen[1] = 40; // shorten total packet size to 40 bytes (20 ip + 20 tcp)
+            flagsOut = TCP_FLAG_SYN | TCP_FLAG_ACK; // something wants to connect - acknowledge it
+            //ppp.seq = ppp.seq + 10000; // create a new sequence number (normally random)
+            seq_out = 10+((seq_in+1)/10)*10; //ppp.seq; // create a new sequence number (normally random)
             break;
         case TCP_FLAG_ACK | TCP_FLAG_PSH:
             flagsOut = TCP_FLAG_ACK | TCP_FLAG_FIN; // for every push we answer once AND close the link
@@ -654,14 +666,14 @@
                 while((dataLen %4 ) !=0) { // dataLen must be a multiple of four
                     dataLen++; // must be a multiple of four
                     dataStart[dataLen-1]=0; // clear the byte in the buffer
-                    ack++;
+                    ack_out++;
                 }
             }
             break;
         case TCP_FLAG_FIN:
         case TCP_FLAG_FIN | TCP_FLAG_ACK:
         case TCP_FLAG_FIN | TCP_FLAG_ACK | TCP_FLAG_PSH:
-            ack++; // for FIN flag we have to increase sequence by 1
+            ack_out++; // for FIN flag we always have to increase sequence by 1
             break;
         default:
             return; // ignore remaining packets
@@ -684,18 +696,18 @@
     memcpy(srctcp, dsttcp,2);
     memcpy(dsttcp, tempHold,2); // swap ip port source/dest
 
-    windowsizetcp[0]=16; // ignore window size negotiation
+    windowsizetcp[0]=2; // ignore window size negotiation
     windowsizetcp[1]=0; // ignore winodw size negotiation
 
-    acktcp[0]=ack>>24;
-    acktcp[1]=ack>>16;
-    acktcp[2]=ack>>8;
-    acktcp[3]=ack>>0; // save ack 32-bit integer
+    acktcp[0]=ack_out>>24;
+    acktcp[1]=ack_out>>16;
+    acktcp[2]=ack_out>>8;
+    acktcp[3]=ack_out>>0; // save ack 32-bit integer
 
-    seqtcp[0]=seq>>24;
-    seqtcp[1]=seq>>16;
-    seqtcp[2]=seq>>8;
-    seqtcp[3]=seq>>0; // save seq 32-bit integer
+    seqtcp[0]=seq_out>>24;
+    seqtcp[1]=seq_out>>16;
+    seqtcp[2]=seq_out>>8;
+    seqtcp[3]=seq_out>>0; // save seq 32-bit integer
 
     flagbitstcp[1] = flagsOut; // set up the new flags
 
@@ -798,7 +810,7 @@
 {
     debug("LCP Config ");
     if (ppp.pkt.buf[7] != 4) {
-        ppp.pkt.buf[4]=4; // allow only no options
+        ppp.pkt.buf[4]=4; // allow only "no options" which means Maximum Receive Unit (MRU) is 1500 bytes
         debug("Reject\n");
         sendFrame();
     } else {
@@ -888,7 +900,8 @@
 
 void wait_for_HDLC_frame()
 {
-    while(1)
+    while(1) {
+        fillbuf();
         if ( rxbufNotEmpty() ) {
             int oldTail = ppp.rx.tail; // remember where the character is located in the buffer
             int rx = pc_getBuf(); // get the character
@@ -905,11 +918,13 @@
                 }
             }
         }
+    }
 }
 
 void scanForConnectString()
 {
     while(ppp.online == 0) {
+        fillbuf();
         // search for Windows Dialup Networking "Direct Connection Between Two Computers" expected connect string
         char * found1 = strstr( (char *)ppp.rx.buf, "CLIENTCLIENT" );
         // also search for HDLC frame start character 0x7e
@@ -940,7 +955,6 @@
     pppInitStruct(); // initialize all the PPP properties
     ppp.seq=1000; // initial TCP sequence number
 
-    pc.attach(&rxHandler,Serial::RxIrq); // start the receive handler
     while(1) {
         scanForConnectString(); // respond to connect command from windows dial up networking
         while(ppp.online) {