2 * FreeRTOS+TCP V2.0.1
\r
3 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
29 * FreeRTOS_TCP_WIN.c
\r
30 * Module which handles the TCP windowing schemes for FreeRTOS-PLUS-TCP
\r
33 #ifndef FREERTOS_TCP_WIN_H
\r
34 #define FREERTOS_TCP_WIN_H
\r
40 extern BaseType_t xTCPWindowLoggingLevel;
\r
42 typedef struct xTCPTimer
\r
47 typedef struct xTCP_SEGMENT
\r
49 uint32_t ulSequenceNumber; /* The sequence number of the first byte in this packet */
\r
50 int32_t lMaxLength; /* Maximum space, number of bytes which can be stored in this segment */
\r
51 int32_t lDataLength; /* Actual number of bytes */
\r
52 int32_t lStreamPos; /* reference to the [t|r]xStream of the socket */
\r
53 TCPTimer_t xTransmitTimer; /* saves a timestamp at the moment this segment gets transmitted (TX only) */
\r
59 ucTransmitCount : 8,/* Number of times the segment has been transmitted, used to calculate the RTT */
\r
60 ucDupAckCount : 8, /* Counts the number of times that a higher segment was ACK'd. After 3 times a Fast Retransmission takes place */
\r
61 bOutstanding : 1, /* It the peer's turn, we're just waiting for an ACK */
\r
62 bAcked : 1, /* This segment has been acknowledged */
\r
63 bIsForRx : 1; /* pdTRUE if segment is used for reception */
\r
67 #if( ipconfigUSE_TCP_WIN != 0 )
\r
68 struct xLIST_ITEM xQueueItem; /* TX only: segments can be linked in one of three queues: xPriorityQueue, xTxQueue, and xWaitQueue */
\r
69 struct xLIST_ITEM xListItem; /* With this item the segment can be connected to a list, depending on who is owning it */
\r
73 typedef struct xTCP_WINSIZE
\r
75 uint32_t ulRxWindowLength;
\r
76 uint32_t ulTxWindowLength;
\r
80 * If TCP time-stamps are being used, they will occupy 12 bytes in
\r
81 * each packet, and thus the message space will become smaller
\r
83 /* Keep this as a multiple of 4 */
\r
84 #if( ipconfigUSE_TCP_WIN == 1 )
\r
85 #if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
\r
86 #define ipSIZE_TCP_OPTIONS ( 16u + 12u )
\r
88 #define ipSIZE_TCP_OPTIONS 16u
\r
91 #if ipconfigUSE_TCP_TIMESTAMPS == 1
\r
92 #define ipSIZE_TCP_OPTIONS ( 12u + 12u )
\r
94 #define ipSIZE_TCP_OPTIONS 12u
\r
99 * Every TCP connection owns a TCP window for the administration of all packets
\r
100 * It owns two sets of segment descriptors, incoming and outgoing
\r
102 typedef struct xTCP_WINDOW
\r
109 bHasInit : 1, /* The window structure has been initialised */
\r
110 bSendFullSize : 1, /* May only send packets with a size equal to MSS (for optimisation) */
\r
111 bTimeStamps : 1; /* Socket is supposed to use TCP time-stamps. This depends on the */
\r
112 } bits; /* party which opens the connection */
\r
115 TCPWinSize_t xSize;
\r
118 uint32_t ulFirstSequenceNumber; /* Logging & debug: the first segment received/sent in this connection
\r
119 * for Tx: initial send sequence number (ISS)
\r
120 * for Rx: initial receive sequence number (IRS) */
\r
121 uint32_t ulCurrentSequenceNumber;/* Tx/Rx: the oldest sequence number not yet confirmed, also SND.UNA / RCV.NXT
\r
122 * In other words: the sequence number of the left side of the sliding window */
\r
123 uint32_t ulFINSequenceNumber; /* The sequence number which carried the FIN flag */
\r
124 uint32_t ulHighestSequenceNumber;/* Sequence number of the right-most byte + 1 */
\r
125 #if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
\r
126 uint32_t ulTimeStamp; /* The value of the TCP timestamp, transmitted or received */
\r
129 uint32_t ulOurSequenceNumber; /* The SEQ number we're sending out */
\r
130 uint32_t ulUserDataLength; /* Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */
\r
131 uint32_t ulNextTxSequenceNumber; /* The sequence number given to the next byte to be added for transmission */
\r
132 int32_t lSRTT; /* Smoothed Round Trip Time, it may increment quickly and it decrements slower */
\r
133 uint8_t ucOptionLength; /* Number of valid bytes in ulOptionsData[] */
\r
134 #if( ipconfigUSE_TCP_WIN == 1 )
\r
135 List_t xPriorityQueue; /* Priority queue: segments which must be sent immediately */
\r
136 List_t xTxQueue; /* Transmit queue: segments queued for transmission */
\r
137 List_t xWaitQueue; /* Waiting queue: outstanding segments */
\r
138 TCPSegment_t *pxHeadSegment; /* points to a segment which has not been transmitted and it's size is still growing (user data being added) */
\r
139 uint32_t ulOptionsData[ipSIZE_TCP_OPTIONS/sizeof(uint32_t)]; /* Contains the options we send out */
\r
140 List_t xTxSegments; /* A linked list of all transmission segments, sorted on sequence number */
\r
141 List_t xRxSegments; /* A linked list of reception segments, order depends on sequence of arrival */
\r
143 /* For tiny TCP, there is only 1 outstanding TX segment */
\r
144 TCPSegment_t xTxSegment; /* Priority queue */
\r
146 uint16_t usOurPortNumber; /* Mostly for debugging/logging: our TCP port number */
\r
147 uint16_t usPeerPortNumber; /* debugging/logging: the peer's TCP port number */
\r
148 uint16_t usMSS; /* Current accepted MSS */
\r
149 uint16_t usMSSInit; /* MSS as configured by the socket owner */
\r
153 /*=============================================================================
\r
155 * Creation and destruction
\r
157 *=============================================================================*/
\r
159 /* Create and initialize a window */
\r
160 void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
\r
161 uint32_t ulTxWindowLength, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
\r
163 /* Destroy a window (always returns NULL)
\r
164 * It will free some resources: a collection of segments */
\r
165 void vTCPWindowDestroy( TCPWindow_t *pxWindow );
\r
167 /* Initialize a window */
\r
168 void vTCPWindowInit( TCPWindow_t *pxWindow, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
\r
170 /*=============================================================================
\r
174 *=============================================================================*/
\r
176 /* if true may be passed directly to user (segment expected and window is empty)
\r
177 * But pxWindow->ackno should always be used to set "BUF->ackno" */
\r
178 int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace );
\r
180 /* When lTCPWindowRxCheck returned false, please call store for this unexpected data */
\r
181 BaseType_t xTCPWindowRxStore( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength );
\r
183 /* This function will be called as soon as a FIN is received. It will return true
\r
184 * if there are no 'open' reception segments */
\r
185 BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow );
\r
187 /* _HT_ Temporary function for testing/debugging
\r
188 * Not used at this moment */
\r
189 void vTCPWinShowSegments( TCPWindow_t *pxWindow, BaseType_t bForRx );
\r
191 /*=============================================================================
\r
195 *=============================================================================*/
\r
197 /* Adds data to the Tx-window */
\r
198 int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax );
\r
200 /* Check data to be sent and calculate the time period we may sleep */
\r
201 BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay );
\r
203 /* See if anything is left to be sent
\r
204 * Function will be called when a FIN has been received. Only when the TX window is clean,
\r
205 * it will return pdTRUE */
\r
206 BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow );
\r
208 /* Fetches data to be sent.
\r
209 * apPos will point to a location with the circular data buffer: txStream */
\r
210 uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition );
\r
212 /* Receive a normal ACK */
\r
213 uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber );
\r
215 /* Receive a SACK option */
\r
216 uint32_t ulTCPWindowTxSack( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast );
\r
223 #endif /* FREERTOS_TCP_WIN_H */
\r