/*
 * FreeRTOS+UDP V1.0.1 (C) 2013 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 ) ( ( uint32_t ) 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++;
	taskEXIT_CRITICAL();

	/* 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 );

	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 uint8_t * pucIPAddress )
	{
	const uint8_t ucDecimalBase = 10;
	uint8_t ucOctet[ socketMAX_IP_ADDRESS_OCTETS ];
	const uint8_t *pucPointerOnEntering;
	uint32_t ulReturn = 0UL, ulOctetNumber, ulValue;
	portBASE_TYPE xResult = pdPASS;

		for( ulOctetNumber = 0; ulOctetNumber < socketMAX_IP_ADDRESS_OCTETS; ulOctetNumber++ )
		{
			ulValue = 0;
			pucPointerOnEntering = pucIPAddress;

			while( ( *pucIPAddress >= ( uint8_t ) '0' ) && ( *pucIPAddress <= ( uint8_t ) '9' ) )
			{
				/* Move previous read characters into the next decimal
				position. */
				ulValue *= ucDecimalBase;

				/* Add the binary value of the ascii character. */
				ulValue += ( *pucIPAddress - ( uint8_t ) '0' );

				/* Move to next character in the string. */
				pucIPAddress++;
			}

			/* Check characters were read. */
			if( pucIPAddress == pucPointerOnEntering )
			{
				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( *pucIPAddress != ( uint8_t ) '.' )
					{
						xResult = pdFAIL;
					}
					else
					{
						/* Move past the dot. */
						pucIPAddress++;
					}
				}
			}

			if( xResult == pdFAIL )
			{
				/* No point going on. */
				break;
			}
		}

		if( *pucIPAddress != ( 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 */
/*-----------------------------------------------------------*/

