A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

Revision:
54:84ef2b29cf7e
Parent:
52:fbc5a46b5e16
Child:
55:e64b8b47a2b6
--- a/tcp/tcp.cpp	Thu Nov 09 15:44:29 2017 +0000
+++ b/tcp/tcp.cpp	Mon Nov 13 08:06:55 2017 +0000
@@ -27,28 +27,35 @@
 
 //Header variables
     
-static    uint16_t    srcPort;
-static    uint16_t    dstPort;
-static    uint32_t     seqnum;
-static    uint32_t     acknum;
-static    int      headersize;
-static    uint8_t       flags;
-static    bool            URG; //indicates that the Urgent pointer field is significant
-static    bool            ACK; //indicates that the Acknowledgment field is significant. All packets after the initial SYN packet sent by the client should have this flag set.
-static    bool            PSH; //Push function. Asks to push the buffered data to the receiving application.
-static    bool            RST; //Reset the connection
-static    bool            SYN; //Synchronize sequence numbers. Only the first packet sent from each end should have this flag set. Some other flags and fields change meaning based on this flag, and some are only valid for when it is set, and others when it is clear.
-static    bool            FIN; //No more data from sender
+static uint16_t    srcPort;
+static uint16_t    dstPort;
+static uint32_t     seqnum;
+static uint32_t     acknum;
+static int      headersize;
+static uint8_t       flags;
+static bool            URG; //indicates that the Urgent pointer field is significant
+static bool            ACK; //indicates that the Acknowledgment field is significant. All packets after the initial SYN packet sent by the client should have this flag set.
+static bool            PSH; //Push function. Asks to push the buffered data to the receiving application.
+static bool            RST; //Reset the connection
+static bool            SYN; //Synchronize sequence numbers. Only the first packet sent from each end should have this flag set. Some other flags and fields change meaning based on this flag, and some are only valid for when it is set, and others when it is clear.
+static bool            FIN; //No more data from sender
 
-static    uint16_t     window;
-static    uint16_t   checksum;
-static    uint16_t     urgent;
-static    int    optionLength;
+static uint16_t     window;
+static uint16_t   checksum;
+static uint16_t     urgent;
+static int    optionLength;
     
-static    char*    pOptions;
-static    void*    pData;
-static    int      dataLength;
-static    uint16_t mss;
+static char*    pOptions;
+static char*    pData;
+static int      dataLength;
+static uint16_t mss;
+
+static bool     isSend = false;
+
+static void (*pTraceback)(void);
+
+static struct tcb* pTcb;
+
 static void logFlags()
 {
     if (URG) Log(" URG");
@@ -65,8 +72,16 @@
         Log("TCP header\r\n");
         LogF("  Source port      %hu\r\n",   srcPort);
         LogF("  Destination port %hu\r\n",   dstPort);
-        LogF("  Sequence number  %u\r\n",    seqnum);
-        LogF("  Ack number       %u\r\n",    acknum);
+        if (isSend)
+        {
+            LogF("  Sequence number  %u (%u)\r\n",  seqnum - pTcb->locIsn, seqnum);
+            LogF("  Ack number       %u (%u)\r\n",  acknum - pTcb->remIsn, acknum);
+        }
+        else
+        {
+            LogF("  Sequence number  %u (%u)\r\n",  seqnum - pTcb->remIsn, seqnum);
+            LogF("  Ack number       %u (%u)\r\n",  acknum - pTcb->locIsn, acknum);
+        }
         LogF("  Header size      %u\r\n",    headersize);
         Log ("  Flags           "); logFlags(); Log("\r\n");
         LogF("  Window           %hu\r\n",   window);
@@ -75,11 +90,18 @@
         LogF("  Urgent pointer   %hu\r\n",   urgent);
         LogF("  Option length    %d\r\n",    optionLength);
         LogF("  Data length      %d\r\n",    dataLength);
+        LogF("  locIsn           %u\r\n",    pTcb->locIsn);
+        LogF("  remIsn           %u\r\n",    pTcb->remIsn);
+        LogF("  locSeq           %u\r\n",    pTcb->locSeq);
+        LogF("  remSeq           %u\r\n",    pTcb->remSeq);
+
     }
     else
     {
         LogF("TCP   header %hu >>> %hu", srcPort, dstPort);
         logFlags();
+        if (isSend) LogF(", seq %u, ack %u", seqnum - pTcb->locIsn, acknum - pTcb->remIsn);
+        else        LogF(", seq %u, ack %u", seqnum - pTcb->remIsn, acknum - pTcb->locIsn);
         Log("\r\n");
     }
 }
@@ -168,7 +190,7 @@
     
     pHeader->checksum   = 0;
 }
-static int stateClosed(struct tcb* pTcb)
+static int stateClosed()
 {
     if (!SYN)    //Reset if anything other than a request to establish conection from client
     {
@@ -214,36 +236,34 @@
     
     return 1;
 }
-static int stateSynReceived(struct tcb* pTcb)
+static int stateSynReceived()
 {
     if (dataLength) LogTimeF("%d bytes data received before TCB established\r\n", dataLength);
     if (ACK)
     {
         pTcb->state   = TCB_ESTABLISHED;
         pTcb->elapsed = TcbElapsed;
-        pTcb->tag     = 0;
+        pTcb->todo     = 0;
     }
     return 0;
 }
-static int stateEstablished(struct tcb* pTcb)
+static int stateEstablished()
 {
     if (!ACK) return 0;              //Ignore any packets which don't contain an ACK
     
     //Handle reception of data
-    if (dataLength)
-    {
-        pTcb->tag = HttpRequest(seqnum - pTcb->remIsn - 1, dataLength, (char*)pData);
-        pTcb->remSeq = seqnum + dataLength;
-    }
+    pTcb->remSeq = seqnum + dataLength;
     acknum = pTcb->remSeq;      //Set the ack num to the next byte expected from the client
-    
+    int positionInRequestStream = seqnum - pTcb->remIsn - 1;
+    int positionInReplyStream   = pTcb->locSeq - pTcb->locIsn - 1;
+    char* pRequestStream = pData;
+    char* pReplyStream   = pOptions;
+
+    HttpHandleRequest(pTraceback, &dataLength, pRequestStream, positionInRequestStream, pReplyStream, positionInReplyStream, mss, &pTcb->todo);
     
     //Rearrange the buffers
     headersize = 20;
-    pData = pOptions;
-   
-    //Handle sending of any data
-    dataLength = HttpReply(pTcb->locSeq - pTcb->locIsn - 1, mss, (char*)pData, pTcb->tag);
+    pData = pReplyStream;
     
     seqnum = pTcb->locSeq;      //Set the sequence number to the first byte of this message
     
@@ -264,7 +284,7 @@
     pTcb->elapsed = TcbElapsed;
     return 1;
 }
-static int stateClosing(struct tcb* pTcb)
+static int stateClosing()
 {
     if (!FIN) return 0;       //Ignore any packets which don't contain a FIN
     
@@ -290,7 +310,9 @@
 
 int TcpHandleReceivedPacket(void (*traceback)(void), int* pSize, void* pPacket)
 {
-    struct tcb* pTcb = TcbGetExisting(srcPort);
+    pTraceback = traceback;
+    isSend = false;
+    pTcb = TcbGetExisting(srcPort);
     if (!pTcb)  pTcb = TcbGetEmpty();
     if (!pTcb)
     {
@@ -342,19 +364,27 @@
         return DO_NOTHING;
     }
     */
+    if (TcpTrace)
+    {
+        if (NetTraceNewLine) Log("\r\n");
+        LogF("TCP server request\r\n");
+        traceback();
+    }
 
+    isSend = true;
     switch (pTcb->state)
     {
-        case TCB_CLOSED:       if (stateClosed     (pTcb)) break; return DO_NOTHING;
-        case TCB_SYN_RECEIVED: if (stateSynReceived(pTcb)) break; return DO_NOTHING;
-        case TCB_ESTABLISHED:  if (stateEstablished(pTcb)) break; return DO_NOTHING;
-        case TCB_CLOSING:      if (stateClosing    (pTcb)) break; return DO_NOTHING;
+        case TCB_CLOSED:       if (stateClosed     ()) break; return DO_NOTHING;
+        case TCB_SYN_RECEIVED: if (stateSynReceived()) break; return DO_NOTHING;
+        case TCB_ESTABLISHED:  if (stateEstablished()) break; return DO_NOTHING;
+        case TCB_CLOSING:      if (stateClosing    ()) break; return DO_NOTHING;
     }
     
     srcPort = dstPort;
     dstPort = pTcb->port;
     
     *pSize = dataLength + headersize;
-    return UNICAST;
+        
+    return ActionMakeFromDestAndTrace(UNICAST, TcpTrace && NetTraceStack);
 
 }