Lab2_web / Mbed 2 deprecated webserverBlinky

Dependencies:   mbed

Fork of webserverBlinky by RealTimeCompLab2

Revision:
87:9f5ac1fabd95
Parent:
85:53e57ff1cf05
Child:
88:b4a71242837c
diff -r 4186c46d968a -r 9f5ac1fabd95 main.cpp
--- a/main.cpp	Thu Jul 20 01:03:13 2017 +0000
+++ b/main.cpp	Fri Jul 21 00:35:24 2017 +0000
@@ -97,11 +97,11 @@
 // a structure to keep all our ppp globals in
 struct pppType {
     int online; // we hunt for a PPP connection if this is zero
-    int ident; // our IP ident value
+    unsigned int ident; // our IP ident value
     unsigned int seq; // our TCP sequence number
     int crc; // for calculating IP and TCP CRCs
     int ledState; // state of LED1
-    int httpFrame;
+    int httpFrameCount;
     struct {
 #define RXBUFLEN (1<<14)
         char buf[RXBUFLEN]; // RXBUFLEN MUST be a power of two because we use & operator for fast wrap-around in ring buffer
@@ -139,7 +139,7 @@
     ppp.ledState=0;
     ppp.hdlc.frameFound=0;
     ppp.hdlc.frameStartIndex=0;
-    ppp.httpFrame=0;
+    ppp.httpFrameCount=0;
 }
 
 void led1Toggle()
@@ -551,7 +551,7 @@
     int nHeader; // byte size of HTTP header
     int contentLengthStart; // index where HTML starts
 
-    ppp.httpFrame++; // increment count of response frames
+    ppp.httpFrameCount++; // increment the number of frames we have made
 
     int rootFetch = strncmp(dataStart, "GET / HTTP/1.1", 14);
 
@@ -572,14 +572,14 @@
         // this is where we insert our web page into the buffer
         n=n+sprintf(n+dataStart,"%s", ourWebPage);
     } 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
+        // all other requests get 404 Not Found response with a http frame count - nice for debugging
+        n=n+sprintf(n+dataStart,"<!DOCTYPE html><title>ppp-blinky</title>"); // html start
+        n=n+sprintf(n+dataStart,"<body>%06d</body>",ppp.httpFrameCount); // body = the http frame count
     }
 
-    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
+    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 two characters (\r\n) - n is now an exact multiple of four
+
 #define CONTENTLENGTHSIZE 5
     char contentLengthString[CONTENTLENGTHSIZE+1];
     snprintf(contentLengthString,CONTENTLENGTHSIZE+1,"%*d",CONTENTLENGTHSIZE,n-nHeader); // print Content-Length with leading spaces and fixed width equal to csize
@@ -594,6 +594,8 @@
 
 void tcpHandler()
 {
+    // IP header
+
     char * ipPkt = ppp.pkt.buf+4; // ip packet start
     char * ihl =        ipPkt;    // bottom 4 bits
     char * pktLen =     ipPkt+2;  // 2 bytes
@@ -605,30 +607,31 @@
     int headerSizeIP = (ihl[0]&0xf)*4;
     int packetLength = (pktLen[0]<<8)|pktLen[1]; // ip total packet length
 
-    char * s             = ppp.pkt.buf+4+headerSizeIP; // start of tcp packet
-    char * srctcp        = s + 0;  // 2 bytes
-    char * dsttcp        = s + 2;  // 2 bytes
-    char * seqtcp        = s + 4;  // 4 bytes
-    char * acktcp        = s + 8;  // 4 bytes
-    char * offset        = s + 12; // 4 bits
-    char * flagbitstcp   = s + 12; // 9 bits
-    char * windowsizetcp = s + 14; // 2 bytes
-    char * checksumtcp   = s + 16; // 2 bytes
+    // TCP header
+
+    char * tcp             = ppp.pkt.buf+4+headerSizeIP; // start of tcp packet
+    char * srctcp        = tcp + 0;  // 2 bytes
+    char * dsttcp        = tcp + 2;  // 2 bytes
+    char * seqtcp        = tcp + 4;  // 4 bytes
+    char * acktcp        = tcp + 8;  // 4 bytes
+    char * offset        = tcp + 12; // 4 bits
+    char * flagbitstcp   = tcp + 12; // 9 bits
+    char * windowsizetcp = tcp + 14; // 2 bytes
+    char * checksumtcp   = tcp + 16; // 2 bytes
 
     int tcpSize = packetLength - headerSizeIP;
     int headerSizeTCP = ((offset[0]>>4)&0x0f)*4; // size of tcp header only
     int protocolIP = protocol[0];
 
-    int flagsTCP = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1];
-
-    char * dataStart = ppp.pkt.buf + 4 + headerSizeIP + headerSizeTCP; // start of data block after TCP header
+    char * tcpDataIn = tcp + headerSizeTCP; // start of data block after TCP header
     int tcpDataSize = tcpSize - headerSizeTCP; // size of data block after TCP header
+    char * tcpDataOut = tcp + 20; // start of outgoing data
 
     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
+    unsigned int seq_out = ack_in; // use their version of our current sequence number
 
 
 #define TCP_FLAG_ACK (1<<4)
@@ -637,9 +640,19 @@
 #define TCP_FLAG_RST (1<<2)
 #define TCP_FLAG_FIN (1<<0)
 
+    // first we shorten the TCP response header to only 20 bytes.
+    // this means we ignore all TCP option requests
+
+    tcpSize = 20; // shorten total TCP packet size to 20 bytes (no data)
+    headerSizeTCP = 20; // shorten outgoing TCP header size 20 bytes
+    offset[0] =  (headerSizeTCP/4)<<4; // shorten tcp header size to 20 bytes
+    packetLength = 40; // shorten total packet size to 40 bytes (20 ip + 20 tcp)
+    pktLen[1] = 40; // set total packet size to 40 bytes (20 ip + 20 tcp)
+    pktLen[0] =  0; // set total packet size to 40 bytes (20 ip + 20 tcp)
+
     int dataLen = 0; // most of our responses will have zero TCP data, only a header
     int flagsOut = TCP_FLAG_ACK; // the default case is an ACK packet
-    int fastResponse = 0; // normally you wait 200ms before sending a packet but this can make it faster
+    int flagsTCP = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1]; // the tcp flags we received
 
     // A sparse TCP flag interpreter that implements simple TCP connections from a single source
     // Clients are allowed ONE push packet, after which the link is closed with a FIN flag in the ACK packet
@@ -647,32 +660,18 @@
 
     switch ( flagsTCP ) {
         case TCP_FLAG_SYN:
+            flagsOut = TCP_FLAG_SYN | TCP_FLAG_ACK; // something wants to connect - acknowledge it
+            seq_out = seq_in+0x1000U; // create a new sequence number using their sequence as a base
             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
-            fastResponse = 1; // we can respond fast to a push
-            if ( strncmp(dataStart, "GET ", 4) == 0) { // do we see an http GET command
-                dataLen = httpResponse(dataStart); // send an http response
-                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_out++;
-                }
+            if ( strncmp(tcpDataIn, "GET ", 4) == 0) { // check for an http GET command
+                dataLen = httpResponse(tcpDataOut); // send an http response
             }
             break;
         case TCP_FLAG_FIN:
         case TCP_FLAG_FIN | TCP_FLAG_ACK:
-        case TCP_FLAG_FIN | TCP_FLAG_ACK | TCP_FLAG_PSH:
             ack_out++; // for FIN flag we always have to increase sequence by 1
             break;
         default:
@@ -683,7 +682,7 @@
     // The TCP flag handling is now done
     // Now we have to recalculate all the header sizes, swap IP address/port source and destination, and do the IP and TCP checksums
 
-    ppp.ident++; //
+    ppp.ident++; // get next ident number for our packet
     ident[0] = ppp.ident>>8;
     ident[1] = ppp.ident>>0; // insert OUR ident
 
@@ -696,7 +695,7 @@
     memcpy(srctcp, dsttcp,2);
     memcpy(dsttcp, tempHold,2); // swap ip port source/dest
 
-    windowsizetcp[0]=2; // ignore window size negotiation
+    windowsizetcp[0]=4; // ignore window size negotiation
     windowsizetcp[1]=0; // ignore winodw size negotiation
 
     acktcp[0]=ack_out>>24;
@@ -726,7 +725,7 @@
     // 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.
 
-    char * pseudoHeader = s-12; // mark the start of the TCP pseudo-header
+    char * pseudoHeader = tcp-12; // mark the start of the TCP pseudo-header
     memcpy(tempHold, pseudoHeader, 12); // preserve the 12 bytes of the IP header where the TCP pseudo-Header will be built
     memcpy( pseudoHeader+0, srcAdr, 8); // IP source and destination addresses from IP header
     memset( pseudoHeader+8, 0, 1); // reserved, set to zero
@@ -741,15 +740,8 @@
     unsigned int pseudoHeaderSum=dataCheckSum((unsigned char *)pseudoHeader,tcpSize+12); // calculate the TCP checksum starting at the pseudo-header
     checksumtcp[0]=pseudoHeaderSum>>8;
     checksumtcp[1]=pseudoHeaderSum;
-    memcpy( s-12, tempHold, 12); // restore the 12 bytes that the pseudo-header overwrote
+    memcpy( tcp-12, tempHold, 12); // restore the 12 bytes that the pseudo-header overwrote
 
-    if (fastResponse==1) {
-        fastResponse=0; // reset and skip 200 ms wait
-    } else {
-        // normally, you wait 200 ms before responding to a TCP packet
-        // remove the wait to respond faster
-        // wait(0.2);
-    }
     sendFrame(); // All preparation complete - send the TCP response
     dumpHeaderIP();
     dumpHeaderTCP();