mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2025-06-21 07:41:15 +08:00
MISRA compliance changes for FreeRTOS_TCP_IP.c (#160)
* MISRA tcp-ip changes * Changes after Hein's comments on original PR * Update FreeRTOS_TCP_IP.c Co-authored-by: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com>
This commit is contained in:

committed by
GitHub

parent
a457f43c66
commit
ae4d4d38d9
@ -703,7 +703,7 @@ BaseType_t xDoRelease = xReleaseAfterSend;
|
|||||||
EthernetHeader_t *pxEthernetHeader;
|
EthernetHeader_t *pxEthernetHeader;
|
||||||
uint32_t ulFrontSpace, ulSpace, ulSourceAddress, ulWinSize;
|
uint32_t ulFrontSpace, ulSpace, ulSourceAddress, ulWinSize;
|
||||||
const TCPWindow_t *pxTCPWindow;
|
const TCPWindow_t *pxTCPWindow;
|
||||||
NetworkBufferDescriptor_t *pxNetworkBuffer = pxDescriptor; /* To avoid error: "function parameter modified [MISRA 2012 Rule 17.8, advisory]" */
|
NetworkBufferDescriptor_t *pxNetworkBuffer = pxDescriptor;
|
||||||
NetworkBufferDescriptor_t xTempBuffer;
|
NetworkBufferDescriptor_t xTempBuffer;
|
||||||
/* For sending, a pseudo network buffer will be used, as explained above. */
|
/* For sending, a pseudo network buffer will be used, as explained above. */
|
||||||
|
|
||||||
@ -713,11 +713,11 @@ NetworkBufferDescriptor_t xTempBuffer;
|
|||||||
|
|
||||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||||
{
|
{
|
||||||
xTempBuffer.pxNextBuffer = NULL;
|
pxNetworkBuffer->pxNextBuffer = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
pxNetworkBuffer->pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
||||||
xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
|
pxNetworkBuffer->xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
|
||||||
xDoRelease = pdFALSE;
|
xDoRelease = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,6 +739,7 @@ NetworkBufferDescriptor_t xTempBuffer;
|
|||||||
if( pxNetworkBuffer != NULL )
|
if( pxNetworkBuffer != NULL )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto a TCPPacket_t struct for easy access to the fields. */
|
||||||
pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
|
pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
|
||||||
pxIPHeader = &pxTCPPacket->xIPHeader;
|
pxIPHeader = &pxTCPPacket->xIPHeader;
|
||||||
pxEthernetHeader = &pxTCPPacket->xEthernetHeader;
|
pxEthernetHeader = &pxTCPPacket->xEthernetHeader;
|
||||||
@ -1045,7 +1046,8 @@ uint32_t ulInitialSequenceNumber = 0;
|
|||||||
uint16_t usLength;
|
uint16_t usLength;
|
||||||
|
|
||||||
/* The MAC-address of the peer (or gateway) has been found,
|
/* The MAC-address of the peer (or gateway) has been found,
|
||||||
now prepare the initial TCP packet and some fields in the socket. */
|
* now prepare the initial TCP packet and some fields in the socket. Map
|
||||||
|
* the buffer onto the TCPPacket_t struct to easily access it's field. */
|
||||||
pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxSocket->u.xTCP.xPacket.u.ucLastPacket );
|
pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxSocket->u.xTCP.xPacket.u.ucLastPacket );
|
||||||
pxIPHeader = &pxTCPPacket->xIPHeader;
|
pxIPHeader = &pxTCPPacket->xIPHeader;
|
||||||
|
|
||||||
@ -1159,8 +1161,9 @@ uint8_t ucLength;
|
|||||||
if( pxTCPHeader->ucTCPOffset <= ( 5U << 4U ) )
|
if( pxTCPHeader->ucTCPOffset <= ( 5U << 4U ) )
|
||||||
{
|
{
|
||||||
/* Avoid integer underflow in computation of ucLength. */
|
/* Avoid integer underflow in computation of ucLength. */
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ucLength = ( ( ( pxTCPHeader->ucTCPOffset >> 4U ) - 5U ) << 2U );
|
ucLength = ( ( ( pxTCPHeader->ucTCPOffset >> 4U ) - 5U ) << 2U );
|
||||||
uxOptionsLength = ( size_t ) ucLength;
|
uxOptionsLength = ( size_t ) ucLength;
|
||||||
if( pxNetworkBuffer->xDataLength > uxOptionOffset )
|
if( pxNetworkBuffer->xDataLength > uxOptionOffset )
|
||||||
@ -1197,6 +1200,9 @@ uint8_t ucLength;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static size_t prvSingleStepTCPHeaderOptions( const uint8_t * const pucPtr,
|
static size_t prvSingleStepTCPHeaderOptions( const uint8_t * const pucPtr,
|
||||||
@ -1207,25 +1213,25 @@ static size_t prvSingleStepTCPHeaderOptions( const uint8_t * const pucPtr,
|
|||||||
UBaseType_t uxNewMSS;
|
UBaseType_t uxNewMSS;
|
||||||
size_t uxRemainingOptionsBytes = uxTotalLength;
|
size_t uxRemainingOptionsBytes = uxTotalLength;
|
||||||
uint8_t ucLen;
|
uint8_t ucLen;
|
||||||
size_t uxIndex = 0U;
|
size_t uxIndex;
|
||||||
TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
||||||
|
BaseType_t xReturn = pdFALSE;
|
||||||
|
|
||||||
if( pucPtr[ 0U ] == tcpTCP_OPT_END )
|
if( pucPtr[ 0U ] == tcpTCP_OPT_END )
|
||||||
{
|
{
|
||||||
/* End of options. */
|
/* End of options. */
|
||||||
return 0U;
|
uxIndex = 0U;
|
||||||
}
|
}
|
||||||
if( pucPtr[ 0U ] == tcpTCP_OPT_NOOP )
|
else if( pucPtr[ 0U ] == tcpTCP_OPT_NOOP )
|
||||||
{
|
{
|
||||||
/* NOP option, inserted to make the length a multiple of 4. */
|
/* NOP option, inserted to make the length a multiple of 4. */
|
||||||
return 1U;
|
uxIndex = 1U;
|
||||||
}
|
}
|
||||||
|
else if( uxRemainingOptionsBytes < 2U )
|
||||||
|
{
|
||||||
/* Any other well-formed option must be at least two bytes: the option
|
/* Any other well-formed option must be at least two bytes: the option
|
||||||
type byte followed by a length byte. */
|
type byte followed by a length byte. */
|
||||||
if( uxRemainingOptionsBytes < 2U )
|
uxIndex = 0U;
|
||||||
{
|
|
||||||
return 0U;
|
|
||||||
}
|
}
|
||||||
#if( ipconfigUSE_TCP_WIN != 0 )
|
#if( ipconfigUSE_TCP_WIN != 0 )
|
||||||
else if( pucPtr[ 0 ] == tcpTCP_OPT_WSOPT )
|
else if( pucPtr[ 0 ] == tcpTCP_OPT_WSOPT )
|
||||||
@ -1234,8 +1240,10 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
|||||||
/* Confirm that the option fits in the remaining buffer space. */
|
/* Confirm that the option fits in the remaining buffer space. */
|
||||||
if( ( uxRemainingOptionsBytes < tcpTCP_OPT_WSOPT_LEN ) || ( pucPtr[ 1 ] != tcpTCP_OPT_WSOPT_LEN ) )
|
if( ( uxRemainingOptionsBytes < tcpTCP_OPT_WSOPT_LEN ) || ( pucPtr[ 1 ] != tcpTCP_OPT_WSOPT_LEN ) )
|
||||||
{
|
{
|
||||||
return 0U;
|
uxIndex = 0U;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Option is only valid in SYN phase. */
|
/* Option is only valid in SYN phase. */
|
||||||
if( xHasSYNFlag != 0 )
|
if( xHasSYNFlag != 0 )
|
||||||
{
|
{
|
||||||
@ -1244,15 +1252,17 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
|||||||
}
|
}
|
||||||
uxIndex = tcpTCP_OPT_WSOPT_LEN;
|
uxIndex = tcpTCP_OPT_WSOPT_LEN;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* ipconfigUSE_TCP_WIN */
|
#endif /* ipconfigUSE_TCP_WIN */
|
||||||
else if( pucPtr[ 0 ] == tcpTCP_OPT_MSS )
|
else if( pucPtr[ 0 ] == tcpTCP_OPT_MSS )
|
||||||
{
|
{
|
||||||
/* Confirm that the option fits in the remaining buffer space. */
|
/* Confirm that the option fits in the remaining buffer space. */
|
||||||
if( ( uxRemainingOptionsBytes < tcpTCP_OPT_MSS_LEN ) || ( pucPtr[ 1 ] != tcpTCP_OPT_MSS_LEN ) )
|
if( ( uxRemainingOptionsBytes < tcpTCP_OPT_MSS_LEN ) || ( pucPtr[ 1 ] != tcpTCP_OPT_MSS_LEN ) )
|
||||||
{
|
{
|
||||||
return 0U;
|
uxIndex = 0U;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* An MSS option with the correct option length. FreeRTOS_htons()
|
/* An MSS option with the correct option length. FreeRTOS_htons()
|
||||||
is not needed here because usChar2u16() already returns a host
|
is not needed here because usChar2u16() already returns a host
|
||||||
endian number. */
|
endian number. */
|
||||||
@ -1263,12 +1273,20 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
|||||||
/* Perform a basic check on the the new MSS. */
|
/* Perform a basic check on the the new MSS. */
|
||||||
if( uxNewMSS == 0U )
|
if( uxNewMSS == 0U )
|
||||||
{
|
{
|
||||||
return 0U;
|
uxIndex = 0U;
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Return Condition found. */
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", pxSocket->u.xTCP.usInitMSS, uxNewMSS ) );
|
FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", pxSocket->u.xTCP.usInitMSS, uxNewMSS ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If a 'return' condition has not been found. */
|
||||||
|
if( xReturn == pdFALSE )
|
||||||
|
{
|
||||||
if( pxSocket->u.xTCP.usInitMSS > uxNewMSS )
|
if( pxSocket->u.xTCP.usInitMSS > uxNewMSS )
|
||||||
{
|
{
|
||||||
/* our MSS was bigger than the MSS of the other party: adapt it. */
|
/* our MSS was bigger than the MSS of the other party: adapt it. */
|
||||||
@ -1289,6 +1307,8 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
|||||||
|
|
||||||
uxIndex = tcpTCP_OPT_MSS_LEN;
|
uxIndex = tcpTCP_OPT_MSS_LEN;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* All other options have a length field, so that we easily
|
/* All other options have a length field, so that we easily
|
||||||
@ -1299,8 +1319,11 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
|||||||
/* If the length field is too small or too big, the options are
|
/* If the length field is too small or too big, the options are
|
||||||
* malformed, don't process them further.
|
* malformed, don't process them further.
|
||||||
*/
|
*/
|
||||||
return 0U;
|
uxIndex = 0U;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxIndex = 0U;
|
||||||
|
|
||||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||||
{
|
{
|
||||||
@ -1326,6 +1349,7 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
|||||||
|
|
||||||
uxIndex += ( size_t ) ucLen;
|
uxIndex += ( size_t ) ucLen;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return uxIndex;
|
return uxIndex;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -1660,14 +1684,14 @@ static NetworkBufferDescriptor_t *prvTCPBufferResize( const FreeRTOS_Socket_t *p
|
|||||||
int32_t lDataLen, UBaseType_t uxOptionsLength )
|
int32_t lDataLen, UBaseType_t uxOptionsLength )
|
||||||
{
|
{
|
||||||
NetworkBufferDescriptor_t *pxReturn;
|
NetworkBufferDescriptor_t *pxReturn;
|
||||||
int32_t lNeeded;
|
size_t uxNeeded;
|
||||||
BaseType_t xResize;
|
BaseType_t xResize;
|
||||||
|
|
||||||
if( xBufferAllocFixedSize != pdFALSE )
|
if( xBufferAllocFixedSize != pdFALSE )
|
||||||
{
|
{
|
||||||
/* Network buffers are created with a fixed size and can hold the largest
|
/* Network buffers are created with a fixed size and can hold the largest
|
||||||
MTU. */
|
MTU. */
|
||||||
lNeeded = ( int32_t ) ipTOTAL_ETHERNET_FRAME_SIZE;
|
uxNeeded = ( size_t ) ipTOTAL_ETHERNET_FRAME_SIZE;
|
||||||
/* and therefore, the buffer won't be too small.
|
/* and therefore, the buffer won't be too small.
|
||||||
Only ask for a new network buffer in case none was supplied. */
|
Only ask for a new network buffer in case none was supplied. */
|
||||||
if( pxNetworkBuffer == NULL )
|
if( pxNetworkBuffer == NULL )
|
||||||
@ -1683,11 +1707,16 @@ BaseType_t xResize;
|
|||||||
{
|
{
|
||||||
/* Network buffers are created with a variable size. See if it must
|
/* Network buffers are created with a variable size. See if it must
|
||||||
grow. */
|
grow. */
|
||||||
lNeeded = FreeRTOS_max_int32( ( int32_t ) sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ),
|
uxNeeded = ipNUMERIC_CAST( size_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen;
|
||||||
ipNUMERIC_CAST( int32_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen );
|
|
||||||
|
if( uxNeeded < sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) )
|
||||||
|
{
|
||||||
|
uxNeeded = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
|
||||||
|
}
|
||||||
|
|
||||||
/* In case we were called from a TCP timer event, a buffer must be
|
/* In case we were called from a TCP timer event, a buffer must be
|
||||||
created. Otherwise, test 'xDataLength' of the provided buffer. */
|
created. Otherwise, test 'xDataLength' of the provided buffer. */
|
||||||
if( ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded ) )
|
if( ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < uxNeeded ) )
|
||||||
{
|
{
|
||||||
xResize = pdTRUE;
|
xResize = pdTRUE;
|
||||||
}
|
}
|
||||||
@ -1702,12 +1731,12 @@ BaseType_t xResize;
|
|||||||
/* The caller didn't provide a network buffer or the provided buffer is
|
/* The caller didn't provide a network buffer or the provided buffer is
|
||||||
too small. As we must send-out a data packet, a buffer will be created
|
too small. As we must send-out a data packet, a buffer will be created
|
||||||
here. */
|
here. */
|
||||||
pxReturn = pxGetNetworkBufferWithDescriptor( ( uint32_t ) lNeeded, 0U );
|
pxReturn = pxGetNetworkBufferWithDescriptor( uxNeeded, 0U );
|
||||||
|
|
||||||
if( pxReturn != NULL )
|
if( pxReturn != NULL )
|
||||||
{
|
{
|
||||||
/* Set the actual packet size, in case the returned buffer is larger. */
|
/* Set the actual packet size, in case the returned buffer is larger. */
|
||||||
pxReturn->xDataLength = ( size_t ) lNeeded;
|
pxReturn->xDataLength = uxNeeded;
|
||||||
|
|
||||||
/* Copy the existing data to the new created buffer. */
|
/* Copy the existing data to the new created buffer. */
|
||||||
if( pxNetworkBuffer != NULL )
|
if( pxNetworkBuffer != NULL )
|
||||||
@ -1765,6 +1794,7 @@ int32_t lStreamPos;
|
|||||||
pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
||||||
pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
||||||
lDataLen = 0;
|
lDataLen = 0;
|
||||||
@ -1792,6 +1822,9 @@ int32_t lStreamPos;
|
|||||||
{
|
{
|
||||||
*ppxNetworkBuffer = pxNewBuffer;
|
*ppxNetworkBuffer = pxNewBuffer;
|
||||||
pucEthernetBuffer = pxNewBuffer->pucEthernetBuffer;
|
pucEthernetBuffer = pxNewBuffer->pucEthernetBuffer;
|
||||||
|
|
||||||
|
/* Map the byte stream onto ProtocolHeaders_t struct for easy
|
||||||
|
* access to the fields. */
|
||||||
pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
||||||
|
|
||||||
pucSendData = &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength ] );
|
pucSendData = &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength ] );
|
||||||
@ -2037,6 +2070,7 @@ int32_t lCount, lLength;
|
|||||||
*/
|
*/
|
||||||
static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer )
|
static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
||||||
TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader );
|
TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader );
|
||||||
@ -2133,10 +2167,13 @@ uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr );
|
|||||||
*/
|
*/
|
||||||
static BaseType_t prvCheckRxData( const NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData )
|
static BaseType_t prvCheckRxData( const NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData )
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ ( size_t ) ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
&( pxNetworkBuffer->pucEthernetBuffer[ ( size_t ) ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
||||||
const TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader );
|
const TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader );
|
||||||
int32_t lLength, lTCPHeaderLength, lReceiveLength, lUrgentLength;
|
int32_t lLength, lTCPHeaderLength, lReceiveLength, lUrgentLength;
|
||||||
|
|
||||||
|
/* Map the buffer onto an IPHeader_t struct for easy access to fields. */
|
||||||
const IPHeader_t *pxIPHeader = ipPOINTER_CAST( const IPHeader_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) );
|
const IPHeader_t *pxIPHeader = ipPOINTER_CAST( const IPHeader_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) );
|
||||||
const size_t xIPHeaderLength = ipSIZE_OF_IPv4_HEADER;
|
const size_t xIPHeaderLength = ipSIZE_OF_IPv4_HEADER;
|
||||||
uint16_t usLength;
|
uint16_t usLength;
|
||||||
@ -2205,6 +2242,7 @@ uint16_t usLength;
|
|||||||
static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, const uint8_t *pucRecvData,
|
static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, const uint8_t *pucRecvData,
|
||||||
NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength )
|
NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength )
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *,
|
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *,
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
||||||
const TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
const TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
||||||
@ -2282,6 +2320,7 @@ BaseType_t xResult = 0;
|
|||||||
/* Set the TCP options (if any) for the outgoing packet. */
|
/* Set the TCP options (if any) for the outgoing packet. */
|
||||||
static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer )
|
static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
||||||
TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
||||||
@ -2344,6 +2383,7 @@ UBaseType_t uxOptionsLength = pxTCPWindow->ucOptionLength;
|
|||||||
static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer,
|
static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer,
|
||||||
uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
|
uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
||||||
TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
||||||
@ -2353,19 +2393,21 @@ uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber );
|
|||||||
BaseType_t xSendLength = 0;
|
BaseType_t xSendLength = 0;
|
||||||
|
|
||||||
/* Either expect a ACK or a SYN+ACK. */
|
/* Either expect a ACK or a SYN+ACK. */
|
||||||
uint16_t usExpect = ( uint16_t ) tcpTCP_FLAG_ACK;
|
uint8_t ucExpect = tcpTCP_FLAG_ACK;
|
||||||
if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN )
|
if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN )
|
||||||
{
|
{
|
||||||
usExpect |= ( uint16_t ) tcpTCP_FLAG_SYN;
|
ucExpect |= tcpTCP_FLAG_SYN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ipNUMERIC_CAST( uint16_t, ucTCPFlags & 0x17U ) != usExpect )
|
const uint8_t ucFlagsMask = tcpTCP_FLAG_ACK | tcpTCP_FLAG_RST | tcpTCP_FLAG_SYN | tcpTCP_FLAG_FIN;
|
||||||
|
|
||||||
|
if( ( ucTCPFlags & ucFlagsMask ) != ucExpect )
|
||||||
{
|
{
|
||||||
/* eSYN_RECEIVED: flags 0010 expected, not 0002. */
|
/* eSYN_RECEIVED: flags 0010 expected, not 0002. */
|
||||||
/* eSYN_RECEIVED: flags ACK expected, not SYN. */
|
/* eSYN_RECEIVED: flags ACK expected, not SYN. */
|
||||||
FreeRTOS_debug_printf( ( "%s: flags %04X expected, not %04X\n",
|
FreeRTOS_debug_printf( ( "%s: flags %04X expected, not %04X\n",
|
||||||
( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eSYN_RECEIVED ) ? "eSYN_RECEIVED" : "eCONNECT_SYN",
|
( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eSYN_RECEIVED ) ? "eSYN_RECEIVED" : "eCONNECT_SYN",
|
||||||
usExpect, ucTCPFlags ) );
|
ucExpect, ucTCPFlags ) );
|
||||||
vTCPStateChange( pxSocket, eCLOSE_WAIT );
|
vTCPStateChange( pxSocket, eCLOSE_WAIT );
|
||||||
/* Send RST with the expected sequence and ACK numbers,
|
/* Send RST with the expected sequence and ACK numbers,
|
||||||
otherwise the packet will be ignored. */
|
otherwise the packet will be ignored. */
|
||||||
@ -2383,6 +2425,7 @@ BaseType_t xSendLength = 0;
|
|||||||
|
|
||||||
if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN )
|
if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN )
|
||||||
{
|
{
|
||||||
|
/* Map the Last packet onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
ProtocolHeaders_t *pxLastHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
ProtocolHeaders_t *pxLastHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
&( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
||||||
|
|
||||||
@ -2460,6 +2503,7 @@ BaseType_t xSendLength = 0;
|
|||||||
static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
|
static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
|
||||||
uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
|
uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
|
||||||
{
|
{
|
||||||
|
/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
&( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) );
|
||||||
TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
||||||
@ -2623,6 +2667,7 @@ uint16_t usWindow;
|
|||||||
static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
|
static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
|
||||||
uint32_t ulReceiveLength, BaseType_t xByteCount )
|
uint32_t ulReceiveLength, BaseType_t xByteCount )
|
||||||
{
|
{
|
||||||
|
/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( *ppxNetworkBuffer ) ] ) );
|
&( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( *ppxNetworkBuffer ) ] ) );
|
||||||
const TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
const TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
|
||||||
@ -2767,6 +2812,7 @@ BaseType_t xSendLength = xByteCount;
|
|||||||
*/
|
*/
|
||||||
static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
|
static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
|
||||||
{
|
{
|
||||||
|
/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */
|
||||||
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *,
|
||||||
&( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( *ppxNetworkBuffer ) ] ) );
|
&( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( *ppxNetworkBuffer ) ] ) );
|
||||||
TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader );
|
TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader );
|
||||||
@ -2951,14 +2997,15 @@ static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNe
|
|||||||
( void ) ucTCPFlags;
|
( void ) ucTCPFlags;
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto the TCPPacket_t struct for easy access to the fields. */
|
||||||
TCPPacket_t *pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
|
TCPPacket_t *pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
|
||||||
const BaseType_t xSendLength = ( BaseType_t )
|
const uint32_t ulSendLength = ( uint32_t )
|
||||||
( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ); /* Plus 0 options. */
|
( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ); /* Plus 0 options. */
|
||||||
|
|
||||||
pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
|
pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
|
||||||
pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER ) << 2;
|
pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER ) << 2;
|
||||||
|
|
||||||
prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
|
prvTCPReturnPacket( NULL, pxNetworkBuffer, ulSendLength, pdFALSE );
|
||||||
}
|
}
|
||||||
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
|
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
|
||||||
|
|
||||||
@ -3013,6 +3060,8 @@ BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxDescriptor )
|
|||||||
{
|
{
|
||||||
/* Function might modify the parameter. */
|
/* Function might modify the parameter. */
|
||||||
NetworkBufferDescriptor_t *pxNetworkBuffer = pxDescriptor;
|
NetworkBufferDescriptor_t *pxNetworkBuffer = pxDescriptor;
|
||||||
|
|
||||||
|
/* Map the buffer onto a ProtocolHeaders_t struct for easy access to the fields. */
|
||||||
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *,
|
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *,
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
||||||
FreeRTOS_Socket_t *pxSocket;
|
FreeRTOS_Socket_t *pxSocket;
|
||||||
@ -3031,9 +3080,11 @@ const IPHeader_t *pxIPHeader;
|
|||||||
/* Check for a minimum packet size. */
|
/* Check for a minimum packet size. */
|
||||||
if( pxNetworkBuffer->xDataLength < ( ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) + ipSIZE_OF_TCP_HEADER ) )
|
if( pxNetworkBuffer->xDataLength < ( ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) + ipSIZE_OF_TCP_HEADER ) )
|
||||||
{
|
{
|
||||||
return pdFAIL;
|
xResult = pdFAIL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Map the ethernet buffer onto the IPHeader_t struct for easy access to the fields. */
|
||||||
pxIPHeader = ipPOINTER_CAST( const IPHeader_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) );
|
pxIPHeader = ipPOINTER_CAST( const IPHeader_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) );
|
||||||
ulLocalIP = FreeRTOS_htonl( pxIPHeader->ulDestinationIPAddress );
|
ulLocalIP = FreeRTOS_htonl( pxIPHeader->ulDestinationIPAddress );
|
||||||
ulRemoteIP = FreeRTOS_htonl( pxIPHeader->ulSourceIPAddress );
|
ulRemoteIP = FreeRTOS_htonl( pxIPHeader->ulSourceIPAddress );
|
||||||
@ -3160,7 +3211,7 @@ const IPHeader_t *pxIPHeader;
|
|||||||
/* Update the copy of the TCP header only (skipping eth and IP
|
/* Update the copy of the TCP header only (skipping eth and IP
|
||||||
headers). It might be used later on, whenever data must be sent
|
headers). It might be used later on, whenever data must be sent
|
||||||
to the peer. */
|
to the peer. */
|
||||||
const BaseType_t lOffset = ipNUMERIC_CAST( BaseType_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) );
|
const size_t lOffset = ipNUMERIC_CAST( size_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) );
|
||||||
( void ) memcpy( &( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ lOffset ] ),
|
( void ) memcpy( &( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ lOffset ] ),
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ lOffset ] ),
|
&( pxNetworkBuffer->pucEthernetBuffer[ lOffset ] ),
|
||||||
ipSIZE_OF_TCP_HEADER );
|
ipSIZE_OF_TCP_HEADER );
|
||||||
@ -3233,7 +3284,7 @@ const IPHeader_t *pxIPHeader;
|
|||||||
/* Return pdPASS to tell that the network buffer is 'consumed'. */
|
/* Return pdPASS to tell that the network buffer is 'consumed'. */
|
||||||
xResult = pdPASS;
|
xResult = pdPASS;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* pdPASS being returned means the buffer has been consumed. */
|
/* pdPASS being returned means the buffer has been consumed. */
|
||||||
return xResult;
|
return xResult;
|
||||||
}
|
}
|
||||||
@ -3241,6 +3292,7 @@ const IPHeader_t *pxIPHeader;
|
|||||||
|
|
||||||
static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
|
static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||||
{
|
{
|
||||||
|
/* Map the ethernet buffer onto a TCPPacket_t struct for easy access to the fields. */
|
||||||
const TCPPacket_t * pxTCPPacket = ipPOINTER_CAST( const TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
|
const TCPPacket_t * pxTCPPacket = ipPOINTER_CAST( const TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
|
||||||
FreeRTOS_Socket_t *pxReturn = NULL;
|
FreeRTOS_Socket_t *pxReturn = NULL;
|
||||||
uint32_t ulInitialSequenceNumber;
|
uint32_t ulInitialSequenceNumber;
|
||||||
@ -3307,6 +3359,7 @@ uint32_t ulInitialSequenceNumber;
|
|||||||
|
|
||||||
if( ( ulInitialSequenceNumber != 0U ) && ( pxReturn != NULL ) )
|
if( ( ulInitialSequenceNumber != 0U ) && ( pxReturn != NULL ) )
|
||||||
{
|
{
|
||||||
|
/* Map the byte stream onto the ProtocolHeaders_t for easy access to the fields. */
|
||||||
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *,
|
const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *,
|
||||||
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) );
|
||||||
|
|
||||||
|
@ -401,6 +401,7 @@ socket events. */
|
|||||||
(right) = tmp; \
|
(right) = tmp; \
|
||||||
} while ( ipFALSE_BOOL )
|
} while ( ipFALSE_BOOL )
|
||||||
|
|
||||||
|
/* WARNING: Do NOT use this macro when the array was received as a parameter. */
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
#define ARRAY_SIZE(x) ( ( BaseType_t ) ( sizeof( x ) / sizeof( ( x )[ 0 ] ) ) )
|
#define ARRAY_SIZE(x) ( ( BaseType_t ) ( sizeof( x ) / sizeof( ( x )[ 0 ] ) ) )
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user