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