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