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