Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Revision:
74:c3756bfa960e
Child:
75:603b10404183
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tcp/tcpsend.c	Mon Oct 29 09:33:44 2018 +0000
@@ -0,0 +1,130 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+#include    "log.h"
+#include    "net.h"
+#include "action.h"
+#include    "tcp.h"
+#include "tcphdr.h"
+#include    "tcb.h"
+#include    "ip4.h"
+#include   "dhcp.h"
+#include   "http.h"
+#include    "led.h"
+#include "tcpsend.h"
+
+
+
+static int sendData(void* pPacket, struct tcb* pTcb)
+{
+    int dataLength = 0;
+    char* pData = (char*)pPacket + TcpHdrSizeGet();
+    switch (pTcb->locPort)
+    {
+        case 80:
+            HttpSendReply(&dataLength, pData, pTcb->bytesSentToRem - 1, pTcb->remMss, pTcb->todo);
+            break;
+        default:
+            break;
+    }    
+    
+    pTcb->lastSendTime = TcbElapsed;
+    
+    return dataLength;
+}
+
+int TcpSend(int* pSize, void* pPacket, struct tcb* pTcb, int sendType)
+{
+    int dataLength = 0;
+    TcpHdrMakeEmpty();
+    int locMss = *pSize - TcpHdrSizeGet();
+    switch (pTcb->state)
+    {
+        case TCB_SYN_RECEIVED:
+            if (pTcb->bytesSentToRem == 0)
+            {
+                TcpHdrMssSet(locMss);
+                TcpHdrSYN = true;
+            }
+            break;
+            
+        case TCB_ESTABLISHED:
+            if (!pTcb->sentFin)
+            {
+                if (pTcb->bytesSentToRem - pTcb->bytesAckdByRem < pTcb->window)
+                {
+                    if (pTcb->todo)
+                    {
+                        dataLength = sendData(pPacket, pTcb);
+                        if (dataLength < pTcb->remMss)
+                        {
+                            TcpHdrFIN     = true;
+                            pTcb->sentFin = true;
+                        }
+                    }
+                    else
+                    {
+                        if (pTcb->rcvdFin)
+                        {
+                            TcpHdrFIN     = true;
+                            pTcb->sentFin = true;
+                        }
+                    }
+                }
+            }
+            break;
+    }
+
+    //See if have need to acknowledge received bytes
+    bool rcvdSeqHasAdvanced = pTcb->bytesRcvdFromRem > pTcb->bytesAckdToRem;
+    
+    //Record the number of bytes acknowledged to the remote
+    pTcb->bytesAckdToRem = pTcb->bytesRcvdFromRem;
+    
+    //Specify the start of the data being sent and acknowledge the data received
+    TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn;  //Set up the acknowledgement field ready to send
+    TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn;  //Set up the start of the message before adding the bytes sent
+
+    //Record the number of bytes sent
+    uint32_t bytesToSend = 0;
+    if (TcpHdrSYN) bytesToSend += 1;            //Add one to acknowledge the SYN
+                   bytesToSend += dataLength;   //Add the number of bytes received
+    if (TcpHdrFIN) bytesToSend += 1;            //Add one to acknowledge the FIN
+
+    pTcb->bytesSentToRem += bytesToSend;
+    
+    if (rcvdSeqHasAdvanced || bytesToSend || sendType == TCP_RESEND_ACK || sendType == TCP_SEND_RESET)
+    {
+        //Set the acknowledge flag
+        TcpHdrACK = true;
+        TcpHdrRST = sendType == TCP_SEND_RESET;
+        
+        //Swap the ports for the reply
+        TcpHdrSrcPort = pTcb->locPort;
+        TcpHdrDstPort = pTcb->remPort;
+                
+        //Specify the receive window size to not throttle
+        TcpHdrWindow = 4000;
+        
+        //Write the header
+        TcpHdrWriteToPacket(pPacket);
+        
+        //Calculate the size of the reply
+        *pSize = TcpHdrSizeGet() + dataLength;
+            
+        return ActionMakeFromDestAndTrace(UNICAST, TcpDoTrace && NetTraceStack);
+    }
+    else
+    {
+        return DO_NOTHING;
+    }
+}
+int TcpPollForPacketToSend(int* pSize, void* pPacket, int ipType, int* pRemArIndex)
+{
+    struct tcb* pTcb = TcbGetNext(); //This loops around the TCBs
+    if (pTcb->ipType != ipType) return DO_NOTHING;
+    *pRemArIndex = pTcb->remArIndex;
+    int action = TcpSend(pSize, pPacket, pTcb, TCP_SEND_NORMAL);
+    return action;
+}
+