Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
Diff: tcp/tcp.c
- Revision:
- 74:c3756bfa960e
- Parent:
- 73:43e3d7fb3d60
- Child:
- 88:1ba13e6062a3
--- a/tcp/tcp.c Tue Oct 23 06:46:50 2018 +0000 +++ b/tcp/tcp.c Mon Oct 29 09:33:44 2018 +0000 @@ -1,260 +1,5 @@ -#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" - - -//Payload variables -static int dataLength; -static int maxMss = 0; - bool TcpTrace = false; -static bool doTrace = false; - -static struct tcb* pTcb; - -static void resetConnectionOut(char* message) -{ - if (TcpTrace) - { - LogTime("TCP "); - Log(message); - Log("\r\n"); - } - dataLength = 0; - TcpHdrClearOptions(); - TcpHdrACK = false; - TcpHdrPSH = false; - TcpHdrRST = true; - TcpHdrSYN = false; - TcpHdrFIN = false; - - pTcb->state = TCB_EMPTY; -} -static void startConnectionIn(void *pPacket, void* pCachedRemIp) -{ - TcpHdrReadOptions(pPacket); //Get the MSS - if (TcpHdrMss > maxMss) TcpHdrMss = maxMss; - - pTcb->mss = TcpHdrMss; - pTcb->state = TCB_SYN_RECEIVED; - pTcb->elapsed = TcbElapsed; - pTcb->pIp = pCachedRemIp; - pTcb->port = TcpHdrSrcPort; - pTcb->hadFin = false; -} -static void startConnectionOut(void* pPacket) -{ - TcpHdrMss = maxMss; //Ethernet 1500 - 20 - 20; or, in our case 768 - 20 - 20 - TcpHdrWriteOptions(pPacket); - dataLength = 0; - - TcpHdrACK = true; //Send ACK and SYN - TcpHdrPSH = false; - TcpHdrRST = false; - TcpHdrSYN = true; - TcpHdrFIN = false; -} -static void establishConnectionIn() -{ - pTcb->state = TCB_ESTABLISHED; - pTcb->elapsed = TcbElapsed; - pTcb->todo = 0; -} -static void handleEstablishedConnectionIn(void* pPacket) -{ - char* pData = (char*)pPacket + TcpHdrSize; - HttpHandleRequest(dataLength, pData, pTcb->recdBytes - 1, &pTcb->todo); -} -static void handleEstablishedConnectionOut(void* pPacket) -{ - TcpHdrClearOptions(); - char* pData = (char*)pPacket + TcpHdrSize; - HttpSendReply(&dataLength, pData, pTcb->sentBytes - 1, TcpHdrMss, pTcb->todo); - - TcpHdrACK = true; //Send ACK - TcpHdrRST = false; - TcpHdrSYN = false; - TcpHdrPSH = false; - - if (dataLength < TcpHdrMss) //If a part packet then there can be no more to send - { - TcpHdrFIN = true; //Inform the client that we have no more to send after this - if (pTcb->hadFin) pTcb->state = TCB_ACK_WAIT; //Passive close - else pTcb->state = TCB_FIN_WAIT; //Active close - } - else - { - TcpHdrFIN = false; - } - - pTcb->elapsed = TcbElapsed; -} -static void closeConnectionOut() -{ - TcpHdrACK = true; //Send ACK - TcpHdrPSH = false; - TcpHdrRST = false; - TcpHdrSYN = false; - TcpHdrFIN = false; - - TcpHdrClearOptions(); - dataLength = 0; - - pTcb->state = TCB_EMPTY; -} +bool TcpDoTrace = false; -int TcpHandleReceivedPacket(void (*traceback)(void), int sizeRx, void* pPacketRx, int* pSizeTx, void* pPacketTx, int type, void* pCachedRemIp) -{ - TcpHdrRead(pPacketRx); - - dataLength = sizeRx - TcpHdrSize; - maxMss = *pSizeTx - TcpHdrSize; - - doTrace = false; - - //Filter out unwanted links - switch (TcpHdrDstPort) - { - case 80: - if (HttpTrace) - { - if (NetTraceNewLine) Log("\r\n"); - LogTime("HTTP server request\r\n"); - doTrace = true; - } - break; - - default: - if (TcpTrace) - { - if (NetTraceNewLine) Log("\r\n"); - LogTimeF("TCP unknown port %d\r\n", TcpHdrDstPort); - if (NetTraceStack) traceback(); - } - return DO_NOTHING; //Ignore unknown ports - } - - //Get the Transmission Control Block - pTcb = TcbGetExisting(TcpHdrSrcPort); - if (!pTcb) pTcb = TcbGetEmpty(); - if (!pTcb) - { - if (TcpTrace) - { - if (NetTraceNewLine) Log("\r\n"); - LogTime("TCP no more tcbs are available\r\n"); - if (NetTraceStack) traceback(); - } - return DO_NOTHING; //Bomb out if no more tcbs are available - } - - //Handle request to reset - if (TcpHdrRST) - { - if (TcpTrace) - { - if (NetTraceNewLine) Log("\r\n"); - LogTime("TCP received reset - resetting TCB\r\n"); - if (NetTraceStack) traceback(); - } - pTcb->state = TCB_EMPTY; //Reset connection - return DO_NOTHING; //Don't reply - } - - //Handle request to synchronise - if (TcpHdrSYN) - { - pTcb->recvIsn = TcpHdrSeqNum; - pTcb->sendIsn = TcbGetIsn(); - pTcb->recdBytes = 0; - pTcb->sentBytes = 0; - } - else - { - pTcb->recdBytes = TcpHdrSeqNum - pTcb->recvIsn; - pTcb->sentBytes = TcpHdrAckNum - pTcb->sendIsn; - } - - if (doTrace && NetTraceStack) traceback(); //This will already include the TCP header - - if (TcpHdrSYN) pTcb->recdBytes += 1; //Add one to acknowledge the SYN - pTcb->recdBytes += dataLength; //Add the number of bytes received - if (TcpHdrFIN) pTcb->recdBytes += 1; //Add one to acknowledge the FIN - - switch (pTcb->state) - { - case TCB_EMPTY: - if (!TcpHdrSYN) { resetConnectionOut("received other than a SYN when connection closed"); break; } - startConnectionIn(pPacketRx, pCachedRemIp); - startConnectionOut(pPacketTx); - break; - - case TCB_SYN_RECEIVED: - if (dataLength) { resetConnectionOut("data received before connection established"); break; } - if (!TcpHdrACK) { resetConnectionOut("received other than an ACK before connection established"); break; } - establishConnectionIn(); - return DO_NOTHING; - - case TCB_ESTABLISHED: - if (!TcpHdrACK) { resetConnectionOut("received other than an ACK during established conection"); break; } - if (TcpHdrFIN) pTcb->hadFin = true; //When reply is all sent only a passive close is needed - handleEstablishedConnectionIn (pPacketRx); - handleEstablishedConnectionOut(pPacketTx); - break; - - case TCB_FIN_WAIT: //End of active close - if (!TcpHdrFIN) return DO_NOTHING; //Ignore ACK to our FIN. Wait for FIN then close. - closeConnectionOut(); - break; - - case TCB_ACK_WAIT: //End of passive close - if (!TcpHdrACK) { resetConnectionOut("received other than an ACK when closing half open connection"); break; } - pTcb->state = TCB_EMPTY; - return DO_NOTHING; - } - - //Specify the start of the data being sent and acknowledge the data received - TcpHdrAckNum = pTcb->recdBytes + pTcb->recvIsn; //Set up the acknowledgement field ready to send - TcpHdrSeqNum = pTcb->sentBytes + pTcb->sendIsn; //Set up the start of the message before adding the bytes sent - - //Keep a record of where we expect the next packet send to start - if (TcpHdrSYN) pTcb->sentBytes += 1; //Add one to acknowledge the SYN - pTcb->sentBytes += dataLength; //Record the next sequence number - if (TcpHdrFIN) pTcb->sentBytes += 1; //Add one to acknowledge the FIN - - //Swap the ports for the reply - TcpHdrSrcPort = TcpHdrDstPort; - TcpHdrDstPort = pTcb->port; - - //Specify the receive window size to not throttle - TcpHdrWindow = 4000; - - //Calculate the size of the reply - *pSizeTx = TcpHdrSize + dataLength; - - return ActionMakeFromDestAndTrace(UNICAST, doTrace && NetTraceStack); -} - -int TcpPollForPacketToSend(int* pSize, void* pPacket, int type, void* pCachedRemIp) -{ - int dataLength = *pSize - TcpHdrSize; - - int action = DO_NOTHING; - - TcpHdrSrcPort = TcpHdrDstPort; - TcpHdrDstPort = pTcb->port; - - *pSize = TcpHdrSize + dataLength; - return action; -} -