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:
Fri May 17 15:01:32 2019 +0000
Revision:
147:a6093b52e654
Parent:
146:0fc66d610fd6
Child:
156:be12b8fd5b21
Split HttpPollReply into HttpPoll and HttpReply to allow TSL to work

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