mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-10-17 10:17:45 -04:00
FreeRTOS+TCP : add memory statistics and dump packets, v3 (#83)
* FreeRTOS+TCP : add memory statistics and dump packets, v3 * Two changes as requested by Aniruddha Co-authored-by: Hein Tibosch <hein@htibosch.net> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>
This commit is contained in:
parent
072a173c9d
commit
98bfc38bf3
4 changed files with 1200 additions and 0 deletions
658
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/tools/tcp_dump_packets.c
Normal file
658
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/tools/tcp_dump_packets.c
Normal file
|
@ -0,0 +1,658 @@
|
|||
/*
|
||||
* FreeRTOS+TCP V2.2.1
|
||||
* 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://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* tcp_dump_packets.c
|
||||
* Used in the PC/Win project to dump Ethernet packets, along with some description.
|
||||
* See tools/tcp_dump_packets.md for further description.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include <FreeRTOS.h>
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
#if( ipconfigUSE_DUMP_PACKETS != 0 )
|
||||
|
||||
#include "tcp_dump_packets.h"
|
||||
|
||||
/* The priority of the windows thread. */
|
||||
#define dumpPROCESS_THREAD_PRIORITY THREAD_PRIORITY_NORMAL
|
||||
|
||||
/* There is a stream buffer between the FreeRTOS tasks sending network packets,
|
||||
and the Windows thread that writes these packets to disk. The macro 'dumpITEM_COUNT'
|
||||
determines the number of full-size packets that can be stored in this stream buffer. */
|
||||
#ifndef dumpITEM_COUNT
|
||||
#define dumpITEM_COUNT 32
|
||||
#endif
|
||||
|
||||
/* Packets are written in hex notation, no more than 16 bytes on a row. */
|
||||
#ifndef dumpBYTES_PER_ROW
|
||||
#define dumpBYTES_PER_ROW 16
|
||||
#endif
|
||||
|
||||
/* The TCP port number reserved for a DNS server. */
|
||||
#define dnsDNS_PORT 0x0035u
|
||||
|
||||
/* Some const values describing the 'flags' in a TCP packet. */
|
||||
#define tcpTCP_FLAG_FIN 0x0001u /* No more data from sender */
|
||||
#define tcpTCP_FLAG_SYN 0x0002u /* Synchronize sequence numbers */
|
||||
#define tcpTCP_FLAG_RST 0x0004u /* Reset the connection */
|
||||
#define tcpTCP_FLAG_PSH 0x0008u /* Push function: please push buffered data to the recv application */
|
||||
#define tcpTCP_FLAG_ACK 0x0010u /* Acknowledgment field is significant */
|
||||
|
||||
/* A macro to add a type, both as a numeric value, as well as a string. */
|
||||
#define ADD_TYPE( FLAGS ) \
|
||||
vAddType( flag_##FLAGS, #FLAGS )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static char pcTypeString[ 255 ];
|
||||
static uint32_t ulTypeMask;
|
||||
|
||||
/* The name of the C source file to be written. */
|
||||
static char pcCodeFileName[ MAX_PATH ];
|
||||
|
||||
/* The name of the header file to be written. */
|
||||
static char pcHeaderFileName[ MAX_PATH ];
|
||||
|
||||
/* A stream buffer between the FreeRTOS tasks and the Windows thread. */
|
||||
static StreamBuffer_t *xPacketBuffer;
|
||||
|
||||
/* A process handle of the Windows thread. */
|
||||
static HANDLE pvProcessHandle;
|
||||
|
||||
static UBaseType_t uxNextPacketNumber;
|
||||
static BaseType_t xFirstPacket = 1;
|
||||
|
||||
/* Bollean 'xDumpingReady' becomes true once all desired packet have been collected.
|
||||
Further packets will be dropped (ignored). */
|
||||
static volatile BaseType_t xDumpingReady = pdFALSE;
|
||||
|
||||
static DumpEntries_t *pxCurrentEntries;
|
||||
|
||||
static uint16_t usSourcePort;
|
||||
static uint16_t usDestinationPort;
|
||||
|
||||
typedef struct xBufferheader
|
||||
{
|
||||
size_t uxLength;
|
||||
UBaseType_t bIncoming : 1;
|
||||
} Bufferheader_t;
|
||||
|
||||
static DumpEntries_t xExampleEntries = {
|
||||
.uxEntryCount = 4, /* No more than 'dumpMAX_DUMP_ENTRIES' elements. */
|
||||
.xEntries = {
|
||||
{ .ulMask = flag_IN | flag_UDP, .uxMax = 2u },
|
||||
{ .ulMask = flag_IN | flag_ARP, .uxMax = 2u },
|
||||
{ .ulMask = flag_IN | flag_TCP, .uxMax = 5u },
|
||||
{ .ulMask = flag_IN | flag_SYN, .uxMax = 1u },
|
||||
}
|
||||
};
|
||||
|
||||
const char pcHeaderCode[] =
|
||||
"/*\n"
|
||||
" * This file was created automatically by 'dump_packets.c'\n"
|
||||
" */\n"
|
||||
"\n"
|
||||
"/* Standard includes. */\n"
|
||||
"#include <stdio.h>\n"
|
||||
"#include <stdint.h>\n"
|
||||
"#include <stdarg.h>\n"
|
||||
"#include <io.h>\n"
|
||||
"#include <ctype.h>\n"
|
||||
"\n"
|
||||
"/* FreeRTOS includes. */\n"
|
||||
"#include <FreeRTOS.h>\n"
|
||||
"#include <task.h>\n\n"
|
||||
"#include \"%s\"\n\n";
|
||||
|
||||
const char pcHeaderHeader[] =
|
||||
"/*\n"
|
||||
" * This file was created automatically by 'dump_packets.c'\n"
|
||||
" */\n"
|
||||
"\n"
|
||||
"#ifndef PACKET_LIST_H\n\n"
|
||||
"#define PACKET_LIST_H\n\n"
|
||||
"typedef struct xDumpPacket\n"
|
||||
"{\n"
|
||||
" const uint8_t *pucData;\n"
|
||||
" size_t uxLength;\n"
|
||||
" uint32_t ulType;\n"
|
||||
" uint16_t usSource;\n"
|
||||
" uint16_t usDestination;\n"
|
||||
"} DumpPacket_t;\n\n";
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The Windows thread that actually writes the network packets to a C source and header file. */
|
||||
static DWORD WINAPI prvWritePackets( LPVOID lpParameter );
|
||||
|
||||
static void vAddProtocolTags( uint8_t *pucEthernetBuffer, BaseType_t xIPType );
|
||||
static void vDetermineMessageType( uint8_t *pucBuffer, BaseType_t xIncoming );
|
||||
static void vActualDump( uint8_t *pucBuffer, size_t uxLength, BaseType_t xIncoming );
|
||||
static void vAddType( uint32_t ulFlags, const char *pcFlagName );
|
||||
static void vWriteHeaderFile( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void dump_packet_init( const char *pcFileName, DumpEntries_t *pxEntries )
|
||||
{
|
||||
size_t uxIndex;
|
||||
|
||||
snprintf( pcCodeFileName, sizeof pcCodeFileName, "%s.c", pcFileName );
|
||||
snprintf( pcHeaderFileName, sizeof pcHeaderFileName, "%s.h", pcFileName );
|
||||
|
||||
if( pxEntries == NULL )
|
||||
{
|
||||
pxEntries = &( xExampleEntries );
|
||||
}
|
||||
configASSERT( pxEntries->uxEntryCount > 0 );
|
||||
configASSERT( pxEntries->uxEntryCount <= dumpMAX_DUMP_ENTRIES );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxEntries->uxEntryCount; uxIndex++ )
|
||||
{
|
||||
pxEntries->xEntries[ uxIndex ].uxCount = 0;
|
||||
}
|
||||
|
||||
pxCurrentEntries = pxEntries;
|
||||
|
||||
if( xPacketBuffer == NULL )
|
||||
{
|
||||
size_t uxLength, uxSize;
|
||||
|
||||
/* Enough space for e.g. 32 buffers and length words. */
|
||||
uxLength = dumpITEM_COUNT * ( sizeof( void * ) + ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER );
|
||||
uxSize = ( sizeof( *xPacketBuffer ) + uxLength ) - sizeof( xPacketBuffer->ucArray );
|
||||
xPacketBuffer = ( StreamBuffer_t * ) pvPortMalloc( uxSize );
|
||||
configASSERT( xPacketBuffer != NULL );
|
||||
vStreamBufferClear( xPacketBuffer );
|
||||
xPacketBuffer->LENGTH = uxLength;
|
||||
}
|
||||
|
||||
if( pvProcessHandle == NULL )
|
||||
{
|
||||
pvProcessHandle = CreateThread( NULL, 0, prvWritePackets, NULL, CREATE_SUSPENDED, NULL );
|
||||
if( pvProcessHandle != NULL )
|
||||
{
|
||||
SetThreadPriority( pvProcessHandle, dumpPROCESS_THREAD_PRIORITY );
|
||||
SetThreadPriorityBoost( pvProcessHandle, TRUE );
|
||||
SetThreadAffinityMask( pvProcessHandle, 0x0E );
|
||||
ResumeThread( pvProcessHandle );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void dump_packet( const uint8_t *pucBuffer, size_t uxLength, BaseType_t xIncoming )
|
||||
{
|
||||
/* This function shall be called from a normal FreeRTOS task only. */
|
||||
if( xPacketBuffer != NULL )
|
||||
{
|
||||
if( xDumpingReady == pdFALSE )
|
||||
{
|
||||
size_t uxSpace = uxStreamBufferGetSpace( xPacketBuffer );
|
||||
size_t uxNeeded = uxLength + sizeof( size_t );
|
||||
|
||||
if( uxNeeded < uxSpace )
|
||||
{
|
||||
Bufferheader_t xheader;
|
||||
|
||||
xheader.uxLength = uxLength;
|
||||
xheader.bIncoming = xIncoming;
|
||||
uxStreamBufferAdd( xPacketBuffer, 0u, ( const uint8_t * ) &( xheader ), sizeof( xheader ) );
|
||||
uxStreamBufferAdd( xPacketBuffer, 0u, pucBuffer, uxLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Drop this packet. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The Windows thread 'prvWritePackets()' had received enough packets.
|
||||
The packet buffer may be freed. */
|
||||
vPortFree( xPacketBuffer );
|
||||
xPacketBuffer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static DWORD WINAPI prvWritePackets( LPVOID lpParameter )
|
||||
{
|
||||
/* This is a Windows thread, not a FreeRTOS task. FreeRTOS API's may not be called. */
|
||||
for( ;; )
|
||||
{
|
||||
Sleep( 100 );
|
||||
|
||||
while( ( xPacketBuffer != NULL ) && ( xDumpingReady == pdFALSE ) )
|
||||
{
|
||||
Bufferheader_t xHeader;
|
||||
size_t uxBytes = uxStreamBufferGetSize( xPacketBuffer );
|
||||
|
||||
if( uxBytes <= sizeof( xHeader ) )
|
||||
break;
|
||||
|
||||
/* Peek the number of bytes available. */
|
||||
uxStreamBufferGet( xPacketBuffer, 0u, ( uint8_t * ) &( xHeader ), sizeof( xHeader ), pdTRUE );
|
||||
if( uxBytes >= sizeof( xHeader ) + xHeader.uxLength );
|
||||
{
|
||||
size_t xBytesRead;
|
||||
uint8_t pcBuffer[ ipconfigNETWORK_MTU ];
|
||||
size_t xActualCount;
|
||||
|
||||
uxStreamBufferGet( xPacketBuffer, 0u, NULL, sizeof( xHeader ), pdFALSE );
|
||||
xActualCount = uxStreamBufferGet( xPacketBuffer, 0u, pcBuffer, xHeader.uxLength, pdFALSE );
|
||||
vActualDump( pcBuffer, xActualCount, xHeader.bIncoming );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int _fprintf( FILE *pxHandle, const char* pcFormat, ... )
|
||||
{
|
||||
char pcString[ 255 ];
|
||||
BaseType_t iCount;
|
||||
|
||||
va_list args;
|
||||
va_start (args, pcFormat);
|
||||
iCount = vsnprintf( pcString, sizeof pcString, pcFormat, args);
|
||||
va_end (args);
|
||||
fwrite( pcString, 1u, iCount, pxHandle );
|
||||
|
||||
return iCount;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vWriteHeaderFile( void )
|
||||
{
|
||||
FILE *outfile;
|
||||
|
||||
outfile = fopen( pcHeaderFileName, "w" );
|
||||
if( outfile != NULL )
|
||||
{
|
||||
fwrite( pcHeaderHeader, 1u, sizeof( pcHeaderHeader ) - 1u, outfile );
|
||||
_fprintf( outfile, "#define dumpPACKET_COUNT %lu\n\n",
|
||||
( uxNextPacketNumber < 1u ) ? 1u : uxNextPacketNumber );
|
||||
_fprintf( outfile, "extern DumpPacket_t *xPacketList[ dumpPACKET_COUNT ];\n\n" );
|
||||
_fprintf( outfile, "#endif PACKET_LIST_H\n" );
|
||||
|
||||
fclose ( outfile );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vAddType( uint32_t ulFlags, const char *pcFlagName )
|
||||
{
|
||||
size_t uxLength = strlen( pcTypeString );
|
||||
char pcString[ 64 ];
|
||||
BaseType_t iCount;
|
||||
|
||||
ulTypeMask |= ulFlags;
|
||||
|
||||
if( uxLength == 0 )
|
||||
{
|
||||
snprintf( pcTypeString, sizeof pcTypeString, "%s", pcFlagName );
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( pcTypeString + uxLength, sizeof pcTypeString - 1, " | %s", pcFlagName );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vAddProtocolTags( uint8_t *pucEthernetBuffer, BaseType_t xIPType )
|
||||
{
|
||||
ProtocolHeaders_t *pxProtocolHeaders;
|
||||
#if( ipconfigUSE_IPv6 != 0 )
|
||||
const IPHeader_IPv6_t * pxIPHeader_IPv6;
|
||||
#endif
|
||||
UBaseType_t uxHeaderLength;
|
||||
uint8_t ucProtocol;
|
||||
IPPacket_t * pxIPPacket;
|
||||
IPHeader_t * pxIPHeader;
|
||||
|
||||
pxIPPacket = ( IPPacket_t * ) pucEthernetBuffer;
|
||||
pxIPHeader = &( pxIPPacket->xIPHeader );
|
||||
#if( ipconfigUSE_IPv6 != 0 )
|
||||
pxIPHeader_IPv6 = ipPOINTER_CAST( const IPHeader_IPv6_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) );
|
||||
if( pxIPPacket->xEthernetHeader.usFrameType == ipIPv6_FRAME_TYPE )
|
||||
{
|
||||
uxHeaderLength = ipSIZE_OF_IPv6_HEADER;
|
||||
ucProtocol = pxIPHeader_IPv6->ucNextHeader;
|
||||
pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ] ) );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
size_t uxLength = ( size_t ) pxIPHeader->ucVersionHeaderLength;
|
||||
|
||||
/* Check if the IP headers are acceptable and if it has our destination.
|
||||
The lowest four bits of 'ucVersionHeaderLength' indicate the IP-header
|
||||
length in multiples of 4. */
|
||||
uxHeaderLength = ( size_t ) ( ( uxLength & 0x0Fu ) << 2 );
|
||||
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
|
||||
pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxHeaderLength ] ) );
|
||||
}
|
||||
|
||||
switch( ucProtocol )
|
||||
{
|
||||
case ipPROTOCOL_ICMP :
|
||||
ADD_TYPE( ICMP4 );
|
||||
break;
|
||||
|
||||
#if( ipconfigUSE_IPv6 != 0 )
|
||||
case ipPROTOCOL_ICMP_IPv6:
|
||||
ADD_TYPE( ICMP6 );
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ipPROTOCOL_UDP :
|
||||
{
|
||||
ADD_TYPE( UDP );
|
||||
usSourcePort = pxProtocolHeaders->xUDPHeader.usSourcePort;
|
||||
usDestinationPort = pxProtocolHeaders->xUDPHeader.usDestinationPort;
|
||||
if( usSourcePort == FreeRTOS_htons( dnsDNS_PORT) )
|
||||
{
|
||||
ADD_TYPE( DNS );
|
||||
ADD_TYPE( REPLY );
|
||||
}
|
||||
else if( usDestinationPort == FreeRTOS_htons( dnsDNS_PORT) )
|
||||
{
|
||||
ADD_TYPE( DNS );
|
||||
ADD_TYPE( REQUEST );
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if ipconfigUSE_TCP == 1
|
||||
case ipPROTOCOL_TCP :
|
||||
{
|
||||
ADD_TYPE( TCP );
|
||||
usSourcePort = pxProtocolHeaders->xTCPHeader.usSourcePort;
|
||||
usDestinationPort = pxProtocolHeaders->xTCPHeader.usDestinationPort;
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_SYN ) != 0u )
|
||||
{
|
||||
ADD_TYPE( SYN );
|
||||
}
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_FIN ) != 0u )
|
||||
{
|
||||
ADD_TYPE( FIN );
|
||||
}
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_RST ) != 0u )
|
||||
{
|
||||
ADD_TYPE( RST );
|
||||
}
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_ACK ) != 0u )
|
||||
{
|
||||
ADD_TYPE( ACK );
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vDetermineMessageType( uint8_t *pucBuffer, BaseType_t xIncoming )
|
||||
{
|
||||
EthernetHeader_t *pxEthernetHeader;
|
||||
|
||||
if( xIncoming != 0 )
|
||||
{
|
||||
ADD_TYPE( IN );
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_TYPE( OUT );
|
||||
}
|
||||
pxEthernetHeader = ( EthernetHeader_t * ) pucBuffer;
|
||||
|
||||
/* Interpret the received Ethernet packet. */
|
||||
switch( pxEthernetHeader->usFrameType )
|
||||
{
|
||||
case ipARP_FRAME_TYPE :
|
||||
{
|
||||
ARPPacket_t * pxARPFrame;
|
||||
ARPHeader_t *pxARPHeader;
|
||||
|
||||
/* The Ethernet frame contains an ARP packet. */
|
||||
ADD_TYPE( FRAME_ARP );
|
||||
pxARPFrame = ( ARPPacket_t * ) pucBuffer;
|
||||
pxARPHeader = &( pxARPFrame->xARPHeader );
|
||||
ADD_TYPE( ARP );
|
||||
switch( pxARPHeader->usOperation )
|
||||
{
|
||||
case ipARP_REQUEST:
|
||||
ADD_TYPE( REQUEST );
|
||||
break;
|
||||
case ipARP_REPLY:
|
||||
ADD_TYPE( REPLY );
|
||||
break;
|
||||
default:
|
||||
ADD_TYPE( UNKNOWN );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ipIPv4_FRAME_TYPE :
|
||||
{
|
||||
ADD_TYPE( FRAME_4 );
|
||||
vAddProtocolTags( pucBuffer, 4 );
|
||||
}
|
||||
break;
|
||||
|
||||
#if( ipconfigUSE_IPv6 != 0 )
|
||||
case ipIPv6_FRAME_TYPE :
|
||||
{
|
||||
ADD_TYPE( FRAME_6 );
|
||||
vAddProtocolTags( pucBuffer, 6 );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default :
|
||||
/* No other packet types are handled. Nothing to do. */
|
||||
ADD_TYPE( Unknown_FRAME );
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vActualDump( uint8_t *pucBuffer, size_t uxLength, BaseType_t xIncoming )
|
||||
{
|
||||
char pcString[ 513 ];
|
||||
size_t uxOffset;
|
||||
size_t uxIndex;
|
||||
size_t uxCompleteCount = 0;
|
||||
BaseType_t xUseIt = pdFALSE;
|
||||
|
||||
usSourcePort = 0u;
|
||||
usDestinationPort = 0u;
|
||||
pcTypeString[ 0 ] = 0;
|
||||
ulTypeMask = 0uL;
|
||||
|
||||
if( pxCurrentEntries == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vDetermineMessageType( pucBuffer, xIncoming );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxCurrentEntries->uxEntryCount; uxIndex++ )
|
||||
{
|
||||
if( pxCurrentEntries->xEntries[ uxIndex ].uxCount < pxCurrentEntries->xEntries[ uxIndex ].uxMax )
|
||||
{
|
||||
uint32_t ulMask = pxCurrentEntries->xEntries[ uxIndex ].ulMask;
|
||||
|
||||
if( ( ulMask & ulTypeMask ) == ulMask )
|
||||
{
|
||||
pxCurrentEntries->xEntries[ uxIndex ].uxCount++;
|
||||
xUseIt = pdTRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCompleteCount++;
|
||||
}
|
||||
}
|
||||
FreeRTOS_printf( ( "prvWritePackets: done %d/%d : (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
|
||||
uxCompleteCount,
|
||||
pxCurrentEntries->uxEntryCount,
|
||||
pxCurrentEntries->xEntries[ 0 ].uxCount, pxCurrentEntries->xEntries[ 0 ].uxMax,
|
||||
pxCurrentEntries->xEntries[ 1 ].uxCount, pxCurrentEntries->xEntries[ 1 ].uxMax,
|
||||
pxCurrentEntries->xEntries[ 2 ].uxCount, pxCurrentEntries->xEntries[ 2 ].uxMax,
|
||||
pxCurrentEntries->xEntries[ 3 ].uxCount, pxCurrentEntries->xEntries[ 3 ].uxMax ) );
|
||||
if( uxCompleteCount >= pxCurrentEntries->uxEntryCount )
|
||||
{
|
||||
FreeRTOS_printf( ( "prvWritePackets: all %lu packets have been collected\n", pxCurrentEntries->uxEntryCount ) );
|
||||
if( pxCurrentEntries != NULL )
|
||||
{
|
||||
FILE *outfile = fopen( pcCodeFileName, ( xFirstPacket != 0 ) ? "w" : "a+" );
|
||||
if ( outfile == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "Can not create '%s'\n", pcCodeFileName ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Create a list with pointers to each network packet.
|
||||
DumpPacket_t *xPacketList[ dumpPACKET_COUNT ] =
|
||||
{
|
||||
&xPacket_0000,
|
||||
&xPacket_0001,
|
||||
&xPacket_0002,
|
||||
&xPacket_0003,
|
||||
}
|
||||
*/
|
||||
_fprintf( outfile, "\nDumpPacket_t *xPacketList[ dumpPACKET_COUNT ] =\n{\n" );
|
||||
for( uxIndex = 0; uxIndex < uxNextPacketNumber; uxIndex++ )
|
||||
{
|
||||
_fprintf( outfile, "\t&xPacket_%04lu,\n", uxIndex );
|
||||
}
|
||||
_fprintf( outfile, "};\n" );
|
||||
fclose( outfile );
|
||||
vWriteHeaderFile();
|
||||
}
|
||||
pxCurrentEntries = NULL;
|
||||
/* Tell the thread and the function dump_packet() that packet
|
||||
dumping is ready. */
|
||||
xDumpingReady = pdTRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( xUseIt == pdFALSE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
printf("prvWritePackets: Read %lu bytes, type %s\n", uxLength, pcTypeString );
|
||||
|
||||
FILE *outfile = fopen( pcCodeFileName, ( xFirstPacket != 0 ) ? "w" : "a+" );
|
||||
if ( outfile == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "Can not create '%s'\n", pcCodeFileName ) );
|
||||
return;
|
||||
}
|
||||
if( xFirstPacket != 0 )
|
||||
{
|
||||
char *pcPtr;
|
||||
size_t xLength;
|
||||
|
||||
vWriteHeaderFile( pcHeaderFileName );
|
||||
xLength = snprintf( pcString, sizeof pcString, pcHeaderCode, pcHeaderFileName );
|
||||
fwrite( pcString, 1u, xLength, outfile );
|
||||
xFirstPacket = pdFALSE;
|
||||
}
|
||||
|
||||
_fprintf( outfile, "\n/* Packet_%04d */\n", uxNextPacketNumber );
|
||||
_fprintf( outfile, "uint8_t ucPacket_%04lx[ %lu ] =\n{\n", uxNextPacketNumber, uxLength );
|
||||
|
||||
for( uxOffset = 0u; uxOffset < uxLength; )
|
||||
{
|
||||
size_t uxCurLength = 0u;
|
||||
size_t uxLast = uxOffset + dumpBYTES_PER_ROW;
|
||||
BaseType_t xFirst = pdTRUE;
|
||||
|
||||
if( uxLast > uxLength )
|
||||
{
|
||||
uxLast = uxLength;
|
||||
}
|
||||
while( uxOffset < uxLast )
|
||||
{
|
||||
uxCurLength += snprintf( pcString + uxCurLength, sizeof pcString - uxCurLength, "%s0x%02x",
|
||||
( uxCurLength == 0 ) ? "\t" : ", ", pucBuffer[ uxOffset ] );
|
||||
uxOffset++;
|
||||
}
|
||||
if( uxCurLength != 0u )
|
||||
{
|
||||
uxCurLength += snprintf( pcString + uxCurLength, sizeof pcString - uxCurLength, "%s\n",
|
||||
( uxOffset == uxLength ) ? "\n};" : "," );
|
||||
fwrite( pcString, 1u, uxCurLength, outfile );
|
||||
}
|
||||
}
|
||||
|
||||
_fprintf( outfile, "\n");
|
||||
|
||||
_fprintf( outfile,
|
||||
"DumpPacket_t xPacket_%04lx =\n{\n"
|
||||
"\t.pucData = ucPacket_%04lx,\n"
|
||||
"\t.uxLength = %lu,\n"
|
||||
"\t.ulType = 0x%lX, /* %s */\n",
|
||||
uxNextPacketNumber, uxNextPacketNumber, uxLength, ulTypeMask, pcTypeString );
|
||||
|
||||
if( usSourcePort != 0u )
|
||||
{
|
||||
_fprintf( outfile,
|
||||
"\t.usSource = %u,\n", FreeRTOS_ntohs( usSourcePort ) );
|
||||
}
|
||||
if( usSourcePort != 0u )
|
||||
{
|
||||
_fprintf( outfile,
|
||||
"\t.usDestination = %u,\n", FreeRTOS_ntohs( usDestinationPort ) );
|
||||
}
|
||||
|
||||
_fprintf( outfile,
|
||||
"};\n"
|
||||
"/*-----------------------------------------------------------*/\n\n" );
|
||||
fclose( outfile );
|
||||
uxNextPacketNumber++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ( ipconfigUSE_DUMP_PACKETS != 0 ) */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue