/*
 * 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
 */

/*
 * FreeRTOS_TCP_IP.c
 * Module which handles the TCP connections for FreeRTOS+TCP.
 * It depends on  FreeRTOS_TCP_WIN.c, which handles the TCP windowing
 * schemes.
 *
 * Endianness: in this module all ports and IP addresses are stored in
 * host byte-order, except fields in the IP-packets
 */

/* Standard includes. */
#include <stdint.h>
#include <stdio.h>

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_TCP_IP.h"
#include "FreeRTOS_DHCP.h"
#include "NetworkInterface.h"
#include "NetworkBufferManagement.h"
#include "FreeRTOS_ARP.h"
#include "FreeRTOS_TCP_WIN.h"


/* Just make sure the contents doesn't get compiled if TCP is not enabled. */
#if ipconfigUSE_TCP == 1

/* This compile-time test was moved to here because some macro's
were unknown within 'FreeRTOSIPConfigDefaults.h'.  It tests whether
the defined MTU size can contain at least a complete TCP packet. */

#if ( ( ipconfigTCP_MSS + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) > ipconfigNETWORK_MTU )
	#error The ipconfigTCP_MSS setting in FreeRTOSIPConfig.h is too large.
#endif

/*
 * The meaning of the TCP flags:
 */
#define ipTCP_FLAG_FIN			0x0001u /* No more data from sender */
#define ipTCP_FLAG_SYN			0x0002u /* Synchronize sequence numbers */
#define ipTCP_FLAG_RST			0x0004u /* Reset the connection */
#define ipTCP_FLAG_PSH			0x0008u /* Push function: please push buffered data to the recv application */
#define ipTCP_FLAG_ACK			0x0010u /* Acknowledgment field is significant */
#define ipTCP_FLAG_URG			0x0020u /* Urgent pointer field is significant */
#define ipTCP_FLAG_ECN			0x0040u /* ECN-Echo */
#define ipTCP_FLAG_CWR			0x0080u /* Congestion Window Reduced */
#define ipTCP_FLAG_NS			0x0100u /* ECN-nonce concealment protection */
#define ipTCP_FLAG_RSV			0x0E00u /* Reserved, keep 0 */

/* A mask to filter all protocol flags. */
#define ipTCP_FLAG_CTRL			0x001Fu

/*
 * A few values of the TCP options:
 */
#define TCP_OPT_END				0u   /* End of TCP options list */
#define TCP_OPT_NOOP			1u   /* "No-operation" TCP option */
#define TCP_OPT_MSS				2u   /* Maximum segment size TCP option */
#define TCP_OPT_WSOPT			3u   /* TCP Window Scale Option (3-byte long) */
#define TCP_OPT_SACK_P			4u   /* Advertize that SACK is permitted */
#define TCP_OPT_SACK_A			5u   /* SACK option with first/last */
#define TCP_OPT_TIMESTAMP		8u   /* Time-stamp option */

#define TCP_OPT_MSS_LEN			4u   /* Length of TCP MSS option. */
#define TCP_OPT_WSOPT_LEN		3u   /* Length of TCP WSOPT option. */

#define TCP_OPT_TIMESTAMP_LEN	10	/* fixed length of the time-stamp option */

#ifndef ipconfigTCP_ACK_EARLIER_PACKET
	#define ipconfigTCP_ACK_EARLIER_PACKET		1
#endif

/*
 * The macro NOW_CONNECTED() is use to determine if the connection makes a
 * transition from connected to non-connected and vice versa.
 * NOW_CONNECTED() returns true when the status has one of these values:
 * eESTABLISHED, eFIN_WAIT_1, eFIN_WAIT_2, eCLOSING, eLAST_ACK, eTIME_WAIT
 * Technically the connection status is closed earlier, but the library wants
 * to prevent that the socket will be deleted before the last ACK has been
 * and thus causing a 'RST' packet on either side.
 */
#define NOW_CONNECTED( status )\
	( ( status >= eESTABLISHED ) && ( status != eCLOSE_WAIT ) )

/*
 * The highest 4 bits in the TCP offset byte indicate the total length of the
 * TCP header, divided by 4.
 */
#define VALID_BITS_IN_TCP_OFFSET_BYTE		( 0xF0u )

/*
 * Acknowledgements to TCP data packets may be delayed as long as more is being expected.
 * A normal delay would be 200ms.  Here a much shorter delay of 20 ms is being used to
 * gain performance.
 */
#define DELAYED_ACK_SHORT_DELAY_MS			( 2 )
#define DELAYED_ACK_LONGER_DELAY_MS			( 20 )

/*
 * The MSS (Maximum Segment Size) will be taken as large as possible. However, packets with
 * an MSS of 1460 bytes won't be transported through the internet.  The MSS will be reduced
 * to 1400 bytes.
 */
#define REDUCED_MSS_THROUGH_INTERNET		( 1400 )

/*
 * When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
 * the number 5 (words) in the higher niblle of the TCP-offset byte.
 */
#define TCP_OFFSET_LENGTH_BITS			( 0xf0u )
#define TCP_OFFSET_STANDARD_LENGTH		( 0x50u )

/*
 * Each TCP socket is checked regularly to see if it can send data packets.
 * By default, the maximum number of packets sent during one check is limited to 8.
 * This amount may be further limited by setting the socket's TX window size.
 */
#if( !defined( SEND_REPEATED_COUNT ) )
	#define SEND_REPEATED_COUNT		( 8 )
#endif /* !defined( SEND_REPEATED_COUNT ) */

/*
 * Define a maximum perdiod of time (ms) to leave a TCP-socket unattended.
 * When a TCP timer expires, retries and keep-alive messages will be checked.
 */
#ifndef	tcpMAXIMUM_TCP_WAKEUP_TIME_MS
	#define	tcpMAXIMUM_TCP_WAKEUP_TIME_MS		20000u
#endif

/*
 * The names of the different TCP states may be useful in logging.
 */
#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
	static const char *pcStateNames[] = {
		"eCLOSED",
		"eTCP_LISTEN",
		"eCONNECT_SYN",
		"eSYN_FIRST",
		"eSYN_RECEIVED",
		"eESTABLISHED",
		"eFIN_WAIT_1",
		"eFIN_WAIT_2",
		"eCLOSE_WAIT",
		"eCLOSING",
		"eLAST_ACK",
		"eTIME_WAIT",
		"eUNKNOWN",
};
#endif /* ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) */

/*
 * Returns true if the socket must be checked.  Non-active sockets are waiting
 * for user action, either connect() or close().
 */
static BaseType_t prvTCPSocketIsActive( UBaseType_t uxStatus );

/*
 * Either sends a SYN or calls prvTCPSendRepeated (for regular messages).
 */
static int32_t prvTCPSendPacket( FreeRTOS_Socket_t *pxSocket );

/*
 * Try to send a series of messages.
 */
static int32_t prvTCPSendRepeated( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );

/*
 * Return or send a packet to the other party.
 */
static void prvTCPReturnPacket( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
	uint32_t ulLen, BaseType_t xReleaseAfterSend );

/*
 * Initialise the data structures which keep track of the TCP windowing system.
 */
static void prvTCPCreateWindow( FreeRTOS_Socket_t *pxSocket );

/*
 * Let ARP look-up the MAC-address of the peer and initialise the first SYN
 * packet.
 */
static BaseType_t prvTCPPrepareConnect( FreeRTOS_Socket_t *pxSocket );

#if( ipconfigHAS_DEBUG_PRINTF != 0 )
	/*
	 * For logging and debugging: make a string showing the TCP flags.
	 */
	static const char *prvTCPFlagMeaning( UBaseType_t xFlags);
#endif /* ipconfigHAS_DEBUG_PRINTF != 0 */

/*
 * Parse the TCP option(s) received, if present.
 */
static void prvCheckOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );

/*
 * Identify and deal with a single TCP header option, advancing the pointer to
 * the header. This function returns pdTRUE or pdFALSE depending on whether the
 * caller should continue to parse more header options or break the loop.
 */
static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow);

/*
 * Skip past TCP header options when doing Selective ACK, until there are no
 * more options left.
 */
static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const ppucLen );

/*
 * Set the initial properties in the options fields, like the preferred
 * value of MSS and whether SACK allowed.  Will be transmitted in the state
 * 'eCONNECT_SYN'.
 */
static UBaseType_t prvSetSynAckOptions( FreeRTOS_Socket_t *pxSocket, TCPPacket_t * pxTCPPacket );

/*
 * For anti-hang protection and TCP keep-alive messages.  Called in two places:
 * after receiving a packet and after a state change.  The socket's alive timer
 * may be reset.
 */
static void prvTCPTouchSocket( FreeRTOS_Socket_t *pxSocket );

/*
 * Prepare an outgoing message, if anything has to be sent.
 */
static int32_t prvTCPPrepareSend( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, UBaseType_t uxOptionsLength );

/*
 * Calculate when this socket needs to be checked to do (re-)transmissions.
 */
static TickType_t prvTCPNextTimeout( FreeRTOS_Socket_t *pxSocket );

/*
 * The API FreeRTOS_send() adds data to the TX stream.  Add
 * this data to the windowing system to it can be transmitted.
 */
static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket );

/*
 *  Called to handle the closure of a TCP connection.
 */
static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );

/*
 * Called from prvTCPHandleState().  Find the TCP payload data and check and
 * return its length.
 */
static BaseType_t prvCheckRxData( NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData );

/*
 * Called from prvTCPHandleState().  Check if the payload data may be accepted.
 * If so, it will be added to the socket's reception queue.
 */
static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, uint8_t *pucRecvData,
	NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength );

/*
 * Set the TCP options (if any) for the outgoing packet.
 */
static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );

/*
 * Called from prvTCPHandleState() as long as the TCP status is eSYN_RECEIVED to
 * eCONNECT_SYN.
 */
static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
	uint32_t ulReceiveLength, UBaseType_t uxOptionsLength );

/*
 * Called from prvTCPHandleState() as long as the TCP status is eESTABLISHED.
 */
static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
	uint32_t ulReceiveLength, UBaseType_t uxOptionsLength );

/*
 * Called from prvTCPHandleState().  There is data to be sent.
 * If ipconfigUSE_TCP_WIN is defined, and if only an ACK must be sent, it will
 * be checked if it would better be postponed for efficiency.
 */
static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
	uint32_t ulReceiveLength, BaseType_t xSendLength );

/*
 * The heart of all: check incoming packet for valid data and acks and do what
 * is necessary in each state.
 */
static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );

/*
 * Common code for sending a TCP protocol control packet (i.e. no options, no
 * payload, just flags).
 */
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
                                                 uint8_t ucTCPFlags );

/*
 * A "challenge ACK" is as per https://tools.ietf.org/html/rfc5961#section-3.2,
 * case #3. In summary, an RST was received with a sequence number that is
 * unexpected but still within the window.
 */
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer );

/*
 * Reply to a peer with the RST flag on, in case a packet can not be handled.
 */
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer );

/*
 * Set the initial value for MSS (Maximum Segment Size) to be used.
 */
static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket );

/*
 * Return either a newly created socket, or the current socket in a connected
 * state (depends on the 'bReuseSocket' flag).
 */
static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );

/*
 * After a listening socket receives a new connection, it may duplicate itself.
 * The copying takes place in prvTCPSocketCopy.
 */
static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t *pxNewSocket, FreeRTOS_Socket_t *pxSocket );

/*
 * prvTCPStatusAgeCheck() will see if the socket has been in a non-connected
 * state for too long.  If so, the socket will be closed, and -1 will be
 * returned.
 */
#if( ipconfigTCP_HANG_PROTECTION == 1 )
	static BaseType_t prvTCPStatusAgeCheck( FreeRTOS_Socket_t *pxSocket );
#endif

static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
	int32_t lDataLen, UBaseType_t uxOptionsLength );

#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
	const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState );
#endif

#if( ipconfigUSE_TCP_WIN != 0 )
	static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket );
#endif

/*
 * Generate a randomized TCP Initial Sequence Number per RFC.
 */
extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
													uint16_t usSourcePort,
													uint32_t ulDestinationAddress,
													uint16_t usDestinationPort );

/*-----------------------------------------------------------*/

/* prvTCPSocketIsActive() returns true if the socket must be checked.
 * Non-active sockets are waiting for user action, either connect()
 * or close(). */
static BaseType_t prvTCPSocketIsActive( UBaseType_t uxStatus )
{
	switch( uxStatus )
	{
	case eCLOSED:
	case eCLOSE_WAIT:
	case eFIN_WAIT_2:
	case eCLOSING:
	case eTIME_WAIT:
		return pdFALSE;
	default:
		return pdTRUE;
	}
}
/*-----------------------------------------------------------*/

#if( ipconfigTCP_HANG_PROTECTION == 1 )

	static BaseType_t prvTCPStatusAgeCheck( FreeRTOS_Socket_t *pxSocket )
	{
	BaseType_t xResult;
		switch( pxSocket->u.xTCP.ucTCPState )
		{
		case eESTABLISHED:
			/* If the 'ipconfigTCP_KEEP_ALIVE' option is enabled, sockets in
			state ESTABLISHED can be protected using keep-alive messages. */
			xResult = pdFALSE;
			break;
		case eCLOSED:
		case eTCP_LISTEN:
		case eCLOSE_WAIT:
			/* These 3 states may last for ever, up to the owner. */
			xResult = pdFALSE;
			break;
		default:
			/* All other (non-connected) states will get anti-hanging
			protection. */
			xResult = pdTRUE;
			break;
		}
		if( xResult != pdFALSE )
		{
			/* How much time has past since the last active moment which is
			defined as A) a state change or B) a packet has arrived. */
			TickType_t xAge = xTaskGetTickCount( ) - pxSocket->u.xTCP.xLastActTime;

			/* ipconfigTCP_HANG_PROTECTION_TIME is in units of seconds. */
			if( xAge > ( ipconfigTCP_HANG_PROTECTION_TIME * configTICK_RATE_HZ ) )
			{
				#if( ipconfigHAS_DEBUG_PRINTF == 1 )
				{
					FreeRTOS_debug_printf( ( "Inactive socket closed: port %u rem %lxip:%u status %s\n",
						pxSocket->usLocalPort,
						pxSocket->u.xTCP.ulRemoteIP,
						pxSocket->u.xTCP.usRemotePort,
						FreeRTOS_GetTCPStateName( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) ) );
				}
				#endif /* ipconfigHAS_DEBUG_PRINTF */

				/* Move to eCLOSE_WAIT, user may close the socket. */
				vTCPStateChange( pxSocket, eCLOSE_WAIT );

				/* When 'bPassQueued' true, this socket is an orphan until it
				gets connected. */
				if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED )
				{
					if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
					{
						/* As it did not get connected, and the user can never
						accept() it anymore, it will be deleted now.  Called from
						the IP-task, so it's safe to call the internal Close
						function: vSocketClose(). */
						vSocketClose( pxSocket );
					}
					/* Return a negative value to tell to inform the caller
					xTCPTimerCheck()
					that the socket got closed and may not be accessed anymore. */
					xResult = -1;
				}
			}
		}
		return xResult;
	}
	/*-----------------------------------------------------------*/

#endif

/*
 * As soon as a TCP socket timer expires, this function xTCPSocketCheck
 * will be called (from xTCPTimerCheck)
 * It can send a delayed ACK or new data
 * Sequence of calling (normally) :
 * IP-Task:
 *		xTCPTimerCheck()				// Check all sockets ( declared in FreeRTOS_Sockets.c )
 *		xTCPSocketCheck()				// Either send a delayed ACK or call prvTCPSendPacket()
 *		prvTCPSendPacket()				// Either send a SYN or call prvTCPSendRepeated ( regular messages )
 *		prvTCPSendRepeated()			// Send at most 8 messages on a row
 *			prvTCPReturnPacket()		// Prepare for returning
 *			xNetworkInterfaceOutput()	// Sends data to the NIC ( declared in portable/NetworkInterface/xxx )
 */
BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket )
{
BaseType_t xResult = 0;
BaseType_t xReady = pdFALSE;

	if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.txStream != NULL ) )
	{
		/* The API FreeRTOS_send() might have added data to the TX stream.  Add
		this data to the windowing system to it can be transmitted. */
		prvTCPAddTxData( pxSocket );
	}

	#if ipconfigUSE_TCP_WIN == 1
	{
		if( pxSocket->u.xTCP.pxAckMessage != NULL )
		{
			/* The first task of this regular socket check is to send-out delayed
			ACK's. */
			if( pxSocket->u.xTCP.bits.bUserShutdown == pdFALSE_UNSIGNED )
			{
				/* Earlier data was received but not yet acknowledged.  This
				function is called when the TCP timer for the socket expires, the
				ACK may be sent now. */
				if( pxSocket->u.xTCP.ucTCPState != eCLOSED )
				{
					if( xTCPWindowLoggingLevel > 1 && ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) )
					{
						FreeRTOS_debug_printf( ( "Send[%u->%u] del ACK %lu SEQ %lu (len %u)\n",
							pxSocket->usLocalPort,
							pxSocket->u.xTCP.usRemotePort,
							pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber,
							pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber   - pxSocket->u.xTCP.xTCPWindow.tx.ulFirstSequenceNumber,
							ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) );
					}

					prvTCPReturnPacket( pxSocket, pxSocket->u.xTCP.pxAckMessage, ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER, ipconfigZERO_COPY_TX_DRIVER );

					#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
					{
						/* The ownership has been passed to the SEND routine,
						clear the pointer to it. */
						pxSocket->u.xTCP.pxAckMessage = NULL;
					}
					#endif /* ipconfigZERO_COPY_TX_DRIVER */
				}
				if( prvTCPNextTimeout( pxSocket ) > 1 )
				{
					/* Tell the code below that this function is ready. */
					xReady = pdTRUE;
				}
			}
			else
			{
				/* The user wants to perform an active shutdown(), skip sending
				the	delayed	ACK.  The function prvTCPSendPacket() will send the
				FIN	along with the ACK's. */
			}

			if( pxSocket->u.xTCP.pxAckMessage != NULL )
			{
				vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
				pxSocket->u.xTCP.pxAckMessage = NULL;
			}
		}
	}
	#endif /* ipconfigUSE_TCP_WIN */

	if( xReady == pdFALSE )
	{
		/* The second task of this regular socket check is sending out data. */
		if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) ||
			( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ) )
		{
			prvTCPSendPacket( pxSocket );
		}

		/* Set the time-out for the next wakeup for this socket. */
		prvTCPNextTimeout( pxSocket );

		#if( ipconfigTCP_HANG_PROTECTION == 1 )
		{
			/* In all (non-connected) states in which keep-alive messages can not be sent
			the anti-hang protocol will close sockets that are 'hanging'. */
			xResult = prvTCPStatusAgeCheck( pxSocket );
		}
		#endif
	}

	return xResult;
}
/*-----------------------------------------------------------*/

/*
 * prvTCPSendPacket() will be called when the socket time-out has been reached.
 * It is only called by xTCPSocketCheck().
 */
static int32_t prvTCPSendPacket( FreeRTOS_Socket_t *pxSocket )
{
int32_t lResult = 0;
UBaseType_t uxOptionsLength;
TCPPacket_t *pxTCPPacket;
NetworkBufferDescriptor_t *pxNetworkBuffer;

	if( pxSocket->u.xTCP.ucTCPState != eCONNECT_SYN )
	{
		/* The connection is in s state other than SYN. */
		pxNetworkBuffer = NULL;

		/* prvTCPSendRepeated() will only create a network buffer if necessary,
		i.e. when data must be sent to the peer. */
		lResult = prvTCPSendRepeated( pxSocket, &pxNetworkBuffer );

		if( pxNetworkBuffer != NULL )
		{
			vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
		}
	}
	else
	{
		if( pxSocket->u.xTCP.ucRepCount >= 3u )
		{
			/* The connection is in the SYN status. The packet will be repeated
			to most 3 times.  When there is no response, the socket get the
			status 'eCLOSE_WAIT'. */
			FreeRTOS_debug_printf( ( "Connect: giving up %lxip:%u\n",
				pxSocket->u.xTCP.ulRemoteIP,		/* IP address of remote machine. */
				pxSocket->u.xTCP.usRemotePort ) );	/* Port on remote machine. */
			vTCPStateChange( pxSocket, eCLOSE_WAIT );
		}
		else if( ( pxSocket->u.xTCP.bits.bConnPrepared != pdFALSE_UNSIGNED ) || ( prvTCPPrepareConnect( pxSocket ) == pdTRUE ) )
		{
			/* Or else, if the connection has been prepared, or can be prepared
			now, proceed to send the packet with the SYN flag.
			prvTCPPrepareConnect() prepares 'xPacket' and returns pdTRUE if
			the Ethernet address of the peer or the gateway is found. */
			pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;

			/* About to send a SYN packet.  Call prvSetSynAckOptions() to set
			the proper options: The size of MSS and whether SACK's are
			allowed. */
			uxOptionsLength = prvSetSynAckOptions( pxSocket, pxTCPPacket );

			/* Return the number of bytes to be sent. */
			lResult = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );

			/* Set the TCP offset field:  ipSIZE_OF_TCP_HEADER equals 20 and
			uxOptionsLength is always a multiple of 4.  The complete expression
			would be:
			ucTCPOffset = ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) / 4 ) << 4 */
			pxTCPPacket->xTCPHeader.ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );

			/* Repeat Count is used for a connecting socket, to limit the number
			of tries. */
			pxSocket->u.xTCP.ucRepCount++;

			/* Send the SYN message to make a connection.  The messages is
			stored in the socket field 'xPacket'.  It will be wrapped in a
			pseudo network buffer descriptor before it will be sent. */
			prvTCPReturnPacket( pxSocket, NULL, ( uint32_t ) lResult, pdFALSE );
		}
	}

	/* Return the total number of bytes sent. */
	return lResult;
}
/*-----------------------------------------------------------*/

/*
 * prvTCPSendRepeated will try to send a series of messages, as long as there is
 * data to be sent and as long as the transmit window isn't full.
 */
static int32_t prvTCPSendRepeated( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
{
UBaseType_t uxIndex;
int32_t lResult = 0;
UBaseType_t uxOptionsLength = 0u;
int32_t xSendLength;

	for( uxIndex = 0u; uxIndex < ( UBaseType_t ) SEND_REPEATED_COUNT; uxIndex++ )
	{
		/* prvTCPPrepareSend() might allocate a network buffer if there is data
		to be sent. */
		xSendLength = prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength );
		if( xSendLength <= 0 )
		{
			break;
		}

		/* And return the packet to the peer. */
		prvTCPReturnPacket( pxSocket, *ppxNetworkBuffer, ( uint32_t ) xSendLength, ipconfigZERO_COPY_TX_DRIVER );

		#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
		{
			*ppxNetworkBuffer = NULL;
		}
		#endif /* ipconfigZERO_COPY_TX_DRIVER */

		lResult += xSendLength;
	}

	/* Return the total number of bytes sent. */
	return lResult;
}
/*-----------------------------------------------------------*/

/*
 * Return (or send) a packet the the peer.  The data is stored in pxBuffer,
 * which may either point to a real network buffer or to a TCP socket field
 * called 'xTCP.xPacket'.   A temporary xNetworkBuffer will be used to pass
 * the data to the NIC.
 */
static void prvTCPReturnPacket( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulLen, BaseType_t xReleaseAfterSend )
{
TCPPacket_t * pxTCPPacket;
IPHeader_t *pxIPHeader;
EthernetHeader_t *pxEthernetHeader;
uint32_t ulFrontSpace, ulSpace, ulSourceAddress, ulWinSize;
TCPWindow_t *pxTCPWindow;
NetworkBufferDescriptor_t xTempBuffer;
/* For sending, a pseudo network buffer will be used, as explained above. */

	if( pxNetworkBuffer == NULL )
	{
		pxNetworkBuffer = &xTempBuffer;

		#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
		{
			xTempBuffer.pxNextBuffer = NULL;
		}
		#endif
		xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
		xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
		xReleaseAfterSend = pdFALSE;
	}

	#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
	{
		if( xReleaseAfterSend == pdFALSE )
		{
			pxNetworkBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, ( BaseType_t ) pxNetworkBuffer->xDataLength );
			if( pxNetworkBuffer == NULL )
			{
				FreeRTOS_debug_printf( ( "prvTCPReturnPacket: duplicate failed\n" ) );
			}
			xReleaseAfterSend = pdTRUE;
		}
	}
	#endif /* ipconfigZERO_COPY_TX_DRIVER */

	if( pxNetworkBuffer != NULL )
	{
		pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
		pxIPHeader = &pxTCPPacket->xIPHeader;
		pxEthernetHeader = &pxTCPPacket->xEthernetHeader;

		/* Fill the packet, using hton translations. */
		if( pxSocket != NULL )
		{
			/* Calculate the space in the RX buffer in order to advertise the
			size of this socket's reception window. */
			pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );

			if( pxSocket->u.xTCP.rxStream != NULL )
			{
				/* An RX stream was created already, see how much space is
				available. */
				ulFrontSpace = ( uint32_t ) uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
			}
			else
			{
				/* No RX stream has been created, the full stream size is
				available. */
				ulFrontSpace = ( uint32_t ) pxSocket->u.xTCP.uxRxStreamSize;
			}

			/* Take the minimum of the RX buffer space and the RX window size. */
			ulSpace = FreeRTOS_min_uint32( pxTCPWindow->xSize.ulRxWindowLength, ulFrontSpace );

			if( ( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED ) || ( pxSocket->u.xTCP.bits.bRxStopped != pdFALSE_UNSIGNED ) )
			{
				/* The low-water mark was reached, meaning there was little
				space left.  The socket will wait until the application has read
				or flushed the incoming data, and 'zero-window' will be
				advertised. */
				ulSpace = 0u;
			}

			/* If possible, advertise an RX window size of at least 1 MSS, otherwise
			the peer might start 'zero window probing', i.e. sending small packets
			(1, 2, 4, 8... bytes). */
			if( ( ulSpace < pxSocket->u.xTCP.usCurMSS ) && ( ulFrontSpace >= pxSocket->u.xTCP.usCurMSS ) )
			{
				ulSpace = pxSocket->u.xTCP.usCurMSS;
			}

			/* Avoid overflow of the 16-bit win field. */
			#if( ipconfigUSE_TCP_WIN != 0 )
			{
				ulWinSize = ( ulSpace >> pxSocket->u.xTCP.ucMyWinScaleFactor );
			}
			#else
			{
				ulWinSize = ulSpace;
			}
			#endif
			if( ulWinSize > 0xfffcUL )
			{
				ulWinSize = 0xfffcUL;
			}

			pxTCPPacket->xTCPHeader.usWindow = FreeRTOS_htons( ( uint16_t ) ulWinSize );

			#if( ipconfigHAS_DEBUG_PRINTF != 0 )
			{
				if( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE )
				{
					if( ( xTCPWindowLoggingLevel != 0 ) && ( pxSocket->u.xTCP.bits.bWinChange != pdFALSE_UNSIGNED ) )
					{
					size_t uxFrontSpace;

						if(pxSocket->u.xTCP.rxStream != NULL)
						{
							uxFrontSpace =  uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream ) ;
						}
						else
						{
							uxFrontSpace = 0u;
						}

						FreeRTOS_debug_printf( ( "%s: %lxip:%u: [%lu < %lu] winSize %ld\n",
						pxSocket->u.xTCP.bits.bLowWater ? "STOP" : "GO ",
							pxSocket->u.xTCP.ulRemoteIP,
							pxSocket->u.xTCP.usRemotePort,
							pxSocket->u.xTCP.bits.bLowWater ? pxSocket->u.xTCP.uxLittleSpace : uxFrontSpace, pxSocket->u.xTCP.uxEnoughSpace,
							(int32_t) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulCurrentSequenceNumber ) ) );
					}
				}
			}
			#endif /* ipconfigHAS_DEBUG_PRINTF != 0 */

			/* The new window size has been advertised, switch off the flag. */
			pxSocket->u.xTCP.bits.bWinChange = pdFALSE_UNSIGNED;

			/* Later on, when deciding to delay an ACK, a precise estimate is needed
			of the free RX space.  At this moment, 'ulHighestRxAllowed' would be the
			highest sequence number minus 1 that the socket will accept. */
			pxSocket->u.xTCP.ulHighestRxAllowed = pxTCPWindow->rx.ulCurrentSequenceNumber + ulSpace;

			#if( ipconfigTCP_KEEP_ALIVE == 1 )
				if( pxSocket->u.xTCP.bits.bSendKeepAlive != pdFALSE_UNSIGNED )
				{
					/* Sending a keep-alive packet, send the current sequence number
					minus 1, which will	be recognised as a keep-alive packet an
					responded to by acknowledging the last byte. */
					pxSocket->u.xTCP.bits.bSendKeepAlive = pdFALSE_UNSIGNED;
					pxSocket->u.xTCP.bits.bWaitKeepAlive = pdTRUE_UNSIGNED;

					pxTCPPacket->xTCPHeader.ulSequenceNumber = pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - 1UL;
					pxTCPPacket->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
				}
				else
			#endif
			{
				pxTCPPacket->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber );

				if( ( pxTCPPacket->xTCPHeader.ucTCPFlags & ( uint8_t ) ipTCP_FLAG_FIN ) != 0u )
				{
					/* Suppress FIN in case this packet carries earlier data to be
					retransmitted. */
					uint32_t ulDataLen = ( uint32_t ) ( ulLen - ( ipSIZE_OF_TCP_HEADER + ipSIZE_OF_IPv4_HEADER ) );
					if( ( pxTCPWindow->ulOurSequenceNumber + ulDataLen ) != pxTCPWindow->tx.ulFINSequenceNumber )
					{
						pxTCPPacket->xTCPHeader.ucTCPFlags &= ( ( uint8_t ) ~ipTCP_FLAG_FIN );
						FreeRTOS_debug_printf( ( "Suppress FIN for %lu + %lu < %lu\n",
							pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
							ulDataLen,
							pxTCPWindow->tx.ulFINSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber ) );
					}
				}
			}

			/* Tell which sequence number is expected next time */
			pxTCPPacket->xTCPHeader.ulAckNr = FreeRTOS_htonl( pxTCPWindow->rx.ulCurrentSequenceNumber );
		}
		else
		{
			/* Sending data without a socket, probably replying with a RST flag
			Just swap the two sequence numbers. */
			vFlip_32( pxTCPPacket->xTCPHeader.ulSequenceNumber, pxTCPPacket->xTCPHeader.ulAckNr );
		}

		pxIPHeader->ucTimeToLive		   = ( uint8_t ) ipconfigTCP_TIME_TO_LIVE;
		pxIPHeader->usLength			   = FreeRTOS_htons( ulLen );
		if( ( pxSocket == NULL ) || ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ) )
		{
			/* When pxSocket is NULL, this function is called by prvTCPSendReset()
			and the IP-addresses must be swapped.
			Also swap the IP-addresses in case the IP-tack doesn't have an
			IP-address yet, i.e. when ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ). */
			ulSourceAddress = pxIPHeader->ulDestinationIPAddress;
		}
		else
		{
			ulSourceAddress = *ipLOCAL_IP_ADDRESS_POINTER;
		}
		pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
		pxIPHeader->ulSourceIPAddress = ulSourceAddress;
		vFlip_16( pxTCPPacket->xTCPHeader.usSourcePort, pxTCPPacket->xTCPHeader.usDestinationPort );

		/* Just an increasing number. */
		pxIPHeader->usIdentification = FreeRTOS_htons( usPacketIdentifier );
		usPacketIdentifier++;
		pxIPHeader->usFragmentOffset = 0u;

		#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
		{
			/* calculate the IP header checksum, in case the driver won't do that. */
			pxIPHeader->usHeaderChecksum = 0x00u;
			pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
			pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );

			/* calculate the TCP checksum for an outgoing packet. */
			usGenerateProtocolChecksum( (uint8_t*)pxTCPPacket, pxNetworkBuffer->xDataLength, pdTRUE );

			/* A calculated checksum of 0 must be inverted as 0 means the checksum
			is disabled. */
			if( pxTCPPacket->xTCPHeader.usChecksum == 0x00u )
			{
				pxTCPPacket->xTCPHeader.usChecksum = 0xffffU;
			}
		}
		#endif

	#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
		pxNetworkBuffer->pxNextBuffer = NULL;
	#endif

		/* Important: tell NIC driver how many bytes must be sent. */
		pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;

		/* Fill in the destination MAC addresses. */
		memcpy( ( void * ) &( pxEthernetHeader->xDestinationAddress ), ( void * ) &( pxEthernetHeader->xSourceAddress ),
			sizeof( pxEthernetHeader->xDestinationAddress ) );

		/* The source MAC addresses is fixed to 'ipLOCAL_MAC_ADDRESS'. */
		memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress) , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );

		#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
		{
			if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
			{
			BaseType_t xIndex;

				for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
				{
					pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
				}
				pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
			}
		}
		#endif

		/* Send! */
		xNetworkInterfaceOutput( pxNetworkBuffer, xReleaseAfterSend );

		if( xReleaseAfterSend == pdFALSE )
		{
			/* Swap-back some fields, as pxBuffer probably points to a socket field
			containing the packet header. */
			vFlip_16( pxTCPPacket->xTCPHeader.usSourcePort, pxTCPPacket->xTCPHeader.usDestinationPort);
			pxTCPPacket->xIPHeader.ulSourceIPAddress = pxTCPPacket->xIPHeader.ulDestinationIPAddress;
			memcpy( pxEthernetHeader->xSourceAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
		}
		else
		{
			/* Nothing to do: the buffer has been passed to DMA and will be released after use */
		}
	} /* if( pxNetworkBuffer != NULL ) */
}
/*-----------------------------------------------------------*/

/*
 * The SYN event is very important: the sequence numbers, which have a kind of
 * random starting value, are being synchronised.  The sliding window manager
 * (in FreeRTOS_TCP_WIN.c) needs to know them, along with the Maximum Segment
 * Size (MSS) in use.
 */
static void prvTCPCreateWindow( FreeRTOS_Socket_t *pxSocket )
{
	if( xTCPWindowLoggingLevel )
		FreeRTOS_debug_printf( ( "Limits (using): TCP Win size %lu Water %lu <= %lu <= %lu\n",
			pxSocket->u.xTCP.uxRxWinSize * ipconfigTCP_MSS,
			pxSocket->u.xTCP.uxLittleSpace ,
			pxSocket->u.xTCP.uxEnoughSpace,
			pxSocket->u.xTCP.uxRxStreamSize ) );
	vTCPWindowCreate(
		&pxSocket->u.xTCP.xTCPWindow,
		ipconfigTCP_MSS * pxSocket->u.xTCP.uxRxWinSize,
		ipconfigTCP_MSS * pxSocket->u.xTCP.uxTxWinSize,
		pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber,
		pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber,
		( uint32_t ) pxSocket->u.xTCP.usInitMSS );
}
/*-----------------------------------------------------------*/

/*
 * Connecting sockets have a special state: eCONNECT_SYN.  In this phase,
 * the Ethernet address of the target will be found using ARP.  In case the
 * target IP address is not within the netmask, the hardware address of the
 * gateway will be used.
 */
static BaseType_t prvTCPPrepareConnect( FreeRTOS_Socket_t *pxSocket )
{
TCPPacket_t *pxTCPPacket;
IPHeader_t *pxIPHeader;
eARPLookupResult_t eReturned;
uint32_t ulRemoteIP;
MACAddress_t xEthAddress;
BaseType_t xReturn = pdTRUE;
uint32_t ulInitialSequenceNumber = 0;

	#if( ipconfigHAS_PRINTF != 0 )
	{
		/* Only necessary for nicer logging. */
		memset( xEthAddress.ucBytes, '\0', sizeof( xEthAddress.ucBytes ) );
	}
	#endif /* ipconfigHAS_PRINTF != 0 */

	ulRemoteIP = FreeRTOS_htonl( pxSocket->u.xTCP.ulRemoteIP );

	/* Determine the ARP cache status for the requested IP address. */
	eReturned = eARPGetCacheEntry( &( ulRemoteIP ), &( xEthAddress ) );

	switch( eReturned )
	{
	case eARPCacheHit:		/* An ARP table lookup found a valid entry. */
		break;				/* We can now prepare the SYN packet. */
	case eARPCacheMiss:		/* An ARP table lookup did not find a valid entry. */
	case eCantSendPacket:	/* There is no IP address, or an ARP is still in progress. */
	default:
		/* Count the number of times it couldn't find the ARP address. */
		pxSocket->u.xTCP.ucRepCount++;

		FreeRTOS_debug_printf( ( "ARP for %lxip (using %lxip): rc=%d %02X:%02X:%02X %02X:%02X:%02X\n",
			pxSocket->u.xTCP.ulRemoteIP,
			FreeRTOS_htonl( ulRemoteIP ),
			eReturned,
			xEthAddress.ucBytes[ 0 ],
			xEthAddress.ucBytes[ 1 ],
			xEthAddress.ucBytes[ 2 ],
			xEthAddress.ucBytes[ 3 ],
			xEthAddress.ucBytes[ 4 ],
			xEthAddress.ucBytes[ 5 ] ) );

		/* And issue a (new) ARP request */
		FreeRTOS_OutputARPRequest( ulRemoteIP );

		xReturn = pdFALSE;
	}

	if( xReturn != pdFALSE )
	{
		/* Get a difficult-to-predict initial sequence number for this 4-tuple. */
		ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber( *ipLOCAL_IP_ADDRESS_POINTER,
																	  pxSocket->usLocalPort,
																	  pxSocket->u.xTCP.ulRemoteIP,
																	  pxSocket->u.xTCP.usRemotePort );

		/* Check for a random number generation error. */
		if( 0 == ulInitialSequenceNumber )
		{
			xReturn = pdFALSE;
		}
	}

	if( xReturn != pdFALSE )
	{
		/* The MAC-address of the peer (or gateway) has been found,
		now prepare the initial TCP packet and some fields in the socket. */
		pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
		pxIPHeader = &pxTCPPacket->xIPHeader;

		/* reset the retry counter to zero. */
		pxSocket->u.xTCP.ucRepCount = 0u;

		/* And remember that the connect/SYN data are prepared. */
		pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE_UNSIGNED;

		/* Now that the Ethernet address is known, the initial packet can be
		prepared. */
		memset( pxSocket->u.xTCP.xPacket.u.ucLastPacket, '\0', sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );

		/* Write the Ethernet address in Source, because it will be swapped by
		prvTCPReturnPacket(). */
		memcpy( &pxTCPPacket->xEthernetHeader.xSourceAddress, &xEthAddress, sizeof( xEthAddress ) );

		/* 'ipIPv4_FRAME_TYPE' is already in network-byte-order. */
		pxTCPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;

		pxIPHeader->ucVersionHeaderLength = 0x45u;
		pxIPHeader->usLength = FreeRTOS_htons( sizeof( TCPPacket_t ) - sizeof( pxTCPPacket->xEthernetHeader ) );
		pxIPHeader->ucTimeToLive = ( uint8_t ) ipconfigTCP_TIME_TO_LIVE;

		pxIPHeader->ucProtocol = ( uint8_t ) ipPROTOCOL_TCP;

		/* Addresses and ports will be stored swapped because prvTCPReturnPacket
		will swap them back while replying. */
		pxIPHeader->ulDestinationIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
		pxIPHeader->ulSourceIPAddress = FreeRTOS_htonl( pxSocket->u.xTCP.ulRemoteIP );

		pxTCPPacket->xTCPHeader.usSourcePort = FreeRTOS_htons( pxSocket->u.xTCP.usRemotePort );
		pxTCPPacket->xTCPHeader.usDestinationPort = FreeRTOS_htons( pxSocket->usLocalPort );

		/* We are actively connecting, so the peer's Initial Sequence Number (ISN)
		isn't known yet. */
		pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 0ul;

		/* Start with ISN (Initial Sequence Number). */
		pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;

		/* The TCP header size is 20 bytes, divided by 4 equals 5, which is put in
		the high nibble of the TCP offset field. */
		pxTCPPacket->xTCPHeader.ucTCPOffset = 0x50u;

		/* Only set the SYN flag. */
		pxTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_SYN;

		/* Set the values of usInitMSS / usCurMSS for this socket. */
		prvSocketSetMSS( pxSocket );

		/* The initial sequence numbers at our side are known.  Later
		vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
		first wait for a SYN+ACK reply. */
		prvTCPCreateWindow( pxSocket );
	}

	return xReturn;
}
/*-----------------------------------------------------------*/

/* For logging and debugging: make a string showing the TCP flags
*/
#if( ipconfigHAS_DEBUG_PRINTF != 0 )

	static const char *prvTCPFlagMeaning( UBaseType_t xFlags)
	{
		static char retString[10];
		snprintf(retString, sizeof( retString ), "%c%c%c%c%c%c%c%c%c",
			( xFlags & ipTCP_FLAG_FIN )  ? 'F' : '.',	/* 0x0001: No more data from sender */
			( xFlags & ipTCP_FLAG_SYN )  ? 'S' : '.',	/* 0x0002: Synchronize sequence numbers */
			( xFlags & ipTCP_FLAG_RST )  ? 'R' : '.',	/* 0x0004: Reset the connection */
			( xFlags & ipTCP_FLAG_PSH )  ? 'P' : '.',	/* 0x0008: Push function: please push buffered data to the recv application */
			( xFlags & ipTCP_FLAG_ACK )  ? 'A' : '.',	/* 0x0010: Acknowledgment field is significant */
			( xFlags & ipTCP_FLAG_URG )  ? 'U' : '.',	/* 0x0020: Urgent pointer field is significant */
			( xFlags & ipTCP_FLAG_ECN )  ? 'E' : '.',	/* 0x0040: ECN-Echo */
			( xFlags & ipTCP_FLAG_CWR )  ? 'C' : '.',	/* 0x0080: Congestion Window Reduced */
			( xFlags & ipTCP_FLAG_NS )   ? 'N' : '.');	/* 0x0100: ECN-nonce concealment protection */
		return retString;
	}
	/*-----------------------------------------------------------*/

#endif /* ipconfigHAS_DEBUG_PRINTF */

/*
 * Parse the TCP option(s) received, if present.  It has already been verified
 * that: ((pxTCPHeader->ucTCPOffset & 0xf0) > 0x50), meaning that the TP header
 * is longer than the usual 20 (5 x 4) bytes.
 */
static void prvCheckOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
{
TCPPacket_t * pxTCPPacket;
TCPHeader_t * pxTCPHeader;
const unsigned char *pucPtr;
const unsigned char *pucLast;
TCPWindow_t *pxTCPWindow;
BaseType_t xShouldContinueLoop;

	pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
	pxTCPHeader = &pxTCPPacket->xTCPHeader;

	/* A character pointer to iterate through the option data */
	pucPtr = pxTCPHeader->ucOptdata;
	pucLast = pucPtr + (((pxTCPHeader->ucTCPOffset >> 4) - 5) << 2);
	pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;

	/* Validate options size calculation. */
	if( pucLast > ( pxNetworkBuffer->pucEthernetBuffer + pxNetworkBuffer->xDataLength ) )
	{
		return;
	}

	/* The comparison with pucLast is only necessary in case the option data are
	corrupted, we don't like to run into invalid memory and crash. */
	xShouldContinueLoop = pdTRUE;
	while( ( pucPtr < pucLast ) && ( xShouldContinueLoop == pdTRUE ) )
	{
		xShouldContinueLoop = prvSingleStepTCPHeaderOptions( &pucPtr, &pucLast, &pxSocket, &pxTCPWindow );
	}
}

/*-----------------------------------------------------------*/

static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow)
{
	UBaseType_t uxNewMSS;
	UBaseType_t xRemainingOptionsBytes = ( *ppucLast ) - ( *ppucPtr );
	unsigned char ucLen;

	if( ( *ppucPtr )[ 0 ] == TCP_OPT_END )
	{
		/* End of options. */
		return pdFALSE;
	}
	if( ( *ppucPtr )[ 0 ] == TCP_OPT_NOOP)
	{
		/* NOP option, inserted to make the length a multiple of 4. */
		( *ppucPtr )++;
		return pdTRUE;
	}

	/* Any other well-formed option must be at least two bytes: the option
	type byte followed by a length byte. */
	if( xRemainingOptionsBytes < 2 )
	{
		return pdFALSE;
	}
#if( ipconfigUSE_TCP_WIN != 0 )
	else if( ( *ppucPtr )[ 0 ] == TCP_OPT_WSOPT )
	{
		/* Confirm that the option fits in the remaining buffer space. */
		if( ( xRemainingOptionsBytes < TCP_OPT_WSOPT_LEN ) || ( ( *ppucPtr )[ 1 ] != TCP_OPT_WSOPT_LEN ) )
		{
			return pdFALSE;
		}

		( *ppxSocket )->u.xTCP.ucPeerWinScaleFactor = ( *ppucPtr )[ 2 ];
		( *ppxSocket )->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
		( *ppucPtr ) += TCP_OPT_WSOPT_LEN;
	}
#endif	/* ipconfigUSE_TCP_WIN */
	else if( ( *ppucPtr )[ 0 ] == TCP_OPT_MSS )
	{
		/* Confirm that the option fits in the remaining buffer space. */
		if( ( xRemainingOptionsBytes < TCP_OPT_MSS_LEN )|| ( ( *ppucPtr )[ 1 ] != TCP_OPT_MSS_LEN ) )
		{
			return pdFALSE;
		}

		/* An MSS option with the correct option length.  FreeRTOS_htons()
		is not needed here because usChar2u16() already returns a host
		endian number. */
		uxNewMSS = usChar2u16( ( *ppucPtr ) + 2 );

		if( ( *ppxSocket )->u.xTCP.usInitMSS != uxNewMSS )
		{
			/* Perform a basic check on the the new MSS. */
			if( uxNewMSS == 0 )
			{
				return pdFALSE;
			}

			FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", ( *ppxSocket )->u.xTCP.usInitMSS, uxNewMSS ) );
		}

		if( ( *ppxSocket )->u.xTCP.usInitMSS > uxNewMSS )
		{
			/* our MSS was bigger than the MSS of the other party: adapt it. */
			( *ppxSocket )->u.xTCP.bits.bMssChange = pdTRUE_UNSIGNED;
			if( ( ( *ppxTCPWindow ) != NULL ) && ( ( *ppxSocket )->u.xTCP.usCurMSS > uxNewMSS ) )
			{
				/* The peer advertises a smaller MSS than this socket was
				using.  Use that as well. */
				FreeRTOS_debug_printf( ( "Change mss %d => %lu\n", ( *ppxSocket )->u.xTCP.usCurMSS, uxNewMSS ) );
				( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
			}
			( *ppxTCPWindow )->xSize.ulRxWindowLength = ( ( uint32_t ) uxNewMSS ) * ( ( *ppxTCPWindow )->xSize.ulRxWindowLength / ( ( uint32_t ) uxNewMSS ) );
			( *ppxTCPWindow )->usMSSInit = ( uint16_t ) uxNewMSS;
			( *ppxTCPWindow )->usMSS = ( uint16_t ) uxNewMSS;
			( *ppxSocket )->u.xTCP.usInitMSS = ( uint16_t ) uxNewMSS;
			( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
		}

		#if( ipconfigUSE_TCP_WIN != 1 )
			/* Without scaled windows, MSS is the only interesting option. */
			return pdFALSE;
		#else
			/* Or else we continue to check another option: selective ACK. */
			( *ppucPtr ) += TCP_OPT_MSS_LEN;
		#endif	/* ipconfigUSE_TCP_WIN != 1 */
	}
	else
	{
		/* All other options have a length field, so that we easily
		can skip past them. */
		ucLen = ( *ppucPtr )[ 1 ];
		if( ( ucLen < 2 ) || ( ucLen > xRemainingOptionsBytes ) )
		{
			/* If the length field is too small or too big, the options are
			 * malformed, don't process them further.
			 */
			return pdFALSE;
		}

		#if( ipconfigUSE_TCP_WIN == 1 )
		{
			/* Selective ACK: the peer has received a packet but it is missing
			 * earlier packets. At least this packet does not need retransmission
			 * anymore. ulTCPWindowTxSack( ) takes care of this administration.
			 */
			if( ( *ppucPtr )[0] == TCP_OPT_SACK_A )
			{
				ucLen -= 2;
				( *ppucPtr ) += 2;

				while( ucLen >= 8 )
				{
					prvSkipPastRemainingOptions( ppucPtr, ppxSocket, &ucLen );
				}
				/* ucLen should be 0 by now. */
			}
		}
		#endif	/* ipconfigUSE_TCP_WIN == 1 */

		( *ppucPtr ) += ucLen;
	}
	return pdTRUE;
}

/*-----------------------------------------------------------*/

static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const pucLen )
{
uint32_t ulFirst = ulChar2u32( ( *ppucPtr ) );
uint32_t ulLast  = ulChar2u32( ( *ppucPtr ) + 4 );
uint32_t ulCount = ulTCPWindowTxSack( &( *ppxSocket )->u.xTCP.xTCPWindow, ulFirst, ulLast );
	/* ulTCPWindowTxSack( ) returns the number of bytes which have been acked
	 * starting from the head position.  Advance the tail pointer in txStream.
	 */
	if( ( ( *ppxSocket )->u.xTCP.txStream  != NULL ) && ( ulCount > 0 ) )
	{
		/* Just advancing the tail index, 'ulCount' bytes have been confirmed. */
		uxStreamBufferGet( ( *ppxSocket )->u.xTCP.txStream, 0, NULL, ( size_t ) ulCount, pdFALSE );
		( *ppxSocket )->xEventBits |= eSOCKET_SEND;

		#if ipconfigSUPPORT_SELECT_FUNCTION == 1
		{
			if( ( *ppxSocket )->xSelectBits & eSELECT_WRITE )
			{
				/* The field 'xEventBits' is used to store regular socket events
				 * (at most 8), as well as 'select events', which will be left-shifted.
				 */
				( *ppxSocket )->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
			}
		}
		#endif

		/* In case the socket owner has installed an OnSent handler, call it now.
		 */
		#if( ipconfigUSE_CALLBACKS == 1 )
		{
			if( ipconfigIS_VALID_PROG_ADDRESS( ( *ppxSocket )->u.xTCP.pxHandleSent ) )
			{
				( *ppxSocket )->u.xTCP.pxHandleSent( (Socket_t )( *ppxSocket ), ulCount );
			}
		}
		#endif /* ipconfigUSE_CALLBACKS == 1  */
	}
	( *ppucPtr ) += 8;
	( *pucLen ) -= 8;
}

/*-----------------------------------------------------------*/

#if( ipconfigUSE_TCP_WIN != 0 )

	static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket )
	{
	size_t uxWinSize;
	uint8_t ucFactor;

		/* 'xTCP.uxRxWinSize' is the size of the reception window in units of MSS. */
		uxWinSize = pxSocket->u.xTCP.uxRxWinSize * ( size_t ) pxSocket->u.xTCP.usInitMSS;
		ucFactor = 0u;
		while( uxWinSize > 0xfffful )
		{
			/* Divide by two and increase the binary factor by 1. */
			uxWinSize >>= 1;
			ucFactor++;
		}

		FreeRTOS_debug_printf( ( "prvWinScaleFactor: uxRxWinSize %lu MSS %lu Factor %u\n",
			pxSocket->u.xTCP.uxRxWinSize,
			pxSocket->u.xTCP.usInitMSS,
			ucFactor ) );

		return ucFactor;
	}

#endif
/*-----------------------------------------------------------*/

/*
 * When opening a TCP connection, while SYN's are being sent, the  parties may
 * communicate what MSS (Maximum Segment Size) they intend to use.   MSS is the
 * nett size of the payload, always smaller than MTU.
*/
static UBaseType_t prvSetSynAckOptions( FreeRTOS_Socket_t *pxSocket, TCPPacket_t * pxTCPPacket )
{
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
uint16_t usMSS = pxSocket->u.xTCP.usInitMSS;
UBaseType_t uxOptionsLength;

	/* We send out the TCP Maximum Segment Size option with our SYN[+ACK]. */

	pxTCPHeader->ucOptdata[ 0 ] = ( uint8_t ) TCP_OPT_MSS;
	pxTCPHeader->ucOptdata[ 1 ] = ( uint8_t ) TCP_OPT_MSS_LEN;
	pxTCPHeader->ucOptdata[ 2 ] = ( uint8_t ) ( usMSS >> 8 );
	pxTCPHeader->ucOptdata[ 3 ] = ( uint8_t ) ( usMSS & 0xffu );

	#if( ipconfigUSE_TCP_WIN != 0 )
	{
		pxSocket->u.xTCP.ucMyWinScaleFactor = prvWinScaleFactor( pxSocket );

		pxTCPHeader->ucOptdata[ 4 ] = TCP_OPT_NOOP;
		pxTCPHeader->ucOptdata[ 5 ] = ( uint8_t ) ( TCP_OPT_WSOPT );
		pxTCPHeader->ucOptdata[ 6 ] = ( uint8_t ) ( TCP_OPT_WSOPT_LEN );
		pxTCPHeader->ucOptdata[ 7 ] = ( uint8_t ) pxSocket->u.xTCP.ucMyWinScaleFactor;
		uxOptionsLength = 8u;
	}
	#else
	{
		uxOptionsLength = 4u;
	}
	#endif

	#if( ipconfigUSE_TCP_WIN == 0 )
	{
		return uxOptionsLength;
	}
	#else
	{
		pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_NOOP;
		pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = TCP_OPT_NOOP;
		pxTCPHeader->ucOptdata[ uxOptionsLength + 2 ] = TCP_OPT_SACK_P;	/* 4: Sack-Permitted Option. */
		pxTCPHeader->ucOptdata[ uxOptionsLength + 3 ] = 2;	/* 2: length of this option. */
		uxOptionsLength += 4u;

		return uxOptionsLength; /* bytes, not words. */
	}
	#endif	/* ipconfigUSE_TCP_WIN == 0 */
}

/*
 * For anti-hanging protection and TCP keep-alive messages.  Called in two
 * places: after receiving a packet and after a state change.  The socket's
 * alive timer may be reset.
 */
static void prvTCPTouchSocket( FreeRTOS_Socket_t *pxSocket )
{
	#if( ipconfigTCP_HANG_PROTECTION == 1 )
	{
		pxSocket->u.xTCP.xLastActTime = xTaskGetTickCount( );
	}
	#endif

	#if( ipconfigTCP_KEEP_ALIVE == 1 )
	{
		pxSocket->u.xTCP.bits.bWaitKeepAlive = pdFALSE_UNSIGNED;
		pxSocket->u.xTCP.bits.bSendKeepAlive = pdFALSE_UNSIGNED;
		pxSocket->u.xTCP.ucKeepRepCount = 0u;
		pxSocket->u.xTCP.xLastAliveTime = xTaskGetTickCount();
	}
	#endif

	( void ) pxSocket;
}
/*-----------------------------------------------------------*/

/*
 * Changing to a new state. Centralised here to do specific actions such as
 * resetting the alive timer, calling the user's OnConnect handler to notify
 * that a socket has got (dis)connected, and setting bit to unblock a call to
 * FreeRTOS_select()
 */
void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState )
{
FreeRTOS_Socket_t *xParent = NULL;
BaseType_t bBefore = ( BaseType_t ) NOW_CONNECTED( pxSocket->u.xTCP.ucTCPState );	/* Was it connected ? */
BaseType_t bAfter  = ( BaseType_t ) NOW_CONNECTED( eTCPState );						/* Is it connected now ? */
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
	BaseType_t xPreviousState = ( BaseType_t ) pxSocket->u.xTCP.ucTCPState;
#endif
#if( ipconfigUSE_CALLBACKS == 1 )
	FreeRTOS_Socket_t *xConnected = NULL;
#endif

	/* Has the connected status changed? */
	if( bBefore != bAfter )
	{
		/* Is the socket connected now ? */
		if( bAfter != pdFALSE )
		{
			/* if bPassQueued is true, this socket is an orphan until it gets connected. */
			if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED )
			{
				/* Now that it is connected, find it's parent. */
				if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
				{
					xParent = pxSocket;
				}
				else
				{
					xParent = pxSocket->u.xTCP.pxPeerSocket;
					configASSERT( xParent != NULL );
				}
				if( xParent != NULL )
				{
					if( xParent->u.xTCP.pxPeerSocket == NULL )
					{
						xParent->u.xTCP.pxPeerSocket = pxSocket;
					}

					xParent->xEventBits |= eSOCKET_ACCEPT;

					#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
					{
						/* Library support FreeRTOS_select().  Receiving a new
						connection is being translated as a READ event. */
						if( ( xParent->xSelectBits & eSELECT_READ ) != 0 )
						{
							xParent->xEventBits |= ( eSELECT_READ << SOCKET_EVENT_BIT_COUNT );
						}
					}
					#endif

					#if( ipconfigUSE_CALLBACKS == 1 )
					{
						if( ( ipconfigIS_VALID_PROG_ADDRESS( xParent->u.xTCP.pxHandleConnected ) != pdFALSE ) &&
							( xParent->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED ) )
						{
							/* The listening socket does not become connected itself, in stead
							a child socket is created.
							Postpone a call the OnConnect event until the end of this function. */
							xConnected = xParent;
						}
					}
					#endif
				}

				/* Don't need to access the parent socket anymore, so the
				reference 'pxPeerSocket' may be cleared. */
				pxSocket->u.xTCP.pxPeerSocket = NULL;
				pxSocket->u.xTCP.bits.bPassQueued = pdFALSE_UNSIGNED;

				/* When true, this socket may be returned in a call to accept(). */
				pxSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
			}
			else
			{
				pxSocket->xEventBits |= eSOCKET_CONNECT;

				#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
				{
					if( pxSocket->xSelectBits & eSELECT_WRITE )
					{
						pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
					}
				}
				#endif
			}
		}
		else  /* bAfter == pdFALSE, connection is closed. */
		{
			/* Notify/wake-up the socket-owner by setting a semaphore. */
			pxSocket->xEventBits |= eSOCKET_CLOSED;

			#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
			{
				if( ( pxSocket->xSelectBits & eSELECT_EXCEPT ) != 0 )
				{
					pxSocket->xEventBits |= ( eSELECT_EXCEPT << SOCKET_EVENT_BIT_COUNT );
				}
			}
			#endif
		}
		#if( ipconfigUSE_CALLBACKS == 1 )
		{
			if( ( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleConnected ) != pdFALSE ) && ( xConnected == NULL ) )
			{
				/* The 'connected' state has changed, call the user handler. */
				xConnected = pxSocket;
			}
		}
		#endif /* ipconfigUSE_CALLBACKS */

		if( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE )
		{
			/* Now the socket isn't in an active state anymore so it
			won't need further attention of the IP-task.
			Setting time-out to zero means that the socket won't get checked during
			timer events. */
			pxSocket->u.xTCP.usTimeout = 0u;
		}
	}
	else
	{
		if( eTCPState == eCLOSED )
		{
			/* Socket goes to status eCLOSED because of a RST.
			When nobody owns the socket yet, delete it. */
			if( ( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED ) ||
				( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
			{
				FreeRTOS_debug_printf( ( "vTCPStateChange: Closing socket\n" ) );
				if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
				{
					FreeRTOS_closesocket( pxSocket );
				}
			}
		}
	}

	/* Fill in the new state. */
	pxSocket->u.xTCP.ucTCPState = ( uint8_t ) eTCPState;

	/* touch the alive timers because moving to another state. */
	prvTCPTouchSocket( pxSocket );

	#if( ipconfigHAS_DEBUG_PRINTF == 1 )
	{
	if( ( xTCPWindowLoggingLevel >= 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
		FreeRTOS_debug_printf( ( "Socket %d -> %lxip:%u State %s->%s\n",
			pxSocket->usLocalPort,
			pxSocket->u.xTCP.ulRemoteIP,
			pxSocket->u.xTCP.usRemotePort,
			FreeRTOS_GetTCPStateName( ( UBaseType_t ) xPreviousState ),
			FreeRTOS_GetTCPStateName( ( UBaseType_t ) eTCPState ) ) );
	}
	#endif /* ipconfigHAS_DEBUG_PRINTF */

	#if( ipconfigUSE_CALLBACKS == 1 )
	{
		if( xConnected != NULL )
		{
			/* The 'connected' state has changed, call the OnConnect handler of the parent. */
			xConnected->u.xTCP.pxHandleConnected( ( Socket_t ) xConnected, bAfter );
		}
	}
	#endif
	if( xParent != NULL )
	{
		vSocketWakeUpUser( xParent );
	}
}
/*-----------------------------------------------------------*/

static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
	int32_t lDataLen, UBaseType_t uxOptionsLength )
{
NetworkBufferDescriptor_t *pxReturn;
int32_t lNeeded;
BaseType_t xResize;

	if( xBufferAllocFixedSize != pdFALSE )
	{
		/* Network buffers are created with a fixed size and can hold the largest
		MTU. */
		lNeeded = ( int32_t ) ipTOTAL_ETHERNET_FRAME_SIZE;
		/* and therefore, the buffer won't be too small.
		Only ask for a new network buffer in case none was supplied. */
		xResize = ( pxNetworkBuffer == NULL );
	}
	else
	{
		/* Network buffers are created with a variable size. See if it must
		grow. */
		lNeeded = FreeRTOS_max_int32( ( int32_t ) sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ),
			( int32_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen );
		/* In case we were called from a TCP timer event, a buffer must be
		created.  Otherwise, test 'xDataLength' of the provided buffer. */
		xResize = ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded );
	}

	if( xResize != pdFALSE )
	{
		/* The caller didn't provide a network buffer or the provided buffer is
		too small.  As we must send-out a data packet, a buffer will be created
		here. */
		pxReturn = pxGetNetworkBufferWithDescriptor( ( uint32_t ) lNeeded, 0u );

		if( pxReturn != NULL )
		{
			/* Set the actual packet size, in case the returned buffer is larger. */
			pxReturn->xDataLength = lNeeded;

			/* Copy the existing data to the new created buffer. */
			if( pxNetworkBuffer )
			{
				/* Either from the previous buffer... */
				memcpy( pxReturn->pucEthernetBuffer, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );

				/* ...and release it. */
				vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
			}
			else
			{
				/* Or from the socket field 'xTCP.xPacket'. */
				memcpy( pxReturn->pucEthernetBuffer, pxSocket->u.xTCP.xPacket.u.ucLastPacket, sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );
			}
		}
	}
	else
	{
		/* xResize is false, the network buffer provided was big enough. */
		pxReturn = pxNetworkBuffer;

		/* Thanks to Andrey Ivanov from swissEmbedded for reporting that the
		xDataLength member must get the correct length too! */
		pxNetworkBuffer->xDataLength = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + ( size_t ) lDataLen;
	}

	return pxReturn;
}
/*-----------------------------------------------------------*/

/*
 * Prepare an outgoing message, in case anything has to be sent.
 */
static int32_t prvTCPPrepareSend( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, UBaseType_t uxOptionsLength )
{
int32_t lDataLen;
uint8_t *pucEthernetBuffer, *pucSendData;
TCPPacket_t *pxTCPPacket;
size_t uxOffset;
uint32_t ulDataGot, ulDistance;
TCPWindow_t *pxTCPWindow;
NetworkBufferDescriptor_t *pxNewBuffer;
int32_t lStreamPos;

	if( ( *ppxNetworkBuffer ) != NULL )
	{
		/* A network buffer descriptor was already supplied */
		pucEthernetBuffer = ( *ppxNetworkBuffer )->pucEthernetBuffer;
	}
	else
	{
		/* For now let it point to the last packet header */
		pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
	}

	pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
	pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
	lDataLen = 0;
	lStreamPos = 0;
	pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_ACK;

	if( pxSocket->u.xTCP.txStream != NULL )
	{
		/* ulTCPWindowTxGet will return the amount of data which may be sent
		along with the position in the txStream.
		Why check for MSS > 1 ?
		Because some TCP-stacks (like uIP) use it for flow-control. */
		if( pxSocket->u.xTCP.usCurMSS > 1u )
		{
			lDataLen = ( int32_t ) ulTCPWindowTxGet( pxTCPWindow, pxSocket->u.xTCP.ulWindowSize, &lStreamPos );
		}

		if( lDataLen > 0 )
		{
			/* Check if the current network buffer is big enough, if not,
			resize it. */
			pxNewBuffer = prvTCPBufferResize( pxSocket, *ppxNetworkBuffer, lDataLen, uxOptionsLength );

			if( pxNewBuffer != NULL )
			{
				*ppxNetworkBuffer = pxNewBuffer;
				pucEthernetBuffer = pxNewBuffer->pucEthernetBuffer;
				pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );

				pucSendData = pucEthernetBuffer + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength;

				/* Translate the position in txStream to an offset from the tail
				marker. */
				uxOffset = uxStreamBufferDistance( pxSocket->u.xTCP.txStream, pxSocket->u.xTCP.txStream->uxTail, ( size_t ) lStreamPos );

				/* Here data is copied from the txStream in 'peek' mode.  Only
				when the packets are acked, the tail marker will be updated. */
				ulDataGot = ( uint32_t ) uxStreamBufferGet( pxSocket->u.xTCP.txStream, uxOffset, pucSendData, ( size_t ) lDataLen, pdTRUE );

				#if( ipconfigHAS_DEBUG_PRINTF != 0 )
				{
					if( ulDataGot != ( uint32_t ) lDataLen )
					{
						FreeRTOS_debug_printf( ( "uxStreamBufferGet: pos %lu offs %lu only %lu != %lu\n",
							lStreamPos, uxOffset, ulDataGot, lDataLen ) );
					}
				}
				#endif

				/* If the owner of the socket requests a closure, add the FIN
				flag to the last packet. */
				if( ( pxSocket->u.xTCP.bits.bCloseRequested != pdFALSE_UNSIGNED ) && ( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) )
				{
					ulDistance = ( uint32_t ) uxStreamBufferDistance( pxSocket->u.xTCP.txStream, ( size_t ) lStreamPos, pxSocket->u.xTCP.txStream->uxHead );

					if( ulDistance == ulDataGot )
					{
						#if (ipconfigHAS_DEBUG_PRINTF == 1)
						{
						/* the order of volatile accesses is undefined
							so such workaround */
							size_t uxHead = pxSocket->u.xTCP.txStream->uxHead;
							size_t uxMid = pxSocket->u.xTCP.txStream->uxMid;
							size_t uxTail = pxSocket->u.xTCP.txStream->uxTail;

							FreeRTOS_debug_printf( ( "CheckClose %lu <= %lu (%lu <= %lu <= %lu)\n", ulDataGot, ulDistance,
								uxTail, uxMid, uxHead ) );
						}
						#endif
						/* Although the socket sends a FIN, it will stay in
						ESTABLISHED until all current data has been received or
						delivered. */
						pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_FIN;
						pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->ulOurSequenceNumber + ( uint32_t ) lDataLen;
						pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
					}
				}
			}
			else
			{
				lDataLen = -1;
			}
		}
	}

	if( ( lDataLen >= 0 ) && ( pxSocket->u.xTCP.ucTCPState == eESTABLISHED ) )
	{
		/* See if the socket owner wants to shutdown this connection. */
		if( ( pxSocket->u.xTCP.bits.bUserShutdown != pdFALSE_UNSIGNED ) &&
			( xTCPWindowTxDone( pxTCPWindow ) != pdFALSE ) )
		{
			pxSocket->u.xTCP.bits.bUserShutdown = pdFALSE_UNSIGNED;
			pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_FIN;
			pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
			pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
			pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
			vTCPStateChange( pxSocket, eFIN_WAIT_1 );
		}

		#if( ipconfigTCP_KEEP_ALIVE != 0 )
		{
			if( pxSocket->u.xTCP.ucKeepRepCount > 3u )
			{
				FreeRTOS_debug_printf( ( "keep-alive: giving up %lxip:%u\n",
					pxSocket->u.xTCP.ulRemoteIP,			/* IP address of remote machine. */
					pxSocket->u.xTCP.usRemotePort ) );	/* Port on remote machine. */
				vTCPStateChange( pxSocket, eCLOSE_WAIT );
				lDataLen = -1;
			}
			if( ( lDataLen == 0 ) && ( pxSocket->u.xTCP.bits.bWinChange == pdFALSE_UNSIGNED ) )
			{
				/* If there is no data to be sent, and no window-update message,
				we might want to send a keep-alive message. */
				TickType_t xAge = xTaskGetTickCount( ) - pxSocket->u.xTCP.xLastAliveTime;
				TickType_t xMax;
				xMax = ( ( TickType_t ) ipconfigTCP_KEEP_ALIVE_INTERVAL * configTICK_RATE_HZ );
				if( pxSocket->u.xTCP.ucKeepRepCount )
				{
					xMax = ( 3u * configTICK_RATE_HZ );
				}
				if( xAge > xMax )
				{
					pxSocket->u.xTCP.xLastAliveTime = xTaskGetTickCount( );
					if( xTCPWindowLoggingLevel )
						FreeRTOS_debug_printf( ( "keep-alive: %lxip:%u count %u\n",
							pxSocket->u.xTCP.ulRemoteIP,
							pxSocket->u.xTCP.usRemotePort,
							pxSocket->u.xTCP.ucKeepRepCount ) );
					pxSocket->u.xTCP.bits.bSendKeepAlive = pdTRUE_UNSIGNED;
					pxSocket->u.xTCP.usTimeout = ( ( uint16_t ) pdMS_TO_TICKS( 2500 ) );
					pxSocket->u.xTCP.ucKeepRepCount++;
				}
			}
		}
		#endif /* ipconfigTCP_KEEP_ALIVE */
	}

	/* Anything to send, a change of the advertised window size, or maybe send a
	keep-alive message? */
	if( ( lDataLen > 0 ) ||
		( pxSocket->u.xTCP.bits.bWinChange != pdFALSE_UNSIGNED ) ||
		( pxSocket->u.xTCP.bits.bSendKeepAlive != pdFALSE_UNSIGNED ) )
	{
		pxTCPPacket->xTCPHeader.ucTCPFlags &= ( ( uint8_t ) ~ipTCP_FLAG_PSH );
		pxTCPPacket->xTCPHeader.ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );

		pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_ACK;

		if( lDataLen != 0l )
		{
			pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_PSH;
		}

		lDataLen += ( int32_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
	}

	return lDataLen;
}
/*-----------------------------------------------------------*/

/*
 * Calculate after how much time this socket needs to be checked again.
 */
static TickType_t prvTCPNextTimeout ( FreeRTOS_Socket_t *pxSocket )
{
TickType_t ulDelayMs = ( TickType_t ) tcpMAXIMUM_TCP_WAKEUP_TIME_MS;

	if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
	{
		/* The socket is actively connecting to a peer. */
		if( pxSocket->u.xTCP.bits.bConnPrepared )
		{
			/* Ethernet address has been found, use progressive timeout for
			active connect(). */
			if( pxSocket->u.xTCP.ucRepCount < 3u )
			{
				ulDelayMs = ( 3000UL << ( pxSocket->u.xTCP.ucRepCount - 1u ) );
			}
			else
			{
				ulDelayMs = 11000UL;
			}
		}
		else
		{
			/* Still in the ARP phase: check every half second. */
			ulDelayMs = 500UL;
		}

		FreeRTOS_debug_printf( ( "Connect[%lxip:%u]: next timeout %u: %lu ms\n",
			pxSocket->u.xTCP.ulRemoteIP, pxSocket->u.xTCP.usRemotePort,
			pxSocket->u.xTCP.ucRepCount, ulDelayMs ) );
		pxSocket->u.xTCP.usTimeout = ( uint16_t )pdMS_TO_MIN_TICKS( ulDelayMs );
	}
	else if( pxSocket->u.xTCP.usTimeout == 0u )
	{
		/* Let the sliding window mechanism decide what time-out is appropriate. */
		BaseType_t xResult = xTCPWindowTxHasData( &pxSocket->u.xTCP.xTCPWindow, pxSocket->u.xTCP.ulWindowSize, &ulDelayMs );
		if( ulDelayMs == 0u )
		{
			if( xResult != ( BaseType_t )0 )
			{
				ulDelayMs = 1UL;
			}
			else
			{
				ulDelayMs = tcpMAXIMUM_TCP_WAKEUP_TIME_MS;
			}
		}
		else
		{
			/* ulDelayMs contains the time to wait before a re-transmission. */
		}
		pxSocket->u.xTCP.usTimeout = ( uint16_t )pdMS_TO_MIN_TICKS( ulDelayMs );
	}
	else
	{
		/* field '.usTimeout' has already been set (by the
		keep-alive/delayed-ACK mechanism). */
	}

	/* Return the number of clock ticks before the timer expires. */
	return ( TickType_t ) pxSocket->u.xTCP.usTimeout;
}
/*-----------------------------------------------------------*/

static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket )
{
int32_t lCount, lLength;

	/* A txStream has been created already, see if the socket has new data for
	the sliding window.

	uxStreamBufferMidSpace() returns the distance between rxHead and rxMid.  It contains new
	Tx data which has not been passed to the sliding window yet.  The oldest
	data not-yet-confirmed can be found at rxTail. */
	lLength = ( int32_t ) uxStreamBufferMidSpace( pxSocket->u.xTCP.txStream );

	if( lLength > 0 )
	{
		/* All data between txMid and rxHead will now be passed to the sliding
		window manager, so it can start transmitting them.

		Hand over the new data to the sliding window handler.  It will be
		split-up in chunks of 1460 bytes each (or less, depending on
		ipconfigTCP_MSS). */
		lCount = lTCPWindowTxAdd(	&pxSocket->u.xTCP.xTCPWindow,
								( uint32_t ) lLength,
								( int32_t ) pxSocket->u.xTCP.txStream->uxMid,
								( int32_t ) pxSocket->u.xTCP.txStream->LENGTH );

		/* Move the rxMid pointer forward up to rxHead. */
		if( lCount > 0 )
		{
			vStreamBufferMoveMid( pxSocket->u.xTCP.txStream, ( size_t ) lCount );
		}
	}
}
/*-----------------------------------------------------------*/

/*
 * prvTCPHandleFin() will be called to handle socket closure
 * The Closure starts when either a FIN has been received and accepted,
 * Or when the socket has sent a FIN flag to the peer
 * Before being called, it has been checked that both reception and transmission
 * are complete.
 */
static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
BaseType_t xSendLength = 0;
uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr );

	if( ( ucTCPFlags & ipTCP_FLAG_FIN ) != 0u )
	{
		pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulFINSequenceNumber + 1u;
	}
	if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
	{
		/* We haven't yet replied with a FIN, do so now. */
		pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
		pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
	}
	else
	{
		/* We did send a FIN already, see if it's ACK'd. */
		if( ulAckNr == pxTCPWindow->tx.ulFINSequenceNumber + 1u )
		{
			pxSocket->u.xTCP.bits.bFinAcked = pdTRUE_UNSIGNED;
		}
	}

	if( pxSocket->u.xTCP.bits.bFinAcked == pdFALSE_UNSIGNED )
	{
		pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber;
		pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK | ipTCP_FLAG_FIN;

		/* And wait for the final ACK. */
		vTCPStateChange( pxSocket, eLAST_ACK );
	}
	else
	{
		/* Our FIN has been ACK'd, the outgoing sequence number is now fixed. */
		pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber + 1u;
		if( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED )
		{
			/* We have sent out a FIN but the peer hasn't replied with a FIN
			yet. Do nothing for the moment. */
			pxTCPHeader->ucTCPFlags = 0u;
		}
		else
		{
			if( pxSocket->u.xTCP.bits.bFinLast == pdFALSE_UNSIGNED )
			{
				/* This is the third of the three-way hand shake: the last
				ACK. */
				pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
			}
			else
			{
				/* The other party started the closure, so we just wait for the
				last ACK. */
				pxTCPHeader->ucTCPFlags = 0u;
			}

			/* And wait for the user to close this socket. */
			vTCPStateChange( pxSocket, eCLOSE_WAIT );
		}
	}

	pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;

	if( pxTCPHeader->ucTCPFlags != 0u )
	{
		xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength );
	}

	pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength ) << 2 );

	if( xTCPWindowLoggingLevel != 0 )
	{
		FreeRTOS_debug_printf( ( "TCP: send FIN+ACK (ack %lu, cur/nxt %lu/%lu) ourSeqNr %lu | Rx %lu\n",
			ulAckNr - pxTCPWindow->tx.ulFirstSequenceNumber,
			pxTCPWindow->tx.ulCurrentSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
			pxTCPWindow->ulNextTxSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
			pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
			pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) );
	}

	return xSendLength;
}
/*-----------------------------------------------------------*/

/*
 * prvCheckRxData(): called from prvTCPHandleState()
 *
 * The first thing that will be done is find the TCP payload data
 * and check the length of this data.
 */
static BaseType_t prvCheckRxData( NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &( pxTCPPacket->xTCPHeader );
int32_t lLength, lTCPHeaderLength, lReceiveLength, lUrgentLength;

	/* Determine the length and the offset of the user-data sent to this
	node.

	The size of the TCP header is given in a multiple of 4-byte words (single
	byte, needs no ntoh() translation).  A shift-right 2: is the same as
	(offset >> 4) * 4. */
	lTCPHeaderLength = ( BaseType_t ) ( ( pxTCPHeader->ucTCPOffset & VALID_BITS_IN_TCP_OFFSET_BYTE ) >> 2 );

	/* Let pucRecvData point to the first byte received. */
	*ppucRecvData = pxNetworkBuffer->pucEthernetBuffer + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + lTCPHeaderLength;

	/* Calculate lReceiveLength - the length of the TCP data received.  This is
	equal to the total packet length minus:
	( LinkLayer length (14) + IP header length (20) + size of TCP header(20 +) ).*/
	lReceiveLength = ( ( int32_t ) pxNetworkBuffer->xDataLength ) - ( int32_t ) ipSIZE_OF_ETH_HEADER;
	lLength =  ( int32_t )FreeRTOS_htons( pxTCPPacket->xIPHeader.usLength );

	if( lReceiveLength > lLength )
	{
		/* More bytes were received than the reported length, often because of
		padding bytes at the end. */
		lReceiveLength = lLength;
	}

	/* Subtract the size of the TCP and IP headers and the actual data size is
	known. */
	if( lReceiveLength > ( lTCPHeaderLength + ( int32_t ) ipSIZE_OF_IPv4_HEADER ) )
	{
		lReceiveLength -= ( lTCPHeaderLength + ( int32_t ) ipSIZE_OF_IPv4_HEADER );
	}
	else
	{
		lReceiveLength = 0;
	}

	/* Urgent Pointer:
	This field communicates the current value of the urgent pointer as a
	positive offset from the sequence number in this segment.  The urgent
	pointer points to the sequence number of the octet following the urgent
	data.  This field is only be interpreted in segments with the URG control
	bit set. */
	if( ( pxTCPHeader->ucTCPFlags & ipTCP_FLAG_URG ) != 0u )
	{
		/* Although we ignore the urgent data, we have to skip it. */
		lUrgentLength = ( int32_t ) FreeRTOS_htons( pxTCPHeader->usUrgent );
		*ppucRecvData += lUrgentLength;
		lReceiveLength -= FreeRTOS_min_int32( lReceiveLength, lUrgentLength );
	}

	return ( BaseType_t ) lReceiveLength;
}
/*-----------------------------------------------------------*/

/*
 * prvStoreRxData(): called from prvTCPHandleState()
 *
 * The second thing is to do is check if the payload data may be accepted
 * If so, they will be added to the reception queue.
 */
static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, uint8_t *pucRecvData,
	NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
uint32_t ulSequenceNumber, ulSpace;
int32_t lOffset, lStored;
BaseType_t xResult = 0;

	ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber );

	if( ( ulReceiveLength > 0u ) && ( pxSocket->u.xTCP.ucTCPState >= eSYN_RECEIVED ) )
	{
		/* See if way may accept the data contents and forward it to the socket
		owner.

		If it can't be "accept"ed it may have to be stored and send a selective
		ack (SACK) option to confirm it.  In that case, xTCPWindowRxStore() will be
		called later to store an out-of-order packet (in case lOffset is
		negative). */
		if ( pxSocket->u.xTCP.rxStream )
		{
			ulSpace = ( uint32_t )uxStreamBufferGetSpace ( pxSocket->u.xTCP.rxStream );
		}
		else
		{
			ulSpace = ( uint32_t )pxSocket->u.xTCP.uxRxStreamSize;
		}

		lOffset = lTCPWindowRxCheck( pxTCPWindow, ulSequenceNumber, ulReceiveLength, ulSpace );

		if( lOffset >= 0 )
		{
			/* New data has arrived and may be made available to the user.  See
			if the head marker in rxStream may be advanced,	only if lOffset == 0.
			In case the low-water mark is reached, bLowWater will be set
			"low-water" here stands for "little space". */
			lStored = lTCPAddRxdata( pxSocket, ( uint32_t ) lOffset, pucRecvData, ulReceiveLength );

			if( lStored != ( int32_t ) ulReceiveLength )
			{
				FreeRTOS_debug_printf( ( "lTCPAddRxdata: stored %ld / %lu bytes??\n", lStored, ulReceiveLength ) );

				/* Received data could not be stored.  The socket's flag
				bMallocError has been set.  The socket now has the status
				eCLOSE_WAIT and a RST packet will be sent back. */
				prvTCPSendReset( pxNetworkBuffer );
				xResult = -1;
			}
		}

		/* After a missing packet has come in, higher packets may be passed to
		the user. */
		#if( ipconfigUSE_TCP_WIN == 1 )
		{
			/* Now lTCPAddRxdata() will move the rxHead pointer forward
			so data becomes available to the user immediately
			In case the low-water mark is reached, bLowWater will be set. */
			if( ( xResult == 0 ) && ( pxTCPWindow->ulUserDataLength > 0 ) )
			{
				lTCPAddRxdata( pxSocket, 0ul, NULL, pxTCPWindow->ulUserDataLength );
				pxTCPWindow->ulUserDataLength = 0;
			}
		}
		#endif /* ipconfigUSE_TCP_WIN */
	}
	else
	{
		pxTCPWindow->ucOptionLength = 0u;
	}

	return xResult;
}
/*-----------------------------------------------------------*/

/* Set the TCP options (if any) for the outgoing packet. */
static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
UBaseType_t uxOptionsLength = pxTCPWindow->ucOptionLength;

	#if(	ipconfigUSE_TCP_WIN == 1 )
		if( uxOptionsLength != 0u )
		{
			/* TCP options must be sent because a packet which is out-of-order
			was received. */
			if( xTCPWindowLoggingLevel >= 0 )
				FreeRTOS_debug_printf( ( "SACK[%d,%d]: optlen %lu sending %lu - %lu\n",
					pxSocket->usLocalPort,
					pxSocket->u.xTCP.usRemotePort,
					uxOptionsLength,
					FreeRTOS_ntohl( pxTCPWindow->ulOptionsData[ 1 ] ) - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber,
					FreeRTOS_ntohl( pxTCPWindow->ulOptionsData[ 2 ] ) - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber ) );
			memcpy( pxTCPHeader->ucOptdata, pxTCPWindow->ulOptionsData, ( size_t ) uxOptionsLength );

			/* The header length divided by 4, goes into the higher nibble,
			effectively a shift-left 2. */
			pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
		}
		else
	#endif	/* ipconfigUSE_TCP_WIN */
	if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.bits.bMssChange != pdFALSE_UNSIGNED ) )
	{
		/* TCP options must be sent because the MSS has changed. */
		pxSocket->u.xTCP.bits.bMssChange = pdFALSE_UNSIGNED;
		if( xTCPWindowLoggingLevel >= 0 )
		{
			FreeRTOS_debug_printf( ( "MSS: sending %d\n", pxSocket->u.xTCP.usCurMSS ) );
		}

		pxTCPHeader->ucOptdata[ 0 ] = TCP_OPT_MSS;
		pxTCPHeader->ucOptdata[ 1 ] = TCP_OPT_MSS_LEN;
		pxTCPHeader->ucOptdata[ 2 ] = ( uint8_t ) ( ( pxSocket->u.xTCP.usCurMSS ) >> 8 );
		pxTCPHeader->ucOptdata[ 3 ] = ( uint8_t ) ( ( pxSocket->u.xTCP.usCurMSS ) & 0xffu );
		uxOptionsLength = 4u;
		pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
	}

	return uxOptionsLength;
}
/*-----------------------------------------------------------*/

/*
 * prvHandleSynReceived(): called from prvTCPHandleState()
 *
 * Called from the states: eSYN_RECEIVED and eCONNECT_SYN
 * If the flags received are correct, the socket will move to eESTABLISHED.
 */
static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
	uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber );
BaseType_t xSendLength = 0;

	/* Either expect a ACK or a SYN+ACK. */
	uint16_t usExpect = ( uint16_t ) ipTCP_FLAG_ACK;
	if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
	{
		usExpect |= ( uint16_t ) ipTCP_FLAG_SYN;
	}

	if( ( ucTCPFlags & 0x17u ) != usExpect )
	{
		/* eSYN_RECEIVED: flags 0010 expected, not 0002. */
		/* eSYN_RECEIVED: flags ACK  expected, not SYN. */
		FreeRTOS_debug_printf( ( "%s: flags %04X expected, not %04X\n",
			pxSocket->u.xTCP.ucTCPState == eSYN_RECEIVED ? "eSYN_RECEIVED" : "eCONNECT_SYN",
			usExpect, ucTCPFlags ) );
		vTCPStateChange( pxSocket, eCLOSE_WAIT );
		pxTCPHeader->ucTCPFlags |= ipTCP_FLAG_RST;
		xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
		pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
	}
	else
	{
		pxTCPWindow->usPeerPortNumber = pxSocket->u.xTCP.usRemotePort;
		pxTCPWindow->usOurPortNumber = pxSocket->usLocalPort;

		if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
		{
			TCPPacket_t *pxLastTCPPacket = ( TCPPacket_t * ) ( pxSocket->u.xTCP.xPacket.u.ucLastPacket );

			/* Clear the SYN flag in lastPacket. */
			pxLastTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_ACK;

			/* This socket was the one connecting actively so now perofmr the
			synchronisation. */
			vTCPWindowInit( &pxSocket->u.xTCP.xTCPWindow,
				ulSequenceNumber, pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber, ( uint32_t ) pxSocket->u.xTCP.usCurMSS );
			pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1u;
			pxTCPWindow->tx.ulCurrentSequenceNumber++; /* because we send a TCP_SYN [ | TCP_ACK ]; */
			pxTCPWindow->ulNextTxSequenceNumber++;
		}
		else if( ulReceiveLength == 0u )
		{
			pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber;
		}

		/* The SYN+ACK has been confirmed, increase the next sequence number by
		1. */
		pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1u;

		#if( ipconfigUSE_TCP_WIN == 1 )
		{
			FreeRTOS_debug_printf( ( "TCP: %s %d => %lxip:%d set ESTAB (scaling %u)\n",
				pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ? "active" : "passive",
				pxSocket->usLocalPort,
				pxSocket->u.xTCP.ulRemoteIP,
				pxSocket->u.xTCP.usRemotePort,
				( unsigned ) pxSocket->u.xTCP.bits.bWinScaling ) );
		}
		#endif /* ipconfigUSE_TCP_WIN */

		if( ( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ) || ( ulReceiveLength != 0u ) )
		{
			pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
			xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
			pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
		}
		#if( ipconfigUSE_TCP_WIN != 0 )
		{
			if( pxSocket->u.xTCP.bits.bWinScaling == pdFALSE_UNSIGNED )
			{
				/* The other party did not send a scaling factor.
				A shifting factor in this side must be canceled. */
				pxSocket->u.xTCP.ucMyWinScaleFactor = 0;
				pxSocket->u.xTCP.ucPeerWinScaleFactor = 0;
			}
		}
		#endif /* ipconfigUSE_TCP_WIN */
		/* This was the third step of connecting: SYN, SYN+ACK, ACK	so now the
		connection is established. */
		vTCPStateChange( pxSocket, eESTABLISHED );
	}

	return xSendLength;
}
/*-----------------------------------------------------------*/

/*
 * prvHandleEstablished(): called from prvTCPHandleState()
 *
 * Called if the status is eESTABLISHED.  Data reception has been handled
 * earlier.  Here the ACK's from peer will be checked, and if a FIN is received,
 * the code will check if it may be accepted, i.e. if all expected data has been
 * completely received.
 */
static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
	uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber ), ulCount;
BaseType_t xSendLength = 0, xMayClose = pdFALSE, bRxComplete, bTxDone;
int32_t lDistance, lSendResult;

	/* Remember the window size the peer is advertising. */
	pxSocket->u.xTCP.ulWindowSize = FreeRTOS_ntohs( pxTCPHeader->usWindow );
	#if( ipconfigUSE_TCP_WIN != 0 )
	{
		pxSocket->u.xTCP.ulWindowSize =
			( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor );
	}
	#endif

	if( ( ucTCPFlags & ( uint8_t ) ipTCP_FLAG_ACK ) != 0u )
	{
		ulCount = ulTCPWindowTxAck( pxTCPWindow, FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr ) );

		/* ulTCPWindowTxAck() returns the number of bytes which have been acked,
		starting at 'tx.ulCurrentSequenceNumber'.  Advance the tail pointer in
		txStream. */
		if( ( pxSocket->u.xTCP.txStream != NULL ) && ( ulCount > 0u ) )
		{
			/* Just advancing the tail index, 'ulCount' bytes have been
			confirmed, and because there is new space in the txStream, the
			user/owner should be woken up. */
			/* _HT_ : only in case the socket's waiting? */
			if( uxStreamBufferGet( pxSocket->u.xTCP.txStream, 0u, NULL, ( size_t ) ulCount, pdFALSE ) != 0u )
			{
				pxSocket->xEventBits |= eSOCKET_SEND;

				#if ipconfigSUPPORT_SELECT_FUNCTION == 1
				{
					if( ( pxSocket->xSelectBits & eSELECT_WRITE ) != 0 )
					{
						pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
					}
				}
				#endif
				/* In case the socket owner has installed an OnSent handler,
				call it now. */
				#if( ipconfigUSE_CALLBACKS == 1 )
				{
					if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleSent ) )
					{
						pxSocket->u.xTCP.pxHandleSent( ( Socket_t )pxSocket, ulCount );
					}
				}
				#endif /* ipconfigUSE_CALLBACKS == 1  */
			}
		}
	}

	/* If this socket has a stream for transmission, add the data to the
	outgoing segment(s). */
	if( pxSocket->u.xTCP.txStream != NULL )
	{
		prvTCPAddTxData( pxSocket );
	}

	pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;

	if( ( pxSocket->u.xTCP.bits.bFinAccepted != pdFALSE_UNSIGNED ) || ( ( ucTCPFlags & ( uint8_t ) ipTCP_FLAG_FIN ) != 0u ) )
	{
		/* Peer is requesting to stop, see if we're really finished. */
		xMayClose = pdTRUE;

		/* Checks are only necessary if we haven't sent a FIN yet. */
		if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
		{
			/* xTCPWindowTxDone returns true when all Tx queues are empty. */
			bRxComplete = xTCPWindowRxEmpty( pxTCPWindow );
			bTxDone	 = xTCPWindowTxDone( pxTCPWindow );

			if( ( bRxComplete == 0 ) || ( bTxDone == 0 ) )
			{
				/* Refusing FIN: Rx incomp 1 optlen 4 tx done 1. */
				FreeRTOS_debug_printf( ( "Refusing FIN[%u,%u]: RxCompl %lu tx done %ld\n",
					pxSocket->usLocalPort,
					pxSocket->u.xTCP.usRemotePort,
					bRxComplete, bTxDone ) );
				xMayClose = pdFALSE;
			}
			else
			{
				lDistance = ( int32_t ) ( ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber );

				if( lDistance > 1 )
				{
					FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %ld (cur %lu high %lu)\n",
						lDistance, pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
						pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) );

					xMayClose = pdFALSE;
				}
			}
		}

		if( xTCPWindowLoggingLevel > 0 )
		{
			FreeRTOS_debug_printf( ( "TCP: FIN received, mayClose = %ld (Rx %lu Len %ld, Tx %lu)\n",
				xMayClose, ulSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber, ulReceiveLength,
				pxTCPWindow->tx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.tx.ulFirstSequenceNumber ) );
		}

		if( xMayClose != pdFALSE )
		{
			pxSocket->u.xTCP.bits.bFinAccepted = pdTRUE_UNSIGNED;
			xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer );
		}
	}

	if( xMayClose == pdFALSE )
	{
		pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;

		if( ulReceiveLength != 0u )
		{
			xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
			/* TCP-offsett equals '( ( length / 4 ) << 4 )', resulting in a shift-left 2 */
			pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );

			if( pxSocket->u.xTCP.bits.bFinSent != pdFALSE_UNSIGNED )
			{
				pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber;
			}
		}

		/* Now get data to be transmitted. */
		/* _HT_ patch: since the MTU has be fixed at 1500 in stead of 1526, TCP
		can not	send-out both TCP options and also a full packet. Sending
		options (SACK) is always more urgent than sending data, which can be
		sent later. */
		if( uxOptionsLength == 0u )
		{
			/* prvTCPPrepareSend might allocate a bigger network buffer, if
			necessary. */
			lSendResult = prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength );
			if( lSendResult > 0 )
			{
				xSendLength = ( BaseType_t ) lSendResult;
			}
		}
	}

	return xSendLength;
}
/*-----------------------------------------------------------*/

/*
 * Called from prvTCPHandleState().  There is data to be sent.  If
 * ipconfigUSE_TCP_WIN is defined, and if only an ACK must be sent, it will be
 * checked if it would better be postponed for efficiency.
 */
static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
	uint32_t ulReceiveLength, BaseType_t xSendLength )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
/* Find out what window size we may advertised. */
int32_t lRxSpace;
#if( ipconfigUSE_TCP_WIN == 1 )
	#if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
		const int32_t lMinLength = 0;
	#else
		int32_t lMinLength;
	#endif
#endif

	/* Set the time-out field, so that we'll be called by the IP-task in case no
	next message will be received. */
	lRxSpace = (int32_t)( pxSocket->u.xTCP.ulHighestRxAllowed - pxTCPWindow->rx.ulCurrentSequenceNumber );
	#if ipconfigUSE_TCP_WIN == 1
	{

		#if( ipconfigTCP_ACK_EARLIER_PACKET != 0 )
		{
			lMinLength = ( ( int32_t ) 2 ) * ( ( int32_t ) pxSocket->u.xTCP.usCurMSS );
		}
		#endif /* ipconfigTCP_ACK_EARLIER_PACKET */

		/* In case we're receiving data continuously, we might postpone sending
		an ACK to gain performance. */
		if( ( ulReceiveLength > 0 ) &&							/* Data was sent to this socket. */
			( lRxSpace >= lMinLength ) &&						/* There is Rx space for more data. */
			( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) &&	/* Not in a closure phase. */
			( xSendLength == ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) ) && /* No Tx data or options to be sent. */
			( pxSocket->u.xTCP.ucTCPState == eESTABLISHED ) &&	/* Connection established. */
			( pxTCPHeader->ucTCPFlags == ipTCP_FLAG_ACK ) )		/* There are no other flags than an ACK. */
		{
			if( pxSocket->u.xTCP.pxAckMessage != *ppxNetworkBuffer )
			{
				/* There was still a delayed in queue, delete it. */
				if( pxSocket->u.xTCP.pxAckMessage != 0 )
				{
					vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
				}

				pxSocket->u.xTCP.pxAckMessage = *ppxNetworkBuffer;
			}
			if( ( ulReceiveLength < ( uint32_t ) pxSocket->u.xTCP.usCurMSS ) ||	/* Received a small message. */
				( lRxSpace < ( int32_t ) ( 2U * pxSocket->u.xTCP.usCurMSS ) ) )	/* There are less than 2 x MSS space in the Rx buffer. */
			{
				pxSocket->u.xTCP.usTimeout = ( uint16_t ) pdMS_TO_MIN_TICKS( DELAYED_ACK_SHORT_DELAY_MS );
			}
			else
			{
				/* Normally a delayed ACK should wait 200 ms for a next incoming
				packet.  Only wait 20 ms here to gain performance.  A slow ACK
				for full-size message. */
				pxSocket->u.xTCP.usTimeout = ( uint16_t ) pdMS_TO_MIN_TICKS( DELAYED_ACK_LONGER_DELAY_MS );
			}

			if( ( xTCPWindowLoggingLevel > 1 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
			{
				FreeRTOS_debug_printf( ( "Send[%u->%u] del ACK %lu SEQ %lu (len %lu) tmout %u d %lu\n",
					pxSocket->usLocalPort,
					pxSocket->u.xTCP.usRemotePort,
					pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
					pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
					xSendLength,
					pxSocket->u.xTCP.usTimeout, lRxSpace ) );
			}

			*ppxNetworkBuffer = NULL;
			xSendLength = 0;
		}
		else if( pxSocket->u.xTCP.pxAckMessage != NULL )
		{
			/* As an ACK is not being delayed, remove any earlier delayed ACK
			message. */
			if( pxSocket->u.xTCP.pxAckMessage != *ppxNetworkBuffer )
			{
				vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
			}

			pxSocket->u.xTCP.pxAckMessage = NULL;
		}
	}
	#else
	{
		/* Remove compiler warnings. */
		( void ) ulReceiveLength;
		( void ) pxTCPHeader;
		( void ) lRxSpace;
	}
	#endif /* ipconfigUSE_TCP_WIN */

	if( xSendLength != 0 )
	{
		if( ( xTCPWindowLoggingLevel > 1 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
		{
			FreeRTOS_debug_printf( ( "Send[%u->%u] imm ACK %lu SEQ %lu (len %lu)\n",
				pxSocket->usLocalPort,
				pxSocket->u.xTCP.usRemotePort,
				pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
				pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
				xSendLength ) );
		}

		/* Set the parameter 'xReleaseAfterSend' to the value of
		ipconfigZERO_COPY_TX_DRIVER. */
		prvTCPReturnPacket( pxSocket, *ppxNetworkBuffer, ( uint32_t ) xSendLength, ipconfigZERO_COPY_TX_DRIVER );
		#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
		{
			/* The driver has taken ownership of the Network Buffer. */
			*ppxNetworkBuffer = NULL;
		}
		#endif
	}

	return xSendLength;
}
/*-----------------------------------------------------------*/

/*
 * prvTCPHandleState()
 * is the most important function of this TCP stack
 * We've tried to keep it (relatively short) by putting a lot of code in
 * the static functions above:
 *
 *		prvCheckRxData()
 *		prvStoreRxData()
 *		prvSetOptions()
 *		prvHandleSynReceived()
 *		prvHandleEstablished()
 *		prvSendData()
 *
 * As these functions are declared static, and they're called from one location
 * only, most compilers will inline them, thus avoiding a call and return.
 */
static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
TCPHeader_t *pxTCPHeader = &( pxTCPPacket->xTCPHeader );
BaseType_t xSendLength = 0;
uint32_t ulReceiveLength;	/* Number of bytes contained in the TCP message. */
uint8_t *pucRecvData;
uint32_t ulSequenceNumber = FreeRTOS_ntohl (pxTCPHeader->ulSequenceNumber);

	/* uxOptionsLength: the size of the options to be sent (always a multiple of
	4 bytes)
	1. in the SYN phase, we shall communicate the MSS
	2. in case of a SACK, Selective ACK, ack a segment which comes in
	out-of-order. */
UBaseType_t uxOptionsLength = 0u;
uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );

	/* First get the length and the position of the received data, if any.
	pucRecvData will point to the first byte of the TCP payload. */
	ulReceiveLength = ( uint32_t ) prvCheckRxData( *ppxNetworkBuffer, &pucRecvData );

	if( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED )
	{
		if ( pxTCPWindow->rx.ulCurrentSequenceNumber == ulSequenceNumber + 1u )
		{
			/* This is most probably a keep-alive message from peer.  Setting
			'bWinChange' doesn't cause a window-size-change, the flag is used
			here to force sending an immediate ACK. */
			pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
		}
	}

	/* Keep track of the highest sequence number that might be expected within
	this connection. */
	if( ( ( int32_t ) ( ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulHighestSequenceNumber ) ) > 0 )
	{
		pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + ulReceiveLength;
	}

	/* Storing data may result in a fatal error if malloc() fails. */
	if( prvStoreRxData( pxSocket, pucRecvData, *ppxNetworkBuffer, ulReceiveLength ) < 0 )
	{
		xSendLength = -1;
	}
	else
	{
		uxOptionsLength = prvSetOptions( pxSocket, *ppxNetworkBuffer );

		if( ( pxSocket->u.xTCP.ucTCPState == eSYN_RECEIVED ) && ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) )
		{
			FreeRTOS_debug_printf( ( "eSYN_RECEIVED: ACK expected, not SYN: peer missed our SYN+ACK\n" ) );

			/* In eSYN_RECEIVED a simple ACK is expected, but apparently the
			'SYN+ACK' didn't arrive.  Step back to the previous state in which
			a first incoming SYN is handled.  The SYN was counted already so
			decrease it first. */
			vTCPStateChange( pxSocket, eSYN_FIRST );
		}

		if( ( ( ucTCPFlags & ipTCP_FLAG_FIN ) != 0u ) && ( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED ) )
		{
			/* It's the first time a FIN has been received, remember its
			sequence number. */
			pxTCPWindow->rx.ulFINSequenceNumber = ulSequenceNumber + ulReceiveLength;
			pxSocket->u.xTCP.bits.bFinRecv = pdTRUE_UNSIGNED;

			/* Was peer the first one to send a FIN? */
			if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
			{
				/* If so, don't send the-last-ACK. */
				pxSocket->u.xTCP.bits.bFinLast = pdTRUE_UNSIGNED;
			}
		}

		switch (pxSocket->u.xTCP.ucTCPState)
		{
		case eCLOSED:		/* (server + client) no connection state at all. */
			/* Nothing to do for a closed socket, except waiting for the
			owner. */
			break;

		case eTCP_LISTEN:	/* (server) waiting for a connection request from
							any remote TCP and port. */
			/* The listen state was handled in xProcessReceivedTCPPacket().
			Should not come here. */
			break;

		case eSYN_FIRST:	/* (server) Just received a SYN request for a server
							socket. */
			{
				/* A new socket has been created, reply with a SYN+ACK.
				Acknowledge with seq+1 because the SYN is seen as pseudo data
				with len = 1. */
				uxOptionsLength = prvSetSynAckOptions( pxSocket, pxTCPPacket );
				pxTCPHeader->ucTCPFlags = ipTCP_FLAG_SYN | ipTCP_FLAG_ACK;

				xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );

				/* Set the TCP offset field:  ipSIZE_OF_TCP_HEADER equals 20 and
				uxOptionsLength is a multiple of 4.  The complete expression is:
				ucTCPOffset = ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) / 4 ) << 4 */
				pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
				vTCPStateChange( pxSocket, eSYN_RECEIVED );

				pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1u;
				pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->ulNextTxSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1u; /* because we send a TCP_SYN. */
			}
			break;

		case eCONNECT_SYN:	/* (client) also called SYN_SENT: we've just send a
							SYN, expect	a SYN+ACK and send a ACK now. */
			/* Fall through */
		case eSYN_RECEIVED:	/* (server) we've had a SYN, replied with SYN+SCK
							expect a ACK and do nothing. */
			xSendLength = prvHandleSynReceived( pxSocket, ppxNetworkBuffer, ulReceiveLength, uxOptionsLength );
			break;

		case eESTABLISHED:	/* (server + client) an open connection, data
							received can be	delivered to the user. The normal
							state for the data transfer phase of the connection
							The closing states are also handled here with the
							use of some flags. */
			xSendLength = prvHandleEstablished( pxSocket, ppxNetworkBuffer, ulReceiveLength, uxOptionsLength );
			break;

		case eLAST_ACK:		/* (server + client) waiting for an acknowledgement
							of the connection termination request previously
							sent to the remote TCP (which includes an
							acknowledgement of its connection termination
							request). */
			/* Fall through */
		case eFIN_WAIT_1:	/* (server + client) waiting for a connection termination request from the remote TCP,
							 * or an acknowledgement of the connection termination request previously sent. */
			/* Fall through */
		case eFIN_WAIT_2:	/* (server + client) waiting for a connection termination request from the remote TCP. */
			xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer );
			break;

		case eCLOSE_WAIT:	/* (server + client) waiting for a connection
							termination request from the local user.  Nothing to
							do, connection is closed, wait for owner to close
							this socket. */
			break;

		case eCLOSING:		/* (server + client) waiting for a connection
							termination request acknowledgement from the remote
							TCP. */
			break;

		case eTIME_WAIT:	/* (either server or client) waiting for enough time
							to pass to be sure the remote TCP received the
							acknowledgement of its connection termination
							request. [According to RFC 793 a connection can stay
							in TIME-WAIT for a maximum of four minutes known as
							a MSL (maximum segment lifetime).]  These states are
							implemented implicitly by settings flags like
							'bFinSent', 'bFinRecv', and 'bFinAcked'. */
			break;
		default:
			break;
		}
	}

	if( xSendLength > 0 )
	{
		xSendLength = prvSendData( pxSocket, ppxNetworkBuffer, ulReceiveLength, xSendLength );
	}

	return xSendLength;
}
/*-----------------------------------------------------------*/

static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
                                                 uint8_t ucTCPFlags )
{
#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
    {
        TCPPacket_t *pxTCPPacket = ( TCPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
        const BaseType_t xSendLength = ( BaseType_t )
            ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */

        pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
        pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER + 0u ) << 2;

        prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
    }
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */

    /* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
    ( void )pxNetworkBuffer;
    ( void )ucTCPFlags;

    /* The packet was not consumed. */
    return pdFAIL;
}
/*-----------------------------------------------------------*/

static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
    return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
}
/*-----------------------------------------------------------*/

static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
    return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
                                          ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
}
/*-----------------------------------------------------------*/

static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket )
{
uint32_t ulMSS = ipconfigTCP_MSS;

	if( ( ( FreeRTOS_ntohl( pxSocket->u.xTCP.ulRemoteIP ) ^ *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) != 0ul )
	{
		/* Data for this peer will pass through a router, and maybe through
		the internet.  Limit the MSS to 1400 bytes or less. */
		ulMSS = FreeRTOS_min_uint32( ( uint32_t ) REDUCED_MSS_THROUGH_INTERNET, ulMSS );
	}

	FreeRTOS_debug_printf( ( "prvSocketSetMSS: %lu bytes for %lxip:%u\n", ulMSS, pxSocket->u.xTCP.ulRemoteIP, pxSocket->u.xTCP.usRemotePort ) );

	pxSocket->u.xTCP.usInitMSS = pxSocket->u.xTCP.usCurMSS = ( uint16_t ) ulMSS;
}
/*-----------------------------------------------------------*/

/*
 *	FreeRTOS_TCP_IP has only 2 public functions, this is the second one:
 *	xProcessReceivedTCPPacket()
 *		prvTCPHandleState()
 *			prvTCPPrepareSend()
 *				prvTCPReturnPacket()
 *				xNetworkInterfaceOutput()	// Sends data to the NIC
 *		prvTCPSendRepeated()
 *			prvTCPReturnPacket()		// Prepare for returning
 *			xNetworkInterfaceOutput()	// Sends data to the NIC
*/
BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
FreeRTOS_Socket_t *pxSocket;
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
uint16_t ucTCPFlags;
uint32_t ulLocalIP;
uint16_t xLocalPort;
uint32_t ulRemoteIP;
uint16_t xRemotePort;
uint32_t ulSequenceNumber;
uint32_t ulAckNumber;
BaseType_t xResult = pdPASS;
configASSERT(pxNetworkBuffer);
configASSERT(pxNetworkBuffer->pucEthernetBuffer);

	/* Check for a minimum packet size. */
	if( pxNetworkBuffer->xDataLength >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
	{
		ucTCPFlags = pxTCPPacket->xTCPHeader.ucTCPFlags;
		ulLocalIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulDestinationIPAddress );
		xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
		ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
		xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
        ulSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
        ulAckNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr );

		/* Find the destination socket, and if not found: return a socket listing to
		the destination PORT. */
		pxSocket = ( FreeRTOS_Socket_t * )pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort );
	}
	else
	{
		return pdFAIL;
	}

	if( ( pxSocket == NULL ) || ( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE ) )
	{
		/* A TCP messages is received but either there is no socket with the
		given port number or the there is a socket, but it is in one of these
		non-active states:  eCLOSED, eCLOSE_WAIT, eFIN_WAIT_2, eCLOSING, or
		eTIME_WAIT. */

		FreeRTOS_debug_printf( ( "TCP: No active socket on port %d (%lxip:%d)\n", xLocalPort, ulRemoteIP, xRemotePort ) );

		/* Send a RST to all packets that can not be handled.  As a result
		the other party will get a ECONN error.  There are two exceptions:
		1) A packet that already has the RST flag set.
		2) A packet that only has the ACK flag set.
		A packet with only the ACK flag set might be the last ACK in
	 	a three-way hand-shake that closes a connection. */
		if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) != ipTCP_FLAG_ACK ) &&
			( ( ucTCPFlags & ipTCP_FLAG_RST ) == 0u ) )
		{
			prvTCPSendReset( pxNetworkBuffer );
		}

		/* The packet can't be handled. */
		xResult = pdFAIL;
	}
	else
	{
		pxSocket->u.xTCP.ucRepCount = 0u;

		if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
		{
			/* The matching socket is in a listening state.  Test if the peer
			has set the SYN flag. */
			if( ( ucTCPFlags & ipTCP_FLAG_CTRL ) != ipTCP_FLAG_SYN )
			{
				/* What happens: maybe after a reboot, a client doesn't know the
				connection had gone.  Send a RST in order to get a new connect
				request. */
				#if( ipconfigHAS_DEBUG_PRINTF == 1 )
				{
				FreeRTOS_debug_printf( ( "TCP: Server can't handle flags: %s from %lxip:%u to port %u\n",
					prvTCPFlagMeaning( ( UBaseType_t ) ucTCPFlags ), ulRemoteIP, xRemotePort, xLocalPort ) );
				}
				#endif /* ipconfigHAS_DEBUG_PRINTF */

				if( ( ucTCPFlags & ipTCP_FLAG_RST ) == 0u )
				{
					prvTCPSendReset( pxNetworkBuffer );
				}
				xResult = pdFAIL;
			}
			else
			{
				/* prvHandleListen() will either return a newly created socket
				(if bReuseSocket is false), otherwise it returns the current
				socket which will later get connected. */
				pxSocket = prvHandleListen( pxSocket, pxNetworkBuffer );

				if( pxSocket == NULL )
				{
					xResult = pdFAIL;
				}
			}
		}	/* if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN ). */
		else
		{
			/* This is not a socket in listening mode. Check for the RST
			flag. */
			if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
			{
                FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );

                /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */
                if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
                {
                    /* Per the above RFC, "In the SYN-SENT state ... the RST is
                    acceptable if the ACK field acknowledges the SYN." */
                    if( ulAckNumber == pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1 )
                    {
                        vTCPStateChange( pxSocket, eCLOSED );
                    }
                }
                else
                {
                    /* Check whether the packet matches the next expected sequence number. */
                    if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber )
                    {
                        vTCPStateChange( pxSocket, eCLOSED );
                    }
                    /* Otherwise, check whether the packet is within the receive window. */
                    else if( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber &&
                             ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber +
                                                  pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) )
                    {
                        /* Send a challenge ACK. */
                        prvTCPSendChallengeAck( pxNetworkBuffer );
                    }
                }

                /* Otherwise, do nothing. In any case, the packet cannot be handled. */
				xResult = pdFAIL;
			}
			else if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) )
			{
				/* SYN flag while this socket is already connected. */
				FreeRTOS_debug_printf( ( "TCP: SYN unexpected from %lxip:%u\n", ulRemoteIP, xRemotePort ) );

				/* The packet cannot be handled. */
				xResult = pdFAIL;
			}
			else
			{
				/* Update the copy of the TCP header only (skipping eth and IP
				headers).  It might be used later on, whenever data must be sent
				to the peer. */
				const BaseType_t lOffset = ( BaseType_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER );
				memcpy( pxSocket->u.xTCP.xPacket.u.ucLastPacket + lOffset, pxNetworkBuffer->pucEthernetBuffer + lOffset, ipSIZE_OF_TCP_HEADER );
			}
		}
	}

	if( xResult != pdFAIL )
	{
		/* Touch the alive timers because we received a message	for this
		socket. */
		prvTCPTouchSocket( pxSocket );

		/* Parse the TCP option(s), if present. */
		/* _HT_ : if we're in the SYN phase, and peer does not send a MSS option,
		then we MUST assume an MSS size of 536 bytes for backward compatibility. */

		/* When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
		the number 5 (words) in the higher niblle of the TCP-offset byte. */
		if( ( pxTCPPacket->xTCPHeader.ucTCPOffset & TCP_OFFSET_LENGTH_BITS ) > TCP_OFFSET_STANDARD_LENGTH )
		{
			prvCheckOptions( pxSocket, pxNetworkBuffer );
		}


		#if( ipconfigUSE_TCP_WIN == 1 )
		{
			pxSocket->u.xTCP.ulWindowSize = FreeRTOS_ntohs( pxTCPPacket->xTCPHeader.usWindow );
			pxSocket->u.xTCP.ulWindowSize =
				( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor );
		}
		#endif

		/* In prvTCPHandleState() the incoming messages will be handled
		depending on the current state of the connection. */
		if( prvTCPHandleState( pxSocket, &pxNetworkBuffer ) > 0 )
		{
			/* prvTCPHandleState() has sent a message, see if there are more to
			be transmitted. */
			#if( ipconfigUSE_TCP_WIN == 1 )
			{
				prvTCPSendRepeated( pxSocket, &pxNetworkBuffer );
			}
			#endif /* ipconfigUSE_TCP_WIN */
		}

		if( pxNetworkBuffer != NULL )
		{
			/* We must check if the buffer is unequal to NULL, because the
			socket might keep a reference to it in case a delayed ACK must be
			sent. */
			vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
			pxNetworkBuffer = NULL;
		}

		/* And finally, calculate when this socket wants to be woken up. */
		prvTCPNextTimeout ( pxSocket );
		/* Return pdPASS to tell that the network buffer is 'consumed'. */
		xResult = pdPASS;
	}

	/* pdPASS being returned means the buffer has been consumed. */
	return xResult;
}
/*-----------------------------------------------------------*/

static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
{
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
FreeRTOS_Socket_t *pxReturn = NULL;
uint32_t ulInitialSequenceNumber;

	/* Assume that a new Initial Sequence Number will be required. Request
	it now in order to fail out if necessary. */
	ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber( *ipLOCAL_IP_ADDRESS_POINTER,
																  pxSocket->usLocalPort,
																  pxTCPPacket->xIPHeader.ulSourceIPAddress,
																  pxTCPPacket->xTCPHeader.usSourcePort );

	/* A pure SYN (without ACK) has come in, create a new socket to answer
	it. */
	if( 0 != ulInitialSequenceNumber )
	{
		if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
		{
			/* The flag bReuseSocket indicates that the same instance of the
			listening socket should be used for the connection. */
			pxReturn = pxSocket;
			pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
			pxSocket->u.xTCP.pxPeerSocket = pxSocket;
		}
		else
		{
			/* The socket does not have the bReuseSocket flag set meaning create a
			new socket when a connection comes in. */
			pxReturn = NULL;

			if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog )
			{
				FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n",
					pxSocket->usLocalPort,
					pxSocket->u.xTCP.usChildCount,
					pxSocket->u.xTCP.usBacklog,
					pxSocket->u.xTCP.usChildCount == 1 ? "" : "ren" ) );
				prvTCPSendReset( pxNetworkBuffer );
			}
			else
			{
				FreeRTOS_Socket_t *pxNewSocket = ( FreeRTOS_Socket_t * )
					FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );

				if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) )
				{
					FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) );
					prvTCPSendReset( pxNetworkBuffer );
				}
				else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE )
				{
					/* The socket will be connected immediately, no time for the
					owner to setsockopt's, therefore copy properties of the server
					socket to the new socket.  Only the binding might fail (due to
					lack of resources). */
					pxReturn = pxNewSocket;
				}
			}
		}
	}

	if( ( 0 != ulInitialSequenceNumber ) && ( pxReturn != NULL ) )
	{
		pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
		pxReturn->u.xTCP.ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
		pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;

		/* Here is the SYN action. */
		pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
		prvSocketSetMSS( pxReturn );

		prvTCPCreateWindow( pxReturn );

		vTCPStateChange( pxReturn, eSYN_FIRST );

		/* Make a copy of the header up to the TCP header.  It is needed later
		on, whenever data must be sent to the peer. */
		memcpy( pxReturn->u.xTCP.xPacket.u.ucLastPacket, pxNetworkBuffer->pucEthernetBuffer, sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) );
	}
	return pxReturn;
}
/*-----------------------------------------------------------*/

/*
 * Duplicates a socket after a listening socket receives a connection.
 */
static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t *pxNewSocket, FreeRTOS_Socket_t *pxSocket )
{
struct freertos_sockaddr xAddress;

	pxNewSocket->xReceiveBlockTime = pxSocket->xReceiveBlockTime;
	pxNewSocket->xSendBlockTime = pxSocket->xSendBlockTime;
	pxNewSocket->ucSocketOptions = pxSocket->ucSocketOptions;
	pxNewSocket->u.xTCP.uxRxStreamSize = pxSocket->u.xTCP.uxRxStreamSize;
	pxNewSocket->u.xTCP.uxTxStreamSize = pxSocket->u.xTCP.uxTxStreamSize;
	pxNewSocket->u.xTCP.uxLittleSpace = pxSocket->u.xTCP.uxLittleSpace;
	pxNewSocket->u.xTCP.uxEnoughSpace = pxSocket->u.xTCP.uxEnoughSpace;
	pxNewSocket->u.xTCP.uxRxWinSize  = pxSocket->u.xTCP.uxRxWinSize;
	pxNewSocket->u.xTCP.uxTxWinSize  = pxSocket->u.xTCP.uxTxWinSize;

	#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
	{
		pxNewSocket->pxUserSemaphore = pxSocket->pxUserSemaphore;
	}
	#endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */

	#if( ipconfigUSE_CALLBACKS == 1 )
	{
		/* In case call-backs are used, copy them from parent to child. */
		pxNewSocket->u.xTCP.pxHandleConnected = pxSocket->u.xTCP.pxHandleConnected;
		pxNewSocket->u.xTCP.pxHandleReceive = pxSocket->u.xTCP.pxHandleReceive;
		pxNewSocket->u.xTCP.pxHandleSent = pxSocket->u.xTCP.pxHandleSent;
	}
	#endif /* ipconfigUSE_CALLBACKS */

	#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
	{
		/* Child socket of listening sockets will inherit the Socket Set
		Otherwise the owner has no chance of including it into the set. */
		if( pxSocket->pxSocketSet )
		{
			pxNewSocket->pxSocketSet = pxSocket->pxSocketSet;
			pxNewSocket->xSelectBits = pxSocket->xSelectBits | eSELECT_READ | eSELECT_EXCEPT;
		}
	}
	#endif /* ipconfigSUPPORT_SELECT_FUNCTION */

	/* And bind it to the same local port as its parent. */
	xAddress.sin_addr = *ipLOCAL_IP_ADDRESS_POINTER;
	xAddress.sin_port = FreeRTOS_htons( pxSocket->usLocalPort );

	#if( ipconfigTCP_HANG_PROTECTION == 1 )
	{
		/* Only when there is anti-hanging protection, a socket may become an
		orphan temporarily.  Once this socket is really connected, the owner of
		the server socket will be notified. */

		/* When bPassQueued is true, the socket is an orphan until it gets
		connected. */
		pxNewSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
		pxNewSocket->u.xTCP.pxPeerSocket = pxSocket;
	}
	#else
	{
		/* A reference to the new socket may be stored and the socket is marked
		as 'passable'. */

		/* When bPassAccept is pdTRUE_UNSIGNED this socket may be returned in a call to
		accept(). */
		pxNewSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
		if(pxSocket->u.xTCP.pxPeerSocket == NULL )
		{
			pxSocket->u.xTCP.pxPeerSocket = pxNewSocket;
		}
	}
	#endif

	pxSocket->u.xTCP.usChildCount++;

	FreeRTOS_debug_printf( ( "Gain: Socket %u now has %u / %u child%s\n",
		pxSocket->usLocalPort,
		pxSocket->u.xTCP.usChildCount,
		pxSocket->u.xTCP.usBacklog,
		pxSocket->u.xTCP.usChildCount == 1u ? "" : "ren" ) );

	/* Now bind the child socket to the same port as the listening socket. */
	if( vSocketBind ( pxNewSocket, &xAddress, sizeof( xAddress ), pdTRUE ) != 0 )
	{
		FreeRTOS_debug_printf( ( "TCP: Listen: new socket bind error\n" ) );
		vSocketClose( pxNewSocket );
		return pdFALSE;
	}

	return pdTRUE;
}
/*-----------------------------------------------------------*/

#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )

	const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState )
	{
		if( ulState >= ( UBaseType_t ) ARRAY_SIZE( pcStateNames ) )
		{
			ulState = ( UBaseType_t ) ARRAY_SIZE( pcStateNames ) - 1u;
		}
		return pcStateNames[ ulState ];
	}

#endif /* ( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) ) */
/*-----------------------------------------------------------*/

/*
 * In the API accept(), the user asks is there is a new client?  As API's can
 * not walk through the xBoundTCPSocketsList the IP-task will do this.
 */
BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket )
{
TickType_t xLocalPort = FreeRTOS_htons( pxSocket->usLocalPort );
ListItem_t *pxIterator;
FreeRTOS_Socket_t *pxFound;
BaseType_t xResult = pdFALSE;

	/* Here xBoundTCPSocketsList can be accessed safely IP-task is the only one
	who has access. */
	for( pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
		pxIterator != ( ListItem_t * ) listGET_END_MARKER( &xBoundTCPSocketsList );
		pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
	{
		if( listGET_LIST_ITEM_VALUE( pxIterator ) == xLocalPort )
		{
			pxFound = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
			if( ( pxFound->ucProtocol == FREERTOS_IPPROTO_TCP ) && ( pxFound->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
			{
				pxSocket->u.xTCP.pxPeerSocket = pxFound;
				FreeRTOS_debug_printf( ( "xTCPCheckNewClient[0]: client on port %u\n", pxSocket->usLocalPort ) );
				xResult = pdTRUE;
				break;
			}
		}
	}
	return xResult;
}
/*-----------------------------------------------------------*/

#endif /* ipconfigUSE_TCP == 1 */

/* Provide access to private members for testing. */
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
	#include "iot_freertos_tcp_test_access_tcp_define.h"
#endif

/* Provide access to private members for verification. */
#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
	#include "aws_freertos_tcp_verification_access_tcp_define.h"
#endif

