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
tcp/tcpsend.c@160:6a1d1d368f80, 2019-09-29 (annotated)
- Committer:
- andrewboyson
- Date:
- Sun Sep 29 18:51:58 2019 +0000
- Revision:
- 160:6a1d1d368f80
- Parent:
- 159:3ebef2d02f7f
- Child:
- 163:f063e374cf2a
Corrected some minor bugs
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| andrewboyson | 74:c3756bfa960e | 1 | #include <stdint.h> |
| andrewboyson | 74:c3756bfa960e | 2 | #include <stdbool.h> |
| andrewboyson | 90:955f4c6e18a9 | 3 | #include <stdarg.h> |
| andrewboyson | 74:c3756bfa960e | 4 | |
| andrewboyson | 93:580fc113d9e9 | 5 | #include "log.h" |
| andrewboyson | 93:580fc113d9e9 | 6 | #include "net.h" |
| andrewboyson | 93:580fc113d9e9 | 7 | #include "action.h" |
| andrewboyson | 93:580fc113d9e9 | 8 | #include "tcp.h" |
| andrewboyson | 93:580fc113d9e9 | 9 | #include "tcphdr.h" |
| andrewboyson | 93:580fc113d9e9 | 10 | #include "tcb.h" |
| andrewboyson | 93:580fc113d9e9 | 11 | #include "ip4.h" |
| andrewboyson | 93:580fc113d9e9 | 12 | #include "dhcp.h" |
| andrewboyson | 159:3ebef2d02f7f | 13 | #include "http.h" |
| andrewboyson | 159:3ebef2d02f7f | 14 | #include "https.h" |
| andrewboyson | 93:580fc113d9e9 | 15 | #include "led.h" |
| andrewboyson | 74:c3756bfa960e | 16 | #include "tcpsend.h" |
| andrewboyson | 93:580fc113d9e9 | 17 | #include "mstimer.h" |
| andrewboyson | 74:c3756bfa960e | 18 | |
| andrewboyson | 120:05b6d67a0cec | 19 | #define TIMEOUT_RETRANSMISSION_MS 700 |
| andrewboyson | 120:05b6d67a0cec | 20 | #define MAX_RETRANSMISSIONS 5 |
| andrewboyson | 120:05b6d67a0cec | 21 | #define TIMEOUT_BROKEN_LINK_MS 600000 |
| andrewboyson | 74:c3756bfa960e | 22 | |
| andrewboyson | 90:955f4c6e18a9 | 23 | static void log(uint16_t remPort, char* fmt, ...) |
| andrewboyson | 90:955f4c6e18a9 | 24 | { |
| andrewboyson | 90:955f4c6e18a9 | 25 | if (TcpTrace) |
| andrewboyson | 90:955f4c6e18a9 | 26 | { |
| andrewboyson | 90:955f4c6e18a9 | 27 | if (NetTraceNewLine) Log("\r\n"); |
| andrewboyson | 90:955f4c6e18a9 | 28 | LogTimeF("TCP port %hu - ", remPort); |
| andrewboyson | 90:955f4c6e18a9 | 29 | va_list argptr; |
| andrewboyson | 90:955f4c6e18a9 | 30 | va_start(argptr, fmt); |
| andrewboyson | 90:955f4c6e18a9 | 31 | LogV(fmt, argptr); |
| andrewboyson | 90:955f4c6e18a9 | 32 | va_end(argptr); |
| andrewboyson | 90:955f4c6e18a9 | 33 | Log("\r\n"); |
| andrewboyson | 90:955f4c6e18a9 | 34 | } |
| andrewboyson | 90:955f4c6e18a9 | 35 | } |
| andrewboyson | 90:955f4c6e18a9 | 36 | |
| andrewboyson | 88:1ba13e6062a3 | 37 | static bool doTrace(uint16_t port) |
| andrewboyson | 88:1ba13e6062a3 | 38 | { |
| andrewboyson | 88:1ba13e6062a3 | 39 | switch (port) |
| andrewboyson | 88:1ba13e6062a3 | 40 | { |
| andrewboyson | 159:3ebef2d02f7f | 41 | case 80: return HttpGetTrace(); |
| andrewboyson | 159:3ebef2d02f7f | 42 | case 443: return HttpsGetTrace(); |
| andrewboyson | 146:0fc66d610fd6 | 43 | default: return false; |
| andrewboyson | 88:1ba13e6062a3 | 44 | } |
| andrewboyson | 88:1ba13e6062a3 | 45 | } |
| andrewboyson | 147:a6093b52e654 | 46 | |
| andrewboyson | 159:3ebef2d02f7f | 47 | static bool addAppData(int *pDataLength, void* pPacket, int connection, uint16_t port, uint32_t windowPositionInStream, int windowSize, bool clientFinished) |
| andrewboyson | 147:a6093b52e654 | 48 | { |
| andrewboyson | 159:3ebef2d02f7f | 49 | uint8_t* pWindow = (uint8_t*)pPacket + TcpHdrSizeGet(); |
| andrewboyson | 145:206bf0d073c7 | 50 | bool finished = false; |
| andrewboyson | 159:3ebef2d02f7f | 51 | *pDataLength = windowSize; |
| andrewboyson | 75:603b10404183 | 52 | switch (port) |
| andrewboyson | 74:c3756bfa960e | 53 | { |
| andrewboyson | 159:3ebef2d02f7f | 54 | case 80: finished = HttpResponse(connection, clientFinished, pDataLength, (char*)pWindow, windowPositionInStream); break; |
| andrewboyson | 159:3ebef2d02f7f | 55 | case 443: finished = HttpsResponse(connection, clientFinished, pDataLength, pWindow, windowPositionInStream); break; |
| andrewboyson | 144:6bd5c54efc7d | 56 | } |
| andrewboyson | 145:206bf0d073c7 | 57 | return finished; |
| andrewboyson | 75:603b10404183 | 58 | } |
| andrewboyson | 89:9b765a67699b | 59 | static int preparePacket(void* pPacket, struct tcb* pTcb, int dataLength, int* pSize) |
| andrewboyson | 75:603b10404183 | 60 | { |
| andrewboyson | 75:603b10404183 | 61 | //Set the acknowledge flag |
| andrewboyson | 75:603b10404183 | 62 | TcpHdrACK = true; |
| andrewboyson | 74:c3756bfa960e | 63 | |
| andrewboyson | 75:603b10404183 | 64 | //Swap the ports for the reply |
| andrewboyson | 89:9b765a67699b | 65 | TcpHdrSrcPort = pTcb->locPort; |
| andrewboyson | 89:9b765a67699b | 66 | TcpHdrDstPort = pTcb->remPort; |
| andrewboyson | 75:603b10404183 | 67 | |
| andrewboyson | 75:603b10404183 | 68 | //Specify the receive window size to not throttle |
| andrewboyson | 75:603b10404183 | 69 | TcpHdrWindow = 4000; |
| andrewboyson | 75:603b10404183 | 70 | |
| andrewboyson | 75:603b10404183 | 71 | //Write the header |
| andrewboyson | 75:603b10404183 | 72 | TcpHdrWriteToPacket(pPacket); |
| andrewboyson | 75:603b10404183 | 73 | |
| andrewboyson | 75:603b10404183 | 74 | //Calculate the size of the reply |
| andrewboyson | 75:603b10404183 | 75 | *pSize = TcpHdrSizeGet() + dataLength; |
| andrewboyson | 75:603b10404183 | 76 | |
| andrewboyson | 89:9b765a67699b | 77 | return ActionMakeFromDestAndTrace(UNICAST, doTrace(pTcb->locPort) && NetTraceStack); |
| andrewboyson | 74:c3756bfa960e | 78 | } |
| andrewboyson | 75:603b10404183 | 79 | int TcpSend(int* pSize, void* pPacket, struct tcb* pTcb) |
| andrewboyson | 74:c3756bfa960e | 80 | { |
| andrewboyson | 74:c3756bfa960e | 81 | int dataLength = 0; |
| andrewboyson | 74:c3756bfa960e | 82 | TcpHdrMakeEmpty(); |
| andrewboyson | 74:c3756bfa960e | 83 | int locMss = *pSize - TcpHdrSizeGet(); |
| andrewboyson | 74:c3756bfa960e | 84 | switch (pTcb->state) |
| andrewboyson | 74:c3756bfa960e | 85 | { |
| andrewboyson | 74:c3756bfa960e | 86 | case TCB_SYN_RECEIVED: |
| andrewboyson | 74:c3756bfa960e | 87 | if (pTcb->bytesSentToRem == 0) |
| andrewboyson | 74:c3756bfa960e | 88 | { |
| andrewboyson | 74:c3756bfa960e | 89 | TcpHdrMssSet(locMss); |
| andrewboyson | 74:c3756bfa960e | 90 | TcpHdrSYN = true; |
| andrewboyson | 74:c3756bfa960e | 91 | } |
| andrewboyson | 74:c3756bfa960e | 92 | break; |
| andrewboyson | 74:c3756bfa960e | 93 | |
| andrewboyson | 74:c3756bfa960e | 94 | case TCB_ESTABLISHED: |
| andrewboyson | 74:c3756bfa960e | 95 | if (!pTcb->sentFin) |
| andrewboyson | 74:c3756bfa960e | 96 | { |
| andrewboyson | 74:c3756bfa960e | 97 | if (pTcb->bytesSentToRem - pTcb->bytesAckdByRem < pTcb->window) |
| andrewboyson | 74:c3756bfa960e | 98 | { |
| andrewboyson | 156:be12b8fd5b21 | 99 | bool finished = addAppData(&dataLength, pPacket, TcbGetId(pTcb), pTcb->locPort, pTcb->bytesSentToRem - 1, pTcb->remMss, pTcb->rcvdFin); |
| andrewboyson | 145:206bf0d073c7 | 100 | if (finished) |
| andrewboyson | 74:c3756bfa960e | 101 | { |
| andrewboyson | 144:6bd5c54efc7d | 102 | TcpHdrFIN = true; |
| andrewboyson | 144:6bd5c54efc7d | 103 | pTcb->sentFin = true; |
| andrewboyson | 74:c3756bfa960e | 104 | } |
| andrewboyson | 74:c3756bfa960e | 105 | } |
| andrewboyson | 74:c3756bfa960e | 106 | } |
| andrewboyson | 74:c3756bfa960e | 107 | break; |
| andrewboyson | 74:c3756bfa960e | 108 | } |
| andrewboyson | 74:c3756bfa960e | 109 | |
| andrewboyson | 79:f50e02fb5c94 | 110 | //Handle the acknowledgement of received bytes |
| andrewboyson | 74:c3756bfa960e | 111 | bool rcvdSeqHasAdvanced = pTcb->bytesRcvdFromRem > pTcb->bytesAckdToRem; |
| andrewboyson | 74:c3756bfa960e | 112 | pTcb->bytesAckdToRem = pTcb->bytesRcvdFromRem; |
| andrewboyson | 79:f50e02fb5c94 | 113 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 74:c3756bfa960e | 114 | |
| andrewboyson | 79:f50e02fb5c94 | 115 | //Specify the start of the data being sent |
| andrewboyson | 79:f50e02fb5c94 | 116 | uint32_t seqToSend = pTcb->bytesSentToRem; |
| andrewboyson | 79:f50e02fb5c94 | 117 | TcpHdrSeqNum = seqToSend + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 74:c3756bfa960e | 118 | |
| andrewboyson | 74:c3756bfa960e | 119 | //Record the number of bytes sent |
| andrewboyson | 74:c3756bfa960e | 120 | uint32_t bytesToSend = 0; |
| andrewboyson | 74:c3756bfa960e | 121 | if (TcpHdrSYN) bytesToSend += 1; //Add one to acknowledge the SYN |
| andrewboyson | 74:c3756bfa960e | 122 | bytesToSend += dataLength; //Add the number of bytes received |
| andrewboyson | 74:c3756bfa960e | 123 | if (TcpHdrFIN) bytesToSend += 1; //Add one to acknowledge the FIN |
| andrewboyson | 74:c3756bfa960e | 124 | |
| andrewboyson | 74:c3756bfa960e | 125 | pTcb->bytesSentToRem += bytesToSend; |
| andrewboyson | 74:c3756bfa960e | 126 | |
| andrewboyson | 79:f50e02fb5c94 | 127 | //Only send a packet if have bytes or an acknowledgement to send |
| andrewboyson | 75:603b10404183 | 128 | if (!rcvdSeqHasAdvanced && !bytesToSend) return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 129 | |
| andrewboyson | 89:9b765a67699b | 130 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 75:603b10404183 | 131 | } |
| andrewboyson | 75:603b10404183 | 132 | int TcpResendLastUnAcked(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 75:603b10404183 | 133 | { |
| andrewboyson | 75:603b10404183 | 134 | int dataLength = 0; |
| andrewboyson | 75:603b10404183 | 135 | TcpHdrMakeEmpty(); |
| andrewboyson | 75:603b10404183 | 136 | int locMss = *pSize - TcpHdrSizeGet(); |
| andrewboyson | 79:f50e02fb5c94 | 137 | uint32_t seqNum = pTcb->bytesAckdByRem; |
| andrewboyson | 75:603b10404183 | 138 | switch (pTcb->state) |
| andrewboyson | 74:c3756bfa960e | 139 | { |
| andrewboyson | 75:603b10404183 | 140 | case TCB_SYN_RECEIVED: |
| andrewboyson | 75:603b10404183 | 141 | TcpHdrMssSet(locMss); |
| andrewboyson | 75:603b10404183 | 142 | TcpHdrSYN = true; |
| andrewboyson | 75:603b10404183 | 143 | break; |
| andrewboyson | 74:c3756bfa960e | 144 | |
| andrewboyson | 75:603b10404183 | 145 | case TCB_ESTABLISHED: |
| andrewboyson | 79:f50e02fb5c94 | 146 | case TCB_CLOSE_FIN_WAIT: |
| andrewboyson | 75:603b10404183 | 147 | { |
| andrewboyson | 156:be12b8fd5b21 | 148 | bool finished = addAppData(&dataLength, pPacket, TcbGetId(pTcb), pTcb->locPort, seqNum - 1, pTcb->remMss, pTcb->rcvdFin); |
| andrewboyson | 145:206bf0d073c7 | 149 | if (finished) |
| andrewboyson | 75:603b10404183 | 150 | { |
| andrewboyson | 75:603b10404183 | 151 | TcpHdrFIN = true; |
| andrewboyson | 75:603b10404183 | 152 | pTcb->sentFin = true; |
| andrewboyson | 75:603b10404183 | 153 | } |
| andrewboyson | 145:206bf0d073c7 | 154 | break; |
| andrewboyson | 75:603b10404183 | 155 | } |
| andrewboyson | 74:c3756bfa960e | 156 | } |
| andrewboyson | 75:603b10404183 | 157 | |
| andrewboyson | 75:603b10404183 | 158 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 75:603b10404183 | 159 | TcpHdrSeqNum = seqNum + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 79:f50e02fb5c94 | 160 | |
| andrewboyson | 89:9b765a67699b | 161 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 75:603b10404183 | 162 | } |
| andrewboyson | 75:603b10404183 | 163 | int TcpResendLastAck(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 75:603b10404183 | 164 | { |
| andrewboyson | 75:603b10404183 | 165 | int dataLength = 0; |
| andrewboyson | 75:603b10404183 | 166 | TcpHdrMakeEmpty(); |
| andrewboyson | 75:603b10404183 | 167 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 75:603b10404183 | 168 | TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 75:603b10404183 | 169 | |
| andrewboyson | 89:9b765a67699b | 170 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 75:603b10404183 | 171 | } |
| andrewboyson | 75:603b10404183 | 172 | int TcpSendReset(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 75:603b10404183 | 173 | { |
| andrewboyson | 75:603b10404183 | 174 | int dataLength = 0; |
| andrewboyson | 75:603b10404183 | 175 | TcpHdrMakeEmpty(); |
| andrewboyson | 75:603b10404183 | 176 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 75:603b10404183 | 177 | TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 75:603b10404183 | 178 | |
| andrewboyson | 75:603b10404183 | 179 | TcpHdrRST = true; |
| andrewboyson | 75:603b10404183 | 180 | |
| andrewboyson | 89:9b765a67699b | 181 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 74:c3756bfa960e | 182 | } |
| andrewboyson | 79:f50e02fb5c94 | 183 | int TcpSendClose(int* pSize, void *pPacket, struct tcb* pTcb) |
| andrewboyson | 79:f50e02fb5c94 | 184 | { |
| andrewboyson | 79:f50e02fb5c94 | 185 | int dataLength = 0; |
| andrewboyson | 79:f50e02fb5c94 | 186 | TcpHdrMakeEmpty(); |
| andrewboyson | 79:f50e02fb5c94 | 187 | TcpHdrFIN = true; |
| andrewboyson | 79:f50e02fb5c94 | 188 | pTcb->sentFin = true; |
| andrewboyson | 79:f50e02fb5c94 | 189 | pTcb->bytesSentToRem += 1; //For the FIN |
| andrewboyson | 79:f50e02fb5c94 | 190 | TcpHdrAckNum = pTcb->bytesAckdToRem + pTcb->remIsn; //Set up the acknowledgement field ready to send |
| andrewboyson | 79:f50e02fb5c94 | 191 | TcpHdrSeqNum = pTcb->bytesSentToRem + pTcb->locIsn; //Set up the start of the message before adding the bytes sent |
| andrewboyson | 79:f50e02fb5c94 | 192 | |
| andrewboyson | 89:9b765a67699b | 193 | return preparePacket(pPacket, pTcb, dataLength, pSize); |
| andrewboyson | 79:f50e02fb5c94 | 194 | } |
| andrewboyson | 79:f50e02fb5c94 | 195 | |
| andrewboyson | 80:4ef1500fca1d | 196 | int TcpPollForPacketToSend(int* pSize, void* pPacket, int ipType, int* pRemArIndex, int* pLocIpScope) |
| andrewboyson | 74:c3756bfa960e | 197 | { |
| andrewboyson | 83:08c983006a6e | 198 | //Loops around the TCBs, moving on if empty but staying if not the right type |
| andrewboyson | 79:f50e02fb5c94 | 199 | static struct tcb* pTcb = NULL; //Passing a pointer containing NULL to TcbGetNext causes it to return the first TCB |
| andrewboyson | 79:f50e02fb5c94 | 200 | static bool stay = false; |
| andrewboyson | 83:08c983006a6e | 201 | if (!stay) pTcb = TcbGetNext(pTcb); |
| andrewboyson | 79:f50e02fb5c94 | 202 | stay = false; |
| andrewboyson | 78:9d8fc88df405 | 203 | if (!pTcb->state) return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 204 | if (pTcb->ipType != ipType) |
| andrewboyson | 79:f50e02fb5c94 | 205 | { |
| andrewboyson | 79:f50e02fb5c94 | 206 | stay = true; |
| andrewboyson | 79:f50e02fb5c94 | 207 | return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 208 | } |
| andrewboyson | 79:f50e02fb5c94 | 209 | |
| andrewboyson | 79:f50e02fb5c94 | 210 | //Check and make available the remote AR index |
| andrewboyson | 79:f50e02fb5c94 | 211 | if (pTcb->remArIndex < 0) |
| andrewboyson | 79:f50e02fb5c94 | 212 | { |
| andrewboyson | 90:955f4c6e18a9 | 213 | log(pTcb->remPort, "missing remote AR index -> reaping TCB"); |
| andrewboyson | 79:f50e02fb5c94 | 214 | pTcb->state = TCB_EMPTY; |
| andrewboyson | 79:f50e02fb5c94 | 215 | return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 216 | } |
| andrewboyson | 79:f50e02fb5c94 | 217 | *pRemArIndex = pTcb->remArIndex; |
| andrewboyson | 80:4ef1500fca1d | 218 | |
| andrewboyson | 80:4ef1500fca1d | 219 | //Return the local IP scope |
| andrewboyson | 80:4ef1500fca1d | 220 | if (pLocIpScope) *pLocIpScope = pTcb->locIpScope; |
| andrewboyson | 87:40d46a979cdb | 221 | |
| andrewboyson | 79:f50e02fb5c94 | 222 | //Reap old ones |
| andrewboyson | 133:a37eb35a03f1 | 223 | if (MsTimerRelative(pTcb->timeLastRcvd, TIMEOUT_BROKEN_LINK_MS)) |
| andrewboyson | 79:f50e02fb5c94 | 224 | { |
| andrewboyson | 90:955f4c6e18a9 | 225 | log(pTcb->remPort, "broken link -> reaping TCB"); |
| andrewboyson | 79:f50e02fb5c94 | 226 | pTcb->state = TCB_EMPTY; |
| andrewboyson | 79:f50e02fb5c94 | 227 | return DO_NOTHING; |
| andrewboyson | 79:f50e02fb5c94 | 228 | } |
| andrewboyson | 78:9d8fc88df405 | 229 | |
| andrewboyson | 79:f50e02fb5c94 | 230 | //Reset the RTO if all bytes are acknowledged |
| andrewboyson | 79:f50e02fb5c94 | 231 | if (pTcb->bytesSentToRem == pTcb->bytesAckdByRem) |
| andrewboyson | 79:f50e02fb5c94 | 232 | { |
| andrewboyson | 93:580fc113d9e9 | 233 | pTcb->timeSendsBeingAcked = MsTimerCount; |
| andrewboyson | 82:20781198d26d | 234 | pTcb->countSendsNotAcked = 0; |
| andrewboyson | 79:f50e02fb5c94 | 235 | } |
| andrewboyson | 75:603b10404183 | 236 | |
| andrewboyson | 79:f50e02fb5c94 | 237 | //Check if have unacknowledged send bytes after the RTO |
| andrewboyson | 133:a37eb35a03f1 | 238 | if (MsTimerRelative(pTcb->timeSendsBeingAcked, TIMEOUT_RETRANSMISSION_MS)) |
| andrewboyson | 75:603b10404183 | 239 | { |
| andrewboyson | 82:20781198d26d | 240 | pTcb->countSendsNotAcked++; |
| andrewboyson | 82:20781198d26d | 241 | if (pTcb->countSendsNotAcked > MAX_RETRANSMISSIONS) |
| andrewboyson | 82:20781198d26d | 242 | { |
| andrewboyson | 90:955f4c6e18a9 | 243 | log(pTcb->remPort, "reached maximum retransmissions -> sending reset"); |
| andrewboyson | 90:955f4c6e18a9 | 244 | pTcb->state = TCB_EMPTY; |
| andrewboyson | 90:955f4c6e18a9 | 245 | return TcpSendReset(pSize, pPacket, pTcb); |
| andrewboyson | 82:20781198d26d | 246 | } |
| andrewboyson | 90:955f4c6e18a9 | 247 | else |
| andrewboyson | 79:f50e02fb5c94 | 248 | { |
| andrewboyson | 90:955f4c6e18a9 | 249 | log(pTcb->remPort, "only had ack of %lu while sent %lu -> resending", pTcb->bytesAckdByRem, pTcb->bytesSentToRem); |
| andrewboyson | 93:580fc113d9e9 | 250 | pTcb->timeSendsBeingAcked = MsTimerCount; |
| andrewboyson | 90:955f4c6e18a9 | 251 | return TcpResendLastUnAcked(pSize, pPacket, pTcb); |
| andrewboyson | 79:f50e02fb5c94 | 252 | } |
| andrewboyson | 75:603b10404183 | 253 | } |
| andrewboyson | 90:955f4c6e18a9 | 254 | else |
| andrewboyson | 90:955f4c6e18a9 | 255 | { |
| andrewboyson | 90:955f4c6e18a9 | 256 | //If haven't had to do anything else then do a normal send |
| andrewboyson | 90:955f4c6e18a9 | 257 | return TcpSend(pSize, pPacket, pTcb); |
| andrewboyson | 90:955f4c6e18a9 | 258 | } |
| andrewboyson | 74:c3756bfa960e | 259 | } |
| andrewboyson | 74:c3756bfa960e | 260 |