RealtimeCompLab2

Dependencies:   mbed

Fork of PPP-Blinky by Nicolas Nackel

Revision:
77:abf92baebb42
Parent:
76:00e208cceb8b
Child:
78:809c2631a5eb
--- a/main.cpp	Wed Jul 05 20:05:42 2017 +0000
+++ b/main.cpp	Sat Jul 08 10:10:12 2017 +0000
@@ -42,6 +42,8 @@
 #define v0 1
 // verbosity flag used in debug printouts - change to 0 to see less debug info. Lots of interesting info.
 #define v1 1
+// verbosity flag used in debug printouts - change to 0 to see less debug info. Lots of interesting info.
+#define v2 0
 
 // this is the webpage we serve when we get an HTTP request
 // keep size under 900 bytes to fit into a single frame
@@ -97,7 +99,8 @@
         int len; // number of bytes in buffer
         int crc; // PPP CRC (frame check)
         //char * buf; // the actual buffer
-        char buf[3300]; // send and receive buffer large enough for unstuffed (decoded) hdlc frames
+#define TCP_max_size 3300
+        char buf[TCP_max_size]; // send and receive buffer large enough for unstuffed (decoded) hdlc frames
     } pkt; // ppp buffer objects
     struct {
         int frameStartIndex; // frame start marker
@@ -333,7 +336,7 @@
 
 unsigned int dataCheckSum(unsigned char * ptr, int len)
 {
-    
+
     unsigned int sum=0;
     unsigned char placeHolder;
     if (len&1) {
@@ -394,7 +397,7 @@
         int icmpIdent = (icmpType[4]<<8)|icmpType[5];
         int icmpSequence = (icmpType[6]<<8)|icmpType[7];
 #endif
-        debug("ICMP PING %d.%d.%d.d %d.%d.%d.%d ", srcAdr[0],srcAdr[1],srcAdr[2],srcAdr[3],dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]);
+        debug("ICMP PING %d.%d.%d.%d %d.%d.%d.%d ", srcAdr[0],srcAdr[1],srcAdr[2],srcAdr[3],dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]);
         debug("Ident %04x Sequence %04d ",icmpIdent,icmpSequence);
         char src[4];
         char dst[4];
@@ -458,7 +461,7 @@
     char * flags =      ipPkt+6; // 2 bits
     char * ttl =        ipPkt+8; // 1 byte
     char * protocol =   ipPkt+9; // 1 byte
-    unsigned char * headercheck= ipPkt+10; // 2 bytes
+    char * headercheck= ipPkt+10; // 2 bytes
 #endif
     char * srcAdr =     ipPkt+12; // 4 bytes
     char * dstAdr =     ipPkt+16; // 4 bytes = total of 20 bytes
@@ -512,14 +515,16 @@
     if (flags & (1<<6)) flagInfo[6]='E';
     if (flags & (1<<7)) flagInfo[7]='C';
     if (flags & (1<<8)) flagInfo[8]='N';
-    if (v0) {
-        debug("Flags %s Seq %u Ack %u", flagInfo, seq, ack); // show the flags in debug
+    if (v1) {
+        debug("Flags %s Seq %u Ack %u\n", flagInfo, seq, ack); // show the flags in debug
     }
 }
 
 int httpResponse(char * dataStart)
 {
     int n=0; // number of bytes we have printed so far
+    int nHeader; // byte size of HTTP header
+
     if(strncmp(dataStart, "GET / HTTP/1.1", 14) == 0 ) {
         n=n+sprintf(n+dataStart,"HTTP/1.1 200 OK\r\nServer: PPP-Blinky\r\n"); // http header
         n=n+sprintf(n+dataStart,"Content-Length: "); // http header
@@ -527,8 +532,7 @@
         n=n+sprintf(n+dataStart,"?????\r\n"); // leave five spaces for content length - will be updated later
         n=n+sprintf(n+dataStart,"Connection: close\r\n"); // close connection immediately
         n=n+sprintf(n+dataStart,"Content-Type: text/html; charset=us-ascii\r\n\r\n"); // http header must end with empty line (\r\n)
-        int nHeader=n; // byte size of the HTTP header. Note - seems like this must be 1+(multiple of four)
-
+        nHeader=n; // size of HTTP header
         // this is where we insert our web page into the buffer
         n=n+sprintf(n+dataStart,"%s\r\n", ourWebPage);
 
@@ -537,9 +541,6 @@
         snprintf(contentLengthString,CONTENTLENGTHSIZE+1,"%*d",CONTENTLENGTHSIZE,n-nHeader); // print Content-Length with leading spaces and fixed width equal to csize
         memcpy(dataStart+contentLengthStart, contentLengthString, CONTENTLENGTHSIZE); // copy Content-Length to it's place in the send buffer
 
-        if (v0) {
-            debug("HTTP GET BufferSize %d*32=%d Header %d Content-Length %d Total %d Available %d\n",dataLen/32,dataLen,nHeader,contentLength,n,dataLen-n);
-        }
     } else { // all remaining requests get 404 Not Found response and heap size
         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
@@ -547,7 +548,7 @@
         n=n+sprintf(n+dataStart,"?????\r\n"); // leave five spaces for content length - will be updated later
         n=n+sprintf(n+dataStart,"Connection: close\r\n"); // close connection immediately
         n=n+sprintf(n+dataStart,"Content-Type: text/html; charset=us-ascii\r\n\r\n"); // http header must end with empty line (\r\n)
-        int nHeader=n; // byte total of all headers. Note - seems like this must be 1+(multiple of four)
+        nHeader=n; // size of HTTP header
 
         n=n+sprintf(n+dataStart,"<!DOCTYPE html><html><head></head>"); // html start
         n=n+sprintf(n+dataStart,"<body><h1>File Not Found. Stack=0x%08x</h1></body>",&nHeader);
@@ -556,11 +557,11 @@
         char contentLengthString[CONTENTLENGTHSIZE+1]; // temporary buffer to create Content-Length string
         snprintf(contentLengthString,CONTENTLENGTHSIZE+1,"%*d",CONTENTLENGTHSIZE,n-nHeader); // print Content-Length with leading spaces and fixed width equal to csize
         memcpy(dataStart+contentLengthStart, contentLengthString, CONTENTLENGTHSIZE); // copy Content-Length to it's place in the send buffer
+    }
+    if (v2) {
+        debug("HTTP Response: HTTP-header %d HTTP-content %d HTTP-total %d\n",nHeader,n-nHeader,n);
+    }
 
-        if (v0) {
-            debug("HTTP GET BufSize %d*32=%d Header %d Content-Length %d Total %d Available %d\n",dataLen/32,dataLen,nHeader,contentLength,n,dataLen-n);
-        }
-    }
     return n; // total byte size of our response
 }
 
@@ -594,13 +595,13 @@
     int headerSizeTCP = ((offset[0]>>4)&0x0f)*4; // size of tcp header only
     int protocolIP = protocol[0];
 
-    unsigned int seq = (seqtcp[0]<<24)|(seqtcp[1]<<16)|(seqtcp[2]<<8)|(seqtcp[3]);
-    unsigned int ack = (acktcp[0]<<24)|(acktcp[1]<<16)|(acktcp[2]<<8)|(acktcp[3]);
-
     int flagsTCP = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1];
 
     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]);
 
 #define TCP_FLAG_ACK (1<<4)
 #define TCP_FLAG_SYN (1<<1)
@@ -612,39 +613,37 @@
     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
 
-    ppp.seq = ack;    // always adopt their sequence number calculation in place of doing our own calculation
-
     // 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
     // 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;
         case TCP_FLAG_SYN:
             flagsOut = TCP_FLAG_SYN | TCP_FLAG_ACK; // something wants to connect - ack it
-            seq++; // for SYN flag we have to increase sequence by 1
+            ack++; // for SYN flag we have to increase sequence by 1
             break;
-        case TCP_FLAG_ACK | TCP_FLAG_PSH:            
+        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
+                    dataLen++; // must be a multiple of four
+                    dataStart[dataLen-1]=0; // clear the byte in the buffer
                 }
             }
             break;
-        case TCP_FLAG_FIN:            
+        case TCP_FLAG_FIN:
         case TCP_FLAG_FIN | TCP_FLAG_ACK:
         case TCP_FLAG_FIN | TCP_FLAG_ACK | TCP_FLAG_PSH:
-            seq++; // for FIN flag we have to increase sequence by 1
+            ack++; // for FIN flag we have to increase sequence by 1
             break;
-        default: 
+        default:
             return; // ignore remaining packets
     }
-    
+
     // 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
 
@@ -657,9 +656,6 @@
     memcpy(srctcp, dsttcp,2);
     memcpy(dsttcp, tempHold,2); // swap ip port source/dest
 
-    ack = seq + tcpDataSize; // acknowledge the number of data bytes that they sent by adding it to "our" sequence number
-    seq = ppp.seq; // set up the sequence number we have to respond with
-
     acktcp[0]=ack>>24;
     acktcp[1]=ack>>16;
     acktcp[2]=ack>>8;
@@ -709,10 +705,9 @@
     } else {
         // normally, you wait 200 ms before sending a TCP packet
         // remove the wait to respond faster
-        // wait(0.2);
+         wait(0.05);
     }
     sendFrame(); // All done! Send the TCP packet
-    ppp.seq = ppp.seq + dataLen; // increase OUR sequence by the outgoing data length - for the next round
 }
 
 void dumpDataTCP()
@@ -770,8 +765,13 @@
     if (v0) {
         debug("i%04x f%d t%d p%d C%04x\n",identIP,flagsIP,ttlIP,protocolIP,checksumIP);
     }
-    dumpHeaderTCP();
-    dumpDataTCP();
+    if (v1) {
+        dumpHeaderTCP();
+    }
+
+    if (v2) {
+        dumpDataTCP();
+    }
     tcpHandler();
 }
 
@@ -919,11 +919,11 @@
 {
     if ( ppp.online==0 ) {
         // look for Windows Dialup Networking "Direct Connection Between Two Computers" expected connect string
-        char * clientFound = strstr( (char *)ppp.rx.buf, "CLIENTCLIENT" ); 
+        char * clientFound = strstr( (char *)ppp.rx.buf, "CLIENTCLIENT" );
         if( clientFound ) {
             strcpy( clientFound, "FOUND!FOUND!" ); // overwrite so we don't find it again
             // respond with Windows Dialup networking expected "Direct Connection Between Two Computers" response string
-            pc.printf("CLIENTSERVER"); 
+            pc.printf("CLIENTSERVER");
             ppp.online=1; // we are connected, so stop looking for the string
             debug("Connect string found\n");
         }