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

Committer:
andrewboyson
Date:
Wed May 08 12:15:13 2019 +0000
Revision:
142:a8c0890a58d1
Parent:
131:774f7f367031
Child:
144:6bd5c54efc7d
Updated the lpc1768 module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 74:c3756bfa960e 1 #include <stdint.h>
andrewboyson 74:c3756bfa960e 2 #include <stdbool.h>
andrewboyson 75:603b10404183 3 #include <stdarg.h>
andrewboyson 74:c3756bfa960e 4
andrewboyson 74:c3756bfa960e 5 #include "log.h"
andrewboyson 74:c3756bfa960e 6 #include "net.h"
andrewboyson 74:c3756bfa960e 7 #include "action.h"
andrewboyson 74:c3756bfa960e 8 #include "tcp.h"
andrewboyson 74:c3756bfa960e 9 #include "tcphdr.h"
andrewboyson 74:c3756bfa960e 10 #include "tcpsend.h"
andrewboyson 74:c3756bfa960e 11 #include "tcb.h"
andrewboyson 74:c3756bfa960e 12 #include "ip4.h"
andrewboyson 74:c3756bfa960e 13 #include "dhcp.h"
andrewboyson 74:c3756bfa960e 14 #include "http.h"
andrewboyson 111:3600389d1add 15 #include "https.h"
andrewboyson 74:c3756bfa960e 16 #include "led.h"
andrewboyson 93:580fc113d9e9 17 #include "mstimer.h"
andrewboyson 142:a8c0890a58d1 18 #include "restart.h"
andrewboyson 89:9b765a67699b 19
andrewboyson 89:9b765a67699b 20 static void log(void (*traceback)(void), char* fmt, ...)
andrewboyson 74:c3756bfa960e 21 {
andrewboyson 78:9d8fc88df405 22 if (TcpTrace)
andrewboyson 78:9d8fc88df405 23 {
andrewboyson 78:9d8fc88df405 24 if (NetTraceNewLine) Log("\r\n");
andrewboyson 89:9b765a67699b 25 LogTimeF("TCP port %hu - ", TcpHdrSrcPort);
andrewboyson 75:603b10404183 26 va_list argptr;
andrewboyson 75:603b10404183 27 va_start(argptr, fmt);
andrewboyson 75:603b10404183 28 LogV(fmt, argptr);
andrewboyson 75:603b10404183 29 va_end(argptr);
andrewboyson 75:603b10404183 30 Log("\r\n");
andrewboyson 75:603b10404183 31 if (NetTraceStack) traceback();
andrewboyson 75:603b10404183 32 }
andrewboyson 75:603b10404183 33 }
andrewboyson 75:603b10404183 34
andrewboyson 88:1ba13e6062a3 35 static void handleSyn(void *pPacket, int ipType, int remArIndex, int locMss, struct tcb* pTcb)
andrewboyson 74:c3756bfa960e 36 {
andrewboyson 74:c3756bfa960e 37 //Get the MSS to use for sends - it is the lower of the MSS advertised by the remote host and our local MSS
andrewboyson 74:c3756bfa960e 38 int remMss = TcpHdrMssGet();
andrewboyson 74:c3756bfa960e 39 pTcb->remMss = remMss ? remMss : 536; //default MSS for IPv4 [576 - 20(TCP) - 20(IP)];
andrewboyson 74:c3756bfa960e 40 if (pTcb->remMss > locMss) pTcb->remMss = locMss;
andrewboyson 74:c3756bfa960e 41
andrewboyson 93:580fc113d9e9 42 pTcb->timeSendsBeingAcked = MsTimerCount;
andrewboyson 82:20781198d26d 43 pTcb->countSendsNotAcked = 0;
andrewboyson 79:f50e02fb5c94 44 pTcb->rcvdFin = false;
andrewboyson 79:f50e02fb5c94 45 pTcb->sentFin = false;
andrewboyson 79:f50e02fb5c94 46 pTcb->todo = 0;
andrewboyson 126:62edacc9f14d 47 pTcb->postComplete = false;
andrewboyson 131:774f7f367031 48 pTcb->delayUntil = MsTimerCount;
andrewboyson 79:f50e02fb5c94 49 pTcb->remIsn = TcpHdrSeqNum;
andrewboyson 79:f50e02fb5c94 50 pTcb->locIsn = TcbGetIsn();
andrewboyson 79:f50e02fb5c94 51 pTcb->bytesRcvdFromRem = 0;
andrewboyson 79:f50e02fb5c94 52 pTcb->bytesAckdByRem = 0;
andrewboyson 79:f50e02fb5c94 53 pTcb->bytesAckdToRem = 0;
andrewboyson 79:f50e02fb5c94 54 pTcb->bytesSentToRem = 0;
andrewboyson 74:c3756bfa960e 55 }
andrewboyson 88:1ba13e6062a3 56 static void handleReceivedData(void* pPacket, int dataLength, uint32_t position, struct tcb* pTcb)
andrewboyson 74:c3756bfa960e 57 {
andrewboyson 74:c3756bfa960e 58 pTcb->window = TcpHdrWindow;
andrewboyson 74:c3756bfa960e 59 char* pData = (char*)pPacket + TcpHdrSizeGet();
andrewboyson 74:c3756bfa960e 60 switch (pTcb->locPort)
andrewboyson 74:c3756bfa960e 61 {
andrewboyson 74:c3756bfa960e 62 case 80:
andrewboyson 131:774f7f367031 63 HttpHandleRequest(dataLength, pData, position, &pTcb->todo, &pTcb->postComplete, &pTcb->delayUntil);
andrewboyson 74:c3756bfa960e 64 break;
andrewboyson 111:3600389d1add 65 case 443:
andrewboyson 111:3600389d1add 66 HttpsHandleRequest(dataLength, pData, position, &pTcb->todo);
andrewboyson 111:3600389d1add 67 break;
andrewboyson 74:c3756bfa960e 68 default:
andrewboyson 74:c3756bfa960e 69 break;
andrewboyson 74:c3756bfa960e 70 }
andrewboyson 74:c3756bfa960e 71 }
andrewboyson 90:955f4c6e18a9 72 static int sendResetFromPacket(int* pSizeTx, void* pPacketTx, int ipType, int remArIndex, int locIpScope, int seqLengthRcvd)
andrewboyson 89:9b765a67699b 73 {
andrewboyson 90:955f4c6e18a9 74 /*RFC793 p36 If the connection does not exist (CLOSED) then a reset is sent
andrewboyson 90:955f4c6e18a9 75 in response to any incoming segment except another reset.
andrewboyson 90:955f4c6e18a9 76 If the incoming segment has an ACK field, the reset takes its sequence number from the ACK field of the segment,
andrewboyson 90:955f4c6e18a9 77 otherwise the reset has sequence number zero
andrewboyson 90:955f4c6e18a9 78 and
andrewboyson 90:955f4c6e18a9 79 the ACK field is set to the sum of the sequence number and segment length of the incoming segment.
andrewboyson 90:955f4c6e18a9 80 The connection remains in the CLOSED state.
andrewboyson 90:955f4c6e18a9 81 In TcpSendReset TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send
andrewboyson 90:955f4c6e18a9 82 TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent
andrewboyson 90:955f4c6e18a9 83 */
andrewboyson 90:955f4c6e18a9 84
andrewboyson 89:9b765a67699b 85 struct tcb tcb;
andrewboyson 89:9b765a67699b 86 struct tcb* pTcb = &tcb;
andrewboyson 93:580fc113d9e9 87 pTcb->timeLastRcvd = MsTimerCount;
andrewboyson 89:9b765a67699b 88 pTcb->remArIndex = remArIndex;
andrewboyson 89:9b765a67699b 89 pTcb->ipType = ipType;
andrewboyson 89:9b765a67699b 90 pTcb->locIpScope = locIpScope;
andrewboyson 89:9b765a67699b 91 pTcb->remPort = TcpHdrSrcPort;
andrewboyson 89:9b765a67699b 92 pTcb->locPort = TcpHdrDstPort;
andrewboyson 89:9b765a67699b 93 pTcb->window = TcpHdrWindow;
andrewboyson 89:9b765a67699b 94 pTcb->state = TCB_EMPTY;
andrewboyson 89:9b765a67699b 95
andrewboyson 93:580fc113d9e9 96 pTcb->timeSendsBeingAcked = MsTimerCount;
andrewboyson 90:955f4c6e18a9 97 pTcb->countSendsNotAcked = 0;
andrewboyson 90:955f4c6e18a9 98 pTcb->rcvdFin = false;
andrewboyson 90:955f4c6e18a9 99 pTcb->sentFin = false;
andrewboyson 90:955f4c6e18a9 100 pTcb->todo = 0;
andrewboyson 126:62edacc9f14d 101 pTcb->postComplete = false;
andrewboyson 131:774f7f367031 102 pTcb->delayUntil = MsTimerCount;
andrewboyson 90:955f4c6e18a9 103 pTcb->remIsn = TcpHdrSeqNum + seqLengthRcvd; //Ack number
andrewboyson 90:955f4c6e18a9 104 pTcb->locIsn = TcpHdrACK ? TcpHdrAckNum : 0; //Seq number
andrewboyson 90:955f4c6e18a9 105 pTcb->bytesRcvdFromRem = 0;
andrewboyson 90:955f4c6e18a9 106 pTcb->bytesAckdByRem = 0;
andrewboyson 90:955f4c6e18a9 107 pTcb->bytesAckdToRem = 0;
andrewboyson 90:955f4c6e18a9 108 pTcb->bytesSentToRem = 0;
andrewboyson 90:955f4c6e18a9 109
andrewboyson 89:9b765a67699b 110 return TcpSendReset(pSizeTx, pPacketTx, pTcb);
andrewboyson 89:9b765a67699b 111 }
andrewboyson 74:c3756bfa960e 112
andrewboyson 80:4ef1500fca1d 113 int TcpHandleReceivedPacket(void (*traceback)(void), int sizeRx, void* pPacketRx, int* pSizeTx, void* pPacketTx, int ipType, int remArIndex, int locIpScope)
andrewboyson 74:c3756bfa960e 114 {
andrewboyson 142:a8c0890a58d1 115 int lastRestartPoint = RestartPoint;
andrewboyson 142:a8c0890a58d1 116 RestartPoint = FAULT_POINT_TcpHandleReceivedPacket;
andrewboyson 97:d91f7db00235 117
andrewboyson 90:955f4c6e18a9 118 int action = DO_NOTHING;
andrewboyson 89:9b765a67699b 119 bool traceRequested = false;
andrewboyson 86:55bc5ddac16c 120
andrewboyson 89:9b765a67699b 121 TcpHdrReadFromPacket(pPacketRx);
andrewboyson 89:9b765a67699b 122
andrewboyson 78:9d8fc88df405 123 if (remArIndex < 0)
andrewboyson 78:9d8fc88df405 124 {
andrewboyson 89:9b765a67699b 125 log(traceback, "invalid remote AR index %d -> ignored packet", remArIndex);
andrewboyson 142:a8c0890a58d1 126 RestartPoint = lastRestartPoint;
andrewboyson 78:9d8fc88df405 127 return DO_NOTHING;
andrewboyson 78:9d8fc88df405 128 }
andrewboyson 142:a8c0890a58d1 129 RestartPoint += 100;
andrewboyson 78:9d8fc88df405 130
andrewboyson 74:c3756bfa960e 131 int dataLength = sizeRx - TcpHdrSizeGet();
andrewboyson 74:c3756bfa960e 132 int locMss = *pSizeTx - TcpHdrSizeGet();
andrewboyson 74:c3756bfa960e 133
andrewboyson 90:955f4c6e18a9 134 //Calculate the sequence length of the received packet
andrewboyson 90:955f4c6e18a9 135 int seqLengthRcvd = 0;
andrewboyson 90:955f4c6e18a9 136 if (TcpHdrSYN) seqLengthRcvd += 1; //Add one to acknowledge the SYN
andrewboyson 90:955f4c6e18a9 137 seqLengthRcvd += dataLength; //Add the number of bytes received
andrewboyson 90:955f4c6e18a9 138 if (TcpHdrFIN) seqLengthRcvd += 1; //Add one to acknowledge the FIN
andrewboyson 90:955f4c6e18a9 139
andrewboyson 74:c3756bfa960e 140 //Filter out unwanted links
andrewboyson 142:a8c0890a58d1 141 RestartPoint++;
andrewboyson 74:c3756bfa960e 142 switch (TcpHdrDstPort)
andrewboyson 74:c3756bfa960e 143 {
andrewboyson 74:c3756bfa960e 144 case 80:
andrewboyson 74:c3756bfa960e 145 if (HttpTrace)
andrewboyson 74:c3756bfa960e 146 {
andrewboyson 74:c3756bfa960e 147 if (NetTraceNewLine) Log("\r\n");
andrewboyson 74:c3756bfa960e 148 LogTime("HTTP server request\r\n");
andrewboyson 89:9b765a67699b 149 traceRequested = true;
andrewboyson 74:c3756bfa960e 150 }
andrewboyson 74:c3756bfa960e 151 break;
andrewboyson 74:c3756bfa960e 152
andrewboyson 111:3600389d1add 153 case 443:
andrewboyson 111:3600389d1add 154 if (HttpsTrace)
andrewboyson 111:3600389d1add 155 {
andrewboyson 111:3600389d1add 156 if (NetTraceNewLine) Log("\r\n");
andrewboyson 111:3600389d1add 157 LogTime("HTTPS server request\r\n");
andrewboyson 111:3600389d1add 158 traceRequested = true;
andrewboyson 111:3600389d1add 159 }
andrewboyson 111:3600389d1add 160 break;
andrewboyson 111:3600389d1add 161
andrewboyson 89:9b765a67699b 162 default: //Send reset if unknown port
andrewboyson 89:9b765a67699b 163 log(traceback, "unhandled local port %hu -> sent reset", TcpHdrDstPort);
andrewboyson 90:955f4c6e18a9 164 action = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope, seqLengthRcvd);
andrewboyson 142:a8c0890a58d1 165 RestartPoint = lastRestartPoint;
andrewboyson 90:955f4c6e18a9 166 return action;
andrewboyson 74:c3756bfa960e 167 }
andrewboyson 74:c3756bfa960e 168
andrewboyson 76:17534bde28d3 169 //Get the Transmission Control Block
andrewboyson 142:a8c0890a58d1 170 RestartPoint++;
andrewboyson 88:1ba13e6062a3 171 struct tcb* pTcb = TcbGetExisting(ipType, remArIndex, locIpScope, TcpHdrSrcPort, TcpHdrDstPort);
andrewboyson 76:17534bde28d3 172 if (!pTcb) pTcb = TcbGetEmpty();
andrewboyson 89:9b765a67699b 173 if (!pTcb) //send reset if no more tcbs are available
andrewboyson 76:17534bde28d3 174 {
andrewboyson 89:9b765a67699b 175 log(traceback, "no more tcbs available -> sent reset");
andrewboyson 90:955f4c6e18a9 176 action = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope, seqLengthRcvd);
andrewboyson 142:a8c0890a58d1 177 RestartPoint = lastRestartPoint;
andrewboyson 90:955f4c6e18a9 178 return action;
andrewboyson 76:17534bde28d3 179 }
andrewboyson 93:580fc113d9e9 180 pTcb->timeLastRcvd = MsTimerCount;
andrewboyson 76:17534bde28d3 181 pTcb->remArIndex = remArIndex;
andrewboyson 76:17534bde28d3 182 pTcb->ipType = ipType;
andrewboyson 81:50bfdd512f23 183 pTcb->locIpScope = locIpScope;
andrewboyson 76:17534bde28d3 184 pTcb->remPort = TcpHdrSrcPort;
andrewboyson 76:17534bde28d3 185 pTcb->locPort = TcpHdrDstPort;
andrewboyson 76:17534bde28d3 186 pTcb->window = TcpHdrWindow;
andrewboyson 75:603b10404183 187
andrewboyson 74:c3756bfa960e 188 //Handle request to reset
andrewboyson 142:a8c0890a58d1 189 RestartPoint++;
andrewboyson 74:c3756bfa960e 190 if (TcpHdrRST)
andrewboyson 74:c3756bfa960e 191 {
andrewboyson 76:17534bde28d3 192 if (pTcb->state)
andrewboyson 74:c3756bfa960e 193 {
andrewboyson 89:9b765a67699b 194 log(traceback, "received reset -> reaped TCB");
andrewboyson 75:603b10404183 195 pTcb->state = TCB_EMPTY;
andrewboyson 74:c3756bfa960e 196 }
andrewboyson 142:a8c0890a58d1 197 RestartPoint = lastRestartPoint;
andrewboyson 74:c3756bfa960e 198 return DO_NOTHING; //Don't reply
andrewboyson 74:c3756bfa960e 199 }
andrewboyson 74:c3756bfa960e 200
andrewboyson 74:c3756bfa960e 201 //Handle request to synchronise
andrewboyson 142:a8c0890a58d1 202 RestartPoint++;
andrewboyson 74:c3756bfa960e 203 if (TcpHdrSYN)
andrewboyson 74:c3756bfa960e 204 {
andrewboyson 76:17534bde28d3 205 if (pTcb->state)
andrewboyson 75:603b10404183 206 {
andrewboyson 89:9b765a67699b 207 log(traceback, "received a SYN on an open connection -> sent reset");
andrewboyson 75:603b10404183 208 pTcb->state = TCB_EMPTY;
andrewboyson 90:955f4c6e18a9 209 action = TcpSendReset(pSizeTx, pPacketTx, pTcb);
andrewboyson 142:a8c0890a58d1 210 RestartPoint = lastRestartPoint;
andrewboyson 90:955f4c6e18a9 211 return action;
andrewboyson 75:603b10404183 212 }
andrewboyson 76:17534bde28d3 213 else
andrewboyson 75:603b10404183 214 {
andrewboyson 88:1ba13e6062a3 215 handleSyn(pPacketRx, ipType, remArIndex, locMss, pTcb);
andrewboyson 75:603b10404183 216 }
andrewboyson 74:c3756bfa960e 217 }
andrewboyson 74:c3756bfa960e 218
andrewboyson 90:955f4c6e18a9 219 //Handle non SYN packet on an empty connection
andrewboyson 142:a8c0890a58d1 220 RestartPoint++;
andrewboyson 76:17534bde28d3 221 if (!TcpHdrSYN && !pTcb->state)
andrewboyson 76:17534bde28d3 222 {
andrewboyson 90:955f4c6e18a9 223
andrewboyson 89:9b765a67699b 224 log(traceback, "non SYN packet received on a closed connection -> sent reset");
andrewboyson 78:9d8fc88df405 225 pTcb->state = TCB_EMPTY;
andrewboyson 90:955f4c6e18a9 226 action = sendResetFromPacket(pSizeTx, pPacketTx, ipType, remArIndex, locIpScope, seqLengthRcvd);
andrewboyson 142:a8c0890a58d1 227 RestartPoint = lastRestartPoint;
andrewboyson 90:955f4c6e18a9 228 return action;
andrewboyson 76:17534bde28d3 229 }
andrewboyson 76:17534bde28d3 230
andrewboyson 79:f50e02fb5c94 231 //Check if the acks of bytes sent has progressed and reset the timer
andrewboyson 142:a8c0890a58d1 232 RestartPoint++;
andrewboyson 91:879545b19260 233 uint32_t ackRcvdFromRem = TcpHdrACK ? TcpHdrAckNum - pTcb->locIsn : 0;
andrewboyson 82:20781198d26d 234 if (ackRcvdFromRem > pTcb->bytesAckdByRem)
andrewboyson 82:20781198d26d 235 {
andrewboyson 93:580fc113d9e9 236 pTcb->timeSendsBeingAcked = MsTimerCount;
andrewboyson 82:20781198d26d 237 pTcb->countSendsNotAcked = 0;
andrewboyson 82:20781198d26d 238 }
andrewboyson 79:f50e02fb5c94 239
andrewboyson 79:f50e02fb5c94 240 //Record the number of bytes acked by the remote host
andrewboyson 142:a8c0890a58d1 241 RestartPoint++;
andrewboyson 79:f50e02fb5c94 242 pTcb->bytesAckdByRem = ackRcvdFromRem;
andrewboyson 79:f50e02fb5c94 243
andrewboyson 76:17534bde28d3 244 /* If the connection is in a synchronized state
andrewboyson 76:17534bde28d3 245 any unacceptable segment (out of window sequence number or
andrewboyson 76:17534bde28d3 246 unacceptible acknowledgment number) must elicit only an empty
andrewboyson 76:17534bde28d3 247 acknowledgment segment containing the current send-sequence number
andrewboyson 76:17534bde28d3 248 and an acknowledgment indicating the next sequence number expected
andrewboyson 76:17534bde28d3 249 to be received, and the connection remains in the same state.*/
andrewboyson 142:a8c0890a58d1 250 RestartPoint++;
andrewboyson 74:c3756bfa960e 251 uint32_t seqRcvdFromRem = TcpHdrSeqNum - pTcb->remIsn;
andrewboyson 78:9d8fc88df405 252 if (seqRcvdFromRem != pTcb->bytesAckdToRem)
andrewboyson 78:9d8fc88df405 253 {
andrewboyson 79:f50e02fb5c94 254 //Only warn non keep-alives
andrewboyson 79:f50e02fb5c94 255 if (seqRcvdFromRem != 0 || pTcb->bytesAckdToRem != 1)
andrewboyson 79:f50e02fb5c94 256 {
andrewboyson 89:9b765a67699b 257 log(traceback, "seq rcvd is %d and last seq ackd was %d -> resent last ACK", seqRcvdFromRem, pTcb->bytesAckdToRem);
andrewboyson 79:f50e02fb5c94 258 }
andrewboyson 90:955f4c6e18a9 259 action = TcpResendLastAck(pSizeTx, pPacketTx, pTcb);
andrewboyson 142:a8c0890a58d1 260 RestartPoint = lastRestartPoint;
andrewboyson 90:955f4c6e18a9 261 return action;
andrewboyson 78:9d8fc88df405 262 }
andrewboyson 90:955f4c6e18a9 263 //Ignore data before established
andrewboyson 142:a8c0890a58d1 264 RestartPoint++;
andrewboyson 90:955f4c6e18a9 265 if (pTcb->state != TCB_ESTABLISHED && dataLength)
andrewboyson 90:955f4c6e18a9 266 {
andrewboyson 90:955f4c6e18a9 267 log(traceback, "data received before connection established -> sent reset");
andrewboyson 90:955f4c6e18a9 268 pTcb->state = TCB_EMPTY;
andrewboyson 90:955f4c6e18a9 269 action = TcpSendReset(pSizeTx, pPacketTx, pTcb);
andrewboyson 142:a8c0890a58d1 270 RestartPoint = lastRestartPoint;
andrewboyson 90:955f4c6e18a9 271 return action;
andrewboyson 90:955f4c6e18a9 272 }
andrewboyson 90:955f4c6e18a9 273
andrewboyson 74:c3756bfa960e 274 //Handle FIN
andrewboyson 142:a8c0890a58d1 275 RestartPoint++;
andrewboyson 74:c3756bfa960e 276 if (TcpHdrFIN) pTcb->rcvdFin = true; //When reply is all sent only a passive close is needed
andrewboyson 90:955f4c6e18a9 277
andrewboyson 90:955f4c6e18a9 278 //From now on there are no errors so display traceback if requested
andrewboyson 142:a8c0890a58d1 279 RestartPoint++;
andrewboyson 90:955f4c6e18a9 280 if (traceRequested && NetTraceStack) traceback();
andrewboyson 74:c3756bfa960e 281
andrewboyson 75:603b10404183 282 //Record the number of bytes received from the remote host
andrewboyson 142:a8c0890a58d1 283 RestartPoint++;
andrewboyson 76:17534bde28d3 284 pTcb->bytesRcvdFromRem += seqLengthRcvd;
andrewboyson 74:c3756bfa960e 285
andrewboyson 76:17534bde28d3 286 switch (pTcb->state) //This is the state of the connection BEFORE this packet arrived
andrewboyson 74:c3756bfa960e 287 {
andrewboyson 74:c3756bfa960e 288 case TCB_EMPTY:
andrewboyson 74:c3756bfa960e 289 pTcb->state = TCB_SYN_RECEIVED;
andrewboyson 74:c3756bfa960e 290 break;
andrewboyson 74:c3756bfa960e 291
andrewboyson 74:c3756bfa960e 292 case TCB_SYN_RECEIVED:
andrewboyson 74:c3756bfa960e 293 pTcb->state = TCB_ESTABLISHED;
andrewboyson 74:c3756bfa960e 294 break;
andrewboyson 74:c3756bfa960e 295
andrewboyson 74:c3756bfa960e 296 case TCB_ESTABLISHED:
andrewboyson 88:1ba13e6062a3 297 if (dataLength) handleReceivedData (pPacketRx, dataLength, seqRcvdFromRem - 1, pTcb);
andrewboyson 74:c3756bfa960e 298 if (pTcb->sentFin)
andrewboyson 74:c3756bfa960e 299 {
andrewboyson 77:6cb7d92c37f3 300 pTcb->state = pTcb->rcvdFin ? TCB_EMPTY : TCB_CLOSE_FIN_WAIT;
andrewboyson 74:c3756bfa960e 301 }
andrewboyson 74:c3756bfa960e 302 break;
andrewboyson 74:c3756bfa960e 303
andrewboyson 74:c3756bfa960e 304 case TCB_CLOSE_FIN_WAIT: //End of active close
andrewboyson 74:c3756bfa960e 305 if (TcpHdrFIN)
andrewboyson 74:c3756bfa960e 306 {
andrewboyson 74:c3756bfa960e 307 pTcb->state = TCB_EMPTY;//Ignore ACK to our FIN. Wait for FIN then close.
andrewboyson 74:c3756bfa960e 308 }
andrewboyson 74:c3756bfa960e 309 break;
andrewboyson 74:c3756bfa960e 310
andrewboyson 74:c3756bfa960e 311 }
andrewboyson 74:c3756bfa960e 312
andrewboyson 142:a8c0890a58d1 313 RestartPoint++;
andrewboyson 90:955f4c6e18a9 314 action = TcpSend(pSizeTx, pPacketTx, pTcb);
andrewboyson 86:55bc5ddac16c 315
andrewboyson 142:a8c0890a58d1 316 RestartPoint = lastRestartPoint;
andrewboyson 90:955f4c6e18a9 317 return action;
andrewboyson 74:c3756bfa960e 318 }