/*
 * FreeRTOS+TCP V2.0.11
 * 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://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */

/******************************************************************************
 *
 * See the following web page for essential buffer allocation scheme usage and
 * configuration details:
 * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
 *
 ******************************************************************************/

/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
THAT WILL FRAGMENT THE HEAP MEMORY.  For example, heap_2 must not be used,
heap_4 can be used. */


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

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

/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkInterface.h"
#include "NetworkBufferManagement.h"

/* The obtained network buffer must be large enough to hold a packet that might
replace the packet that was requested to be sent. */
#if ipconfigUSE_TCP == 1
	#define baMINIMAL_BUFFER_SIZE		sizeof( TCPPacket_t )
#else
	#define baMINIMAL_BUFFER_SIZE		sizeof( ARPPacket_t )
#endif /* ipconfigUSE_TCP == 1 */

/*_RB_ This is too complex not to have an explanation. */
#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
	#define ASSERT_CONCAT_(a, b) a##b
	#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
	#define STATIC_ASSERT(e) \
		;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }

	STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
#endif

/* A list of free (available) NetworkBufferDescriptor_t structures. */
static List_t xFreeBuffersList;

/* Some statistics about the use of buffers. */
static size_t uxMinimumFreeNetworkBuffers;

/* Declares the pool of NetworkBufferDescriptor_t structures that are available
to the system.  All the network buffers referenced from xFreeBuffersList exist
in this array.  The array is not accessed directly except during initialisation,
when the xFreeBuffersList is filled (as all the buffers are free when the system
is booted). */
static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];

/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
network buffers have a variable size: resizing may be necessary */
const BaseType_t xBufferAllocFixedSize = pdFALSE;

/* The semaphore used to obtain network buffers. */
static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;

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

BaseType_t xNetworkBuffersInitialise( void )
{
BaseType_t xReturn, x;

	/* Only initialise the buffers and their associated kernel objects if they
	have not been initialised before. */
	if( xNetworkBufferSemaphore == NULL )
	{
		xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
		configASSERT( xNetworkBufferSemaphore );

		if( xNetworkBufferSemaphore != NULL )
		{
			#if ( configQUEUE_REGISTRY_SIZE > 0 )
			{
				vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
			}
			#endif /* configQUEUE_REGISTRY_SIZE */

			/* If the trace recorder code is included name the semaphore for viewing
			in FreeRTOS+Trace.  */
			#if( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
			{
				extern QueueHandle_t xNetworkEventQueue;
				vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
				vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
			}
			#endif /*  ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */

			vListInitialise( &xFreeBuffersList );

			/* Initialise all the network buffers.  No storage is allocated to
			the buffers yet. */
			for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
			{
				/* Initialise and set the owner of the buffer list items. */
				xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
				vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
				listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );

				/* Currently, all buffers are available for use. */
				vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
			}

			uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
		}
	}

	if( xNetworkBufferSemaphore == NULL )
	{
		xReturn = pdFAIL;
	}
	else
	{
		xReturn = pdPASS;
	}

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

uint8_t *pucGetNetworkBuffer( size_t *pxRequestedSizeBytes )
{
uint8_t *pucEthernetBuffer;
size_t xSize = *pxRequestedSizeBytes;

	if( xSize < baMINIMAL_BUFFER_SIZE )
	{
		/* Buffers must be at least large enough to hold a TCP-packet with
		headers, or an ARP packet, in case TCP is not included. */
		xSize = baMINIMAL_BUFFER_SIZE;
	}

	/* Round up xSize to the nearest multiple of N bytes,
	where N equals 'sizeof( size_t )'. */
	if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
	{
		xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
	}
	*pxRequestedSizeBytes = xSize;

	/* Allocate a buffer large enough to store the requested Ethernet frame size
	and a pointer to a network buffer structure (hence the addition of
	ipBUFFER_PADDING bytes). */
	pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
	configASSERT( pucEthernetBuffer );

	if( pucEthernetBuffer != NULL )
	{
		/* Enough space is left at the start of the buffer to place a pointer to
		the network buffer structure that references this Ethernet buffer.
		Return a pointer to the start of the Ethernet buffer itself. */
		pucEthernetBuffer += ipBUFFER_PADDING;
	}

	return pucEthernetBuffer;
}
/*-----------------------------------------------------------*/

void vReleaseNetworkBuffer( uint8_t *pucEthernetBuffer )
{
	/* There is space before the Ethernet buffer in which a pointer to the
	network buffer that references this Ethernet buffer is stored.  Remove the
	space before freeing the buffer. */
	if( pucEthernetBuffer != NULL )
	{
		pucEthernetBuffer -= ipBUFFER_PADDING;
		vPortFree( ( void * ) pucEthernetBuffer );
	}
}
/*-----------------------------------------------------------*/

NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
{
NetworkBufferDescriptor_t *pxReturn = NULL;
size_t uxCount;

	if( xNetworkBufferSemaphore != NULL )
	{
		if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
		{
			/* ARP packets can replace application packets, so the storage must be
			at least large enough to hold an ARP. */
			xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
		}

		/* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
		to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
		xRequestedSizeBytes += 2u;
		if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
		{
			xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
		}

		/* If there is a semaphore available, there is a network buffer available. */
		if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
		{
			/* Protect the structure as it is accessed from tasks and interrupts. */
			taskENTER_CRITICAL();
			{
				pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
				uxListRemove( &( pxReturn->xBufferListItem ) );
			}
			taskEXIT_CRITICAL();

			/* Reading UBaseType_t, no critical section needed. */
			uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );

			if( uxMinimumFreeNetworkBuffers > uxCount )
			{
				uxMinimumFreeNetworkBuffers = uxCount;
			}

			/* Allocate storage of exactly the requested size to the buffer. */
			configASSERT( pxReturn->pucEthernetBuffer == NULL );
			if( xRequestedSizeBytes > 0 )
			{
				/* Extra space is obtained so a pointer to the network buffer can
				be stored at the beginning of the buffer. */
				pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );

				if( pxReturn->pucEthernetBuffer == NULL )
				{
					/* The attempt to allocate storage for the buffer payload failed,
					so the network buffer structure cannot be used and must be
					released. */
					vReleaseNetworkBufferAndDescriptor( pxReturn );
					pxReturn = NULL;
				}
				else
				{
					/* Store a pointer to the network buffer structure in the
					buffer storage area, then move the buffer pointer on past the
					stored pointer so the pointer value is not overwritten by the
					application when the buffer is used. */
					*( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
					pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;

					/* Store the actual size of the allocated buffer, which may be
					greater than the original requested size. */
					pxReturn->xDataLength = xRequestedSizeBytes;

					#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
					{
						/* make sure the buffer is not linked */
						pxReturn->pxNextBuffer = NULL;
					}
					#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
				}
			}
			else
			{
				/* A descriptor is being returned without an associated buffer being
				allocated. */
			}
		}
	}

	if( pxReturn == NULL )
	{
		iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
	}
	else
	{
		iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
	}

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

void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xListItemAlreadyInFreeList;

	/* Ensure the buffer is returned to the list of free buffers before the
	counting semaphore is 'given' to say a buffer is available.  Release the
	storage allocated to the buffer payload.  THIS FILE SHOULD NOT BE USED
	IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
	MEMORY.  For example, heap_2 must not be used, heap_4 can be used. */
	vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
	pxNetworkBuffer->pucEthernetBuffer = NULL;

	taskENTER_CRITICAL();
	{
		xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );

		if( xListItemAlreadyInFreeList == pdFALSE )
		{
			vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
		}
	}
	taskEXIT_CRITICAL();

	/*
	 * Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
	 * The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
	 */
	if( xListItemAlreadyInFreeList == pdFALSE )
	{
		if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
		{
			iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
		}
	}
	else
	{
		iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
	}
}
/*-----------------------------------------------------------*/

/*
 * Returns the number of free network buffers
 */
UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
{
	return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
}
/*-----------------------------------------------------------*/

UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
{
	return uxMinimumFreeNetworkBuffers;
}
/*-----------------------------------------------------------*/

NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes )
{
size_t xOriginalLength;
uint8_t *pucBuffer;

	xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
	xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;

	pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );

	if( pucBuffer == NULL )
	{
		/* In case the allocation fails, return NULL. */
		pxNetworkBuffer = NULL;
	}
	else
	{
		pxNetworkBuffer->xDataLength = xNewSizeBytes;
		if( xNewSizeBytes > xOriginalLength )
		{
			xNewSizeBytes = xOriginalLength;
		}

		memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
		vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
		pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
	}

	return pxNetworkBuffer;
}

