X-Git-Url: https://git.sur5r.net/?p=freertos;a=blobdiff_plain;f=FreeRTOS-Plus%2FSource%2FFreeRTOS-Plus-TCP%2Finclude%2FFreeRTOS_IP_Private.h;fp=FreeRTOS-Plus%2FSource%2FFreeRTOS-Plus-TCP%2Finclude%2FFreeRTOS_IP_Private.h;h=0d8c0387210aab5920e844f08aae3d365de89bdd;hp=8604abed05a7030da1f59af9c5f9d8b9444337f1;hb=b15dfacb6026af3b0ba697e5753844923b468d2b;hpb=4334233a064299a09d167a497889d3860932a587 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h index 8604abed0..0d8c03872 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h @@ -1,827 +1,827 @@ -/* - * FreeRTOS+TCP V2.2.0 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -#ifndef FREERTOS_IP_PRIVATE_H -#define FREERTOS_IP_PRIVATE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Application level configuration options. */ -#include "FreeRTOSIPConfig.h" -#include "FreeRTOSIPConfigDefaults.h" -#include "FreeRTOS_Sockets.h" -#include "IPTraceMacroDefaults.h" -#include "FreeRTOS_Stream_Buffer.h" -#if( ipconfigUSE_TCP == 1 ) - #include "FreeRTOS_TCP_WIN.h" - #include "FreeRTOS_TCP_IP.h" -#endif - -#include "event_groups.h" - -typedef struct xNetworkAddressingParameters -{ - uint32_t ulDefaultIPAddress; - uint32_t ulNetMask; - uint32_t ulGatewayAddress; - uint32_t ulDNSServerAddress; - uint32_t ulBroadcastAddress; -} NetworkAddressingParameters_t; - -extern BaseType_t xTCPWindowLoggingLevel; - -/*-----------------------------------------------------------*/ -/* Protocol headers. */ -/*-----------------------------------------------------------*/ - -#include "pack_struct_start.h" -struct xETH_HEADER -{ - MACAddress_t xDestinationAddress; /* 0 + 6 = 6 */ - MACAddress_t xSourceAddress; /* 6 + 6 = 12 */ - uint16_t usFrameType; /* 12 + 2 = 14 */ -} -#include "pack_struct_end.h" -typedef struct xETH_HEADER EthernetHeader_t; - -#include "pack_struct_start.h" -struct xARP_HEADER -{ - uint16_t usHardwareType; /* 0 + 2 = 2 */ - uint16_t usProtocolType; /* 2 + 2 = 4 */ - uint8_t ucHardwareAddressLength; /* 4 + 1 = 5 */ - uint8_t ucProtocolAddressLength; /* 5 + 1 = 6 */ - uint16_t usOperation; /* 6 + 2 = 8 */ - MACAddress_t xSenderHardwareAddress; /* 8 + 6 = 14 */ - uint8_t ucSenderProtocolAddress[ 4 ]; /* 14 + 4 = 18 */ - MACAddress_t xTargetHardwareAddress; /* 18 + 6 = 24 */ - uint32_t ulTargetProtocolAddress; /* 24 + 4 = 28 */ -} -#include "pack_struct_end.h" -typedef struct xARP_HEADER ARPHeader_t; - -#include "pack_struct_start.h" -struct xIP_HEADER -{ - uint8_t ucVersionHeaderLength; /* 0 + 1 = 1 */ - uint8_t ucDifferentiatedServicesCode; /* 1 + 1 = 2 */ - uint16_t usLength; /* 2 + 2 = 4 */ - uint16_t usIdentification; /* 4 + 2 = 6 */ - uint16_t usFragmentOffset; /* 6 + 2 = 8 */ - uint8_t ucTimeToLive; /* 8 + 1 = 9 */ - uint8_t ucProtocol; /* 9 + 1 = 10 */ - uint16_t usHeaderChecksum; /* 10 + 2 = 12 */ - uint32_t ulSourceIPAddress; /* 12 + 4 = 16 */ - uint32_t ulDestinationIPAddress; /* 16 + 4 = 20 */ -} -#include "pack_struct_end.h" -typedef struct xIP_HEADER IPHeader_t; - -#include "pack_struct_start.h" -struct xIGMP_HEADER -{ - uint8_t ucVersionType; /* 0 + 1 = 1 */ - uint8_t ucMaxResponseTime; /* 1 + 1 = 2 */ - uint16_t usChecksum; /* 2 + 2 = 4 */ - uint32_t usGroupAddress; /* 4 + 4 = 8 */ -} -#include "pack_struct_end.h" -typedef struct xIGMP_HEADER IGMPHeader_t; - -#include "pack_struct_start.h" -struct xICMP_HEADER -{ - uint8_t ucTypeOfMessage; /* 0 + 1 = 1 */ - uint8_t ucTypeOfService; /* 1 + 1 = 2 */ - uint16_t usChecksum; /* 2 + 2 = 4 */ - uint16_t usIdentifier; /* 4 + 2 = 6 */ - uint16_t usSequenceNumber; /* 6 + 2 = 8 */ -} -#include "pack_struct_end.h" -typedef struct xICMP_HEADER ICMPHeader_t; - -#include "pack_struct_start.h" -struct xUDP_HEADER -{ - uint16_t usSourcePort; /* 0 + 2 = 2 */ - uint16_t usDestinationPort; /* 2 + 2 = 4 */ - uint16_t usLength; /* 4 + 2 = 6 */ - uint16_t usChecksum; /* 6 + 2 = 8 */ -} -#include "pack_struct_end.h" -typedef struct xUDP_HEADER UDPHeader_t; - -#include "pack_struct_start.h" -struct xTCP_HEADER -{ - uint16_t usSourcePort; /* + 2 = 2 */ - uint16_t usDestinationPort; /* + 2 = 4 */ - uint32_t ulSequenceNumber; /* + 4 = 8 */ - uint32_t ulAckNr; /* + 4 = 12 */ - uint8_t ucTCPOffset; /* + 1 = 13 */ - uint8_t ucTCPFlags; /* + 1 = 14 */ - uint16_t usWindow; /* + 2 = 15 */ - uint16_t usChecksum; /* + 2 = 18 */ - uint16_t usUrgent; /* + 2 = 20 */ -#if ipconfigUSE_TCP == 1 - /* the option data is not a part of the TCP header */ - uint8_t ucOptdata[ipSIZE_TCP_OPTIONS]; /* + 12 = 32 */ -#endif -} -#include "pack_struct_end.h" -typedef struct xTCP_HEADER TCPHeader_t; - -#include "pack_struct_start.h" -struct xPSEUDO_HEADER -{ - uint32_t ulSourceAddress; - uint32_t ulDestinationAddress; - uint8_t ucZeros; - uint8_t ucProtocol; - uint16_t usUDPLength; -} -#include "pack_struct_end.h" -typedef struct xPSEUDO_HEADER PseudoHeader_t; - -/*-----------------------------------------------------------*/ -/* Nested protocol packets. */ -/*-----------------------------------------------------------*/ - -#include "pack_struct_start.h" -struct xARP_PACKET -{ - EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */ - ARPHeader_t xARPHeader; /* 14 + 28 = 42 */ -} -#include "pack_struct_end.h" -typedef struct xARP_PACKET ARPPacket_t; - -#include "pack_struct_start.h" -struct xIP_PACKET -{ - EthernetHeader_t xEthernetHeader; - IPHeader_t xIPHeader; -} -#include "pack_struct_end.h" -typedef struct xIP_PACKET IPPacket_t; - -#include "pack_struct_start.h" -struct xICMP_PACKET -{ - EthernetHeader_t xEthernetHeader; - IPHeader_t xIPHeader; - ICMPHeader_t xICMPHeader; -} -#include "pack_struct_end.h" -typedef struct xICMP_PACKET ICMPPacket_t; - -#include "pack_struct_start.h" -struct xUDP_PACKET -{ - EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */ - IPHeader_t xIPHeader; /* 14 + 20 = 34 */ - UDPHeader_t xUDPHeader; /* 34 + 8 = 42 */ -} -#include "pack_struct_end.h" -typedef struct xUDP_PACKET UDPPacket_t; - -#include "pack_struct_start.h" -struct xTCP_PACKET -{ - EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */ - IPHeader_t xIPHeader; /* 14 + 20 = 34 */ - TCPHeader_t xTCPHeader; /* 34 + 32 = 66 */ -} -#include "pack_struct_end.h" -typedef struct xTCP_PACKET TCPPacket_t; - -typedef union XPROT_PACKET -{ - ARPPacket_t xARPPacket; - TCPPacket_t xTCPPacket; - UDPPacket_t xUDPPacket; - ICMPPacket_t xICMPPacket; -} ProtocolPacket_t; - - -/* The maximum UDP payload length. */ -#define ipMAX_UDP_PAYLOAD_LENGTH ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER ) - ipSIZE_OF_UDP_HEADER ) - -typedef enum -{ - eReleaseBuffer = 0, /* Processing the frame did not find anything to do - just release the buffer. */ - eProcessBuffer, /* An Ethernet frame has a valid address - continue process its contents. */ - eReturnEthernetFrame, /* The Ethernet frame contains an ARP or ICMP packet that can be returned to its source. */ - eFrameConsumed /* Processing the Ethernet packet contents resulted in the payload being sent to the stack. */ -} eFrameProcessingResult_t; - -typedef enum -{ - eNoEvent = -1, - eNetworkDownEvent, /* 0: The network interface has been lost and/or needs [re]connecting. */ - eNetworkRxEvent, /* 1: The network interface has queued a received Ethernet frame. */ - eNetworkTxEvent, /* 2: Let the IP-task send a network packet. */ - eARPTimerEvent, /* 3: The ARP timer expired. */ - eStackTxEvent, /* 4: The software stack has queued a packet to transmit. */ - eDHCPEvent, /* 5: Process the DHCP state machine. */ - eTCPTimerEvent, /* 6: See if any TCP socket needs attention. */ - eTCPAcceptEvent, /* 7: Client API FreeRTOS_accept() waiting for client connections. */ - eTCPNetStat, /* 8: IP-task is asked to produce a netstat listing. */ - eSocketBindEvent, /* 9: Send a message to the IP-task to bind a socket to a port. */ - eSocketCloseEvent, /*10: Send a message to the IP-task to close a socket. */ - eSocketSelectEvent, /*11: Send a message to the IP-task for select(). */ - eSocketSignalEvent, /*12: A socket must be signalled. */ -} eIPEvent_t; - -typedef struct IP_TASK_COMMANDS -{ - eIPEvent_t eEventType; - void *pvData; -} IPStackEvent_t; - -#define ipBROADCAST_IP_ADDRESS 0xffffffffUL - -/* Offset into the Ethernet frame that is used to temporarily store information -on the fragmentation status of the packet being sent. The value is important, -as it is past the location into which the destination address will get placed. */ -#define ipFRAGMENTATION_PARAMETERS_OFFSET ( 6 ) -#define ipSOCKET_OPTIONS_OFFSET ( 6 ) - -/* Only used when outgoing fragmentation is being used (FreeRTOSIPConfig.h -setting. */ -#define ipGET_UDP_PAYLOAD_OFFSET_FOR_FRAGMENT( usFragmentOffset ) ( ( ( usFragmentOffset ) == 0 ) ? ipUDP_PAYLOAD_OFFSET_IPv4 : ipIP_PAYLOAD_OFFSET ) - -/* The offset into a UDP packet at which the UDP data (payload) starts. */ -#define ipUDP_PAYLOAD_OFFSET_IPv4 ( sizeof( UDPPacket_t ) ) - -/* The offset into an IP packet into which the IP data (payload) starts. */ -#define ipIP_PAYLOAD_OFFSET ( sizeof( IPPacket_t ) ) - -#include "pack_struct_start.h" -struct xUDP_IP_FRAGMENT_PARAMETERS -{ - uint8_t ucSocketOptions; - uint8_t ucPadFor16BitAlignment; - uint16_t usFragmentedPacketOffset; - uint16_t usFragmentLength; - uint16_t usPayloadChecksum; -} -#include "pack_struct_end.h" -typedef struct xUDP_IP_FRAGMENT_PARAMETERS IPFragmentParameters_t; - -#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) - - /* Ethernet frame types. */ - #define ipARP_FRAME_TYPE ( 0x0608U ) - #define ipIPv4_FRAME_TYPE ( 0x0008U ) - - /* ARP related definitions. */ - #define ipARP_PROTOCOL_TYPE ( 0x0008U ) - #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0100U ) - #define ipARP_REQUEST ( 0x0100U ) - #define ipARP_REPLY ( 0x0200U ) - -#else - - /* Ethernet frame types. */ - #define ipARP_FRAME_TYPE ( 0x0806U ) - #define ipIPv4_FRAME_TYPE ( 0x0800U ) - - /* ARP related definitions. */ - #define ipARP_PROTOCOL_TYPE ( 0x0800U ) - #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0001U ) - #define ipARP_REQUEST ( 0x0001 ) - #define ipARP_REPLY ( 0x0002 ) - -#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */ - - -/* For convenience, a MAC address of all zeros and another of all 0xffs are -defined const for quick reference. */ -extern const MACAddress_t xBroadcastMACAddress; /* all 0xff's */ -extern uint16_t usPacketIdentifier; - -/* Define a default UDP packet header (declared in FreeRTOS_UDP_IP.c) */ -typedef union xUDPPacketHeader -{ - uint8_t ucBytes[24]; - uint32_t ulWords[6]; -} UDPPacketHeader_t; -extern UDPPacketHeader_t xDefaultPartUDPPacketHeader; - -/* Structure that stores the netmask, gateway address and DNS server addresses. */ -extern NetworkAddressingParameters_t xNetworkAddressing; - -/* Structure that stores the defaults for netmask, gateway address and DNS. -These values will be copied to 'xNetworkAddressing' in case DHCP is not used, -and also in case DHCP does not lead to a confirmed request. */ -extern NetworkAddressingParameters_t xDefaultAddressing; - -/* True when BufferAllocation_1.c was included, false for BufferAllocation_2.c */ -extern const BaseType_t xBufferAllocFixedSize; - -/* Defined in FreeRTOS_Sockets.c */ -#if ( ipconfigUSE_TCP == 1 ) - extern List_t xBoundTCPSocketsList; -#endif - -/* The local IP address is accessed from within xDefaultPartUDPPacketHeader, -rather than duplicated in its own variable. */ -#define ipLOCAL_IP_ADDRESS_POINTER ( ( uint32_t * ) &( xDefaultPartUDPPacketHeader.ulWords[ 20u / sizeof(uint32_t) ] ) ) - -/* The local MAC address is accessed from within xDefaultPartUDPPacketHeader, -rather than duplicated in its own variable. */ -#define ipLOCAL_MAC_ADDRESS ( &xDefaultPartUDPPacketHeader.ucBytes[0] ) - -/* ICMP packets are sent using the same function as UDP packets. The port -number is used to distinguish between the two, as 0 is an invalid UDP port. */ -#define ipPACKET_CONTAINS_ICMP_DATA ( 0 ) - -/* For now, the lower 8 bits in 'xEventBits' will be reserved for the above -socket events. */ -#define SOCKET_EVENT_BIT_COUNT 8 - -#define vSetField16( pxBase, xType, xField, usValue ) \ -{ \ - ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( usValue ) >> 8 ); \ - ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( usValue ) & 0xff ); \ -} - -#define vSetField32( pxBase, xType, xField, ulValue ) \ -{ \ - ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( ulValue ) >> 24 ); \ - ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( ( ulValue ) >> 16 ) & 0xff ); \ - ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 2 ] = ( uint8_t ) ( ( ( ulValue ) >> 8 ) & 0xff ); \ - ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 3 ] = ( uint8_t ) ( ( ulValue ) & 0xff ); \ -} - -#define vFlip_16( left, right ) \ - do { \ - uint16_t tmp = (left); \ - (left) = (right); \ - (right) = tmp; \ - } while (0) - -#define vFlip_32( left, right ) \ - do { \ - uint32_t tmp = (left); \ - (left) = (right); \ - (right) = tmp; \ - } while (0) - -#ifndef ARRAY_SIZE - #define ARRAY_SIZE(x) (BaseType_t)(sizeof(x)/sizeof(x)[0]) -#endif - -/* - * A version of FreeRTOS_GetReleaseNetworkBuffer() that can be called from an - * interrupt. If a non zero value is returned, then the calling ISR should - * perform a context switch before exiting the ISR. - */ -BaseType_t FreeRTOS_ReleaseFreeNetworkBufferFromISR( void ); - -/* - * Create a message that contains a command to initialise the network interface. - * This is used during initialisation, and at any time the network interface - * goes down thereafter. The network interface hardware driver is responsible - * for sending the message that contains the network interface down command/ - * event. - * - * Only use the FreeRTOS_NetworkDownFromISR() version if the function is to be - * called from an interrupt service routine. If FreeRTOS_NetworkDownFromISR() - * returns a non-zero value then a context switch should be performed ebfore - * the interrupt is exited. - */ -void FreeRTOS_NetworkDown( void ); -BaseType_t FreeRTOS_NetworkDownFromISR( void ); - -/* - * Processes incoming ARP packets. - */ -eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame ); - -/* - * Inspect an Ethernet frame to see if it contains data that the stack needs to - * process. eProcessBuffer is returned if the frame should be processed by the - * stack. eReleaseBuffer is returned if the frame should be discarded. - */ -eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer ); - -/* - * Return the checksum generated over xDataLengthBytes from pucNextData. - */ -uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes ); - -/* Socket related private functions. */ - -/* - * The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet - * payload size (excluding packet headers) and that the packet in pucEthernetBuffer - * is at least the size of UDPPacket_t. - */ -BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort ); - -/* - * Initialize the socket list data structures for TCP and UDP. - */ -BaseType_t vNetworkSocketsInit( void ); - -/* - * Returns pdTRUE if the IP task has been created and is initialised. Otherwise - * returns pdFALSE. - */ -BaseType_t xIPIsNetworkTaskReady( void ); - -#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 ) - struct xSOCKET; - typedef void (*SocketWakeupCallback_t)( struct xSOCKET * pxSocket ); -#endif - -#if( ipconfigUSE_TCP == 1 ) - - /* - * Actually a user thing, but because xBoundTCPSocketsList, let it do by the - * IP-task - */ - void vTCPNetStat( void ); - - /* - * At least one socket needs to check for timeouts - */ - TickType_t xTCPTimerCheck( BaseType_t xWillSleep ); - - /* Every TCP socket has a buffer space just big enough to store - the last TCP header received. - As a reference of this field may be passed to DMA, force the - alignment to 8 bytes. */ - typedef union - { - struct - { - /* Increase the alignment of this union by adding a 64-bit variable. */ - uint64_t ullAlignmentWord; - } a; - struct - { - /* The next field only serves to give 'ucLastPacket' a correct - alignment of 8 + 2. See comments in FreeRTOS_IP.h */ - uint8_t ucFillPacket[ ipconfigPACKET_FILLER_SIZE ]; - uint8_t ucLastPacket[ sizeof( TCPPacket_t ) ]; - } u; - } LastTCPPacket_t; - - /* - * Note that the values of all short and long integers in these structs - * are being stored in the native-endian way - * Translation should take place when accessing any structure which defines - * network packets, such as IPHeader_t and TCPHeader_t - */ - typedef struct TCPSOCKET - { - uint32_t ulRemoteIP; /* IP address of remote machine */ - uint16_t usRemotePort; /* Port on remote machine */ - struct { - /* Most compilers do like bit-flags */ - uint32_t - bMssChange : 1, /* This socket has seen a change in MSS */ - bPassAccept : 1, /* when true, this socket may be returned in a call to accept() */ - bPassQueued : 1, /* when true, this socket is an orphan until it gets connected - * Why an orphan? Because it may not be returned in a accept() call until it - * gets the state eESTABLISHED */ - bReuseSocket : 1, /* When a listening socket gets a connection, do not create a new instance but keep on using it */ - bCloseAfterSend : 1,/* As soon as the last byte has been transmitted, finalise the connection - * Useful in e.g. FTP connections, where the last data bytes are sent along with the FIN flag */ - bUserShutdown : 1, /* User requesting a graceful shutdown */ - bCloseRequested : 1,/* Request to finalise the connection */ - bLowWater : 1, /* high-water level has been reached. Cleared as soon as 'rx-count < lo-water' */ - bWinChange : 1, /* The value of bLowWater has changed, must send a window update */ - bSendKeepAlive : 1, /* When this flag is true, a TCP keep-alive message must be send */ - bWaitKeepAlive : 1, /* When this flag is true, a TCP keep-alive reply is expected */ - bConnPrepared : 1, /* Connecting socket: Message has been prepared */ - #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 ) - bConnPassed : 1, /* Connecting socket: Socket has been passed in a successful select() */ - #endif /* ipconfigSUPPORT_SELECT_FUNCTION */ - bFinAccepted : 1, /* This socket has received (or sent) a FIN and accepted it */ - bFinSent : 1, /* We've sent out a FIN */ - bFinRecv : 1, /* We've received a FIN from our peer */ - bFinAcked : 1, /* Our FIN packet has been acked */ - bFinLast : 1, /* The last ACK (after FIN and FIN+ACK) has been sent or will be sent by the peer */ - bRxStopped : 1, /* Application asked to temporarily stop reception */ - bMallocError : 1, /* There was an error allocating a stream */ - bWinScaling : 1; /* A TCP-Window Scaling option was offered and accepted in the SYN phase. */ - } bits; - uint32_t ulHighestRxAllowed; - /* The highest sequence number that we can receive at any moment */ - uint16_t usTimeout; /* Time (in ticks) after which this socket needs attention */ - uint16_t usCurMSS; /* Current Maximum Segment Size */ - uint16_t usInitMSS; /* Initial maximum segment Size */ - uint16_t usChildCount; /* In case of a listening socket: number of connections on this port number */ - uint16_t usBacklog; /* In case of a listening socket: maximum number of concurrent connections on this port number */ - uint8_t ucRepCount; /* Send repeat count, for retransmissions - * This counter is separate from the xmitCount in the - * TCP win segments */ - uint8_t ucTCPState; /* TCP state: see eTCP_STATE */ - struct xSOCKET *pxPeerSocket; /* for server socket: child, for child socket: parent */ - #if( ipconfigTCP_KEEP_ALIVE == 1 ) - uint8_t ucKeepRepCount; - TickType_t xLastAliveTime; - #endif /* ipconfigTCP_KEEP_ALIVE */ - #if( ipconfigTCP_HANG_PROTECTION == 1 ) - TickType_t xLastActTime; - #endif /* ipconfigTCP_HANG_PROTECTION */ - size_t uxLittleSpace; - size_t uxEnoughSpace; - size_t uxRxStreamSize; - size_t uxTxStreamSize; - StreamBuffer_t *rxStream; - StreamBuffer_t *txStream; - #if( ipconfigUSE_TCP_WIN == 1 ) - NetworkBufferDescriptor_t *pxAckMessage; - #endif /* ipconfigUSE_TCP_WIN */ - /* Buffer space to store the last TCP header received. */ - LastTCPPacket_t xPacket; - uint8_t tcpflags; /* TCP flags */ - #if( ipconfigUSE_TCP_WIN != 0 ) - uint8_t ucMyWinScaleFactor; - uint8_t ucPeerWinScaleFactor; - #endif - #if( ipconfigUSE_CALLBACKS == 1 ) - FOnTCPReceive_t pxHandleReceive; /* - * In case of a TCP socket: - * typedef void (* FOnTCPReceive_t) (Socket_t xSocket, void *pData, size_t xLength ); - */ - FOnTCPSent_t pxHandleSent; - FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */ - #endif /* ipconfigUSE_CALLBACKS */ - uint32_t ulWindowSize; /* Current Window size advertised by peer */ - size_t uxRxWinSize; /* Fixed value: size of the TCP reception window */ - size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */ - - TCPWindow_t xTCPWindow; - } IPTCPSocket_t; - -#endif /* ipconfigUSE_TCP */ - -typedef struct UDPSOCKET -{ - List_t xWaitingPacketsList; /* Incoming packets */ - #if( ipconfigUDP_MAX_RX_PACKETS > 0 ) - UBaseType_t uxMaxPackets; /* Protection: limits the number of packets buffered per socket */ - #endif /* ipconfigUDP_MAX_RX_PACKETS */ - #if( ipconfigUSE_CALLBACKS == 1 ) - FOnUDPReceive_t pxHandleReceive; /* - * In case of a UDP socket: - * typedef void (* FOnUDPReceive_t) (Socket_t xSocket, void *pData, size_t xLength, struct freertos_sockaddr *pxAddr ); - */ - FOnUDPSent_t pxHandleSent; - #endif /* ipconfigUSE_CALLBACKS */ -} IPUDPSocket_t; - -typedef enum eSOCKET_EVENT { - eSOCKET_RECEIVE = 0x0001, - eSOCKET_SEND = 0x0002, - eSOCKET_ACCEPT = 0x0004, - eSOCKET_CONNECT = 0x0008, - eSOCKET_BOUND = 0x0010, - eSOCKET_CLOSED = 0x0020, - eSOCKET_INTR = 0x0040, - eSOCKET_ALL = 0x007F, -} eSocketEvent_t; - -typedef struct xSOCKET -{ - EventBits_t xEventBits; - EventGroupHandle_t xEventGroup; - - ListItem_t xBoundSocketListItem; /* Used to reference the socket from a bound sockets list. */ - TickType_t xReceiveBlockTime; /* if recv[to] is called while no data is available, wait this amount of time. Unit in clock-ticks */ - 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 */ - - uint16_t usLocalPort; /* Local port on this machine */ - uint8_t ucSocketOptions; - uint8_t ucProtocol; /* choice of FREERTOS_IPPROTO_UDP/TCP */ - #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 ) - SemaphoreHandle_t pxUserSemaphore; - #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */ - #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 ) - SocketWakeupCallback_t pxUserWakeCallback; - #endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */ - - #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 ) - struct xSOCKET_SET *pxSocketSet; - /* User may indicate which bits are interesting for this socket. */ - EventBits_t xSelectBits; - /* These bits indicate the events which have actually occurred. - They are maintained by the IP-task */ - EventBits_t xSocketBits; - #endif /* ipconfigSUPPORT_SELECT_FUNCTION */ - /* TCP/UDP specific fields: */ - /* Before accessing any member of this structure, it should be confirmed */ - /* that the protocol corresponds with the type of structure */ - - union - { - IPUDPSocket_t xUDP; - #if( ipconfigUSE_TCP == 1 ) - IPTCPSocket_t xTCP; - /* Make sure that xTCP is 8-bytes aligned by - declaring a 64-bit variable in the same union */ - uint64_t ullTCPAlignment; - #endif /* ipconfigUSE_TCP */ - } u; -} FreeRTOS_Socket_t; - -#if( ipconfigUSE_TCP == 1 ) - /* - * Lookup a TCP socket, using a multiple matching: both port numbers and - * return IP address. - */ - FreeRTOS_Socket_t *pxTCPSocketLookup( uint32_t ulLocalIP, UBaseType_t uxLocalPort, uint32_t ulRemoteIP, UBaseType_t uxRemotePort ); - -#endif /* ipconfigUSE_TCP */ - -/* - * Look up a local socket by finding a match with the local port. - */ -FreeRTOS_Socket_t *pxUDPSocketLookup( UBaseType_t uxLocalPort ); - -/* - * Called when the application has generated a UDP packet to send. - */ -void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer ); - -/* - * Calculate the upper-layer checksum - * Works both for UDP, ICMP and TCP packages - * bOut = true: checksum will be set in outgoing packets - * bOut = false: checksum will be calculated for incoming packets - * returning 0xffff means: checksum was correct - */ -uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket ); - -/* - * An Ethernet frame has been updated (maybe it was an ARP request or a PING - * request?) and is to be sent back to its source. - */ -void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend ); - -/* - * The internal version of bind() - * If 'ulInternal' is true, it is called by the driver - * The TCP driver needs to bind a socket at the moment a listening socket - * creates a new connected socket - */ -BaseType_t vSocketBind( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr * pxAddress, size_t uxAddressLength, BaseType_t xInternal ); - -/* - * Internal function to add streaming data to a TCP socket. If ulIn == true, - * data will be added to the rxStream, otherwise to the tXStream. Normally data - * will be written with ulOffset == 0, meaning: at the end of the FIFO. When - * packet come in out-of-order, an offset will be used to put it in front and - * the head will not change yet. - */ -int32_t lTCPAddRxdata(FreeRTOS_Socket_t *pxSocket, size_t uxOffset, const uint8_t *pcData, uint32_t ulByteCount); - -/* - * Currently called for any important event. - */ -void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket ); - -/* - * Some helping function, their meaning should be clear - */ -static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr); -static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr) -{ - return ( ( ( uint32_t )apChr[0] ) << 24) | - ( ( ( uint32_t )apChr[1] ) << 16) | - ( ( ( uint32_t )apChr[2] ) << 8) | - ( ( ( uint32_t )apChr[3] ) ); -} - -static portINLINE uint16_t usChar2u16 (const uint8_t *apChr); -static portINLINE uint16_t usChar2u16 (const uint8_t *apChr) -{ - return ( uint16_t ) - ( ( ( ( uint32_t )apChr[0] ) << 8) | - ( ( ( uint32_t )apChr[1] ) ) ); -} - -/* Check a single socket for retransmissions and timeouts */ -BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket ); - -BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket ); - -/* Defined in FreeRTOS_Sockets.c - * Close a socket - */ -void *vSocketClose( FreeRTOS_Socket_t *pxSocket ); - -/* - * Send the event eEvent to the IP task event queue, using a block time of - * zero. Return pdPASS if the message was sent successfully, otherwise return - * pdFALSE. -*/ -BaseType_t xSendEventToIPTask( eIPEvent_t eEvent ); - -/* - * The same as above, but a struct as a parameter, containing: - * eIPEvent_t eEventType; - * void *pvData; - */ -BaseType_t xSendEventStructToIPTask( const IPStackEvent_t *pxEvent, TickType_t xTimeout ); - -/* - * Returns a pointer to the original NetworkBuffer from a pointer to a UDP - * payload buffer. - */ -NetworkBufferDescriptor_t *pxUDPPayloadBuffer_to_NetworkBuffer( void *pvBuffer ); - -#if( ipconfigZERO_COPY_TX_DRIVER != 0 ) - /* - * For the case where the network driver passes a buffer directly to a DMA - * descriptor, this function can be used to translate a 'network buffer' to - * a 'network buffer descriptor'. - */ - NetworkBufferDescriptor_t *pxPacketBuffer_to_NetworkBuffer( const void *pvBuffer ); -#endif - -/* - * Internal: Sets a new state for a TCP socket and performs the necessary - * actions like calling a OnConnected handler to notify the socket owner. - */ -#if( ipconfigUSE_TCP == 1 ) - void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState ); -#endif /* ipconfigUSE_TCP */ - -/*_RB_ Should this be part of the public API? */ -void FreeRTOS_netstat( void ); - -/* Returns pdTRUE is this function is called from the IP-task */ -BaseType_t xIsCallingFromIPTask( void ); - -#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 ) - -typedef struct xSOCKET_SET -{ - EventGroupHandle_t xSelectGroup; - BaseType_t bApiCalled; /* True if the API was calling the private vSocketSelect */ - FreeRTOS_Socket_t *pxSocket; -} SocketSelect_t; - -extern void vSocketSelect( SocketSelect_t *pxSocketSelect ); - -#endif /* ipconfigSUPPORT_SELECT_FUNCTION */ - -void vIPSetDHCPTimerEnableState( BaseType_t xEnableState ); -void vIPReloadDHCPTimer( uint32_t ulLeaseTime ); -#if( ipconfigDNS_USE_CALLBACKS != 0 ) - void vIPReloadDNSTimer( uint32_t ulCheckTime ); - void vIPSetDnsTimerEnableState( BaseType_t xEnableState ); -#endif - -/* Send the network-up event and start the ARP timer. */ -void vIPNetworkUpCalls( void ); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* FREERTOS_IP_PRIVATE_H */ - - - - - - - - - - - - - +/* + * FreeRTOS+TCP V2.2.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://aws.amazon.com/freertos + * http://www.FreeRTOS.org + */ + +#ifndef FREERTOS_IP_PRIVATE_H +#define FREERTOS_IP_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Application level configuration options. */ +#include "FreeRTOSIPConfig.h" +#include "FreeRTOSIPConfigDefaults.h" +#include "FreeRTOS_Sockets.h" +#include "IPTraceMacroDefaults.h" +#include "FreeRTOS_Stream_Buffer.h" +#if( ipconfigUSE_TCP == 1 ) + #include "FreeRTOS_TCP_WIN.h" + #include "FreeRTOS_TCP_IP.h" +#endif + +#include "event_groups.h" + +typedef struct xNetworkAddressingParameters +{ + uint32_t ulDefaultIPAddress; + uint32_t ulNetMask; + uint32_t ulGatewayAddress; + uint32_t ulDNSServerAddress; + uint32_t ulBroadcastAddress; +} NetworkAddressingParameters_t; + +extern BaseType_t xTCPWindowLoggingLevel; + +/*-----------------------------------------------------------*/ +/* Protocol headers. */ +/*-----------------------------------------------------------*/ + +#include "pack_struct_start.h" +struct xETH_HEADER +{ + MACAddress_t xDestinationAddress; /* 0 + 6 = 6 */ + MACAddress_t xSourceAddress; /* 6 + 6 = 12 */ + uint16_t usFrameType; /* 12 + 2 = 14 */ +} +#include "pack_struct_end.h" +typedef struct xETH_HEADER EthernetHeader_t; + +#include "pack_struct_start.h" +struct xARP_HEADER +{ + uint16_t usHardwareType; /* 0 + 2 = 2 */ + uint16_t usProtocolType; /* 2 + 2 = 4 */ + uint8_t ucHardwareAddressLength; /* 4 + 1 = 5 */ + uint8_t ucProtocolAddressLength; /* 5 + 1 = 6 */ + uint16_t usOperation; /* 6 + 2 = 8 */ + MACAddress_t xSenderHardwareAddress; /* 8 + 6 = 14 */ + uint8_t ucSenderProtocolAddress[ 4 ]; /* 14 + 4 = 18 */ + MACAddress_t xTargetHardwareAddress; /* 18 + 6 = 24 */ + uint32_t ulTargetProtocolAddress; /* 24 + 4 = 28 */ +} +#include "pack_struct_end.h" +typedef struct xARP_HEADER ARPHeader_t; + +#include "pack_struct_start.h" +struct xIP_HEADER +{ + uint8_t ucVersionHeaderLength; /* 0 + 1 = 1 */ + uint8_t ucDifferentiatedServicesCode; /* 1 + 1 = 2 */ + uint16_t usLength; /* 2 + 2 = 4 */ + uint16_t usIdentification; /* 4 + 2 = 6 */ + uint16_t usFragmentOffset; /* 6 + 2 = 8 */ + uint8_t ucTimeToLive; /* 8 + 1 = 9 */ + uint8_t ucProtocol; /* 9 + 1 = 10 */ + uint16_t usHeaderChecksum; /* 10 + 2 = 12 */ + uint32_t ulSourceIPAddress; /* 12 + 4 = 16 */ + uint32_t ulDestinationIPAddress; /* 16 + 4 = 20 */ +} +#include "pack_struct_end.h" +typedef struct xIP_HEADER IPHeader_t; + +#include "pack_struct_start.h" +struct xIGMP_HEADER +{ + uint8_t ucVersionType; /* 0 + 1 = 1 */ + uint8_t ucMaxResponseTime; /* 1 + 1 = 2 */ + uint16_t usChecksum; /* 2 + 2 = 4 */ + uint32_t usGroupAddress; /* 4 + 4 = 8 */ +} +#include "pack_struct_end.h" +typedef struct xIGMP_HEADER IGMPHeader_t; + +#include "pack_struct_start.h" +struct xICMP_HEADER +{ + uint8_t ucTypeOfMessage; /* 0 + 1 = 1 */ + uint8_t ucTypeOfService; /* 1 + 1 = 2 */ + uint16_t usChecksum; /* 2 + 2 = 4 */ + uint16_t usIdentifier; /* 4 + 2 = 6 */ + uint16_t usSequenceNumber; /* 6 + 2 = 8 */ +} +#include "pack_struct_end.h" +typedef struct xICMP_HEADER ICMPHeader_t; + +#include "pack_struct_start.h" +struct xUDP_HEADER +{ + uint16_t usSourcePort; /* 0 + 2 = 2 */ + uint16_t usDestinationPort; /* 2 + 2 = 4 */ + uint16_t usLength; /* 4 + 2 = 6 */ + uint16_t usChecksum; /* 6 + 2 = 8 */ +} +#include "pack_struct_end.h" +typedef struct xUDP_HEADER UDPHeader_t; + +#include "pack_struct_start.h" +struct xTCP_HEADER +{ + uint16_t usSourcePort; /* + 2 = 2 */ + uint16_t usDestinationPort; /* + 2 = 4 */ + uint32_t ulSequenceNumber; /* + 4 = 8 */ + uint32_t ulAckNr; /* + 4 = 12 */ + uint8_t ucTCPOffset; /* + 1 = 13 */ + uint8_t ucTCPFlags; /* + 1 = 14 */ + uint16_t usWindow; /* + 2 = 15 */ + uint16_t usChecksum; /* + 2 = 18 */ + uint16_t usUrgent; /* + 2 = 20 */ +#if ipconfigUSE_TCP == 1 + /* the option data is not a part of the TCP header */ + uint8_t ucOptdata[ipSIZE_TCP_OPTIONS]; /* + 12 = 32 */ +#endif +} +#include "pack_struct_end.h" +typedef struct xTCP_HEADER TCPHeader_t; + +#include "pack_struct_start.h" +struct xPSEUDO_HEADER +{ + uint32_t ulSourceAddress; + uint32_t ulDestinationAddress; + uint8_t ucZeros; + uint8_t ucProtocol; + uint16_t usUDPLength; +} +#include "pack_struct_end.h" +typedef struct xPSEUDO_HEADER PseudoHeader_t; + +/*-----------------------------------------------------------*/ +/* Nested protocol packets. */ +/*-----------------------------------------------------------*/ + +#include "pack_struct_start.h" +struct xARP_PACKET +{ + EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */ + ARPHeader_t xARPHeader; /* 14 + 28 = 42 */ +} +#include "pack_struct_end.h" +typedef struct xARP_PACKET ARPPacket_t; + +#include "pack_struct_start.h" +struct xIP_PACKET +{ + EthernetHeader_t xEthernetHeader; + IPHeader_t xIPHeader; +} +#include "pack_struct_end.h" +typedef struct xIP_PACKET IPPacket_t; + +#include "pack_struct_start.h" +struct xICMP_PACKET +{ + EthernetHeader_t xEthernetHeader; + IPHeader_t xIPHeader; + ICMPHeader_t xICMPHeader; +} +#include "pack_struct_end.h" +typedef struct xICMP_PACKET ICMPPacket_t; + +#include "pack_struct_start.h" +struct xUDP_PACKET +{ + EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */ + IPHeader_t xIPHeader; /* 14 + 20 = 34 */ + UDPHeader_t xUDPHeader; /* 34 + 8 = 42 */ +} +#include "pack_struct_end.h" +typedef struct xUDP_PACKET UDPPacket_t; + +#include "pack_struct_start.h" +struct xTCP_PACKET +{ + EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */ + IPHeader_t xIPHeader; /* 14 + 20 = 34 */ + TCPHeader_t xTCPHeader; /* 34 + 32 = 66 */ +} +#include "pack_struct_end.h" +typedef struct xTCP_PACKET TCPPacket_t; + +typedef union XPROT_PACKET +{ + ARPPacket_t xARPPacket; + TCPPacket_t xTCPPacket; + UDPPacket_t xUDPPacket; + ICMPPacket_t xICMPPacket; +} ProtocolPacket_t; + + +/* The maximum UDP payload length. */ +#define ipMAX_UDP_PAYLOAD_LENGTH ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER ) - ipSIZE_OF_UDP_HEADER ) + +typedef enum +{ + eReleaseBuffer = 0, /* Processing the frame did not find anything to do - just release the buffer. */ + eProcessBuffer, /* An Ethernet frame has a valid address - continue process its contents. */ + eReturnEthernetFrame, /* The Ethernet frame contains an ARP or ICMP packet that can be returned to its source. */ + eFrameConsumed /* Processing the Ethernet packet contents resulted in the payload being sent to the stack. */ +} eFrameProcessingResult_t; + +typedef enum +{ + eNoEvent = -1, + eNetworkDownEvent, /* 0: The network interface has been lost and/or needs [re]connecting. */ + eNetworkRxEvent, /* 1: The network interface has queued a received Ethernet frame. */ + eNetworkTxEvent, /* 2: Let the IP-task send a network packet. */ + eARPTimerEvent, /* 3: The ARP timer expired. */ + eStackTxEvent, /* 4: The software stack has queued a packet to transmit. */ + eDHCPEvent, /* 5: Process the DHCP state machine. */ + eTCPTimerEvent, /* 6: See if any TCP socket needs attention. */ + eTCPAcceptEvent, /* 7: Client API FreeRTOS_accept() waiting for client connections. */ + eTCPNetStat, /* 8: IP-task is asked to produce a netstat listing. */ + eSocketBindEvent, /* 9: Send a message to the IP-task to bind a socket to a port. */ + eSocketCloseEvent, /*10: Send a message to the IP-task to close a socket. */ + eSocketSelectEvent, /*11: Send a message to the IP-task for select(). */ + eSocketSignalEvent, /*12: A socket must be signalled. */ +} eIPEvent_t; + +typedef struct IP_TASK_COMMANDS +{ + eIPEvent_t eEventType; + void *pvData; +} IPStackEvent_t; + +#define ipBROADCAST_IP_ADDRESS 0xffffffffUL + +/* Offset into the Ethernet frame that is used to temporarily store information +on the fragmentation status of the packet being sent. The value is important, +as it is past the location into which the destination address will get placed. */ +#define ipFRAGMENTATION_PARAMETERS_OFFSET ( 6 ) +#define ipSOCKET_OPTIONS_OFFSET ( 6 ) + +/* Only used when outgoing fragmentation is being used (FreeRTOSIPConfig.h +setting. */ +#define ipGET_UDP_PAYLOAD_OFFSET_FOR_FRAGMENT( usFragmentOffset ) ( ( ( usFragmentOffset ) == 0 ) ? ipUDP_PAYLOAD_OFFSET_IPv4 : ipIP_PAYLOAD_OFFSET ) + +/* The offset into a UDP packet at which the UDP data (payload) starts. */ +#define ipUDP_PAYLOAD_OFFSET_IPv4 ( sizeof( UDPPacket_t ) ) + +/* The offset into an IP packet into which the IP data (payload) starts. */ +#define ipIP_PAYLOAD_OFFSET ( sizeof( IPPacket_t ) ) + +#include "pack_struct_start.h" +struct xUDP_IP_FRAGMENT_PARAMETERS +{ + uint8_t ucSocketOptions; + uint8_t ucPadFor16BitAlignment; + uint16_t usFragmentedPacketOffset; + uint16_t usFragmentLength; + uint16_t usPayloadChecksum; +} +#include "pack_struct_end.h" +typedef struct xUDP_IP_FRAGMENT_PARAMETERS IPFragmentParameters_t; + +#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) + + /* Ethernet frame types. */ + #define ipARP_FRAME_TYPE ( 0x0608U ) + #define ipIPv4_FRAME_TYPE ( 0x0008U ) + + /* ARP related definitions. */ + #define ipARP_PROTOCOL_TYPE ( 0x0008U ) + #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0100U ) + #define ipARP_REQUEST ( 0x0100U ) + #define ipARP_REPLY ( 0x0200U ) + +#else + + /* Ethernet frame types. */ + #define ipARP_FRAME_TYPE ( 0x0806U ) + #define ipIPv4_FRAME_TYPE ( 0x0800U ) + + /* ARP related definitions. */ + #define ipARP_PROTOCOL_TYPE ( 0x0800U ) + #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0001U ) + #define ipARP_REQUEST ( 0x0001 ) + #define ipARP_REPLY ( 0x0002 ) + +#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */ + + +/* For convenience, a MAC address of all zeros and another of all 0xffs are +defined const for quick reference. */ +extern const MACAddress_t xBroadcastMACAddress; /* all 0xff's */ +extern uint16_t usPacketIdentifier; + +/* Define a default UDP packet header (declared in FreeRTOS_UDP_IP.c) */ +typedef union xUDPPacketHeader +{ + uint8_t ucBytes[24]; + uint32_t ulWords[6]; +} UDPPacketHeader_t; +extern UDPPacketHeader_t xDefaultPartUDPPacketHeader; + +/* Structure that stores the netmask, gateway address and DNS server addresses. */ +extern NetworkAddressingParameters_t xNetworkAddressing; + +/* Structure that stores the defaults for netmask, gateway address and DNS. +These values will be copied to 'xNetworkAddressing' in case DHCP is not used, +and also in case DHCP does not lead to a confirmed request. */ +extern NetworkAddressingParameters_t xDefaultAddressing; + +/* True when BufferAllocation_1.c was included, false for BufferAllocation_2.c */ +extern const BaseType_t xBufferAllocFixedSize; + +/* Defined in FreeRTOS_Sockets.c */ +#if ( ipconfigUSE_TCP == 1 ) + extern List_t xBoundTCPSocketsList; +#endif + +/* The local IP address is accessed from within xDefaultPartUDPPacketHeader, +rather than duplicated in its own variable. */ +#define ipLOCAL_IP_ADDRESS_POINTER ( ( uint32_t * ) &( xDefaultPartUDPPacketHeader.ulWords[ 20u / sizeof(uint32_t) ] ) ) + +/* The local MAC address is accessed from within xDefaultPartUDPPacketHeader, +rather than duplicated in its own variable. */ +#define ipLOCAL_MAC_ADDRESS ( &xDefaultPartUDPPacketHeader.ucBytes[0] ) + +/* ICMP packets are sent using the same function as UDP packets. The port +number is used to distinguish between the two, as 0 is an invalid UDP port. */ +#define ipPACKET_CONTAINS_ICMP_DATA ( 0 ) + +/* For now, the lower 8 bits in 'xEventBits' will be reserved for the above +socket events. */ +#define SOCKET_EVENT_BIT_COUNT 8 + +#define vSetField16( pxBase, xType, xField, usValue ) \ +{ \ + ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( usValue ) >> 8 ); \ + ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( usValue ) & 0xff ); \ +} + +#define vSetField32( pxBase, xType, xField, ulValue ) \ +{ \ + ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( ulValue ) >> 24 ); \ + ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( ( ulValue ) >> 16 ) & 0xff ); \ + ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 2 ] = ( uint8_t ) ( ( ( ulValue ) >> 8 ) & 0xff ); \ + ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 3 ] = ( uint8_t ) ( ( ulValue ) & 0xff ); \ +} + +#define vFlip_16( left, right ) \ + do { \ + uint16_t tmp = (left); \ + (left) = (right); \ + (right) = tmp; \ + } while (0) + +#define vFlip_32( left, right ) \ + do { \ + uint32_t tmp = (left); \ + (left) = (right); \ + (right) = tmp; \ + } while (0) + +#ifndef ARRAY_SIZE + #define ARRAY_SIZE(x) (BaseType_t)(sizeof(x)/sizeof(x)[0]) +#endif + +/* + * A version of FreeRTOS_GetReleaseNetworkBuffer() that can be called from an + * interrupt. If a non zero value is returned, then the calling ISR should + * perform a context switch before exiting the ISR. + */ +BaseType_t FreeRTOS_ReleaseFreeNetworkBufferFromISR( void ); + +/* + * Create a message that contains a command to initialise the network interface. + * This is used during initialisation, and at any time the network interface + * goes down thereafter. The network interface hardware driver is responsible + * for sending the message that contains the network interface down command/ + * event. + * + * Only use the FreeRTOS_NetworkDownFromISR() version if the function is to be + * called from an interrupt service routine. If FreeRTOS_NetworkDownFromISR() + * returns a non-zero value then a context switch should be performed ebfore + * the interrupt is exited. + */ +void FreeRTOS_NetworkDown( void ); +BaseType_t FreeRTOS_NetworkDownFromISR( void ); + +/* + * Processes incoming ARP packets. + */ +eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame ); + +/* + * Inspect an Ethernet frame to see if it contains data that the stack needs to + * process. eProcessBuffer is returned if the frame should be processed by the + * stack. eReleaseBuffer is returned if the frame should be discarded. + */ +eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer ); + +/* + * Return the checksum generated over xDataLengthBytes from pucNextData. + */ +uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes ); + +/* Socket related private functions. */ + +/* + * The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet + * payload size (excluding packet headers) and that the packet in pucEthernetBuffer + * is at least the size of UDPPacket_t. + */ +BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort ); + +/* + * Initialize the socket list data structures for TCP and UDP. + */ +BaseType_t vNetworkSocketsInit( void ); + +/* + * Returns pdTRUE if the IP task has been created and is initialised. Otherwise + * returns pdFALSE. + */ +BaseType_t xIPIsNetworkTaskReady( void ); + +#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 ) + struct xSOCKET; + typedef void (*SocketWakeupCallback_t)( struct xSOCKET * pxSocket ); +#endif + +#if( ipconfigUSE_TCP == 1 ) + + /* + * Actually a user thing, but because xBoundTCPSocketsList, let it do by the + * IP-task + */ + void vTCPNetStat( void ); + + /* + * At least one socket needs to check for timeouts + */ + TickType_t xTCPTimerCheck( BaseType_t xWillSleep ); + + /* Every TCP socket has a buffer space just big enough to store + the last TCP header received. + As a reference of this field may be passed to DMA, force the + alignment to 8 bytes. */ + typedef union + { + struct + { + /* Increase the alignment of this union by adding a 64-bit variable. */ + uint64_t ullAlignmentWord; + } a; + struct + { + /* The next field only serves to give 'ucLastPacket' a correct + alignment of 8 + 2. See comments in FreeRTOS_IP.h */ + uint8_t ucFillPacket[ ipconfigPACKET_FILLER_SIZE ]; + uint8_t ucLastPacket[ sizeof( TCPPacket_t ) ]; + } u; + } LastTCPPacket_t; + + /* + * Note that the values of all short and long integers in these structs + * are being stored in the native-endian way + * Translation should take place when accessing any structure which defines + * network packets, such as IPHeader_t and TCPHeader_t + */ + typedef struct TCPSOCKET + { + uint32_t ulRemoteIP; /* IP address of remote machine */ + uint16_t usRemotePort; /* Port on remote machine */ + struct { + /* Most compilers do like bit-flags */ + uint32_t + bMssChange : 1, /* This socket has seen a change in MSS */ + bPassAccept : 1, /* when true, this socket may be returned in a call to accept() */ + bPassQueued : 1, /* when true, this socket is an orphan until it gets connected + * Why an orphan? Because it may not be returned in a accept() call until it + * gets the state eESTABLISHED */ + bReuseSocket : 1, /* When a listening socket gets a connection, do not create a new instance but keep on using it */ + bCloseAfterSend : 1,/* As soon as the last byte has been transmitted, finalise the connection + * Useful in e.g. FTP connections, where the last data bytes are sent along with the FIN flag */ + bUserShutdown : 1, /* User requesting a graceful shutdown */ + bCloseRequested : 1,/* Request to finalise the connection */ + bLowWater : 1, /* high-water level has been reached. Cleared as soon as 'rx-count < lo-water' */ + bWinChange : 1, /* The value of bLowWater has changed, must send a window update */ + bSendKeepAlive : 1, /* When this flag is true, a TCP keep-alive message must be send */ + bWaitKeepAlive : 1, /* When this flag is true, a TCP keep-alive reply is expected */ + bConnPrepared : 1, /* Connecting socket: Message has been prepared */ + #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 ) + bConnPassed : 1, /* Connecting socket: Socket has been passed in a successful select() */ + #endif /* ipconfigSUPPORT_SELECT_FUNCTION */ + bFinAccepted : 1, /* This socket has received (or sent) a FIN and accepted it */ + bFinSent : 1, /* We've sent out a FIN */ + bFinRecv : 1, /* We've received a FIN from our peer */ + bFinAcked : 1, /* Our FIN packet has been acked */ + bFinLast : 1, /* The last ACK (after FIN and FIN+ACK) has been sent or will be sent by the peer */ + bRxStopped : 1, /* Application asked to temporarily stop reception */ + bMallocError : 1, /* There was an error allocating a stream */ + bWinScaling : 1; /* A TCP-Window Scaling option was offered and accepted in the SYN phase. */ + } bits; + uint32_t ulHighestRxAllowed; + /* The highest sequence number that we can receive at any moment */ + uint16_t usTimeout; /* Time (in ticks) after which this socket needs attention */ + uint16_t usCurMSS; /* Current Maximum Segment Size */ + uint16_t usInitMSS; /* Initial maximum segment Size */ + uint16_t usChildCount; /* In case of a listening socket: number of connections on this port number */ + uint16_t usBacklog; /* In case of a listening socket: maximum number of concurrent connections on this port number */ + uint8_t ucRepCount; /* Send repeat count, for retransmissions + * This counter is separate from the xmitCount in the + * TCP win segments */ + uint8_t ucTCPState; /* TCP state: see eTCP_STATE */ + struct xSOCKET *pxPeerSocket; /* for server socket: child, for child socket: parent */ + #if( ipconfigTCP_KEEP_ALIVE == 1 ) + uint8_t ucKeepRepCount; + TickType_t xLastAliveTime; + #endif /* ipconfigTCP_KEEP_ALIVE */ + #if( ipconfigTCP_HANG_PROTECTION == 1 ) + TickType_t xLastActTime; + #endif /* ipconfigTCP_HANG_PROTECTION */ + size_t uxLittleSpace; + size_t uxEnoughSpace; + size_t uxRxStreamSize; + size_t uxTxStreamSize; + StreamBuffer_t *rxStream; + StreamBuffer_t *txStream; + #if( ipconfigUSE_TCP_WIN == 1 ) + NetworkBufferDescriptor_t *pxAckMessage; + #endif /* ipconfigUSE_TCP_WIN */ + /* Buffer space to store the last TCP header received. */ + LastTCPPacket_t xPacket; + uint8_t tcpflags; /* TCP flags */ + #if( ipconfigUSE_TCP_WIN != 0 ) + uint8_t ucMyWinScaleFactor; + uint8_t ucPeerWinScaleFactor; + #endif + #if( ipconfigUSE_CALLBACKS == 1 ) + FOnTCPReceive_t pxHandleReceive; /* + * In case of a TCP socket: + * typedef void (* FOnTCPReceive_t) (Socket_t xSocket, void *pData, size_t xLength ); + */ + FOnTCPSent_t pxHandleSent; + FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */ + #endif /* ipconfigUSE_CALLBACKS */ + uint32_t ulWindowSize; /* Current Window size advertised by peer */ + size_t uxRxWinSize; /* Fixed value: size of the TCP reception window */ + size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */ + + TCPWindow_t xTCPWindow; + } IPTCPSocket_t; + +#endif /* ipconfigUSE_TCP */ + +typedef struct UDPSOCKET +{ + List_t xWaitingPacketsList; /* Incoming packets */ + #if( ipconfigUDP_MAX_RX_PACKETS > 0 ) + UBaseType_t uxMaxPackets; /* Protection: limits the number of packets buffered per socket */ + #endif /* ipconfigUDP_MAX_RX_PACKETS */ + #if( ipconfigUSE_CALLBACKS == 1 ) + FOnUDPReceive_t pxHandleReceive; /* + * In case of a UDP socket: + * typedef void (* FOnUDPReceive_t) (Socket_t xSocket, void *pData, size_t xLength, struct freertos_sockaddr *pxAddr ); + */ + FOnUDPSent_t pxHandleSent; + #endif /* ipconfigUSE_CALLBACKS */ +} IPUDPSocket_t; + +typedef enum eSOCKET_EVENT { + eSOCKET_RECEIVE = 0x0001, + eSOCKET_SEND = 0x0002, + eSOCKET_ACCEPT = 0x0004, + eSOCKET_CONNECT = 0x0008, + eSOCKET_BOUND = 0x0010, + eSOCKET_CLOSED = 0x0020, + eSOCKET_INTR = 0x0040, + eSOCKET_ALL = 0x007F, +} eSocketEvent_t; + +typedef struct xSOCKET +{ + EventBits_t xEventBits; + EventGroupHandle_t xEventGroup; + + ListItem_t xBoundSocketListItem; /* Used to reference the socket from a bound sockets list. */ + TickType_t xReceiveBlockTime; /* if recv[to] is called while no data is available, wait this amount of time. Unit in clock-ticks */ + 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 */ + + uint16_t usLocalPort; /* Local port on this machine */ + uint8_t ucSocketOptions; + uint8_t ucProtocol; /* choice of FREERTOS_IPPROTO_UDP/TCP */ + #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 ) + SemaphoreHandle_t pxUserSemaphore; + #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */ + #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 ) + SocketWakeupCallback_t pxUserWakeCallback; + #endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */ + + #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 ) + struct xSOCKET_SET *pxSocketSet; + /* User may indicate which bits are interesting for this socket. */ + EventBits_t xSelectBits; + /* These bits indicate the events which have actually occurred. + They are maintained by the IP-task */ + EventBits_t xSocketBits; + #endif /* ipconfigSUPPORT_SELECT_FUNCTION */ + /* TCP/UDP specific fields: */ + /* Before accessing any member of this structure, it should be confirmed */ + /* that the protocol corresponds with the type of structure */ + + union + { + IPUDPSocket_t xUDP; + #if( ipconfigUSE_TCP == 1 ) + IPTCPSocket_t xTCP; + /* Make sure that xTCP is 8-bytes aligned by + declaring a 64-bit variable in the same union */ + uint64_t ullTCPAlignment; + #endif /* ipconfigUSE_TCP */ + } u; +} FreeRTOS_Socket_t; + +#if( ipconfigUSE_TCP == 1 ) + /* + * Lookup a TCP socket, using a multiple matching: both port numbers and + * return IP address. + */ + FreeRTOS_Socket_t *pxTCPSocketLookup( uint32_t ulLocalIP, UBaseType_t uxLocalPort, uint32_t ulRemoteIP, UBaseType_t uxRemotePort ); + +#endif /* ipconfigUSE_TCP */ + +/* + * Look up a local socket by finding a match with the local port. + */ +FreeRTOS_Socket_t *pxUDPSocketLookup( UBaseType_t uxLocalPort ); + +/* + * Called when the application has generated a UDP packet to send. + */ +void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer ); + +/* + * Calculate the upper-layer checksum + * Works both for UDP, ICMP and TCP packages + * bOut = true: checksum will be set in outgoing packets + * bOut = false: checksum will be calculated for incoming packets + * returning 0xffff means: checksum was correct + */ +uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket ); + +/* + * An Ethernet frame has been updated (maybe it was an ARP request or a PING + * request?) and is to be sent back to its source. + */ +void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend ); + +/* + * The internal version of bind() + * If 'ulInternal' is true, it is called by the driver + * The TCP driver needs to bind a socket at the moment a listening socket + * creates a new connected socket + */ +BaseType_t vSocketBind( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr * pxAddress, size_t uxAddressLength, BaseType_t xInternal ); + +/* + * Internal function to add streaming data to a TCP socket. If ulIn == true, + * data will be added to the rxStream, otherwise to the tXStream. Normally data + * will be written with ulOffset == 0, meaning: at the end of the FIFO. When + * packet come in out-of-order, an offset will be used to put it in front and + * the head will not change yet. + */ +int32_t lTCPAddRxdata(FreeRTOS_Socket_t *pxSocket, size_t uxOffset, const uint8_t *pcData, uint32_t ulByteCount); + +/* + * Currently called for any important event. + */ +void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket ); + +/* + * Some helping function, their meaning should be clear + */ +static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr); +static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr) +{ + return ( ( ( uint32_t )apChr[0] ) << 24) | + ( ( ( uint32_t )apChr[1] ) << 16) | + ( ( ( uint32_t )apChr[2] ) << 8) | + ( ( ( uint32_t )apChr[3] ) ); +} + +static portINLINE uint16_t usChar2u16 (const uint8_t *apChr); +static portINLINE uint16_t usChar2u16 (const uint8_t *apChr) +{ + return ( uint16_t ) + ( ( ( ( uint32_t )apChr[0] ) << 8) | + ( ( ( uint32_t )apChr[1] ) ) ); +} + +/* Check a single socket for retransmissions and timeouts */ +BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket ); + +BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket ); + +/* Defined in FreeRTOS_Sockets.c + * Close a socket + */ +void *vSocketClose( FreeRTOS_Socket_t *pxSocket ); + +/* + * Send the event eEvent to the IP task event queue, using a block time of + * zero. Return pdPASS if the message was sent successfully, otherwise return + * pdFALSE. +*/ +BaseType_t xSendEventToIPTask( eIPEvent_t eEvent ); + +/* + * The same as above, but a struct as a parameter, containing: + * eIPEvent_t eEventType; + * void *pvData; + */ +BaseType_t xSendEventStructToIPTask( const IPStackEvent_t *pxEvent, TickType_t xTimeout ); + +/* + * Returns a pointer to the original NetworkBuffer from a pointer to a UDP + * payload buffer. + */ +NetworkBufferDescriptor_t *pxUDPPayloadBuffer_to_NetworkBuffer( void *pvBuffer ); + +#if( ipconfigZERO_COPY_TX_DRIVER != 0 ) + /* + * For the case where the network driver passes a buffer directly to a DMA + * descriptor, this function can be used to translate a 'network buffer' to + * a 'network buffer descriptor'. + */ + NetworkBufferDescriptor_t *pxPacketBuffer_to_NetworkBuffer( const void *pvBuffer ); +#endif + +/* + * Internal: Sets a new state for a TCP socket and performs the necessary + * actions like calling a OnConnected handler to notify the socket owner. + */ +#if( ipconfigUSE_TCP == 1 ) + void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState ); +#endif /* ipconfigUSE_TCP */ + +/*_RB_ Should this be part of the public API? */ +void FreeRTOS_netstat( void ); + +/* Returns pdTRUE is this function is called from the IP-task */ +BaseType_t xIsCallingFromIPTask( void ); + +#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 ) + +typedef struct xSOCKET_SET +{ + EventGroupHandle_t xSelectGroup; + BaseType_t bApiCalled; /* True if the API was calling the private vSocketSelect */ + FreeRTOS_Socket_t *pxSocket; +} SocketSelect_t; + +extern void vSocketSelect( SocketSelect_t *pxSocketSelect ); + +#endif /* ipconfigSUPPORT_SELECT_FUNCTION */ + +void vIPSetDHCPTimerEnableState( BaseType_t xEnableState ); +void vIPReloadDHCPTimer( uint32_t ulLeaseTime ); +#if( ipconfigDNS_USE_CALLBACKS != 0 ) + void vIPReloadDNSTimer( uint32_t ulCheckTime ); + void vIPSetDnsTimerEnableState( BaseType_t xEnableState ); +#endif + +/* Send the network-up event and start the ARP timer. */ +void vIPNetworkUpCalls( void ); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* FREERTOS_IP_PRIVATE_H */ + + + + + + + + + + + + +