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:
Thu May 20 14:32:52 2021 +0000
Revision:
200:5acbc41bf469
Parent:
166:89e3ce39b31b
Increased number of arp entries from 20 to 30 to accommodate the number of WIZ devices plus a few incoming port 80 calls from the internet.

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