xref: /FreeRTOS-Plus-TCP-v3.1.0/source/include/FreeRTOS_IP_Private.h (revision 37bdfe577f3b728058de714e2e747d3c78803f26)
1 /*
2  * FreeRTOS+TCP V3.1.0
3  * Copyright (C) 2022 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  */
27 
28 #ifndef FREERTOS_IP_PRIVATE_H
29 #define FREERTOS_IP_PRIVATE_H
30 /* *INDENT-OFF* */
31 #ifdef __cplusplus
32     extern "C" {
33 #endif
34 /* *INDENT-ON* */
35 
36 /* Application level configuration options. */
37 #include "FreeRTOSIPConfig.h"
38 #include "FreeRTOSIPConfigDefaults.h"
39 #include "FreeRTOS_Sockets.h"
40 #include "IPTraceMacroDefaults.h"
41 #include "FreeRTOS_Stream_Buffer.h"
42 
43 #if ( ipconfigUSE_TCP == 1 )
44     #include "FreeRTOS_TCP_WIN.h"
45     #include "FreeRTOS_TCP_IP.h"
46 #endif
47 
48 #include "semphr.h"
49 
50 #include "event_groups.h"
51 
52 #ifdef TEST
53     int ipFOREVER( void );
54 #else
55     #define ipFOREVER()    1
56 #endif
57 
58 /**
59  * Structure to hold the information about the Network parameters.
60  */
61 typedef struct xNetworkAddressingParameters
62 {
63     uint32_t ulDefaultIPAddress; /**< The default IP address */
64     uint32_t ulNetMask;          /**< The netmask */
65     uint32_t ulGatewayAddress;   /**< The gateway address */
66     uint32_t ulDNSServerAddress; /**< The DNS server address */
67     uint32_t ulBroadcastAddress; /**< The Broadcast address */
68 } NetworkAddressingParameters_t;
69 
70 extern BaseType_t xTCPWindowLoggingLevel;
71 extern QueueHandle_t xNetworkEventQueue;
72 
73 /*-----------------------------------------------------------*/
74 /* Protocol headers.                                         */
75 /*-----------------------------------------------------------*/
76 
77 #include "pack_struct_start.h"
78 struct xETH_HEADER
79 {
80     MACAddress_t xDestinationAddress; /**< Destination address  0 + 6 = 6  */
81     MACAddress_t xSourceAddress;      /**< Source address       6 + 6 = 12 */
82     uint16_t usFrameType;             /**< The EtherType field 12 + 2 = 14 */
83 }
84 #include "pack_struct_end.h"
85 typedef struct xETH_HEADER EthernetHeader_t;
86 
87 #include "pack_struct_start.h"
88 struct xARP_HEADER
89 {
90     uint16_t usHardwareType;              /**< Network Link Protocol type                     0 +  2 =  2 */
91     uint16_t usProtocolType;              /**< The internetwork protocol                      2 +  2 =  4 */
92     uint8_t ucHardwareAddressLength;      /**< Length in octets of a hardware address         4 +  1 =  5 */
93     uint8_t ucProtocolAddressLength;      /**< Length in octets of the internetwork protocol  5 +  1 =  6 */
94     uint16_t usOperation;                 /**< Operation that the sender is performing        6 +  2 =  8 */
95     MACAddress_t xSenderHardwareAddress;  /**< Media address of the sender                    8 +  6 = 14 */
96     uint8_t ucSenderProtocolAddress[ 4 ]; /**< Internetwork address of sender                14 +  4 = 18  */
97     MACAddress_t xTargetHardwareAddress;  /**< Media address of the intended receiver        18 +  6 = 24  */
98     uint32_t ulTargetProtocolAddress;     /**< Internetwork address of the intended receiver 24 +  4 = 28  */
99 }
100 #include "pack_struct_end.h"
101 typedef struct xARP_HEADER ARPHeader_t;
102 
103 #include "pack_struct_start.h"
104 struct xIP_HEADER
105 {
106     uint8_t ucVersionHeaderLength;        /**< The version field + internet header length 0 + 1 =  1 */
107     uint8_t ucDifferentiatedServicesCode; /**< Differentiated services code point + ECN    1 + 1 =  2 */
108     uint16_t usLength;                    /**< Entire Packet size                         2 + 2 =  4 */
109     uint16_t usIdentification;            /**< Identification field                       4 + 2 =  6 */
110     uint16_t usFragmentOffset;            /**< Fragment flags and fragment offset         6 + 2 =  8 */
111     uint8_t ucTimeToLive;                 /**< Time to live field                         8 + 1 =  9 */
112     uint8_t ucProtocol;                   /**< Protocol used in the IP-datagram           9 + 1 = 10 */
113     uint16_t usHeaderChecksum;            /**< Checksum of the IP-header                 10 + 2 = 12 */
114     uint32_t ulSourceIPAddress;           /**< IP address of the source                  12 + 4 = 16 */
115     uint32_t ulDestinationIPAddress;      /**< IP address of the destination             16 + 4 = 20 */
116 }
117 #include "pack_struct_end.h"
118 typedef struct xIP_HEADER IPHeader_t;
119 
120 #include "pack_struct_start.h"
121 struct xICMP_HEADER
122 {
123     uint8_t ucTypeOfMessage;   /**< The ICMP type                     0 + 1 = 1 */
124     uint8_t ucTypeOfService;   /**< The ICMP subtype                  1 + 1 = 2 */
125     uint16_t usChecksum;       /**< The checksum of whole ICMP packet 2 + 2 = 4 */
126     uint16_t usIdentifier;     /**< Used in some types of ICMP        4 + 2 = 6 */
127     uint16_t usSequenceNumber; /**< Used in some types of ICMP        6 + 2 = 8 */
128 }
129 #include "pack_struct_end.h"
130 typedef struct xICMP_HEADER ICMPHeader_t;
131 
132 #include "pack_struct_start.h"
133 struct xUDP_HEADER
134 {
135     uint16_t usSourcePort;      /**< The source port                      0 + 2 = 2 */
136     uint16_t usDestinationPort; /**< The destination port                 2 + 2 = 4 */
137     uint16_t usLength;          /**< The size of the whole UDP packet     4 + 2 = 6 */
138     uint16_t usChecksum;        /**< The checksum of the whole UDP Packet 6 + 2 = 8 */
139 }
140 #include "pack_struct_end.h"
141 typedef struct xUDP_HEADER UDPHeader_t;
142 
143 #include "pack_struct_start.h"
144 struct xTCP_HEADER
145 {
146     uint16_t usSourcePort;                       /**< The Source port                      +  2 =  2 */
147     uint16_t usDestinationPort;                  /**< The destination port                 +  2 =  4 */
148     uint32_t ulSequenceNumber;                   /**< The Sequence number                  +  4 =  8 */
149     uint32_t ulAckNr;                            /**< The acknowledgement number           +  4 = 12 */
150     uint8_t ucTCPOffset;                         /**< The value of TCP offset              +  1 = 13 */
151     uint8_t ucTCPFlags;                          /**< The TCP-flags field                  +  1 = 14 */
152     uint16_t usWindow;                           /**< The size of the receive window       +  2 = 15 */
153     uint16_t usChecksum;                         /**< The checksum of the header           +  2 = 18 */
154     uint16_t usUrgent;                           /**< Pointer to the last urgent data byte +  2 = 20 */
155     #if ipconfigUSE_TCP == 1
156         uint8_t ucOptdata[ ipSIZE_TCP_OPTIONS ]; /**< The options + 12 = 32 */
157     #endif
158 }
159 #include "pack_struct_end.h"
160 typedef struct xTCP_HEADER TCPHeader_t;
161 
162 
163 /*-----------------------------------------------------------*/
164 /* Nested protocol packets.                                  */
165 /*-----------------------------------------------------------*/
166 
167 #include "pack_struct_start.h"
168 struct xARP_PACKET
169 {
170     EthernetHeader_t xEthernetHeader; /**< The ethernet header of an ARP Packet  0 + 14 = 14 */
171     ARPHeader_t xARPHeader;           /**< The ARP header of an ARP Packet       14 + 28 = 42 */
172 }
173 #include "pack_struct_end.h"
174 typedef struct xARP_PACKET ARPPacket_t;
175 
176 #include "pack_struct_start.h"
177 struct xIP_PACKET
178 {
179     EthernetHeader_t xEthernetHeader;
180     IPHeader_t xIPHeader;
181 }
182 #include "pack_struct_end.h"
183 typedef struct xIP_PACKET IPPacket_t;
184 
185 #include "pack_struct_start.h"
186 struct xICMP_PACKET
187 {
188     EthernetHeader_t xEthernetHeader; /**< The Ethernet header of an ICMP packet. */
189     IPHeader_t xIPHeader;             /**< The IP header of an ICMP packet. */
190     ICMPHeader_t xICMPHeader;         /**< The ICMP header of an ICMP packet. */
191 }
192 #include "pack_struct_end.h"
193 typedef struct xICMP_PACKET ICMPPacket_t;
194 
195 #include "pack_struct_start.h"
196 struct xUDP_PACKET
197 {
198     EthernetHeader_t xEthernetHeader; /**< UDP-Packet ethernet header  0 + 14 = 14 */
199     IPHeader_t xIPHeader;             /**< UDP-Packet IP header        14 + 20 = 34 */
200     UDPHeader_t xUDPHeader;           /**< UDP-Packet UDP header       34 +  8 = 42 */
201 }
202 #include "pack_struct_end.h"
203 typedef struct xUDP_PACKET UDPPacket_t;
204 
205 #include "pack_struct_start.h"
206 struct xTCP_PACKET
207 {
208     EthernetHeader_t xEthernetHeader; /**< The ethernet header  0 + 14 = 14 */
209     IPHeader_t xIPHeader;             /**< The IP header        14 + 20 = 34 */
210     TCPHeader_t xTCPHeader;           /**< The TCP header       34 + 32 = 66 */
211 }
212 #include "pack_struct_end.h"
213 typedef struct xTCP_PACKET TCPPacket_t;
214 
215 /**
216  * Union for the protocol packet to save space. Any packet cannot have more than one
217  * of the below protocol packets.
218  */
219 typedef union XPROT_PACKET
220 {
221     ARPPacket_t xARPPacket;   /**< Union member: ARP packet struct */
222     TCPPacket_t xTCPPacket;   /**< Union member: TCP packet struct */
223     UDPPacket_t xUDPPacket;   /**< Union member: UDP packet struct */
224     ICMPPacket_t xICMPPacket; /**< Union member: ICMP packet struct */
225 } ProtocolPacket_t;
226 
227 /**
228  * Union for protocol headers to save space (RAM). Any packet cannot have more than one of
229  * the below protocols.
230  */
231 typedef union xPROT_HEADERS
232 {
233     ICMPHeader_t xICMPHeader; /**< Union member: ICMP header */
234     UDPHeader_t xUDPHeader;   /**< Union member: UDP header */
235     TCPHeader_t xTCPHeader;   /**< Union member: TCP header */
236 } ProtocolHeaders_t;
237 
238 /* The maximum UDP payload length. */
239 #define ipMAX_UDP_PAYLOAD_LENGTH    ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER ) - ipSIZE_OF_UDP_HEADER )
240 
241 typedef enum
242 {
243     eReleaseBuffer = 0,   /* Processing the frame did not find anything to do - just release the buffer. */
244     eProcessBuffer,       /* An Ethernet frame has a valid address - continue process its contents. */
245     eReturnEthernetFrame, /* The Ethernet frame contains an ARP or ICMP packet that can be returned to its source. */
246     eFrameConsumed,       /* Processing the Ethernet packet contents resulted in the payload being sent to the stack. */
247     eWaitingARPResolution /* Frame is awaiting ARP resolution. */
248 } eFrameProcessingResult_t;
249 
250 typedef enum
251 {
252     eNoEvent = -1,
253     eNetworkDownEvent,     /* 0: The network interface has been lost and/or needs [re]connecting. */
254     eNetworkRxEvent,       /* 1: The network interface has queued a received Ethernet frame. */
255     eNetworkTxEvent,       /* 2: Let the IP-task send a network packet. */
256     eARPTimerEvent,        /* 3: The ARP timer expired. */
257     eStackTxEvent,         /* 4: The software stack has queued a packet to transmit. */
258     eDHCPEvent,            /* 5: Process the DHCP state machine. */
259     eTCPTimerEvent,        /* 6: See if any TCP socket needs attention. */
260     eTCPAcceptEvent,       /* 7: Client API FreeRTOS_accept() waiting for client connections. */
261     eTCPNetStat,           /* 8: IP-task is asked to produce a netstat listing. */
262     eSocketBindEvent,      /* 9: Send a message to the IP-task to bind a socket to a port. */
263     eSocketCloseEvent,     /*10: Send a message to the IP-task to close a socket. */
264     eSocketSelectEvent,    /*11: Send a message to the IP-task for select(). */
265     eSocketSignalEvent,    /*12: A socket must be signalled. */
266     eSocketSetDeleteEvent, /*13: A socket set must be deleted. */
267 } eIPEvent_t;
268 
269 /**
270  * Structure for the information of the commands issued to the IP task.
271  */
272 typedef struct IP_TASK_COMMANDS
273 {
274     eIPEvent_t eEventType; /**< The event-type enum */
275     void * pvData;         /**< The data in the event */
276 } IPStackEvent_t;
277 
278 #define ipBROADCAST_IP_ADDRESS               0xffffffffU
279 
280 /* Offset into the Ethernet frame that is used to temporarily store information
281  * on the fragmentation status of the packet being sent.  The value is important,
282  * as it is past the location into which the destination address will get placed. */
283 #define ipFRAGMENTATION_PARAMETERS_OFFSET    ( 6 )
284 #define ipSOCKET_OPTIONS_OFFSET              ( 6 )
285 
286 
287 /* The offset into a UDP packet at which the UDP data (payload) starts. */
288 #define ipUDP_PAYLOAD_OFFSET_IPv4    ( sizeof( UDPPacket_t ) )
289 
290 /* The offset into an IP packet into which the IP data (payload) starts. */
291 #define ipIP_PAYLOAD_OFFSET          ( sizeof( IPPacket_t ) )
292 
293 #if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
294 
295 /* Ethernet frame types. */
296     #define ipARP_FRAME_TYPE                   ( 0x0608U )
297     #define ipIPv4_FRAME_TYPE                  ( 0x0008U )
298 
299 /* ARP related definitions. */
300     #define ipARP_PROTOCOL_TYPE                ( 0x0008U )
301     #define ipARP_HARDWARE_TYPE_ETHERNET       ( 0x0100U )
302     #define ipARP_REQUEST                      ( 0x0100U )
303     #define ipARP_REPLY                        ( 0x0200U )
304 
305 /* The bits in the two byte IP header field that make up the fragment offset value. */
306     #define ipFRAGMENT_OFFSET_BIT_MASK         ( ( uint16_t ) 0xff1fU )
307 
308 /* The bits in the two byte IP header field that make up the flags value. */
309     #define ipFRAGMENT_FLAGS_BIT_MASK          ( ( uint16_t ) 0x00e0U )
310 
311 /* Don't Fragment Flag */
312     #define ipFRAGMENT_FLAGS_DONT_FRAGMENT     ( ( uint16_t ) 0x0040U )
313 
314 /* More Fragments Flag */
315     #define ipFRAGMENT_FLAGS_MORE_FRAGMENTS    ( ( uint16_t ) 0x0020U )
316 
317 #else /* if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) */
318 
319 /* Ethernet frame types. */
320     #define ipARP_FRAME_TYPE                   ( 0x0806U )
321     #define ipIPv4_FRAME_TYPE                  ( 0x0800U )
322 
323 /* ARP related definitions. */
324     #define ipARP_PROTOCOL_TYPE                ( 0x0800U )
325     #define ipARP_HARDWARE_TYPE_ETHERNET       ( 0x0001U )
326     #define ipARP_REQUEST                      ( 0x0001 )
327     #define ipARP_REPLY                        ( 0x0002 )
328 
329 /* The bits in the two byte IP header field that make up the fragment offset value. */
330     #define ipFRAGMENT_OFFSET_BIT_MASK         ( ( uint16_t ) 0x1fffU )
331 
332 /* The bits in the two byte IP header field that make up the flags value. */
333     #define ipFRAGMENT_FLAGS_BIT_MASK          ( ( uint16_t ) 0xe000U )
334 
335 /* Don't Fragment Flag */
336     #define ipFRAGMENT_FLAGS_DONT_FRAGMENT     ( ( uint16_t ) 0x4000U )
337 
338 /* More Fragments Flag */
339     #define ipFRAGMENT_FLAGS_MORE_FRAGMENTS    ( ( uint16_t ) 0x2000U )
340 
341 #endif /* ipconfigBYTE_ORDER */
342 
343 /* For convenience, a MAC address of all zeros and another of all 0xffs are
344  * defined const for quick reference. */
345 extern const MACAddress_t xBroadcastMACAddress; /* all 0xff's */
346 extern uint16_t usPacketIdentifier;
347 
348 /** @brief The list that contains mappings between sockets and port numbers.
349  *         Accesses to this list must be protected by critical sections of
350  *         some kind.
351  */
352 extern List_t xBoundUDPSocketsList;
353 
354 /**
355  * Define a default UDP packet header (declared in FreeRTOS_UDP_IP.c)
356  */
357 typedef union xUDPPacketHeader
358 {
359     uint8_t ucBytes[ 24 ]; /**< Member: 8-bit array */
360     uint32_t ulWords[ 6 ]; /**< Member: 32-bit array */
361 } UDPPacketHeader_t;
362 extern UDPPacketHeader_t xDefaultPartUDPPacketHeader;
363 
364 
365 /* Structure that stores the netmask, gateway address and DNS server addresses. */
366 extern NetworkAddressingParameters_t xNetworkAddressing;
367 
368 /* Structure that stores the defaults for netmask, gateway address and DNS.
369  * These values will be copied to 'xNetworkAddressing' in case DHCP is not used,
370  * and also in case DHCP does not lead to a confirmed request. */
371 /*lint -e9003*/
372 extern NetworkAddressingParameters_t xDefaultAddressing; /*lint !e9003 could define variable 'xDefaultAddressing' at block scope [MISRA 2012 Rule 8.9, advisory]. */
373 
374 /* True when BufferAllocation_1.c was included, false for BufferAllocation_2.c */
375 extern const BaseType_t xBufferAllocFixedSize;
376 
377 /* Defined in FreeRTOS_Sockets.c */
378 #if ( ipconfigUSE_TCP == 1 )
379     extern List_t xBoundTCPSocketsList;
380 #endif
381 
382 /* The local IP address is accessed from within xDefaultPartUDPPacketHeader,
383  * rather than duplicated in its own variable. */
384 #define ipLOCAL_IP_ADDRESS_POINTER     ( ( uint32_t * ) &( xDefaultPartUDPPacketHeader.ulWords[ 20U / sizeof( uint32_t ) ] ) )
385 
386 /* The local MAC address is accessed from within xDefaultPartUDPPacketHeader,
387  * rather than duplicated in its own variable. */
388 #define ipLOCAL_MAC_ADDRESS            ( xDefaultPartUDPPacketHeader.ucBytes )
389 
390 /* ICMP packets are sent using the same function as UDP packets.  The port
391  * number is used to distinguish between the two, as 0 is an invalid UDP port. */
392 #define ipPACKET_CONTAINS_ICMP_DATA    ( 0 )
393 
394 /* For now, the lower 8 bits in 'xEventBits' will be reserved for the above
395  * socket events. */
396 #define SOCKET_EVENT_BIT_COUNT         8
397 
398 #define vSetField16( pxBase, xType, xField, usValue )                                                        \
399     {                                                                                                        \
400         ( ( uint8_t * ) ( pxBase ) )[ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( usValue ) >> 8 );    \
401         ( ( uint8_t * ) ( pxBase ) )[ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( usValue ) & 0xffU ); \
402     }
403 
404 #define vSetField32( pxBase, xType, xField, ulValue )                                                                  \
405     {                                                                                                                  \
406         ( ( uint8_t * ) ( pxBase ) )[ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( ulValue ) >> 24 );             \
407         ( ( uint8_t * ) ( pxBase ) )[ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( ( ulValue ) >> 16 ) & 0xffU ); \
408         ( ( uint8_t * ) ( pxBase ) )[ offsetof( xType, xField ) + 2 ] = ( uint8_t ) ( ( ( ulValue ) >> 8 ) & 0xffU );  \
409         ( ( uint8_t * ) ( pxBase ) )[ offsetof( xType, xField ) + 3 ] = ( uint8_t ) ( ( ulValue ) & 0xffU );           \
410     }
411 
412 #define vFlip_16( left, right )  \
413     do {                         \
414         uint16_t tmp = ( left ); \
415         ( left ) = ( right );    \
416         ( right ) = tmp;         \
417     } while( ipFALSE_BOOL )
418 
419 #define vFlip_32( left, right )  \
420     do {                         \
421         uint32_t tmp = ( left ); \
422         ( left ) = ( right );    \
423         ( right ) = tmp;         \
424     } while( ipFALSE_BOOL )
425 
426 /* WARNING: Do NOT use this macro when the array was received as a parameter. */
427 #ifndef ARRAY_SIZE
428     #define ARRAY_SIZE( x )    ( ( BaseType_t ) ( sizeof( x ) / sizeof( ( x )[ 0 ] ) ) )
429 #endif
430 
431 #ifndef ARRAY_USIZE
432     #define ARRAY_USIZE( x )    ( ( UBaseType_t ) ( sizeof( x ) / sizeof( ( x )[ 0 ] ) ) )
433 #endif
434 
435 /*
436  * Create a message that contains a command to initialise the network interface.
437  * This is used during initialisation, and at any time the network interface
438  * goes down thereafter.  The network interface hardware driver is responsible
439  * for sending the message that contains the network interface down command/
440  * event.
441  *
442  * Only use the FreeRTOS_NetworkDownFromISR() version if the function is to be
443  * called from an interrupt service routine.  If FreeRTOS_NetworkDownFromISR()
444  * returns a non-zero value then a context switch should be performed before
445  * the interrupt is exited.
446  */
447 void FreeRTOS_NetworkDown( void );
448 BaseType_t FreeRTOS_NetworkDownFromISR( void );
449 
450 /*
451  * Processes incoming ARP packets.
452  */
453 eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame );
454 
455 /*
456  * Inspect an Ethernet frame to see if it contains data that the stack needs to
457  * process.  eProcessBuffer is returned if the frame should be processed by the
458  * stack.  eReleaseBuffer is returned if the frame should be discarded.
459  */
460 eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer );
461 
462 /*
463  * Return the checksum generated over xDataLengthBytes from pucNextData.
464  */
465 uint16_t usGenerateChecksum( uint16_t usSum,
466                              const uint8_t * pucNextData,
467                              size_t uxByteCount );
468 
469 /* Socket related private functions. */
470 
471 /*
472  * The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
473  * payload size (excluding packet headers) and that the packet in pucEthernetBuffer
474  * is at least the size of UDPPacket_t.
475  */
476 BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t * pxNetworkBuffer,
477                                       uint16_t usPort,
478                                       BaseType_t * pxIsWaitingForARPResolution );
479 
480 /*
481  * Initialize the socket list data structures for TCP and UDP.
482  */
483 void vNetworkSocketsInit( void );
484 
485 /*
486  * Returns pdTRUE if the IP task has been created and is initialised.  Otherwise
487  * returns pdFALSE.
488  */
489 BaseType_t xIPIsNetworkTaskReady( void );
490 
491 #if ( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
492     struct xSOCKET;
493     typedef void (* SocketWakeupCallback_t)( struct xSOCKET * pxSocket );
494 #endif
495 
496 #if ( ipconfigUSE_TCP == 1 )
497 
498 /*
499  * Actually a user thing, but because xBoundTCPSocketsList, let it do by the
500  * IP-task
501  */
502     #if ( ipconfigHAS_PRINTF != 0 )
503         void vTCPNetStat( void );
504     #endif
505 
506 /*
507  * At least one socket needs to check for timeouts
508  */
509     TickType_t xTCPTimerCheck( BaseType_t xWillSleep );
510 
511 /**
512  * Every TCP socket has a buffer space just big enough to store
513  * the last TCP header received.
514  * As a reference of this field may be passed to DMA, force the
515  * alignment to 8 bytes.
516  */
517     typedef union
518     {
519         struct
520         {
521             uint64_t ullAlignmentWord; /**< Increase the alignment of this union by adding a 64-bit variable. */
522         } a;                           /**< A struct to increase alignment. */
523         struct
524         {
525             /* The next field only serves to give 'ucLastPacket' a correct
526              * alignment of 8 + 2.  See comments in FreeRTOS_IP.h */
527             uint8_t ucFillPacket[ ipconfigPACKET_FILLER_SIZE ];
528             uint8_t ucLastPacket[ sizeof( TCPPacket_t ) ];
529         } u; /**< The structure to give an alignment of 8 + 2 */
530     } LastTCPPacket_t;
531 
532 /**
533  * Note that the values of all short and long integers in these structs
534  * are being stored in the native-endian way
535  * Translation should take place when accessing any structure which defines
536  * network packets, such as IPHeader_t and TCPHeader_t
537  */
538     typedef struct TCPSOCKET
539     {
540         uint32_t ulRemoteIP;   /**< IP address of remote machine */
541         uint16_t usRemotePort; /**< Port on remote machine */
542         struct
543         {
544             /* Most compilers do like bit-flags */
545             uint32_t
546                 bMssChange : 1,        /**< This socket has seen a change in MSS */
547                 bPassAccept : 1,       /**< when true, this socket may be returned in a call to accept() */
548                 bPassQueued : 1,       /**< when true, this socket is an orphan until it gets connected
549                                         * Why an orphan? Because it may not be returned in a accept() call until it
550                                         * gets the state eESTABLISHED */
551                 bReuseSocket : 1,      /**< When a listening socket gets a connection, do not create a new instance but keep on using it */
552                 bCloseAfterSend : 1,   /**< As soon as the last byte has been transmitted, finalise the connection
553                                         * Useful in e.g. FTP connections, where the last data bytes are sent along with the FIN flag */
554                 bUserShutdown : 1,     /**< User requesting a graceful shutdown */
555                 bCloseRequested : 1,   /**< Request to finalise the connection */
556                 bLowWater : 1,         /**< high-water level has been reached. Cleared as soon as 'rx-count < lo-water' */
557                 bWinChange : 1,        /**< The value of bLowWater has changed, must send a window update */
558                 bSendKeepAlive : 1,    /**< When this flag is true, a TCP keep-alive message must be send */
559                 bWaitKeepAlive : 1,    /**< When this flag is true, a TCP keep-alive reply is expected */
560                 bConnPrepared : 1,     /**< Connecting socket: Message has been prepared */
561             #if ( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
562                 bConnPassed : 1,       /**< Connecting socket: Socket has been passed in a successful select()  */
563             #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
564             bFinAccepted : 1,          /**< This socket has received (or sent) a FIN and accepted it */
565                 bFinSent : 1,          /**< We've sent out a FIN */
566                 bFinRecv : 1,          /**< We've received a FIN from our peer */
567                 bFinAcked : 1,         /**< Our FIN packet has been acked */
568                 bFinLast : 1,          /**< The last ACK (after FIN and FIN+ACK) has been sent or will be sent by the peer */
569                 bRxStopped : 1,        /**< Application asked to temporarily stop reception */
570                 bMallocError : 1,      /**< There was an error allocating a stream */
571                 bWinScaling : 1;       /**< A TCP-Window Scaling option was offered and accepted in the SYN phase. */
572         } bits;                        /**< The bits structure */
573         uint32_t ulHighestRxAllowed;   /**< The highest sequence number that we can receive at any moment */
574         uint16_t usTimeout;            /**< Time (in ticks) after which this socket needs attention */
575         uint16_t usMSS;                /**< Current Maximum Segment Size */
576         uint16_t usChildCount;         /**< In case of a listening socket: number of connections on this port number */
577         uint16_t usBacklog;            /**< In case of a listening socket: maximum number of concurrent connections on this port number */
578         uint8_t ucRepCount;            /**< Send repeat count, for retransmissions
579                                         * This counter is separate from the xmitCount in the
580                                         * TCP win segments */
581         eIPTCPState_t eTCPState;       /**< TCP state: see eTCP_STATE */
582         struct xSOCKET * pxPeerSocket; /**< for server socket: child, for child socket: parent */
583         #if ( ipconfigTCP_KEEP_ALIVE == 1 )
584             uint8_t ucKeepRepCount;
585             TickType_t xLastAliveTime; /**< The last value of keepalive time.*/
586         #endif /* ipconfigTCP_KEEP_ALIVE */
587         #if ( ipconfigTCP_HANG_PROTECTION == 1 )
588             TickType_t xLastActTime;                  /**< The last time when hang-protection was done.*/
589         #endif /* ipconfigTCP_HANG_PROTECTION */
590         size_t uxLittleSpace;                         /**< The value deemed as low amount of space. */
591         size_t uxEnoughSpace;                         /**< The value deemed as enough space. */
592         size_t uxRxStreamSize;                        /**< The Receive stream size */
593         size_t uxTxStreamSize;                        /**< The transmit stream size */
594         StreamBuffer_t * rxStream;                    /**< The pointer to the receive stream buffer. */
595         StreamBuffer_t * txStream;                    /**< The pointer to the transmit stream buffer. */
596         #if ( ipconfigUSE_TCP_WIN == 1 )
597             NetworkBufferDescriptor_t * pxAckMessage; /**< The pointer to the ACK message */
598         #endif /* ipconfigUSE_TCP_WIN */
599         LastTCPPacket_t xPacket;                      /**< Buffer space to store the last TCP header received. */
600         uint8_t tcpflags;                             /**< TCP flags */
601         #if ( ipconfigUSE_TCP_WIN != 0 )
602             uint8_t ucMyWinScaleFactor;               /**< Scaling factor of this device. */
603             uint8_t ucPeerWinScaleFactor;             /**< Scaling factor of the peer. */
604         #endif
605         #if ( ipconfigUSE_CALLBACKS == 1 )
606             FOnTCPReceive_t pxHandleReceive;  /**<
607                                                * In case of a TCP socket:
608                                                * typedef void (* FOnTCPReceive_t) (Socket_t xSocket, void *pData, size_t xLength );
609                                                */
610             FOnTCPSent_t pxHandleSent;        /**< Function pointer to handle a successful send event.  */
611             FOnConnected_t pxHandleConnected; /**< Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */
612         #endif /* ipconfigUSE_CALLBACKS */
613         uint32_t ulWindowSize;                /**< Current Window size advertised by peer */
614         size_t uxRxWinSize;                   /**< Fixed value: size of the TCP reception window */
615         size_t uxTxWinSize;                   /**< Fixed value: size of the TCP transmit window */
616 
617         TCPWindow_t xTCPWindow;               /**< The TCP window struct*/
618     } IPTCPSocket_t;
619 
620 #endif /* ipconfigUSE_TCP */
621 
622 /**
623  * Structure to hold the information about a UDP socket.
624  */
625 typedef struct UDPSOCKET
626 {
627     List_t xWaitingPacketsList;   /**< Incoming packets */
628     #if ( ipconfigUDP_MAX_RX_PACKETS > 0 )
629         UBaseType_t uxMaxPackets; /**< Protection: limits the number of packets buffered per socket */
630     #endif /* ipconfigUDP_MAX_RX_PACKETS */
631     #if ( ipconfigUSE_CALLBACKS == 1 )
632         FOnUDPReceive_t pxHandleReceive; /**<
633                                           * In case of a UDP socket:
634                                           * typedef void (* FOnUDPReceive_t) (Socket_t xSocket, void *pData, size_t xLength, struct freertos_sockaddr *pxAddr );
635                                           */
636         FOnUDPSent_t pxHandleSent;       /**< Function pointer to handle the events after a successful send. */
637     #endif /* ipconfigUSE_CALLBACKS */
638 } IPUDPSocket_t;
639 
640 /* Formally typedef'd as eSocketEvent_t. */
641 enum eSOCKET_EVENT
642 {
643     eSOCKET_RECEIVE = 0x0001,
644     eSOCKET_SEND = 0x0002,
645     eSOCKET_ACCEPT = 0x0004,
646     eSOCKET_CONNECT = 0x0008,
647     eSOCKET_BOUND = 0x0010,
648     eSOCKET_CLOSED = 0x0020,
649     eSOCKET_INTR = 0x0040,
650     eSOCKET_ALL = 0x007F,
651 };
652 
653 
654 /**
655  * Structure to hold information for a socket.
656  */
657 typedef struct xSOCKET
658 {
659     EventBits_t xEventBits;                /**< The eventbits to keep track of events. */
660     EventGroupHandle_t xEventGroup;        /**< The event group for this socket. */
661 
662     ListItem_t xBoundSocketListItem;       /**< Used to reference the socket from a bound sockets list. */
663     TickType_t xReceiveBlockTime;          /**< if recv[to] is called while no data is available, wait this amount of time. Unit in clock-ticks */
664     TickType_t xSendBlockTime;             /**< if send[to] is called while there is not enough space to send, wait this amount of time. Unit in clock-ticks */
665 
666     uint16_t usLocalPort;                  /**< Local port on this machine */
667     uint8_t ucSocketOptions;               /**< Socket options */
668     uint8_t ucProtocol;                    /**< choice of FREERTOS_IPPROTO_UDP/TCP */
669     #if ( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
670         SemaphoreHandle_t pxUserSemaphore; /**< The user semaphore */
671     #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
672     #if ( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
673         SocketWakeupCallback_t pxUserWakeCallback; /**< Pointer to the callback function. */
674     #endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
675 
676     #if ( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
677         struct xSOCKET_SET * pxSocketSet; /**< Pointer to the socket set structure */
678         EventBits_t xSelectBits;          /**< User may indicate which bits are interesting for this socket. */
679 
680         EventBits_t xSocketBits;          /**< These bits indicate the events which have actually occurred.
681                                            * They are maintained by the IP-task */
682     #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
683     /* TCP/UDP specific fields: */
684     /* Before accessing any member of this structure, it should be confirmed */
685     /* that the protocol corresponds with the type of structure */
686 
687     union
688     {
689         IPUDPSocket_t xUDP;           /**< Union member: UDP socket*/
690         #if ( ipconfigUSE_TCP == 1 )
691             IPTCPSocket_t xTCP;       /**< Union member: TCP socket */
692 
693             uint64_t ullTCPAlignment; /**< Make sure that xTCP is 8-bytes aligned by
694                                        * declaring a 64-bit variable in the same union */
695         #endif /* ipconfigUSE_TCP */
696     } u;                              /**< Union of TCP/UDP socket */
697 } FreeRTOS_Socket_t;
698 
699 #if ( ipconfigUSE_TCP == 1 )
700 
701 /*
702  * Close the socket another time.
703  */
704     void vSocketCloseNextTime( FreeRTOS_Socket_t * pxSocket );
705 
706 /*
707  * Postpone a call to listen() by the IP-task.
708  */
709     void vSocketListenNextTime( FreeRTOS_Socket_t * pxSocket );
710 
711 /*
712  * Lookup a TCP socket, using a multiple matching: both port numbers and
713  * return IP address.
714  */
715     FreeRTOS_Socket_t * pxTCPSocketLookup( uint32_t ulLocalIP,
716                                            UBaseType_t uxLocalPort,
717                                            uint32_t ulRemoteIP,
718                                            UBaseType_t uxRemotePort );
719 
720 #endif /* ipconfigUSE_TCP */
721 
722 
723 /*
724  * Look up a local socket by finding a match with the local port.
725  */
726 FreeRTOS_Socket_t * pxUDPSocketLookup( UBaseType_t uxLocalPort );
727 
728 /*
729  * Calculate the upper-layer checksum
730  * Works both for UDP, ICMP and TCP packages
731  * bOut = true: checksum will be set in outgoing packets
732  * bOut = false: checksum will be calculated for incoming packets
733  *     returning 0xffff means: checksum was correct
734  */
735 uint16_t usGenerateProtocolChecksum( uint8_t * pucEthernetBuffer,
736                                      size_t uxBufferLength,
737                                      BaseType_t xOutgoingPacket );
738 
739 /*
740  * An Ethernet frame has been updated (maybe it was an ARP request or a PING
741  * request?) and is to be sent back to its source.
742  */
743 void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer,
744                            BaseType_t xReleaseAfterSend );
745 
746 /*
747  * The internal version of bind()
748  * If 'ulInternal' is true, it is called by the driver
749  * The TCP driver needs to bind a socket at the moment a listening socket
750  * creates a new connected socket
751  */
752 BaseType_t vSocketBind( FreeRTOS_Socket_t * pxSocket,
753                         struct freertos_sockaddr * pxBindAddress,
754                         size_t uxAddressLength,
755                         BaseType_t xInternal );
756 
757 /*
758  * Internal function to add streaming data to a TCP socket. If ulIn == true,
759  * data will be added to the rxStream, otherwise to the tXStream.  Normally data
760  * will be written with ulOffset == 0, meaning: at the end of the FIFO.  When
761  * packet come in out-of-order, an offset will be used to put it in front and
762  * the head will not change yet.
763  */
764 int32_t lTCPAddRxdata( FreeRTOS_Socket_t * pxSocket,
765                        size_t uxOffset,
766                        const uint8_t * pcData,
767                        uint32_t ulByteCount );
768 
769 /*
770  * Currently called for any important event.
771  */
772 void vSocketWakeUpUser( FreeRTOS_Socket_t * pxSocket );
773 
774 /*
775  * Some helping function, their meaning should be clear.
776  * Going by MISRA rules, these utility functions should not be defined
777  * if they are not being used anywhere. But their use depends on the
778  * application and hence these functions are defined unconditionally.
779  */
780 extern uint32_t ulChar2u32( const uint8_t * pucPtr );
781 
782 extern uint16_t usChar2u16( const uint8_t * pucPtr );
783 
784 /* Check a single socket for retransmissions and timeouts */
785 BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t * pxSocket );
786 
787 BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t * pxSocket );
788 
789 /* Defined in FreeRTOS_Sockets.c
790  * Close a socket
791  */
792 void * vSocketClose( FreeRTOS_Socket_t * pxSocket );
793 
794 /*
795  * Send the event eEvent to the IP task event queue, using a block time of
796  * zero.  Return pdPASS if the message was sent successfully, otherwise return
797  * pdFALSE.
798  */
799 BaseType_t xSendEventToIPTask( eIPEvent_t eEvent );
800 
801 /*
802  * The same as above, but a struct as a parameter, containing:
803  *      eIPEvent_t eEventType;
804  *      void *pvData;
805  */
806 BaseType_t xSendEventStructToIPTask( const IPStackEvent_t * pxEvent,
807                                      TickType_t uxTimeout );
808 
809 /*
810  * Returns a pointer to the original NetworkBuffer from a pointer to a UDP
811  * payload buffer.
812  */
813 NetworkBufferDescriptor_t * pxUDPPayloadBuffer_to_NetworkBuffer( const void * pvBuffer );
814 
815 /*
816  * Internal: Sets a new state for a TCP socket and performs the necessary
817  * actions like calling a OnConnected handler to notify the socket owner.
818  */
819 #if ( ipconfigUSE_TCP == 1 )
820     void vTCPStateChange( FreeRTOS_Socket_t * pxSocket,
821                           enum eTCP_STATE eTCPState );
822 #endif /* ipconfigUSE_TCP */
823 
824 /* Returns pdTRUE is this function is called from the IP-task */
825 BaseType_t xIsCallingFromIPTask( void );
826 
827 #if ( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
828 
829 /** @brief Structure for event groups of the Socket Select functions */
830     typedef struct xSOCKET_SET
831     {
832         /** @brief Event group for the socket select function.
833          */
834         EventGroupHandle_t xSelectGroup;
835     } SocketSelect_t;
836 
837     extern void vSocketSelect( const SocketSelect_t * pxSocketSet );
838 
839 /** @brief Define the data that must be passed for a 'eSocketSelectEvent'. */
840     typedef struct xSocketSelectMessage
841     {
842         TaskHandle_t xTaskhandle;     /**< Task handle for use in the socket select functionality. */
843         SocketSelect_t * pxSocketSet; /**< The event group for the socket select functionality. */
844     } SocketSelectMessage_t;
845 
846 #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
847 
848 /* Send the network-up event and start the ARP timer. */
849 void vIPNetworkUpCalls( void );
850 
851 /* *INDENT-OFF* */
852 #ifdef __cplusplus
853     } /* extern "C" */
854 #endif
855 /* *INDENT-ON* */
856 
857 #endif /* FREERTOS_IP_PRIVATE_H */
858