/*
 * FreeRTOS+UDP V1.0.3 (C) 2014 Real Time Engineers ltd.
 * All rights reserved
 *
 * This file is part of the FreeRTOS+UDP distribution.  The FreeRTOS+UDP license
 * terms are different to the FreeRTOS license terms.
 *
 * FreeRTOS+UDP uses a dual license model that allows the software to be used
 * under a standard GPL open source license, or a commercial license.  The
 * standard GPL license (unlike the modified GPL license under which FreeRTOS
 * itself is distributed) requires that all software statically linked with
 * FreeRTOS+UDP is also distributed under the same GPL V2 license terms.
 * Details of both license options follow:
 *
 * - Open source licensing -
 * FreeRTOS+UDP is a free download and may be used, modified, evaluated and
 * distributed without charge provided the user adheres to version two of the
 * GNU General Public License (GPL) and does not remove the copyright notice or
 * this text.  The GPL V2 text is available on the gnu.org web site, and on the
 * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.
 *
 * - Commercial licensing -
 * Businesses and individuals that for commercial or other reasons cannot comply
 * with the terms of the GPL V2 license must obtain a commercial license before
 * incorporating FreeRTOS+UDP into proprietary software for distribution in any
 * form.  Commercial licenses can be purchased from http://shop.freertos.org/udp
 * and do not require any source files to be changed.
 *
 * FreeRTOS+UDP is distributed in the hope that it will be useful.  You cannot
 * use FreeRTOS+UDP unless you agree that you use the software 'as is'.
 * FreeRTOS+UDP is provided WITHOUT ANY WARRANTY; without even the implied
 * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they
 * implied, expressed, or statutory.
 *
 * 1 tab == 4 spaces!
 *
 * http://www.FreeRTOS.org
 * http://www.FreeRTOS.org/udp
 *
 */

/* Standard includes. */
#include <stdint.h>

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/* FreeRTOS+UDP includes. */
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_Sockets.h"
#include "NetworkBufferManagement.h"

/* Sanity check the UDP payload length setting is compatible with the
fragmentation setting. */
#if ipconfigCAN_FRAGMENT_OUTGOING_PACKETS == 1
	#if ( ( ipMAX_UDP_PAYLOAD_LENGTH % 8 ) != 0 )
		#error ( ipconfigNETWORK_MTU - 28 ) must be divisible by 8 when fragmentation is used
	#endif /* ipMAX_UDP_PAYLOAD_LENGTH */
#endif /* ipconfigFRAGMENT_OUTGOING_PACKETS */

/* The ItemValue of the sockets xBoundSocketListItem member holds the socket's
port number. */
#define socketSET_SOCKET_ADDRESS( pxSocket, usPort ) listSET_LIST_ITEM_VALUE( ( &( ( pxSocket )->xBoundSocketListItem ) ), ( usPort ) )
#define socketGET_SOCKET_ADDRESS( pxSocket ) listGET_LIST_ITEM_VALUE( ( &( ( pxSocket )->xBoundSocketListItem ) ) )

/* xWaitingPacketSemaphore is not created until the socket is bound, so can be
tested to see if bind() has been called. */
#define socketSOCKET_IS_BOUND( pxSocket ) ( ( portBASE_TYPE ) pxSocket->xWaitingPacketSemaphore )

/* If FreeRTOS_sendto() is called on a socket that is not bound to a port
number then, depending on the FreeRTOSIPConfig.h settings, it might be that a
port number is automatically generated for the socket.  Automatically generated
port numbers will be between socketAUTO_PORT_ALLOCATION_START_NUMBER and
0xffff. */
#define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0xc000 )

/* When the automatically generated port numbers overflow, the next value used
is not set back to socketAUTO_PORT_ALLOCATION_START_NUMBER because it is likely
that the first few automatically generated ports will still be in use.  Instead
it is reset back to the value defined by this constant. */
#define socketAUTO_PORT_ALLOCATION_RESET_NUMBER ( ( uint16_t ) 0xc100 )

/* The number of octets that make up an IP address. */
#define socketMAX_IP_ADDRESS_OCTETS		4
/*-----------------------------------------------------------*/

/*
 * Allocate the next port number from the private allocation range.
 */
static uint16_t prvGetPrivatePortNumber( void );

/*
 * Return the list itme from within pxList that has an item value of
 * xWantedItemValue.  If there is no such list item return NULL.
 */
xListItem * pxListFindListItemWithValue( xList *pxList, portTickType xWantedItemValue );

/*-----------------------------------------------------------*/

typedef struct XSOCKET
{
	xSemaphoreHandle xWaitingPacketSemaphore;
	xList xWaitingPacketsList;
	xListItem xBoundSocketListItem; /* Used to reference the socket from a bound sockets list. */
	portTickType xReceiveBlockTime;
	portTickType xSendBlockTime;
	uint8_t ucSocketOptions;
	#if ipconfigSUPPORT_SELECT_FUNCTION == 1
		xQueueHandle xSelectQueue;
	#endif
} xFreeRTOS_Socket_t;


/* The list that contains mappings between sockets and port numbers.  Accesses
to this list must be protected by critical sections of one kind or another. */
static xList xBoundSocketsList;

/*-----------------------------------------------------------*/

xSocket_t FreeRTOS_socket( portBASE_TYPE xDomain, portBASE_TYPE xType, portBASE_TYPE xProtocol )
{
xFreeRTOS_Socket_t *pxSocket;

	/* Only UDP on Ethernet is currently supported. */
	configASSERT( xDomain == FREERTOS_AF_INET );
	configASSERT( xType == FREERTOS_SOCK_DGRAM );
	configASSERT( xProtocol == FREERTOS_IPPROTO_UDP );
	configASSERT( listLIST_IS_INITIALISED( &xBoundSocketsList ) );

	/* Allocate the structure that will hold the socket information. */
	pxSocket = ( xFreeRTOS_Socket_t * ) pvPortMalloc( sizeof( xFreeRTOS_Socket_t ) );

	if( pxSocket == NULL )
	{
		pxSocket = ( xFreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
		iptraceFAILED_TO_CREATE_SOCKET();
	}
	else
	{
		/* Initialise the socket's members.  The semaphore will be created if
		the socket is bound to an address, for now the pointer to the semaphore
		is just set to NULL to show it has not been created. */
		pxSocket->xWaitingPacketSemaphore = NULL;
		vListInitialise( &( pxSocket->xWaitingPacketsList ) );
		vListInitialiseItem( &( pxSocket->xBoundSocketListItem ) );
		listSET_LIST_ITEM_OWNER( &( pxSocket->xBoundSocketListItem ), ( void * ) pxSocket );
		pxSocket->xSendBlockTime = ( portTickType ) 0;
		pxSocket->xReceiveBlockTime = portMAX_DELAY;
		pxSocket->ucSocketOptions = FREERTOS_SO_UDPCKSUM_OUT;
		#if ipconfigSUPPORT_SELECT_FUNCTION == 1
			pxSocket->xSelectQueue = NULL;
		#endif
	}

	/* Remove compiler warnings in the case the configASSERT() is not defined. */
	( void ) xDomain;
	( void ) xType;
	( void ) xProtocol;

	return ( xSocket_t ) pxSocket;
}
/*-----------------------------------------------------------*/

#if ipconfigSUPPORT_SELECT_FUNCTION == 1

	xSocketSet_t FreeRTOS_CreateSocketSet( unsigned portBASE_TYPE uxEventQueueLength )
	{
	xQueueHandle xSelectQueue;

		/* Create the queue into which the address of sockets that are
		available to read are posted. */
		xSelectQueue = xQueueCreate( uxEventQueueLength, sizeof( xSocket_t ) );

		return ( xSocketSet_t ) xSelectQueue;
	}

#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
/*-----------------------------------------------------------*/

#if ipconfigSUPPORT_SELECT_FUNCTION == 1

	portBASE_TYPE FreeRTOS_FD_SET( xSocket_t xSocket, xSocketSet_t xSocketSet )
	{
	xFreeRTOS_Socket_t *pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;
	portBASE_TYPE xReturn = pdFALSE;
	unsigned portBASE_TYPE uxMessagesWaiting;

		configASSERT( xSocket );

		/* Is the socket already a member of a select group? */
		if( pxSocket->xSelectQueue == NULL )
		{
			taskENTER_CRITICAL();
			{
				/* Are there packets queued on the socket already? */
				uxMessagesWaiting = uxQueueMessagesWaiting( pxSocket->xWaitingPacketSemaphore );

				/* Are there enough notification spaces in the select queue for the
				number of packets already queued on the socket? */
				if( uxQueueSpacesAvailable( ( xQueueHandle ) xSocketSet ) >= uxMessagesWaiting )
				{
					/* Store a pointer to the select group in the socket for
					future reference. */
					pxSocket->xSelectQueue = ( xQueueHandle ) xSocketSet;

					while( uxMessagesWaiting > 0 )
					{
						/* Add notifications of the number of packets that are
						already queued on the socket to the select queue. */
						xQueueSendFromISR( pxSocket->xSelectQueue, &pxSocket, NULL );
						uxMessagesWaiting--;
					}

					xReturn = pdPASS;
				}
			}
			taskEXIT_CRITICAL();
		}

		return xReturn;
	}

#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
/*-----------------------------------------------------------*/

#if ipconfigSUPPORT_SELECT_FUNCTION == 1

	portBASE_TYPE FreeRTOS_FD_CLR( xSocket_t xSocket, xSocketSet_t xSocketSet )
	{
	xFreeRTOS_Socket_t *pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;
	portBASE_TYPE xReturn;

		/* Is the socket a member of the select group? */
		if( pxSocket->xSelectQueue == ( xQueueHandle ) xSocketSet )
		{
			/* The socket is no longer a member of the select group. */
			pxSocket->xSelectQueue = NULL;
			xReturn = pdPASS;
		}
		else
		{
			xReturn = pdFAIL;
		}

		return xReturn;
	}

#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
/*-----------------------------------------------------------*/

#if ipconfigSUPPORT_SELECT_FUNCTION == 1

	xSocket_t FreeRTOS_select( xSocketSet_t xSocketSet, portTickType xBlockTimeTicks )
	{
	xFreeRTOS_Socket_t *pxSocket;

		/* Wait for a socket to be ready to read. */
		if( xQueueReceive( ( xQueueHandle ) xSocketSet, &pxSocket, xBlockTimeTicks ) != pdPASS )
		{
			pxSocket = NULL;
		}

		return ( xSocket_t ) pxSocket;
	}

#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
/*-----------------------------------------------------------*/

int32_t FreeRTOS_recvfrom( xSocket_t xSocket, void *pvBuffer, size_t xBufferLength, uint32_t ulFlags, struct freertos_sockaddr *pxSourceAddress, socklen_t *pxSourceAddressLength )
{
xNetworkBufferDescriptor_t *pxNetworkBuffer;
int32_t lReturn;
xFreeRTOS_Socket_t *pxSocket;

	pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;

	/* The function prototype is designed to maintain the expected Berkeley
	sockets standard, but this implementation does not use all the parameters. */
	( void ) pxSourceAddressLength;

	if( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE )
	{
		/* The semaphore is given when received data is queued on the socket. */
		if( xSemaphoreTake( pxSocket->xWaitingPacketSemaphore, pxSocket->xReceiveBlockTime ) == pdPASS )
		{
			taskENTER_CRITICAL();
			{
				configASSERT( ( listCURRENT_LIST_LENGTH( &( pxSocket->xWaitingPacketsList ) ) > 0U ) );

				/* The owner of the list item is the network buffer. */
				pxNetworkBuffer = ( xNetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->xWaitingPacketsList ) );

				/* Remove the network buffer from the list of buffers waiting to
				be processed by the socket. */
				uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
			}
			taskEXIT_CRITICAL();

			if( ( ulFlags & FREERTOS_ZERO_COPY ) == 0 )
			{
				/* The zero copy flag is not set.  Truncate the length if it
				won't fit in the provided buffer. */
				if( pxNetworkBuffer->xDataLength > xBufferLength )
				{
					iptraceRECVFROM_DISCARDING_BYTES( ( xBufferLength - pxNetworkBuffer->xDataLength ) );
					pxNetworkBuffer->xDataLength = xBufferLength;
				}

				/* Copy the received data into the provided buffer, then
				release the network buffer. */
				memcpy( pvBuffer, ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET ] ), pxNetworkBuffer->xDataLength );
				vNetworkBufferRelease( pxNetworkBuffer );
			}
			else
			{
				/* The zero copy flag was set.  pvBuffer is not a buffer into
				which the received data can be copied, but a pointer that must
				be set to point to the buffer in which the received data has
				already been placed. */
				*( ( void** ) pvBuffer ) = ( void * ) ( &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET ] ) );
			}

			/* The returned value is the data length, which may have been
			capped to the receive buffer size. */
			lReturn = ( int32_t ) pxNetworkBuffer->xDataLength;

			if( pxSourceAddress != NULL )
			{
				pxSourceAddress->sin_port = pxNetworkBuffer->usPort;
				pxSourceAddress->sin_addr = pxNetworkBuffer->ulIPAddress;
			}
		}
		else
		{
			lReturn = FREERTOS_EWOULDBLOCK;
			iptraceRECVFROM_TIMEOUT();
		}
	}
	else
	{
		lReturn = FREERTOS_EINVAL;
	}

	return lReturn;
}
/*-----------------------------------------------------------*/

#if ipconfigCAN_FRAGMENT_OUTGOING_PACKETS == 1

	int32_t FreeRTOS_sendto( xSocket_t xSocket, const void *pvBuffer, size_t xTotalDataLength, uint32_t ulFlags, const struct freertos_sockaddr *pxDestinationAddress, socklen_t xDestinationAddressLength )
	{
	xNetworkBufferDescriptor_t *pxNetworkBuffer;
	xIPFragmentParameters_t *pxFragmentParameters;
	size_t xBytesToSend, xBytesRemaining;
	xIPStackEvent_t xStackTxEvent = { eStackTxEvent, NULL };
	extern xQueueHandle xNetworkEventQueue;
	uint8_t *pucBuffer;
	xTimeOutType xTimeOut;
	portTickType xTicksToWait;
	uint16_t usFragmentOffset;
	xFreeRTOS_Socket_t *pxSocket;

		pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;

		/* The function prototype is designed to maintain the expected Berkeley
		sockets standard, but this implementation does not use all the
		parameters. */
		( void ) xDestinationAddressLength;
		configASSERT( xNetworkEventQueue );
		configASSERT( pvBuffer );

		xBytesRemaining = xTotalDataLength;

		if( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE )
		{
			/* If the socket is not already bound to an address, bind it now.
			Passing NULL as the address parameter tells FreeRTOS_bind() to select
			the address to bind to. */
			FreeRTOS_bind( xSocket, NULL, 0 );
		}

		if( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE )
		{
			/* pucBuffer will be reset if this send turns out to be a zero copy
			send because in that case pvBuffer is actually a pointer to an
			xUserData_t structure, not the UDP payload. */
			pucBuffer = ( uint8_t * ) pvBuffer;
			vTaskSetTimeOutState( &xTimeOut );
			xTicksToWait = pxSocket->xSendBlockTime;

			/* The data being transmitted will be sent in
			ipMAX_UDP_PAYLOAD_LENGTH chunks if xDataLength is greater than the
			network buffer payload size.  Loop until all the data is sent. */
			while( xBytesRemaining > 0 )
			{
				if( xBytesRemaining > ipMAX_UDP_PAYLOAD_LENGTH )
				{
					/* Cap the amount being sent in this packet to the maximum
					UDP payload size.  This will be a multiple of 8 already,
					removing the need to check in the code. */
					xBytesToSend = ipMAX_UDP_PAYLOAD_LENGTH;
				}
				else
				{
					/* Send all remaining bytes - which may well be the total
					number of bytes if the packet was not chopped up. */
					xBytesToSend = xBytesRemaining;
				}

				/* If the zero copy flag is set, then the data is already in a
				network buffer.  Otherwise, get a new network buffer. */
				if( ( ulFlags & FREERTOS_ZERO_COPY ) == 0 )
				{
					if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdTRUE )
					{
						xTicksToWait = 0;
					}

					pxNetworkBuffer = pxNetworkBufferGet( xBytesToSend + sizeof( xUDPPacket_t ), xTicksToWait );
				}
				else
				{
					if( xTotalDataLength > ipMAX_UDP_PAYLOAD_LENGTH )
					{
						/* The packet needs fragmenting, but zero copy buffers
						cannot be fragmented. */
						pxNetworkBuffer = NULL;
					}
					else
					{
						/* When zero copy is used, pvBuffer is a pointer to the
						payload of a buffer that has already been obtained from the
						stack.  Obtain the network buffer pointer from the buffer. */
						pucBuffer = ( uint8_t * ) pvBuffer;
						pucBuffer -= ( ipBUFFER_PADDING + sizeof( xUDPPacket_t ) );
						pxNetworkBuffer = * ( ( xNetworkBufferDescriptor_t ** ) pucBuffer );
					}
				}

				if( pxNetworkBuffer != NULL )
				{
					/* Use the part of the network buffer that will be completed
					by the IP layer as temporary storage to pass extra
					information required by the IP layer. */
					pxFragmentParameters = ( xIPFragmentParameters_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipFRAGMENTATION_PARAMETERS_OFFSET ] );
					pxFragmentParameters->ucSocketOptions = pxSocket->ucSocketOptions;

					if( xBytesRemaining > ipMAX_UDP_PAYLOAD_LENGTH )
					{
						/* The packet is being chopped up, and more data will
						follow. */
						pxFragmentParameters->ucSocketOptions = ( pxSocket->ucSocketOptions | FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET );
					}

					if( xTotalDataLength > ipMAX_UDP_PAYLOAD_LENGTH )
					{
						/* Let the IP layer know this packet has been chopped up,
						and supply the IP layer with any addition information it
						needs to make sense of it. */
						pxFragmentParameters->ucSocketOptions |= FREERTOS_FRAGMENTED_PACKET;
						usFragmentOffset = ( uint16_t ) ( xTotalDataLength - xBytesRemaining );
						pxFragmentParameters->usFragmentedPacketOffset = usFragmentOffset;
						pxFragmentParameters->usFragmentLength = ( uint16_t ) xBytesToSend;
					}
					else
					{
						usFragmentOffset = 0;
					}

					/* Write the payload into the packet.  The IP layer is
					queried to find where in the IP payload the data should be
					written.  This is because the necessary offset is different
					for the first packet, because the first packet leaves space
					for a UDP header.  Note that this changes usFragmentOffset
					from the offset in the entire UDP packet, to the offset
					in the IP packet. */
					if( ( ulFlags & FREERTOS_ZERO_COPY ) == 0 )
					{
						/* Only copy the data if it is not already in the
						expected location. */
						usFragmentOffset = ipGET_UDP_PAYLOAD_OFFSET_FOR_FRAGMENT( usFragmentOffset );
						memcpy( ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ usFragmentOffset ] ), ( void * ) pucBuffer, xBytesToSend );
					}
					pxNetworkBuffer->xDataLength = xTotalDataLength;
					pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;
					pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_ADDRESS( pxSocket );
					pxNetworkBuffer->ulIPAddress = pxDestinationAddress->sin_addr;

					/* Tell the networking task that the packet needs sending. */
					xStackTxEvent.pvData = pxNetworkBuffer;

					if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdTRUE )
					{
						xTicksToWait = 0;
					}

					if( xQueueSendToBack( xNetworkEventQueue, &xStackTxEvent, xTicksToWait ) != pdPASS )
					{
						/* If the buffer was allocated in this function, release it. */
						if( ( ulFlags & FREERTOS_ZERO_COPY ) == 0 )
						{
							vNetworkBufferRelease( pxNetworkBuffer );
						}
						iptraceSTACK_TX_EVENT_LOST( ipSTACK_TX_EVENT );
						break;
					}

					/* Adjust counters ready to either exit the loop, or send
					another chunk of data. */
					xBytesRemaining -= xBytesToSend;
					pucBuffer += xBytesToSend;
				}
				else
				{
					/* If errno was available, errno would be set to
					FREERTOS_ENOPKTS.  As it is, the function must return the
					number of transmitted bytes, so the calling function knows how
					much data was actually sent. */
					break;
				}
			}
		}

		return ( xTotalDataLength - xBytesRemaining );
	} /* Tested */

#else /* ipconfigCAN_FRAGMENT_OUTGOING_PACKETS */

	int32_t FreeRTOS_sendto( xSocket_t xSocket, const void *pvBuffer, size_t xTotalDataLength, uint32_t ulFlags, const struct freertos_sockaddr *pxDestinationAddress, socklen_t xDestinationAddressLength )
	{
	xNetworkBufferDescriptor_t *pxNetworkBuffer;
	xIPStackEvent_t xStackTxEvent = { eStackTxEvent, NULL };
	extern xQueueHandle xNetworkEventQueue;
	xTimeOutType xTimeOut;
	portTickType xTicksToWait;
	int32_t lReturn = 0;
	xFreeRTOS_Socket_t *pxSocket;
	uint8_t *pucBuffer;

		pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;

		/* The function prototype is designed to maintain the expected Berkeley
		sockets standard, but this implementation does not use all the
		parameters. */
		( void ) xDestinationAddressLength;
		configASSERT( xNetworkEventQueue );
		configASSERT( pvBuffer );

		if( xTotalDataLength <= ipMAX_UDP_PAYLOAD_LENGTH )
		{
			if( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE )
			{
				/* If the socket is not already bound to an address, bind it now.
				Passing NULL as the address parameter tells FreeRTOS_bind() to
				select the address to bind to. */
				FreeRTOS_bind( pxSocket, NULL, 0 );
			}

			if( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE )
			{
				xTicksToWait = pxSocket->xSendBlockTime;

				if( ( ulFlags & FREERTOS_ZERO_COPY ) == 0 )
				{
					/* Zero copy is not set, so obtain a network buffer into
					which the payload will be copied. */
					vTaskSetTimeOutState( &xTimeOut );
					pxNetworkBuffer = pxNetworkBufferGet( xTotalDataLength + sizeof( xUDPPacket_t ), xTicksToWait );

					if( pxNetworkBuffer != NULL )
					{
						memcpy( ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET ] ), ( void * ) pvBuffer, xTotalDataLength );

						if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdTRUE )
						{
							/* The entire block time has been used up. */
							xTicksToWait = 0;
						}
					}
				}
				else
				{
					/* When zero copy is used, pvBuffer is a pointer to the
					payload of a buffer that has already been obtained from the
					stack.  Obtain the network buffer pointer from the buffer. */
					pucBuffer = ( uint8_t * ) pvBuffer;
					pucBuffer -= ( ipBUFFER_PADDING + sizeof( xUDPPacket_t ) );
					pxNetworkBuffer = * ( ( xNetworkBufferDescriptor_t ** ) pucBuffer );
				}

				if( pxNetworkBuffer != NULL )
				{
					pxNetworkBuffer->xDataLength = xTotalDataLength;
					pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;
					pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_ADDRESS( pxSocket );
					pxNetworkBuffer->ulIPAddress = pxDestinationAddress->sin_addr;

					/* The socket options are passed to the IP layer in the
					space that will eventually get used by the Ethernet header. */
					pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = pxSocket->ucSocketOptions;

					/* Tell the networking task that the packet needs sending. */
					xStackTxEvent.pvData = pxNetworkBuffer;

					if( xQueueSendToBack( xNetworkEventQueue, &xStackTxEvent, xTicksToWait ) != pdPASS )
					{
						/* If the buffer was allocated in this function, release it. */
						if( ( ulFlags & FREERTOS_ZERO_COPY ) == 0 )
						{
							vNetworkBufferRelease( pxNetworkBuffer );
						}
						iptraceSTACK_TX_EVENT_LOST( ipSTACK_TX_EVENT );
					}
					else
					{
						lReturn = ( int32_t ) xTotalDataLength;
					}
				}
				else
				{
					/* If errno was available, errno would be set to
					FREERTOS_ENOPKTS.  As it is, the function must return the
					number of transmitted bytes, so the calling function knows how
					much data was actually sent. */
					iptraceNO_BUFFER_FOR_SENDTO();
				}
			}
			else
			{
				iptraceSENDTO_SOCKET_NOT_BOUND();
			}
		}
		else
		{
			/* The data is longer than the available buffer space.  Setting
			ipconfigCAN_FRAGMENT_OUTGOING_PACKETS to 1 may allow this packet
			to be sent. */
			iptraceSENDTO_DATA_TOO_LONG();
		}

		return lReturn;
	} /* Tested */

#endif /* ipconfigCAN_FRAGMENT_OUTGOING_PACKETS */
/*-----------------------------------------------------------*/

portBASE_TYPE FreeRTOS_bind( xSocket_t xSocket, struct freertos_sockaddr * pxAddress, socklen_t xAddressLength )
{
portBASE_TYPE xReturn = 0; /* In Berkeley sockets, 0 means pass for bind(). */
xFreeRTOS_Socket_t *pxSocket;
#if ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1
	struct freertos_sockaddr xAddress;
#endif /* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND */

	pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;

	/* The function prototype is designed to maintain the expected Berkeley
	sockets standard, but this implementation does not use all the parameters. */
	( void ) xAddressLength;

	configASSERT( xSocket );
	configASSERT( xSocket != FREERTOS_INVALID_SOCKET );

	#if ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1
	{
		/* pxAddress will be NULL if sendto() was called on a socket without the
		socket being bound to an address.  In this case, automatically allocate
		an address to the socket.  There is a very tiny chance that the allocated
		port will already be in use - if that is the case, then the check below
		[pxListFindListItemWithValue()] will result in an error being returned. */
		if( pxAddress == NULL )
		{
			pxAddress = &xAddress;
			pxAddress->sin_port = prvGetPrivatePortNumber();
		}
	}
	#endif /* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 */

	/* Sockets must be bound before calling FreeRTOS_sendto() if
	ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is not set to 1. */
	configASSERT( pxAddress );

	if( pxAddress != NULL )
	{
		if( pxAddress->sin_port == 0 )
		{
			pxAddress->sin_port = prvGetPrivatePortNumber();
		}

		vTaskSuspendAll();
		{
			/* Check to ensure the port is not already in use. */
			if( pxListFindListItemWithValue( &xBoundSocketsList, ( portTickType ) pxAddress->sin_port ) != NULL )
			{
				xReturn = FREERTOS_EADDRINUSE;
			}
		}
		xTaskResumeAll();

		/* Check that xReturn has not been set before continuing. */
		if( xReturn == 0 )
		{
			if( pxSocket->xWaitingPacketSemaphore == NULL )
			{
				/* Create the semaphore used to count the number of packets that
				are queued on this socket. */
				pxSocket->xWaitingPacketSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFERS, 0 );

				if( pxSocket->xWaitingPacketSemaphore != NULL )
				{
					/* Allocate the port number to the socket. */
					socketSET_SOCKET_ADDRESS( pxSocket, pxAddress->sin_port );
					taskENTER_CRITICAL();
					{
						/* Add the socket to the list of bound ports. */
						vListInsertEnd( &xBoundSocketsList, &( pxSocket->xBoundSocketListItem ) );
					}
					taskEXIT_CRITICAL();
				}
				else
				{
					/* Out of memory. */
					xReturn = FREERTOS_ENOBUFS;
				}
			}
			else
			{
				/* The socket is already bound. */
				xReturn = FREERTOS_EINVAL;
			}
		}
	}
	else
	{
		xReturn = FREERTOS_EADDRNOTAVAIL;
	}

	if( xReturn != 0 )
	{
		iptraceBIND_FAILED( xSocket, ( FreeRTOS_ntohs( pxAddress->sin_port ) ) );
	}

	return xReturn;
} /* Tested */
/*-----------------------------------------------------------*/

portBASE_TYPE FreeRTOS_closesocket( xSocket_t xSocket )
{
xNetworkBufferDescriptor_t *pxNetworkBuffer;
xFreeRTOS_Socket_t *pxSocket;

	pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;

	configASSERT( pxSocket );
	configASSERT( pxSocket != FREERTOS_INVALID_SOCKET );

	/* Socket must be unbound first, to ensure no more packets are queued on
	it. */
	if( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE )
	{
		taskENTER_CRITICAL();
		{
			uxListRemove( &( pxSocket->xBoundSocketListItem ) );
		}
		taskEXIT_CRITICAL();
	}

	/* Now the socket is not bound the list of waiting packets can be
	drained. */
	if( pxSocket->xWaitingPacketSemaphore != NULL )
	{
		while( listCURRENT_LIST_LENGTH( &( pxSocket->xWaitingPacketsList ) ) > 0U )
		{
			pxNetworkBuffer = ( xNetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->xWaitingPacketsList ) );
			uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
			vNetworkBufferRelease( pxNetworkBuffer );
		}
		vSemaphoreDelete( pxSocket->xWaitingPacketSemaphore );
	}

	vPortFree( pxSocket );

	return 0;
} /* Tested */
/*-----------------------------------------------------------*/

void FreeRTOS_SocketsInit( void )
{
	vListInitialise( &xBoundSocketsList );
}
/*-----------------------------------------------------------*/

portBASE_TYPE FreeRTOS_setsockopt( xSocket_t xSocket, int32_t lLevel, int32_t lOptionName, const void *pvOptionValue, size_t xOptionLength )
{
/* The standard Berkeley function returns 0 for success. */
portBASE_TYPE xReturn = 0;
portBASE_TYPE lOptionValue;
xFreeRTOS_Socket_t *pxSocket;

	pxSocket = ( xFreeRTOS_Socket_t * ) xSocket;

	/* The function prototype is designed to maintain the expected Berkeley
	sockets standard, but this implementation does not use all the parameters. */
	( void ) lLevel;
	( void ) xOptionLength;

	configASSERT( xSocket );

	switch( lOptionName )
	{
		case FREERTOS_SO_RCVTIMEO	:
			/* Receive time out. */
			pxSocket->xReceiveBlockTime = *( ( portTickType * ) pvOptionValue );
			break;

		case FREERTOS_SO_SNDTIMEO	:
			/* The send time out is capped for the reason stated in the comments
			where ipconfigMAX_SEND_BLOCK_TIME_TICKS is defined in
			FreeRTOSIPConfig.h (assuming an official configuration file is being
			used. */
			pxSocket->xSendBlockTime = *( ( portTickType * ) pvOptionValue );
			if( pxSocket->xSendBlockTime > ipconfigMAX_SEND_BLOCK_TIME_TICKS )
			{
				pxSocket->xSendBlockTime = ipconfigMAX_SEND_BLOCK_TIME_TICKS;
			}
			break;

		case FREERTOS_SO_UDPCKSUM_OUT :
			/* Turn calculating of the UDP checksum on/off for this socket. */
			lOptionValue = ( portBASE_TYPE ) pvOptionValue;

			if( lOptionValue == 0 )
			{
				pxSocket->ucSocketOptions &= ~FREERTOS_SO_UDPCKSUM_OUT;
			}
			else
			{
				pxSocket->ucSocketOptions |= FREERTOS_SO_UDPCKSUM_OUT;
			}
			break;

		default :
			/* No other options are handled. */
			xReturn = FREERTOS_ENOPROTOOPT;
			break;
	}

	return xReturn;
} /* Tested */
/*-----------------------------------------------------------*/

portBASE_TYPE xProcessReceivedUDPPacket( xNetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort )
{
xListItem *pxListItem;
portBASE_TYPE xReturn = pdPASS;
xFreeRTOS_Socket_t *pxSocket;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	vTaskSuspendAll();
	{
		/* See if there is a list item associated with the port number on the
		list of bound sockets. */
		pxListItem = pxListFindListItemWithValue( &xBoundSocketsList, ( portTickType ) usPort );
	}
	xTaskResumeAll();

	if( pxListItem != NULL )
	{
		/* The owner of the list item is the socket itself. */
		pxSocket = ( xFreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxListItem );

		vTaskSuspendAll();
		{
			#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
			{
				/* Is the socket a member of a select() group? */
				if( pxSocket->xSelectQueue != NULL )
				{
					/* Can the select group be notified that the socket is
					ready to be read? */
					if( xQueueSendFromISR( pxSocket->xSelectQueue, &pxSocket, &xHigherPriorityTaskWoken ) != pdPASS )
					{
						/* Could not notify the select group. */
						xReturn = pdFAIL;
						iptraceFAILED_TO_NOTIFY_SELECT_GROUP( pxSocket );
					}
				}
			}
			#endif

			if( xReturn == pdPASS )
			{
				taskENTER_CRITICAL();
				{
					/* Add the network packet to the list of packets to be
					processed by the socket. */
					vListInsertEnd( &( pxSocket->xWaitingPacketsList ), &( pxNetworkBuffer->xBufferListItem ) );
				}
				taskEXIT_CRITICAL();

				/* The socket's counting semaphore records how many packets are
				waiting	to be processed by the socket. */
				xSemaphoreGiveFromISR( pxSocket->xWaitingPacketSemaphore, &xHigherPriorityTaskWoken );
			}
		}
		if( xTaskResumeAll() == pdFALSE )
		{
			if( xHigherPriorityTaskWoken != pdFALSE )
			{
				taskYIELD();
			}
		}
	}
	else
	{
		xReturn = pdFAIL;
	}

	return xReturn;
}
/*-----------------------------------------------------------*/

static uint16_t prvGetPrivatePortNumber( void )
{
static uint16_t usNextPortToUse = socketAUTO_PORT_ALLOCATION_START_NUMBER - 1;
uint16_t usReturn;

	/* Assign the next port in the range. */
	taskENTER_CRITICAL();
	{
		usNextPortToUse++;

		/* Has it overflowed? */
		if( usNextPortToUse == 0U )
		{
			/* Don't go right back to the start of the dynamic/private port
			range numbers as any persistent sockets are likely to have been
			create first so the early port numbers may still be in use. */
			usNextPortToUse = socketAUTO_PORT_ALLOCATION_RESET_NUMBER;
		}

		usReturn = FreeRTOS_htons( usNextPortToUse );
	}
	taskEXIT_CRITICAL();

	return usReturn;
} /* Tested */
/*-----------------------------------------------------------*/

xListItem * pxListFindListItemWithValue( xList *pxList, portTickType xWantedItemValue )
{
xListItem *pxIterator, *pxReturn;

	pxReturn = NULL;
	for( pxIterator = ( xListItem * ) pxList->xListEnd.pxNext; pxIterator != ( xListItem* ) &( pxList->xListEnd ); pxIterator = ( xListItem * ) pxIterator->pxNext )
	{
		if( pxIterator->xItemValue == xWantedItemValue )
		{
			pxReturn = pxIterator;
			break;
		}
	}

	return pxReturn;
} /* Tested */
/*-----------------------------------------------------------*/

#if ipconfigINCLUDE_FULL_INET_ADDR == 1

	uint32_t FreeRTOS_inet_addr( const char *pcIPAddress )
	{
	const uint8_t ucDecimalBase = 10;
	uint8_t ucOctet[ socketMAX_IP_ADDRESS_OCTETS ];
	const char *pcPointerOnEntering;
	uint32_t ulReturn = 0UL, ulOctetNumber, ulValue;
	portBASE_TYPE xResult = pdPASS;

		for( ulOctetNumber = 0; ulOctetNumber < socketMAX_IP_ADDRESS_OCTETS; ulOctetNumber++ )
		{
			ulValue = 0;
			pcPointerOnEntering = pcIPAddress;

			while( ( *pcIPAddress >= ( uint8_t ) '0' ) && ( *pcIPAddress <= ( uint8_t ) '9' ) )
			{
				/* Move previous read characters into the next decimal
				position. */
				ulValue *= ucDecimalBase;

				/* Add the binary value of the ascii character. */
				ulValue += ( *pcIPAddress - ( uint8_t ) '0' );

				/* Move to next character in the string. */
				pcIPAddress++;
			}

			/* Check characters were read. */
			if( pcIPAddress == pcPointerOnEntering )
			{
				xResult = pdFAIL;
			}

			/* Check the value fits in an 8-bit number. */
			if( ulValue > 0xffUL )
			{
				xResult = pdFAIL;
			}
			else
			{
				ucOctet[ ulOctetNumber ] = ( uint8_t ) ulValue;

				/* Check the next character is as expected. */
				if( ulOctetNumber < ( socketMAX_IP_ADDRESS_OCTETS - 1 ) )
				{
					if( *pcIPAddress != ( uint8_t ) '.' )
					{
						xResult = pdFAIL;
					}
					else
					{
						/* Move past the dot. */
						pcIPAddress++;
					}
				}
			}

			if( xResult == pdFAIL )
			{
				/* No point going on. */
				break;
			}
		}

		if( *pcIPAddress != ( uint8_t ) 0x00 )
		{
			/* Expected the end of the string. */
			xResult = pdFAIL;
		}

		if( ulOctetNumber != socketMAX_IP_ADDRESS_OCTETS )
		{
			/* Didn't read enough octets. */
			xResult = pdFAIL;
		}

		if( xResult == pdPASS )
		{
			ulReturn = FreeRTOS_inet_addr_quick( ucOctet[ 0 ], ucOctet[ 1 ], ucOctet[ 2 ], ucOctet[ 3 ] );
		}

		return ulReturn;
	}

#endif /* ipconfigINCLUDE_FULL_INET_ADDR */
/*-----------------------------------------------------------*/

