Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 77 additions & 2 deletions source/portable/NetworkInterface/WinPCap/NetworkInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,20 @@ static void prvInterruptSimulatorTask( void * pvParameters );
*/
static void prvCreateThreadSafeBuffers( void );

/*
* This function is equivalent to uxStreamBufferAdd from
* FreeRTOS_Stream_Buffer.c in the case that the stream buffer is being used
* as a normal circular buffer (i.e. only the tail and head pointers are
* needed). Thus, this function does not take the offset argument, and does not
* update the front pointer of the stream buffer. This allows the removal of
* the calls to vTaskSuspendAll and xTaskResumeAll, as the head and front
* pointer no longer need to be atomically updated, allowing this function to be
* safely used by a Windows thread.
*/
static size_t prvStreamBufferAdd( StreamBuffer_t * pxBuffer,
const uint8_t * pucData,
size_t uxByteCount );

/*
* Utility function used to format print messages only.
*/
Expand Down Expand Up @@ -189,6 +203,59 @@ static void prvCreateThreadSafeBuffers( void )
xRecvBuffer->LENGTH = xRECV_BUFFER_SIZE + 1;
}
}

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

static size_t prvStreamBufferAdd( StreamBuffer_t * pxBuffer,
const uint8_t * pucData,
size_t uxByteCount )
{
size_t uxSpace, uxNextHead, uxFirst;
size_t uxCount = uxByteCount;

uxSpace = uxStreamBufferGetSpace( pxBuffer );

/* The number of bytes that can be written is the minimum of the number of
* bytes requested and the number available. */
uxCount = FreeRTOS_min_size_t( uxSpace, uxCount );

if( uxCount != 0U )
{
uxNextHead = pxBuffer->uxHead;

if( pucData != NULL )
{
/* Calculate the number of bytes that can be added in the first
* write - which may be less than the total number of bytes that need
* to be added if the buffer will wrap back to the beginning. */
uxFirst = FreeRTOS_min_size_t( pxBuffer->LENGTH - uxNextHead, uxCount );

/* Write as many bytes as can be written in the first write. */
( void ) memcpy( &( pxBuffer->ucArray[ uxNextHead ] ), pucData, uxFirst );

/* If the number of bytes written was less than the number that
* could be written in the first write... */
if( uxCount > uxFirst )
{
/* ...then write the remaining bytes to the start of the
* buffer. */
( void ) memcpy( pxBuffer->ucArray, &( pucData[ uxFirst ] ), uxCount - uxFirst );
}
}

uxNextHead += uxCount;

if( uxNextHead >= pxBuffer->LENGTH )
{
uxNextHead -= pxBuffer->LENGTH;
}

pxBuffer->uxHead = uxNextHead;
}

return uxCount;
}

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

BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer,
Expand Down Expand Up @@ -459,8 +526,16 @@ void pcap_callback( u_char * user,
* Otherwise, there is no action. */
iptraceDUMP_PACKET( ( const uint8_t * ) pkt_data, ( size_t ) pkt_header->caplen, pdTRUE );

uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t * ) pkt_header, sizeof( *pkt_header ) );
uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t * ) pkt_data, ( size_t ) pkt_header->caplen );
/* NOTE. The prvStreamBufferAdd function is used here in place of
* uxStreamBufferAdd since the uxStreamBufferAdd call will suspend
* the FreeRTOS scheduler to atomically update the head and front
* of the stream buffer. Since xRecvBuffer is being used as a regular
* circular buffer (i.e. only the head and tail are needed), this call
* only updates the head of the buffer, removing the need to suspend
* the scheduler, and allowing this function to be safely called from
* a Windows thread. */
prvStreamBufferAdd( xRecvBuffer, ( const uint8_t * ) pkt_header, sizeof( *pkt_header ) );
prvStreamBufferAdd( xRecvBuffer, ( const uint8_t * ) pkt_data, ( size_t ) pkt_header->caplen );
}
}
/*-----------------------------------------------------------*/
Expand Down