mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2025-06-27 12:33:04 +08:00
Fix some build issues in older kernel demo projects.
Update to V2.0.7 of the TCP/IP stack: + Multiple security improvements and fixes in packet parsing routines, DNS caching, and TCP sequence number and ID generation. + Disable NBNS and LLMNR by default. + Add TCP hang protection by default. We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -211,7 +211,10 @@ uint32_t ulTargetProtocolAddress, ulSenderProtocolAddress;
|
||||
|
||||
void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress )
|
||||
{
|
||||
BaseType_t x, xIpEntry = -1, xMacEntry = -1, xUseEntry = 0;
|
||||
BaseType_t x = 0;
|
||||
BaseType_t xIpEntry = -1;
|
||||
BaseType_t xMacEntry = -1;
|
||||
BaseType_t xUseEntry = 0;
|
||||
uint8_t ucMinAgeFound = 0U;
|
||||
|
||||
#if( ipconfigARP_STORES_REMOTE_ADDRESSES == 0 )
|
||||
@ -599,7 +602,7 @@ ARPPacket_t *pxARPPacket;
|
||||
xARPHeader.usOperation;
|
||||
xARPHeader.xTargetHardwareAddress;
|
||||
*/
|
||||
memcpy( ( void * ) &( pxARPPacket->xEthernetHeader ), ( void * ) xDefaultPartARPPacketHeader, sizeof( xDefaultPartARPPacketHeader ) );
|
||||
memcpy( ( void * ) pxARPPacket, ( void * ) xDefaultPartARPPacketHeader, sizeof( xDefaultPartARPPacketHeader ) );
|
||||
memcpy( ( void * ) pxARPPacket->xEthernetHeader.xSourceAddress.ucBytes , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
memcpy( ( void * ) pxARPPacket->xARPHeader.xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -63,17 +63,17 @@
|
||||
#endif
|
||||
|
||||
/* Codes of interest found in the DHCP options field. */
|
||||
#define dhcpIPv4_ZERO_PAD_OPTION_CODE ( 0u )
|
||||
#define dhcpIPv4_SUBNET_MASK_OPTION_CODE ( 1u )
|
||||
#define dhcpIPv4_GATEWAY_OPTION_CODE ( 3u )
|
||||
#define dhcpIPv4_DNS_SERVER_OPTIONS_CODE ( 6u )
|
||||
#define dhcpIPv4_DNS_HOSTNAME_OPTIONS_CODE ( 12u )
|
||||
#define dhcpIPv4_REQUEST_IP_ADDRESS_OPTION_CODE ( 50u )
|
||||
#define dhcpIPv4_LEASE_TIME_OPTION_CODE ( 51u )
|
||||
#define dhcpIPv4_MESSAGE_TYPE_OPTION_CODE ( 53u )
|
||||
#define dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE ( 54u )
|
||||
#define dhcpIPv4_PARAMETER_REQUEST_OPTION_CODE ( 55u )
|
||||
#define dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE ( 61u )
|
||||
#define dhcpZERO_PAD_OPTION_CODE ( 0u )
|
||||
#define dhcpSUBNET_MASK_OPTION_CODE ( 1u )
|
||||
#define dhcpGATEWAY_OPTION_CODE ( 3u )
|
||||
#define dhcpDNS_SERVER_OPTIONS_CODE ( 6u )
|
||||
#define dhcpDNS_HOSTNAME_OPTIONS_CODE ( 12u )
|
||||
#define dhcpREQUEST_IP_ADDRESS_OPTION_CODE ( 50u )
|
||||
#define dhcpLEASE_TIME_OPTION_CODE ( 51u )
|
||||
#define dhcpMESSAGE_TYPE_OPTION_CODE ( 53u )
|
||||
#define dhcpSERVER_IP_ADDRESS_OPTION_CODE ( 54u )
|
||||
#define dhcpPARAMETER_REQUEST_OPTION_CODE ( 55u )
|
||||
#define dhcpCLIENT_IDENTIFIER_OPTION_CODE ( 61u )
|
||||
|
||||
/* The four DHCP message types of interest. */
|
||||
#define dhcpMESSAGE_TYPE_DISCOVER ( 1 )
|
||||
@ -113,9 +113,7 @@ to ensure the walk has not gone past the end of the valid options. 2 bytes is
|
||||
made up of the length byte, and minimum one byte value. */
|
||||
#define dhcpMAX_OPTION_LENGTH_OF_INTEREST ( 2L )
|
||||
|
||||
/* Standard DHCP port numbers and magic cookie value.
|
||||
DHCPv4 uses UDP port number 68 for clients and port number 67 for servers.
|
||||
*/
|
||||
/* Standard DHCP port numbers and magic cookie value. */
|
||||
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
||||
#define dhcpCLIENT_PORT 0x4400u
|
||||
#define dhcpSERVER_PORT 0x4300u
|
||||
@ -361,11 +359,19 @@ BaseType_t xGivingUp = pdFALSE;
|
||||
|
||||
if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
|
||||
{
|
||||
xDHCPData.ulTransactionId++;
|
||||
xDHCPData.xDHCPTxTime = xTaskGetTickCount();
|
||||
xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;
|
||||
prvSendDHCPDiscover( );
|
||||
FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );
|
||||
xDHCPData.ulTransactionId = ipconfigRAND32( );
|
||||
|
||||
if( 0 != xDHCPData.ulTransactionId )
|
||||
{
|
||||
xDHCPData.xDHCPTxTime = xTaskGetTickCount( );
|
||||
xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;
|
||||
prvSendDHCPDiscover( );
|
||||
FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_debug_printf( ( "vDHCPProcess: failed to generate a random Transaction ID\n" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -517,7 +523,7 @@ BaseType_t xGivingUp = pdFALSE;
|
||||
{
|
||||
/* xGivingUp became true either because of a time-out, or because
|
||||
xApplicationDHCPHook() returned another value than 'eDHCPContinue',
|
||||
meaning that the conversion is cancelled from here. */
|
||||
meaning that the conversion is canceled from here. */
|
||||
|
||||
/* Revert to static IP address. */
|
||||
taskENTER_CRITICAL();
|
||||
@ -585,29 +591,24 @@ TickType_t xTimeoutTime = ( TickType_t ) 0;
|
||||
|
||||
static void prvInitialiseDHCP( void )
|
||||
{
|
||||
/* Initialise the parameters that will be set by the DHCP process. */
|
||||
if( xDHCPData.ulTransactionId == 0ul )
|
||||
{
|
||||
xDHCPData.ulTransactionId = ipconfigRAND32();
|
||||
}
|
||||
else
|
||||
{
|
||||
xDHCPData.ulTransactionId++;
|
||||
}
|
||||
/* Initialise the parameters that will be set by the DHCP process. Per
|
||||
https://www.ietf.org/rfc/rfc2131.txt, Transaction ID should be a random
|
||||
value chosen by the client. */
|
||||
xDHCPData.ulTransactionId = ipconfigRAND32();
|
||||
|
||||
/* Check for random number generator API failure. */
|
||||
if( 0 != xDHCPData.ulTransactionId )
|
||||
{
|
||||
xDHCPData.xUseBroadcast = 0;
|
||||
xDHCPData.ulOfferedIPAddress = 0UL;
|
||||
xDHCPData.ulDHCPServerAddress = 0UL;
|
||||
xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
|
||||
/* Check for random number generator API failure. */
|
||||
if( 0 != xDHCPData.ulTransactionId )
|
||||
{
|
||||
xDHCPData.xUseBroadcast = 0;
|
||||
xDHCPData.ulOfferedIPAddress = 0UL;
|
||||
xDHCPData.ulDHCPServerAddress = 0UL;
|
||||
xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
|
||||
|
||||
/* Create the DHCP socket if it has not already been created. */
|
||||
prvCreateDHCPSocket();
|
||||
FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
|
||||
vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
|
||||
}
|
||||
/* Create the DHCP socket if it has not already been created. */
|
||||
prvCreateDHCPSocket();
|
||||
FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
|
||||
vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@ -631,11 +632,14 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
pxDHCPMessage = ( DHCPMessage_t * ) ( pucUDPPayload );
|
||||
|
||||
/* Sanity check. */
|
||||
if( ( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&
|
||||
if( ( lBytes >= sizeof( DHCPMessage_t ) ) &&
|
||||
( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&
|
||||
( pxDHCPMessage->ucOpcode == ( uint8_t ) dhcpREPLY_OPCODE ) &&
|
||||
( pxDHCPMessage->ulTransactionID == FreeRTOS_htonl( xDHCPData.ulTransactionId ) ) )
|
||||
{
|
||||
if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ), ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ) == 0 )
|
||||
if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ),
|
||||
( void * ) ipLOCAL_MAC_ADDRESS,
|
||||
sizeof( MACAddress_t ) ) == 0 )
|
||||
{
|
||||
/* None of the essential options have been processed yet. */
|
||||
ulProcessed = 0ul;
|
||||
@ -648,28 +652,52 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
while( pucByte < pucLastByte )
|
||||
{
|
||||
ucOptionCode = pucByte[ 0 ];
|
||||
if( ucOptionCode == ( uint8_t ) dhcpOPTION_END_BYTE )
|
||||
if( ucOptionCode == dhcpOPTION_END_BYTE )
|
||||
{
|
||||
/* Ready, the last byte has been seen. */
|
||||
break;
|
||||
}
|
||||
if( ucOptionCode == ( uint8_t ) dhcpIPv4_ZERO_PAD_OPTION_CODE )
|
||||
if( ucOptionCode == dhcpZERO_PAD_OPTION_CODE )
|
||||
{
|
||||
/* The value zero is used as a pad byte,
|
||||
it is not followed by a length byte. */
|
||||
pucByte += 1;
|
||||
continue;
|
||||
}
|
||||
ucLength = pucByte[ 1 ];
|
||||
pucByte += 2;
|
||||
|
||||
/* Stop if the response is malformed. */
|
||||
if( pucByte < pucLastByte - 1 )
|
||||
{
|
||||
ucLength = pucByte[ 1 ];
|
||||
pucByte += 2;
|
||||
|
||||
if( pucByte >= pucLastByte - ucLength )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* In most cases, a 4-byte network-endian parameter follows,
|
||||
just get it once here and use later */
|
||||
memcpy( ( void * ) &( ulParameter ), ( void * ) pucByte, ( size_t ) sizeof( ulParameter ) );
|
||||
just get it once here and use later. */
|
||||
if( ucLength >= sizeof( ulParameter ) )
|
||||
{
|
||||
memcpy( ( void * ) &( ulParameter ),
|
||||
( void * ) pucByte,
|
||||
( size_t ) sizeof( ulParameter ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ulParameter = 0;
|
||||
}
|
||||
|
||||
/* Option-specific handling. */
|
||||
switch( ucOptionCode )
|
||||
{
|
||||
case dhcpIPv4_MESSAGE_TYPE_OPTION_CODE :
|
||||
case dhcpMESSAGE_TYPE_OPTION_CODE :
|
||||
|
||||
if( *pucByte == ( uint8_t ) xExpectedMessageType )
|
||||
{
|
||||
@ -691,7 +719,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
}
|
||||
break;
|
||||
|
||||
case dhcpIPv4_SUBNET_MASK_OPTION_CODE :
|
||||
case dhcpSUBNET_MASK_OPTION_CODE :
|
||||
|
||||
if( ucLength == sizeof( uint32_t ) )
|
||||
{
|
||||
@ -699,9 +727,9 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
}
|
||||
break;
|
||||
|
||||
case dhcpIPv4_GATEWAY_OPTION_CODE :
|
||||
/* The DHCP server may send more than 1 gateway addresses. */
|
||||
if( ucLength >= sizeof( uint32_t ) )
|
||||
case dhcpGATEWAY_OPTION_CODE :
|
||||
|
||||
if( ucLength == sizeof( uint32_t ) )
|
||||
{
|
||||
/* ulProcessed is not incremented in this case
|
||||
because the gateway is not essential. */
|
||||
@ -709,7 +737,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
}
|
||||
break;
|
||||
|
||||
case dhcpIPv4_DNS_SERVER_OPTIONS_CODE :
|
||||
case dhcpDNS_SERVER_OPTIONS_CODE :
|
||||
|
||||
/* ulProcessed is not incremented in this case
|
||||
because the DNS server is not essential. Only the
|
||||
@ -717,7 +745,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
xNetworkAddressing.ulDNSServerAddress = ulParameter;
|
||||
break;
|
||||
|
||||
case dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE :
|
||||
case dhcpSERVER_IP_ADDRESS_OPTION_CODE :
|
||||
|
||||
if( ucLength == sizeof( uint32_t ) )
|
||||
{
|
||||
@ -738,7 +766,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
}
|
||||
break;
|
||||
|
||||
case dhcpIPv4_LEASE_TIME_OPTION_CODE :
|
||||
case dhcpLEASE_TIME_OPTION_CODE :
|
||||
|
||||
if( ucLength == sizeof( xDHCPData.ulLeaseTime ) )
|
||||
{
|
||||
@ -789,7 +817,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||
}
|
||||
|
||||
FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );
|
||||
} /* if( lBytes > 0 ) */
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
@ -825,9 +853,6 @@ uint8_t *pucUDPPayloadBuffer;
|
||||
pxDHCPMessage->ucOpcode = ( uint8_t ) xOpcode;
|
||||
pxDHCPMessage->ucAddressType = ( uint8_t ) dhcpADDRESS_TYPE_ETHERNET;
|
||||
pxDHCPMessage->ucAddressLength = ( uint8_t ) dhcpETHERNET_ADDRESS_LENGTH;
|
||||
|
||||
/* ulTransactionID doesn't really need a htonl() translation, but when DHCP
|
||||
times out, it is nicer to see an increasing number in this ID field */
|
||||
pxDHCPMessage->ulTransactionID = FreeRTOS_htonl( xDHCPData.ulTransactionId );
|
||||
pxDHCPMessage->ulDHCPCookie = ( uint32_t ) dhcpCOOKIE;
|
||||
if( xDHCPData.xUseBroadcast != pdFALSE )
|
||||
@ -851,7 +876,7 @@ uint8_t *pucUDPPayloadBuffer;
|
||||
|
||||
/* Point to where the OPTION_END was stored to add data. */
|
||||
pucPtr = &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + ( *pxOptionsArraySize - 1 ) ] );
|
||||
pucPtr[ 0 ] = dhcpIPv4_DNS_HOSTNAME_OPTIONS_CODE;
|
||||
pucPtr[ 0 ] = dhcpDNS_HOSTNAME_OPTIONS_CODE;
|
||||
pucPtr[ 1 ] = ( uint8_t ) xNameLength;
|
||||
memcpy( ( void *) ( pucPtr + 2 ), pucHostName, xNameLength );
|
||||
pucPtr[ 2 + xNameLength ] = dhcpOPTION_END_BYTE;
|
||||
@ -880,15 +905,15 @@ static const uint8_t ucDHCPRequestOptions[] =
|
||||
/* Do not change the ordering without also changing
|
||||
dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and
|
||||
dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */
|
||||
dhcpIPv4_MESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
|
||||
dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
|
||||
dhcpIPv4_REQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
|
||||
dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
|
||||
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
|
||||
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
|
||||
dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
|
||||
dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
|
||||
dhcpOPTION_END_BYTE
|
||||
};
|
||||
size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
|
||||
|
||||
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, ( uint8_t ) dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );
|
||||
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );
|
||||
|
||||
/* Copy in the IP address being requested. */
|
||||
memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpREQUESTED_IP_ADDRESS_OFFSET ] ),
|
||||
@ -917,14 +942,14 @@ struct freertos_sockaddr xAddress;
|
||||
static const uint8_t ucDHCPDiscoverOptions[] =
|
||||
{
|
||||
/* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */
|
||||
dhcpIPv4_MESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
|
||||
dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
|
||||
dhcpIPv4_PARAMETER_REQUEST_OPTION_CODE, 3, dhcpIPv4_SUBNET_MASK_OPTION_CODE, dhcpIPv4_GATEWAY_OPTION_CODE, dhcpIPv4_DNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
|
||||
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
|
||||
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
|
||||
dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, dhcpDNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
|
||||
dhcpOPTION_END_BYTE
|
||||
};
|
||||
size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
|
||||
|
||||
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, ( uint8_t ) dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );
|
||||
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );
|
||||
|
||||
FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
|
||||
iptraceSENDING_DHCP_DISCOVER();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -47,17 +47,17 @@
|
||||
#if( ipconfigUSE_DNS != 0 )
|
||||
|
||||
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
||||
#define dnsDNS_PORT 0x3500u
|
||||
#define dnsONE_QUESTION 0x0100u
|
||||
#define dnsOUTGOING_FLAGS 0x0001u /* Standard query. */
|
||||
#define dnsRX_FLAGS_MASK 0x0f80u /* The bits of interest in the flags field of incoming DNS messages. */
|
||||
#define dnsEXPECTED_RX_FLAGS 0x0080u /* Should be a response, without any errors. */
|
||||
#define dnsDNS_PORT 0x3500
|
||||
#define dnsONE_QUESTION 0x0100
|
||||
#define dnsOUTGOING_FLAGS 0x0001 /* Standard query. */
|
||||
#define dnsRX_FLAGS_MASK 0x0f80 /* The bits of interest in the flags field of incoming DNS messages. */
|
||||
#define dnsEXPECTED_RX_FLAGS 0x0080 /* Should be a response, without any errors. */
|
||||
#else
|
||||
#define dnsDNS_PORT 0x0035u
|
||||
#define dnsONE_QUESTION 0x0001u
|
||||
#define dnsOUTGOING_FLAGS 0x0100u /* Standard query. */
|
||||
#define dnsRX_FLAGS_MASK 0x800fu /* The bits of interest in the flags field of incoming DNS messages. */
|
||||
#define dnsEXPECTED_RX_FLAGS 0x8000u /* Should be a response, without any errors. */
|
||||
#define dnsDNS_PORT 0x0035
|
||||
#define dnsONE_QUESTION 0x0001
|
||||
#define dnsOUTGOING_FLAGS 0x0100 /* Standard query. */
|
||||
#define dnsRX_FLAGS_MASK 0x800f /* The bits of interest in the flags field of incoming DNS messages. */
|
||||
#define dnsEXPECTED_RX_FLAGS 0x8000 /* Should be a response, without any errors. */
|
||||
|
||||
#endif /* ipconfigBYTE_ORDER */
|
||||
|
||||
@ -72,29 +72,33 @@ name field is an offset to the string, rather than the string itself. */
|
||||
#define dnsNAME_IS_OFFSET ( ( uint8_t ) 0xc0 )
|
||||
|
||||
/* NBNS flags. */
|
||||
#define dnsNBNS_FLAGS_RESPONSE 0x8000u
|
||||
#define dnsNBNS_FLAGS_OPCODE_MASK 0x7800u
|
||||
#define dnsNBNS_FLAGS_OPCODE_QUERY 0x0000u
|
||||
#define dnsNBNS_FLAGS_OPCODE_REGISTRATION 0x2800u
|
||||
#define dnsNBNS_FLAGS_RESPONSE 0x8000
|
||||
#define dnsNBNS_FLAGS_OPCODE_MASK 0x7800
|
||||
#define dnsNBNS_FLAGS_OPCODE_QUERY 0x0000
|
||||
#define dnsNBNS_FLAGS_OPCODE_REGISTRATION 0x2800
|
||||
|
||||
/* Host types. */
|
||||
#define dnsTYPE_A_HOST 0x0001u
|
||||
#define dnsCLASS_IN 0x0001u
|
||||
#define dnsTYPE_A_HOST 0x01
|
||||
#define dnsCLASS_IN 0x01
|
||||
|
||||
/* LLMNR constants. */
|
||||
#define dnsLLMNR_TTL_VALUE 300000u
|
||||
#define dnsLLMNR_FLAGS_IS_REPONSE 0x8000u
|
||||
#define dnsLLMNR_TTL_VALUE 300000
|
||||
#define dnsLLMNR_FLAGS_IS_REPONSE 0x8000
|
||||
|
||||
/* NBNS constants. */
|
||||
#define dnsNBNS_TTL_VALUE 3600u /* 1 hour valid */
|
||||
#define dnsNBNS_TYPE_NET_BIOS 0x0020u
|
||||
#define dnsNBNS_CLASS_IN 0x0001u
|
||||
#define dnsNBNS_NAME_FLAGS 0x6000u
|
||||
#define dnsNBNS_TTL_VALUE 3600 /* 1 hour valid */
|
||||
#define dnsNBNS_TYPE_NET_BIOS 0x0020
|
||||
#define dnsNBNS_CLASS_IN 0x01
|
||||
#define dnsNBNS_NAME_FLAGS 0x6000
|
||||
#define dnsNBNS_ENCODED_NAME_LENGTH 32
|
||||
|
||||
/* If the queried NBNS name matches with the device's name,
|
||||
the query will be responded to with these flags: */
|
||||
#define dnsNBNS_QUERY_RESPONSE_FLAGS 0x8500u
|
||||
#define dnsNBNS_QUERY_RESPONSE_FLAGS ( 0x8500 )
|
||||
|
||||
/* Flag DNS parsing errors in situations where an IPv4 address is the return
|
||||
type. */
|
||||
#define dnsPARSE_ERROR 0UL
|
||||
|
||||
/*
|
||||
* Create a socket and bind it to the standard DNS port number. Return the
|
||||
@ -110,12 +114,12 @@ static size_t prvCreateDNSMessage( uint8_t *pucUDPPayloadBuffer, const char *pcH
|
||||
/*
|
||||
* Simple routine that jumps over the NAME field of a resource record.
|
||||
*/
|
||||
static uint8_t *prvSkipNameField( uint8_t *pucByte );
|
||||
static uint8_t *prvSkipNameField( uint8_t *pucByte, size_t xSourceLen );
|
||||
|
||||
/*
|
||||
* Process a response packet from a DNS server.
|
||||
*/
|
||||
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, TickType_t xIdentifier );
|
||||
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, TickType_t xIdentifier );
|
||||
|
||||
/*
|
||||
* Prepare and send a message to a DNS server. 'xReadTimeOut_ms' will be passed as
|
||||
@ -131,18 +135,19 @@ static uint32_t prvGetHostByName( const char *pcHostName, TickType_t xIdentifier
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_NBNS == 1 )
|
||||
static portINLINE void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, uint32_t ulIPAddress );
|
||||
static portINLINE void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, uint32_t ulIPAddress );
|
||||
#endif /* ipconfigUSE_NBNS */
|
||||
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
static uint8_t *prvReadNameField( uint8_t *pucByte, char *pcName, BaseType_t xLen );
|
||||
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, BaseType_t xLookUp );
|
||||
static uint8_t *prvReadNameField( uint8_t *pucByte, size_t xSourceLen, char *pcName, size_t xLen );
|
||||
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, uint32_t ulTTL, BaseType_t xLookUp );
|
||||
|
||||
typedef struct xDNS_CACHE_TABLE_ROW
|
||||
{
|
||||
uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
|
||||
char pcName[ipconfigDNS_CACHE_NAME_LENGTH]; /* The name of the host */
|
||||
uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
|
||||
char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ]; /* The name of the host */
|
||||
uint32_t ulTTL; /* Time-to-Live (in seconds) from the DNS server. */
|
||||
uint32_t ulTimeWhenAddedInSeconds;
|
||||
} DNSCacheRow_t;
|
||||
|
||||
static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
|
||||
@ -180,6 +185,18 @@ struct xDNSTail
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xDNSTail DNSTail_t;
|
||||
|
||||
/* DNS answer record header. */
|
||||
#include "pack_struct_start.h"
|
||||
struct xDNSAnswerRecord
|
||||
{
|
||||
uint16_t usType;
|
||||
uint16_t usClass;
|
||||
uint32_t ulTTL;
|
||||
uint16_t usDataLength;
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
@ -239,7 +256,7 @@ typedef struct xDNSTail DNSTail_t;
|
||||
uint32_t FreeRTOS_dnslookup( const char *pcHostName )
|
||||
{
|
||||
uint32_t ulIPAddress = 0UL;
|
||||
prvProcessDNSCache( pcHostName, &ulIPAddress, pdTRUE );
|
||||
prvProcessDNSCache( pcHostName, &ulIPAddress, 0, pdTRUE );
|
||||
return ulIPAddress;
|
||||
}
|
||||
#endif /* ipconfigUSE_DNS_CACHE == 1 */
|
||||
@ -396,64 +413,70 @@ uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName, FOnDNSEvent pCallback
|
||||
#endif
|
||||
{
|
||||
uint32_t ulIPAddress = 0UL;
|
||||
static uint16_t usIdentifier = 0u;
|
||||
TickType_t xReadTimeOut_ms = 1200U;
|
||||
/* Generate a unique identifier for this query. Keep it in a local variable
|
||||
as gethostbyname() may be called from different threads */
|
||||
TickType_t xIdentifier = ( TickType_t )usIdentifier++;
|
||||
TickType_t xReadTimeOut_ms = ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME;
|
||||
TickType_t xIdentifier = 0;
|
||||
|
||||
/* If the supplied hostname is IP address, convert it to uint32_t
|
||||
and return. */
|
||||
#if( ipconfigINCLUDE_FULL_INET_ADDR == 1 )
|
||||
{
|
||||
ulIPAddress = FreeRTOS_inet_addr( pcHostName );
|
||||
}
|
||||
#endif /* ipconfigINCLUDE_FULL_INET_ADDR == 1 */
|
||||
/* If the supplied hostname is IP address, convert it to uint32_t
|
||||
and return. */
|
||||
#if( ipconfigINCLUDE_FULL_INET_ADDR == 1 )
|
||||
{
|
||||
ulIPAddress = FreeRTOS_inet_addr( pcHostName );
|
||||
}
|
||||
#endif /* ipconfigINCLUDE_FULL_INET_ADDR == 1 */
|
||||
|
||||
/* If a DNS cache is used then check the cache before issuing another DNS
|
||||
request. */
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
{
|
||||
if( ulIPAddress == 0UL )
|
||||
{
|
||||
ulIPAddress = FreeRTOS_dnslookup( pcHostName );
|
||||
if( ulIPAddress != 0 )
|
||||
{
|
||||
FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* prvGetHostByName will be called to start a DNS lookup */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_DNS_CACHE == 1 */
|
||||
/* If a DNS cache is used then check the cache before issuing another DNS
|
||||
request. */
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
{
|
||||
if( ulIPAddress == 0UL )
|
||||
{
|
||||
ulIPAddress = FreeRTOS_dnslookup( pcHostName );
|
||||
if( ulIPAddress != 0 )
|
||||
{
|
||||
FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* prvGetHostByName will be called to start a DNS lookup */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_DNS_CACHE == 1 */
|
||||
|
||||
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
||||
{
|
||||
if( pCallback != NULL )
|
||||
{
|
||||
if( ulIPAddress == 0UL )
|
||||
{
|
||||
/* The user has provided a callback function, so do not block on recvfrom() */
|
||||
xReadTimeOut_ms = 0;
|
||||
vDNSSetCallBack( pcHostName, pvSearchID, pCallback, xTimeout, ( TickType_t ) xIdentifier );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The IP address is known, do the call-back now. */
|
||||
pCallback( pcHostName, pvSearchID, ulIPAddress );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Generate a unique identifier. */
|
||||
if( 0 == ulIPAddress )
|
||||
{
|
||||
xIdentifier = ( TickType_t )ipconfigRAND32( );
|
||||
}
|
||||
|
||||
if( ulIPAddress == 0UL)
|
||||
{
|
||||
ulIPAddress = prvGetHostByName( pcHostName, xIdentifier, xReadTimeOut_ms );
|
||||
}
|
||||
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
||||
{
|
||||
if( pCallback != NULL )
|
||||
{
|
||||
if( ulIPAddress == 0UL )
|
||||
{
|
||||
/* The user has provided a callback function, so do not block on recvfrom() */
|
||||
if( 0 != xIdentifier )
|
||||
{
|
||||
xReadTimeOut_ms = 0;
|
||||
vDNSSetCallBack( pcHostName, pvSearchID, pCallback, xTimeout, ( TickType_t )xIdentifier );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The IP address is known, do the call-back now. */
|
||||
pCallback( pcHostName, pvSearchID, ulIPAddress );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ulIPAddress;
|
||||
if( ulIPAddress == 0UL && 0 != xIdentifier )
|
||||
{
|
||||
ulIPAddress = prvGetHostByName( pcHostName, xIdentifier, xReadTimeOut_ms );
|
||||
}
|
||||
|
||||
return ulIPAddress;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@ -467,7 +490,7 @@ uint32_t ulAddressLength = sizeof( struct freertos_sockaddr );
|
||||
BaseType_t xAttempt;
|
||||
int32_t lBytes;
|
||||
size_t xPayloadLength, xExpectedPayloadLength;
|
||||
TickType_t xWriteTimeOut_ms = 100U;
|
||||
TickType_t xWriteTimeOut_ms = ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
BaseType_t bHasDot = pdFALSE;
|
||||
@ -544,7 +567,7 @@ TickType_t xWriteTimeOut_ms = 100U;
|
||||
if( lBytes > 0 )
|
||||
{
|
||||
/* The reply was received. Process it. */
|
||||
ulIPAddress = prvParseDNSReply( pucUDPPayloadBuffer, xIdentifier );
|
||||
ulIPAddress = prvParseDNSReply( pucUDPPayloadBuffer, lBytes, xIdentifier );
|
||||
|
||||
/* Finished with the buffer. The zero copy interface
|
||||
is being used, so the buffer must be freed by the
|
||||
@ -649,33 +672,74 @@ static const DNSMessage_t xDefaultPartDNSHeader =
|
||||
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
|
||||
static uint8_t *prvReadNameField( uint8_t *pucByte, char *pcName, BaseType_t xLen )
|
||||
static uint8_t *prvReadNameField( uint8_t *pucByte, size_t xSourceLen, char *pcName, size_t xDestLen )
|
||||
{
|
||||
BaseType_t xNameLen = 0;
|
||||
size_t xNameLen = 0;
|
||||
BaseType_t xCount;
|
||||
|
||||
if( 0 == xSourceLen )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Determine if the name is the fully coded name, or an offset to the name
|
||||
elsewhere in the message. */
|
||||
if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
|
||||
{
|
||||
/* Jump over the two byte offset. */
|
||||
pucByte += sizeof( uint16_t );
|
||||
|
||||
if( xSourceLen > sizeof( uint16_t ) )
|
||||
{
|
||||
pucByte += sizeof( uint16_t );
|
||||
}
|
||||
else
|
||||
{
|
||||
pucByte = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pucByte points to the full name. Walk over the string. */
|
||||
while( *pucByte != 0x00 )
|
||||
/* pucByte points to the full name. Walk over the string. */
|
||||
while( NULL != pucByte && *pucByte != 0x00 && xSourceLen > 1 )
|
||||
{
|
||||
BaseType_t xCount;
|
||||
if( xNameLen && xNameLen < xLen - 1 )
|
||||
pcName[xNameLen++] = '.';
|
||||
for( xCount = *(pucByte++); xCount--; pucByte++ )
|
||||
/* If this is not the first time through the loop, then add a
|
||||
separator in the output. */
|
||||
if( xNameLen > 0 && xNameLen < xDestLen - 1 )
|
||||
{
|
||||
pcName[ xNameLen++ ] = '.';
|
||||
}
|
||||
|
||||
/* Process the first/next sub-string. */
|
||||
for( xCount = *(pucByte++), xSourceLen--;
|
||||
xCount-- && xSourceLen > 1;
|
||||
pucByte++, xSourceLen-- )
|
||||
{
|
||||
if( xNameLen < xLen - 1 )
|
||||
pcName[xNameLen++] = *( ( char * ) pucByte );
|
||||
if( xNameLen < xDestLen - 1 )
|
||||
{
|
||||
pcName[ xNameLen++ ] = *( ( char * )pucByte );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DNS name is too big for the provided buffer. */
|
||||
pucByte = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pucByte++;
|
||||
/* Confirm that a fully formed name was found. */
|
||||
if( NULL != pucByte )
|
||||
{
|
||||
if( 0x00 == *pucByte )
|
||||
{
|
||||
pucByte++;
|
||||
xSourceLen--;
|
||||
pcName[ xNameLen++ ] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
pucByte = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pucByte;
|
||||
@ -683,27 +747,60 @@ static const DNSMessage_t xDefaultPartDNSHeader =
|
||||
#endif /* ipconfigUSE_DNS_CACHE == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static uint8_t *prvSkipNameField( uint8_t *pucByte )
|
||||
static uint8_t *prvSkipNameField( uint8_t *pucByte, size_t xSourceLen )
|
||||
{
|
||||
/* Determine if the name is the fully coded name, or an offset to the name
|
||||
size_t xChunkLength;
|
||||
|
||||
if( 0 == xSourceLen )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Determine if the name is the fully coded name, or an offset to the name
|
||||
elsewhere in the message. */
|
||||
if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
|
||||
{
|
||||
/* Jump over the two byte offset. */
|
||||
pucByte += sizeof( uint16_t );
|
||||
|
||||
if( xSourceLen > sizeof( uint16_t ) )
|
||||
{
|
||||
pucByte += sizeof( uint16_t );
|
||||
}
|
||||
else
|
||||
{
|
||||
pucByte = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pucByte points to the full name. Walk over the string. */
|
||||
while( *pucByte != 0x00 )
|
||||
/* pucByte points to the full name. Walk over the string. */
|
||||
while( *pucByte != 0x00 && xSourceLen > 1 )
|
||||
{
|
||||
/* The number of bytes to jump for each name section is stored in the byte
|
||||
before the name section. */
|
||||
pucByte += ( *pucByte + 1 );
|
||||
xChunkLength = *pucByte + 1;
|
||||
|
||||
if( xSourceLen > xChunkLength )
|
||||
{
|
||||
xSourceLen -= xChunkLength;
|
||||
pucByte += xChunkLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
pucByte = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pucByte++;
|
||||
/* Confirm that a fully formed name was found. */
|
||||
if( NULL != pucByte )
|
||||
{
|
||||
if( 0x00 == *pucByte )
|
||||
{
|
||||
pucByte++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pucByte = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pucByte;
|
||||
@ -712,10 +809,25 @@ static uint8_t *prvSkipNameField( uint8_t *pucByte )
|
||||
|
||||
uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
||||
DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
|
||||
uint8_t *pucUDPPayloadBuffer;
|
||||
size_t xPlayloadBufferLength;
|
||||
DNSMessage_t *pxDNSMessageHeader;
|
||||
|
||||
prvParseDNSReply( pucUDPPayloadBuffer, ( uint32_t ) pxDNSMessageHeader->usIdentifier );
|
||||
xPlayloadBufferLength = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
|
||||
if ( xPlayloadBufferLength < sizeof( DNSMessage_t ) )
|
||||
{
|
||||
return pdFAIL;
|
||||
}
|
||||
|
||||
pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
||||
pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
|
||||
|
||||
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t ) )
|
||||
{
|
||||
prvParseDNSReply( pucUDPPayloadBuffer,
|
||||
xPlayloadBufferLength,
|
||||
( uint32_t )pxDNSMessageHeader->usIdentifier );
|
||||
}
|
||||
|
||||
/* The packet was not consumed. */
|
||||
return pdFAIL;
|
||||
@ -727,9 +839,14 @@ DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
|
||||
uint32_t ulNBNSHandlePacket (NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
|
||||
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( *pxUDPPacket );
|
||||
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
||||
|
||||
prvTreatNBNS( pucUDPPayloadBuffer, pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t) )
|
||||
{
|
||||
prvTreatNBNS( pucUDPPayloadBuffer,
|
||||
pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ),
|
||||
pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
}
|
||||
|
||||
/* The packet was not consumed. */
|
||||
return pdFAIL;
|
||||
@ -738,28 +855,42 @@ DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
|
||||
#endif /* ipconfigUSE_NBNS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, TickType_t xIdentifier )
|
||||
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, TickType_t xIdentifier )
|
||||
{
|
||||
DNSMessage_t *pxDNSMessageHeader;
|
||||
DNSAnswerRecord_t *pxDNSAnswerRecord;
|
||||
uint32_t ulIPAddress = 0UL;
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
char *pcRequestedName = NULL;
|
||||
#endif
|
||||
uint8_t *pucByte;
|
||||
size_t xSourceBytesRemaining;
|
||||
uint16_t x, usDataLength, usQuestions;
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
uint16_t usType = 0, usClass = 0;
|
||||
#endif
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
char pcName[128] = ""; /*_RB_ What is the significance of 128? Probably too big to go on the stack for a small MCU but don't know how else it could be made re-entrant. Might be necessary. */
|
||||
char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ] = "";
|
||||
#endif
|
||||
|
||||
/* Ensure that the buffer is of at least minimal DNS message length. */
|
||||
if( xBufferLength < sizeof( DNSMessage_t ) )
|
||||
{
|
||||
return dnsPARSE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSourceBytesRemaining = xBufferLength;
|
||||
}
|
||||
|
||||
/* Parse the DNS message header. */
|
||||
pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
|
||||
|
||||
if( pxDNSMessageHeader->usIdentifier == ( uint16_t ) xIdentifier )
|
||||
{
|
||||
/* Start at the first byte after the header. */
|
||||
pucByte = pucUDPPayloadBuffer + sizeof( DNSMessage_t );
|
||||
xSourceBytesRemaining -= sizeof( DNSMessage_t );
|
||||
|
||||
/* Skip any question records. */
|
||||
usQuestions = FreeRTOS_ntohs( pxDNSMessageHeader->usQuestions );
|
||||
@ -777,56 +908,100 @@ uint16_t x, usDataLength, usQuestions;
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
if( x == 0 )
|
||||
{
|
||||
pucByte = prvReadNameField( pucByte, pcName, sizeof( pcName ) );
|
||||
pucByte = prvReadNameField( pucByte,
|
||||
xSourceBytesRemaining,
|
||||
pcName,
|
||||
sizeof( pcName ) );
|
||||
|
||||
/* Check for a malformed response. */
|
||||
if( NULL == pucByte )
|
||||
{
|
||||
return dnsPARSE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSourceBytesRemaining = ( pucUDPPayloadBuffer + xBufferLength ) - pucByte;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* ipconfigUSE_DNS_CACHE */
|
||||
{
|
||||
/* Skip the variable length pcName field. */
|
||||
pucByte = prvSkipNameField( pucByte );
|
||||
}
|
||||
pucByte = prvSkipNameField( pucByte,
|
||||
xSourceBytesRemaining );
|
||||
|
||||
/* Check for a malformed response. */
|
||||
if( NULL == pucByte )
|
||||
{
|
||||
return dnsPARSE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSourceBytesRemaining = pucUDPPayloadBuffer + xBufferLength - pucByte;
|
||||
}
|
||||
}
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
{
|
||||
/* usChar2u16 returns value in host endianness. */
|
||||
usType = usChar2u16( pucByte );
|
||||
usClass = usChar2u16( pucByte + 2 );
|
||||
}
|
||||
#endif /* ipconfigUSE_LLMNR */
|
||||
/* Check the remaining buffer size. */
|
||||
if( xSourceBytesRemaining >= sizeof( uint32_t ) )
|
||||
{
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
{
|
||||
/* usChar2u16 returns value in host endianness */
|
||||
usType = usChar2u16( pucByte );
|
||||
usClass = usChar2u16( pucByte + 2 );
|
||||
}
|
||||
#endif /* ipconfigUSE_LLMNR */
|
||||
|
||||
/* Skip the type and class fields. */
|
||||
pucByte += sizeof( uint32_t );
|
||||
/* Skip the type and class fields. */
|
||||
pucByte += sizeof( uint32_t );
|
||||
xSourceBytesRemaining -= sizeof( uint32_t );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Malformed response. */
|
||||
return dnsPARSE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search through the answers records. */
|
||||
/* Search through the answer records. */
|
||||
pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers );
|
||||
|
||||
if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
|
||||
{
|
||||
for( x = 0; x < pxDNSMessageHeader->usAnswers; x++ )
|
||||
{
|
||||
pucByte = prvSkipNameField( pucByte );
|
||||
pucByte = prvSkipNameField( pucByte,
|
||||
xSourceBytesRemaining );
|
||||
|
||||
/* Is the type field that of an A record? */
|
||||
if( usChar2u16( pucByte ) == dnsTYPE_A_HOST )
|
||||
/* Check for a malformed response. */
|
||||
if( NULL == pucByte )
|
||||
{
|
||||
return dnsPARSE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSourceBytesRemaining = pucUDPPayloadBuffer + xBufferLength - pucByte;
|
||||
}
|
||||
|
||||
/* Is there enough data for an IPv4 A record answer and, if so,
|
||||
is this an A record? */
|
||||
if( xSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) &&
|
||||
usChar2u16( pucByte ) == dnsTYPE_A_HOST )
|
||||
{
|
||||
/* This is the required record. Skip the type, class, and
|
||||
time to live fields, plus the first byte of the data
|
||||
length. */
|
||||
pucByte += ( sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint8_t ) );
|
||||
/* This is the required record type and is of sufficient size. */
|
||||
pxDNSAnswerRecord = ( DNSAnswerRecord_t * )pucByte;
|
||||
|
||||
/* Sanity check the data length. */
|
||||
if( ( size_t ) *pucByte == sizeof( uint32_t ) )
|
||||
/* Sanity check the data length of an IPv4 answer. */
|
||||
if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == sizeof( uint32_t ) )
|
||||
{
|
||||
/* Skip the second byte of the length. */
|
||||
pucByte++;
|
||||
|
||||
/* Copy the IP address out of the record. */
|
||||
memcpy( ( void * ) &ulIPAddress, ( void * ) pucByte, sizeof( uint32_t ) );
|
||||
memcpy( &ulIPAddress,
|
||||
pucByte + sizeof( DNSAnswerRecord_t ),
|
||||
sizeof( uint32_t ) );
|
||||
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
{
|
||||
prvProcessDNSCache( pcName, &ulIPAddress, pdFALSE );
|
||||
prvProcessDNSCache( pcName, &ulIPAddress, pxDNSAnswerRecord->ulTTL, pdFALSE );
|
||||
}
|
||||
#endif /* ipconfigUSE_DNS_CACHE */
|
||||
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
||||
@ -837,24 +1012,37 @@ uint16_t x, usDataLength, usQuestions;
|
||||
#endif /* ipconfigDNS_USE_CALLBACKS != 0 */
|
||||
}
|
||||
|
||||
pucByte += sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t );
|
||||
xSourceBytesRemaining -= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) );
|
||||
break;
|
||||
}
|
||||
else
|
||||
else if( xSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) )
|
||||
{
|
||||
/* Skip the type, class and time to live fields. */
|
||||
pucByte += ( sizeof( uint32_t ) + sizeof( uint32_t ) );
|
||||
/* It's not an A record, so skip it. Get the header location
|
||||
and then jump over the header. */
|
||||
pxDNSAnswerRecord = ( DNSAnswerRecord_t * )pucByte;
|
||||
pucByte += sizeof( DNSAnswerRecord_t );
|
||||
xSourceBytesRemaining -= sizeof( DNSAnswerRecord_t );
|
||||
|
||||
/* Determine the length of the answer data from the header. */
|
||||
usDataLength = FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength );
|
||||
|
||||
/* Determine the length of the data in the field. */
|
||||
memcpy( ( void * ) &usDataLength, ( void * ) pucByte, sizeof( uint16_t ) );
|
||||
usDataLength = FreeRTOS_ntohs( usDataLength );
|
||||
|
||||
/* Jump over the data length bytes, and the data itself. */
|
||||
pucByte += usDataLength + sizeof( uint16_t );
|
||||
/* Jump over the answer. */
|
||||
if( xSourceBytesRemaining >= usDataLength )
|
||||
{
|
||||
pucByte += usDataLength;
|
||||
xSourceBytesRemaining -= usDataLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Malformed response. */
|
||||
return dnsPARSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
else if( ( usQuestions != ( uint16_t )0u ) && ( usType == ( uint16_t )dnsTYPE_A_HOST ) && ( usClass == ( uint16_t )dnsCLASS_IN ) )
|
||||
else if( usQuestions && ( usType == dnsTYPE_A_HOST ) && ( usClass == dnsCLASS_IN ) )
|
||||
{
|
||||
/* If this is not a reply to our DNS request, it might an LLMNR
|
||||
request. */
|
||||
@ -867,7 +1055,7 @@ uint16_t x, usDataLength, usQuestions;
|
||||
|
||||
if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
|
||||
{
|
||||
BaseType_t xDataLength = pxNetworkBuffer->xDataLength + sizeof( UDPHeader_t ) +
|
||||
BaseType_t xDataLength = xBufferLength + sizeof( UDPHeader_t ) +
|
||||
sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
|
||||
|
||||
/* The field xDataLength was set to the length of the UDP payload.
|
||||
@ -900,7 +1088,7 @@ uint16_t x, usDataLength, usQuestions;
|
||||
{
|
||||
pxAnswer = (LLMNRAnswer_t *)pucByte;
|
||||
|
||||
/* Leave 'usIdentifier' and 'usQuestions' untouched. */
|
||||
/* We leave 'usIdentifier' and 'usQuestions' untouched */
|
||||
vSetField16( pxDNSMessageHeader, DNSMessage_t, usFlags, dnsLLMNR_FLAGS_IS_REPONSE ); /* Set the response flag */
|
||||
vSetField16( pxDNSMessageHeader, DNSMessage_t, usAnswers, 1 ); /* Provide a single answer */
|
||||
vSetField16( pxDNSMessageHeader, DNSMessage_t, usAuthorityRRs, 0 ); /* No authority */
|
||||
@ -935,13 +1123,20 @@ uint16_t x, usDataLength, usQuestions;
|
||||
|
||||
#if( ipconfigUSE_NBNS == 1 )
|
||||
|
||||
static void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, uint32_t ulIPAddress )
|
||||
static void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, uint32_t ulIPAddress )
|
||||
{
|
||||
uint16_t usFlags, usType, usClass;
|
||||
uint8_t *pucSource, *pucTarget;
|
||||
uint8_t ucByte;
|
||||
uint8_t ucNBNSName[ 17 ];
|
||||
|
||||
/* Check for minimum buffer size. */
|
||||
if( xBufferLength < sizeof( NBNSRequest_t ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read the request flags in host endianness. */
|
||||
usFlags = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usFlags ) );
|
||||
|
||||
if( ( usFlags & dnsNBNS_FLAGS_OPCODE_MASK ) == dnsNBNS_FLAGS_OPCODE_QUERY )
|
||||
@ -986,7 +1181,7 @@ uint16_t x, usDataLength, usQuestions;
|
||||
{
|
||||
/* If this is a response from another device,
|
||||
add the name to the DNS cache */
|
||||
prvProcessDNSCache( ( char * ) ucNBNSName, &ulIPAddress, pdFALSE );
|
||||
prvProcessDNSCache( ( char * ) ucNBNSName, &ulIPAddress, 0, pdFALSE );
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -1012,7 +1207,6 @@ uint16_t x, usDataLength, usQuestions;
|
||||
{
|
||||
NetworkBufferDescriptor_t *pxNewBuffer;
|
||||
BaseType_t xDataLength = pxNetworkBuffer->xDataLength + sizeof( UDPHeader_t ) +
|
||||
|
||||
sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
|
||||
|
||||
/* The field xDataLength was set to the length of the UDP payload.
|
||||
@ -1127,7 +1321,7 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
|
||||
|
||||
/* calculate the UDP checksum for outgoing package */
|
||||
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, pdTRUE );
|
||||
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, lNetLength, pdTRUE );
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1143,10 +1337,12 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||
|
||||
#if( ipconfigUSE_DNS_CACHE == 1 )
|
||||
|
||||
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, BaseType_t xLookUp )
|
||||
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, uint32_t ulTTL, BaseType_t xLookUp )
|
||||
{
|
||||
BaseType_t x;
|
||||
BaseType_t xFound = pdFALSE;
|
||||
uint32_t ulCurrentTimeSeconds =
|
||||
xTaskGetTickCount( ) / portTICK_PERIOD_MS / 1000;
|
||||
static BaseType_t xFreeEntry = 0;
|
||||
|
||||
/* For each entry in the DNS cache table. */
|
||||
@ -1157,16 +1353,29 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||
break;
|
||||
}
|
||||
|
||||
if( strncmp( xDNSCache[ x ].pcName, pcName, sizeof( xDNSCache[ x ].pcName ) ) == 0 )
|
||||
if( 0 == strcmp( xDNSCache[ x ].pcName, pcName ) )
|
||||
{
|
||||
/* Is this function called for a lookup or to add/update an IP address? */
|
||||
if( xLookUp != pdFALSE )
|
||||
{
|
||||
*pulIP = xDNSCache[ x ].ulIPAddress;
|
||||
/* Confirm that the record is still fresh. */
|
||||
if( ulCurrentTimeSeconds <
|
||||
xDNSCache[ x ].ulTimeWhenAddedInSeconds +
|
||||
FreeRTOS_ntohl( xDNSCache[ x ].ulTTL ) )
|
||||
{
|
||||
*pulIP = xDNSCache[ x ].ulIPAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Age out the old cached record. */
|
||||
xDNSCache[ x ].pcName[ 0 ] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xDNSCache[ x ].ulIPAddress = *pulIP;
|
||||
xDNSCache[ x ].ulTTL = ulTTL;
|
||||
xDNSCache[ x ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
|
||||
}
|
||||
|
||||
xFound = pdTRUE;
|
||||
@ -1182,15 +1391,21 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Called to add or update an item */
|
||||
strncpy( xDNSCache[ xFreeEntry ].pcName, pcName, sizeof( xDNSCache[ xFreeEntry ].pcName ) );
|
||||
xDNSCache[ xFreeEntry ].ulIPAddress = *pulIP;
|
||||
/* Add or update the item. */
|
||||
if( strlen( pcName ) < ipconfigDNS_CACHE_NAME_LENGTH )
|
||||
{
|
||||
strcpy( xDNSCache[ xFreeEntry ].pcName, pcName );
|
||||
|
||||
xFreeEntry++;
|
||||
if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES )
|
||||
{
|
||||
xFreeEntry = 0;
|
||||
}
|
||||
xDNSCache[ xFreeEntry ].ulIPAddress = *pulIP;
|
||||
xDNSCache[ xFreeEntry ].ulTTL = ulTTL;
|
||||
xDNSCache[ xFreeEntry ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
|
||||
|
||||
xFreeEntry++;
|
||||
if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES )
|
||||
{
|
||||
xFreeEntry = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1204,4 +1419,9 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||
|
||||
#endif /* ipconfigUSE_DNS != 0 */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Provide access to private members for testing. */
|
||||
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
|
||||
#include "aws_freertos_tcp_test_access_dns_define.h"
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -65,9 +65,7 @@ a constant. */
|
||||
|
||||
|
||||
/* Time delay between repeated attempts to initialise the network hardware. */
|
||||
#ifndef ipINITIALISATION_RETRY_DELAY
|
||||
#define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
|
||||
#endif
|
||||
#define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
|
||||
|
||||
/* Defines how often the ARP timer callback function is executed. The time is
|
||||
shorted in the Windows simulator as simulated time is not real time. */
|
||||
@ -186,7 +184,7 @@ static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetwor
|
||||
/*
|
||||
* Process incoming IP packets.
|
||||
*/
|
||||
static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer );
|
||||
static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer );
|
||||
|
||||
#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
|
||||
/*
|
||||
@ -356,11 +354,12 @@ struct freertos_sockaddr xAddress;
|
||||
/* Calculate the acceptable maximum sleep time. */
|
||||
xNextIPSleep = prvCalculateSleepTime();
|
||||
|
||||
/* Wait until there is something to do. The event is initialised to "no
|
||||
event" in case the following call exits due to a time out rather than a
|
||||
message being received. */
|
||||
xReceivedEvent.eEventType = eNoEvent;
|
||||
xQueueReceive( xNetworkEventQueue, ( void * ) &xReceivedEvent, xNextIPSleep );
|
||||
/* Wait until there is something to do. If the following call exits
|
||||
* due to a time out rather than a message being received, set a
|
||||
* 'NoEvent' value. */
|
||||
if ( xQueueReceive( xNetworkEventQueue, ( void * ) &xReceivedEvent, xNextIPSleep ) == pdFALSE ) {
|
||||
xReceivedEvent.eEventType = eNoEvent;
|
||||
}
|
||||
|
||||
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
|
||||
{
|
||||
@ -655,14 +654,8 @@ static void prvCheckNetworkTimers( void )
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
{
|
||||
BaseType_t xWillSleep;
|
||||
/* xStart keeps a copy of the last time this function was active,
|
||||
and during every call it will be updated with xTaskGetTickCount()
|
||||
'0' means: not yet initialised (although later '0' might be returned
|
||||
by xTaskGetTickCount(), which is no problem). */
|
||||
static TickType_t xStart = ( TickType_t ) 0;
|
||||
TickType_t xTimeNow, xNextTime;
|
||||
TickType_t xNextTime;
|
||||
BaseType_t xCheckTCPSockets;
|
||||
extern uint32_t ulNextInitialSequenceNumber;
|
||||
|
||||
if( uxQueueMessagesWaiting( xNetworkEventQueue ) == 0u )
|
||||
{
|
||||
@ -673,19 +666,6 @@ static void prvCheckNetworkTimers( void )
|
||||
xWillSleep = pdFALSE;
|
||||
}
|
||||
|
||||
xTimeNow = xTaskGetTickCount();
|
||||
|
||||
if( xStart != ( TickType_t ) 0 )
|
||||
{
|
||||
/* It is advised to increment the Initial Sequence Number every 4
|
||||
microseconds which makes 250 times per ms. This will make it harder
|
||||
for a third party to 'guess' our sequence number and 'take over'
|
||||
a TCP connection */
|
||||
ulNextInitialSequenceNumber += ipINITIAL_SEQUENCE_NUMBER_FACTOR * ( ( xTimeNow - xStart ) * portTICK_PERIOD_MS );
|
||||
}
|
||||
|
||||
xStart = xTimeNow;
|
||||
|
||||
/* Sockets need to be checked if the TCP timer has expired. */
|
||||
xCheckTCPSockets = prvIPTimerCheck( &xTCPTimer );
|
||||
|
||||
@ -823,6 +803,10 @@ void *pvReturn;
|
||||
|
||||
if( pxNetworkBuffer != NULL )
|
||||
{
|
||||
/* Set the actual packet size in case a bigger buffer was returned. */
|
||||
pxNetworkBuffer->xDataLength =
|
||||
sizeof( UDPPacket_t ) + xRequestedSizeBytes;
|
||||
|
||||
/* Leave space for the UPD header. */
|
||||
pvReturn = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
|
||||
}
|
||||
@ -847,6 +831,11 @@ NetworkBufferDescriptor_t * pxNewBuffer;
|
||||
|
||||
if( pxNewBuffer != NULL )
|
||||
{
|
||||
/* Set the actual packet size in case a bigger buffer than requested
|
||||
was returned. */
|
||||
pxNewBuffer->xDataLength = xNewLength;
|
||||
|
||||
/* Copy the original packet information. */
|
||||
pxNewBuffer->ulIPAddress = pxNetworkBuffer->ulIPAddress;
|
||||
pxNewBuffer->usPort = pxNetworkBuffer->usPort;
|
||||
pxNewBuffer->usBoundPort = pxNetworkBuffer->usBoundPort;
|
||||
@ -997,10 +986,7 @@ BaseType_t xReturn = pdFALSE;
|
||||
|
||||
/* Added to prevent ARP flood to gateway. Ensure the
|
||||
gateway is on the same subnet as the IP address. */
|
||||
if( xNetworkAddressing.ulGatewayAddress != 0ul )
|
||||
{
|
||||
configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
|
||||
}
|
||||
configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
|
||||
}
|
||||
#endif /* ipconfigUSE_DHCP == 1 */
|
||||
|
||||
@ -1009,10 +995,13 @@ BaseType_t xReturn = pdFALSE;
|
||||
memcpy( ( void * ) ipLOCAL_MAC_ADDRESS, ( void * ) ucMACAddress, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
|
||||
/* Prepare the sockets interface. */
|
||||
vNetworkSocketsInit();
|
||||
|
||||
/* Create the task that processes Ethernet and stack events. */
|
||||
xReturn = xTaskCreate( prvIPTask, "IP-task", ( uint16_t ) ipconfigIP_TASK_STACK_SIZE_WORDS, NULL, ( UBaseType_t ) ipconfigIP_TASK_PRIORITY, &xIPTaskHandle );
|
||||
xReturn = vNetworkSocketsInit();
|
||||
|
||||
if( pdTRUE == xReturn )
|
||||
{
|
||||
/* Create the task that processes Ethernet and stack events. */
|
||||
xReturn = xTaskCreate( prvIPTask, "IP-task", ( uint16_t )ipconfigIP_TASK_STACK_SIZE_WORDS, NULL, ( UBaseType_t )ipconfigIP_TASK_PRIORITY, &xIPTaskHandle );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1356,35 +1345,52 @@ void vIPNetworkUpCalls( void )
|
||||
static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
|
||||
{
|
||||
EthernetHeader_t *pxEthernetHeader;
|
||||
volatile eFrameProcessingResult_t eReturned; /* Volatile to prevent complier warnings when ipCONSIDER_FRAME_FOR_PROCESSING just sets it to eProcessBuffer. */
|
||||
eFrameProcessingResult_t eReturned = eReleaseBuffer;
|
||||
|
||||
configASSERT( pxNetworkBuffer );
|
||||
|
||||
/* Interpret the Ethernet frame. */
|
||||
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
|
||||
pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
|
||||
if( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) )
|
||||
{
|
||||
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
|
||||
pxEthernetHeader = ( EthernetHeader_t * )( pxNetworkBuffer->pucEthernetBuffer );
|
||||
|
||||
if( eReturned == eProcessBuffer )
|
||||
{
|
||||
/* Interpret the received Ethernet packet. */
|
||||
switch( pxEthernetHeader->usFrameType )
|
||||
{
|
||||
case ipARP_FRAME_TYPE :
|
||||
/* The Ethernet frame contains an ARP packet. */
|
||||
eReturned = eARPProcessPacket( ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
|
||||
break;
|
||||
if( eReturned == eProcessBuffer )
|
||||
{
|
||||
/* Interpret the received Ethernet packet. */
|
||||
switch( pxEthernetHeader->usFrameType )
|
||||
{
|
||||
case ipARP_FRAME_TYPE:
|
||||
/* The Ethernet frame contains an ARP packet. */
|
||||
if( pxNetworkBuffer->xDataLength >= sizeof( ARPPacket_t ) )
|
||||
{
|
||||
eReturned = eARPProcessPacket( ( ARPPacket_t * )pxNetworkBuffer->pucEthernetBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturned = eReleaseBuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
case ipIPv4_FRAME_TYPE :
|
||||
/* The Ethernet frame contains an IP packet. */
|
||||
eReturned = prvProcessIPPacket( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer );
|
||||
break;
|
||||
case ipIPv4_FRAME_TYPE:
|
||||
/* The Ethernet frame contains an IP packet. */
|
||||
if( pxNetworkBuffer->xDataLength >= sizeof( IPPacket_t ) )
|
||||
{
|
||||
eReturned = prvProcessIPPacket( ( IPPacket_t * )pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturned = eReleaseBuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
/* No other packet types are handled. Nothing to do. */
|
||||
eReturned = eReleaseBuffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
/* No other packet types are handled. Nothing to do. */
|
||||
eReturned = eReleaseBuffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform any actions that resulted from processing the Ethernet frame. */
|
||||
switch( eReturned )
|
||||
@ -1433,9 +1439,9 @@ eFrameProcessingResult_t eReturn = eProcessBuffer;
|
||||
This method may decrease the usage of sparse network buffers. */
|
||||
uint32_t ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
|
||||
|
||||
/* Ensure that the incoming packet is not fragmented (fragmentation
|
||||
was only supported for outgoing packets, and is not currently
|
||||
not supported at all). */
|
||||
/* Ensure that the incoming packet is not fragmented (only outgoing
|
||||
packets can be fragmented) as these are the only handled IP frames
|
||||
currently. */
|
||||
if( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U )
|
||||
{
|
||||
/* Can not handle, fragmented packet. */
|
||||
@ -1481,7 +1487,7 @@ eFrameProcessingResult_t eReturn = eProcessBuffer;
|
||||
eReturn = eReleaseBuffer;
|
||||
}
|
||||
/* Is the upper-layer checksum (TCP/UDP/ICMP) correct? */
|
||||
else if( usGenerateProtocolChecksum( ( uint8_t * )( pxNetworkBuffer->pucEthernetBuffer ), pdFALSE ) != ipCORRECT_CRC )
|
||||
else if( usGenerateProtocolChecksum( ( uint8_t * )( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength, pdFALSE ) != ipCORRECT_CRC )
|
||||
{
|
||||
/* Protocol checksum not accepted. */
|
||||
eReturn = eReleaseBuffer;
|
||||
@ -1500,13 +1506,22 @@ eFrameProcessingResult_t eReturn = eProcessBuffer;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer )
|
||||
static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer )
|
||||
{
|
||||
eFrameProcessingResult_t eReturn;
|
||||
const IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
|
||||
IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
|
||||
UBaseType_t uxHeaderLength = ( UBaseType_t ) ( ( pxIPHeader->ucVersionHeaderLength & 0x0Fu ) << 2 );
|
||||
uint8_t ucProtocol;
|
||||
|
||||
/* Bound the calculated header length: take away the Ethernet header size,
|
||||
then check if the IP header is claiming to be longer than the remaining
|
||||
total packet size. Also check for minimal header field length. */
|
||||
if( uxHeaderLength > pxNetworkBuffer->xDataLength - ipSIZE_OF_ETH_HEADER ||
|
||||
uxHeaderLength < ipSIZE_OF_IPv4_HEADER )
|
||||
{
|
||||
return eReleaseBuffer;
|
||||
}
|
||||
|
||||
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
|
||||
/* Check if the IP headers are acceptable and if it has our destination. */
|
||||
eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );
|
||||
@ -1520,15 +1535,21 @@ uint8_t ucProtocol;
|
||||
* Note: IP options are mostly use in Multi-cast protocols */
|
||||
const size_t optlen = ( ( size_t ) uxHeaderLength ) - ipSIZE_OF_IPv4_HEADER;
|
||||
/* From: the previous start of UDP/ICMP/TCP data */
|
||||
uint8_t *pucSource = ( ( uint8_t * ) pxIPHeader ) + uxHeaderLength;
|
||||
uint8_t *pucSource = ( uint8_t* )(pxNetworkBuffer->pucEthernetBuffer + sizeof( EthernetHeader_t ) + uxHeaderLength);
|
||||
/* To: the usual start of UDP/ICMP/TCP data at offset 20 from IP header */
|
||||
uint8_t *pucTarget = ( ( uint8_t * ) pxIPHeader ) + ipSIZE_OF_IPv4_HEADER;
|
||||
uint8_t *pucTarget = ( uint8_t* )(pxNetworkBuffer->pucEthernetBuffer + sizeof( EthernetHeader_t ) + ipSIZE_OF_IPv4_HEADER);
|
||||
/* How many: total length minus the options and the lower headers */
|
||||
const size_t xMoveLen = pxNetworkBuffer->xDataLength - optlen - ipSIZE_OF_IPv4_HEADER - ipSIZE_OF_ETH_HEADER;
|
||||
|
||||
memmove( pucTarget, pucSource, xMoveLen );
|
||||
pxNetworkBuffer->xDataLength -= optlen;
|
||||
|
||||
/* Fix-up new version/header length field in IP packet. */
|
||||
pxIPHeader->ucVersionHeaderLength =
|
||||
( pxIPHeader->ucVersionHeaderLength & 0xF0 ) | /* High nibble is the version. */
|
||||
( ( ipSIZE_OF_IPv4_HEADER >> 2 ) & 0x0F ); /* Low nibble is the header size, in bytes, divided by four. */
|
||||
}
|
||||
|
||||
/* Add the IP and MAC addresses to the ARP table if they are not
|
||||
already there - otherwise refresh the age of the existing
|
||||
entry. */
|
||||
@ -1552,11 +1573,18 @@ uint8_t ucProtocol;
|
||||
be able to validate what it receives. */
|
||||
#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
|
||||
{
|
||||
ICMPPacket_t *pxICMPPacket = ( ICMPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
|
||||
if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
|
||||
{
|
||||
eReturn = prvProcessICMPPacket( pxICMPPacket );
|
||||
}
|
||||
if( pxNetworkBuffer->xDataLength >= sizeof( ICMPPacket_t ) )
|
||||
{
|
||||
ICMPPacket_t *pxICMPPacket = ( ICMPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
|
||||
if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
|
||||
{
|
||||
eReturn = prvProcessICMPPacket( pxICMPPacket );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturn = eReleaseBuffer;
|
||||
}
|
||||
}
|
||||
#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
|
||||
break;
|
||||
@ -1566,23 +1594,47 @@ uint8_t ucProtocol;
|
||||
/* The IP packet contained a UDP frame. */
|
||||
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
|
||||
|
||||
/* Note the header values required prior to the
|
||||
checksum generation as the checksum pseudo header
|
||||
may clobber some of these values. */
|
||||
pxNetworkBuffer->xDataLength = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t );
|
||||
/* HT:endian: fields in pxNetworkBuffer (usPort, ulIPAddress) were network order */
|
||||
pxNetworkBuffer->usPort = pxUDPPacket->xUDPHeader.usSourcePort;
|
||||
pxNetworkBuffer->ulIPAddress = pxUDPPacket->xIPHeader.ulSourceIPAddress;
|
||||
/* Only proceed if the payload length indicated in the header
|
||||
appears to be valid. */
|
||||
if ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) )
|
||||
{
|
||||
/* Ensure that downstream UDP packet handling has the lesser
|
||||
* of: the actual network buffer Ethernet frame length, or
|
||||
* the sender's UDP packet header payload length, minus the
|
||||
* size of the UDP header.
|
||||
*
|
||||
* The size of the UDP packet structure in this implementation
|
||||
* includes the size of the Ethernet header, the size of
|
||||
* the IP header, and the size of the UDP header.
|
||||
*/
|
||||
|
||||
pxNetworkBuffer->xDataLength -= sizeof( UDPPacket_t );
|
||||
if( ( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t ) ) <
|
||||
pxNetworkBuffer->xDataLength )
|
||||
{
|
||||
pxNetworkBuffer->xDataLength = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) -
|
||||
sizeof( UDPHeader_t );
|
||||
}
|
||||
|
||||
/* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM:
|
||||
* In some cases, the upper-layer checksum has been calculated
|
||||
* by the NIC driver */
|
||||
/* Pass the packet payload to the UDP sockets implementation. */
|
||||
/* HT:endian: xProcessReceivedUDPPacket wanted network order */
|
||||
if( xProcessReceivedUDPPacket( pxNetworkBuffer, pxUDPPacket->xUDPHeader.usDestinationPort ) == pdPASS )
|
||||
{
|
||||
eReturn = eFrameConsumed;
|
||||
}
|
||||
/* Fields in pxNetworkBuffer (usPort, ulIPAddress) are network order. */
|
||||
pxNetworkBuffer->usPort = pxUDPPacket->xUDPHeader.usSourcePort;
|
||||
pxNetworkBuffer->ulIPAddress = pxUDPPacket->xIPHeader.ulSourceIPAddress;
|
||||
|
||||
/* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM:
|
||||
* In some cases, the upper-layer checksum has been calculated
|
||||
* by the NIC driver.
|
||||
*
|
||||
* Pass the packet payload to the UDP sockets implementation. */
|
||||
if( xProcessReceivedUDPPacket( pxNetworkBuffer,
|
||||
pxUDPPacket->xUDPHeader.usDestinationPort ) == pdPASS )
|
||||
{
|
||||
eReturn = eFrameConsumed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturn = eReleaseBuffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1739,7 +1791,7 @@ uint8_t ucProtocol;
|
||||
#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, BaseType_t xOutgoingPacket )
|
||||
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket )
|
||||
{
|
||||
uint32_t ulLength;
|
||||
uint16_t usChecksum, *pusChecksum;
|
||||
@ -1751,13 +1803,48 @@ uint8_t ucProtocol;
|
||||
const char *pcType;
|
||||
#endif
|
||||
|
||||
pxIPPacket = ( const IPPacket_t * ) pucEthernetBuffer;
|
||||
uxIPHeaderLength = ( UBaseType_t ) ( 4u * ( pxIPPacket->xIPHeader.ucVersionHeaderLength & 0x0Fu ) ); /*_RB_ Why 4? */
|
||||
pxProtPack = ( ProtocolPacket_t * ) ( pucEthernetBuffer + ( uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ) );
|
||||
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
|
||||
/* Check for minimum packet size. */
|
||||
if( uxBufferLength < sizeof( IPPacket_t ) )
|
||||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
|
||||
/* Parse the packet length. */
|
||||
pxIPPacket = ( const IPPacket_t * ) pucEthernetBuffer;
|
||||
|
||||
/* Per https://tools.ietf.org/html/rfc791, the four-bit Internet Header
|
||||
Length field contains the length of the internet header in 32-bit words. */
|
||||
uxIPHeaderLength = ( UBaseType_t )
|
||||
( sizeof( uint32_t ) * ( pxIPPacket->xIPHeader.ucVersionHeaderLength & 0x0Fu ) );
|
||||
|
||||
/* Check for minimum packet size. */
|
||||
if( uxBufferLength < sizeof( IPPacket_t ) + uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER )
|
||||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
if( uxBufferLength < FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) )
|
||||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
|
||||
/* Identify the next protocol. */
|
||||
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
|
||||
|
||||
/* N.B., if this IP packet header includes Options, then the following
|
||||
assignment results in a pointer into the protocol packet with the Ethernet
|
||||
and IP headers incorrectly aligned. However, either way, the "third"
|
||||
protocol (Layer 3 or 4) header will be aligned, which is the convenience
|
||||
of this calculation. */
|
||||
pxProtPack = ( ProtocolPacket_t * ) ( pucEthernetBuffer + ( uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ) );
|
||||
|
||||
/* Switch on the Layer 3/4 protocol. */
|
||||
if( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP )
|
||||
{
|
||||
if( uxBufferLength < uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_UDP_HEADER )
|
||||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
|
||||
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) );
|
||||
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
|
||||
{
|
||||
@ -1767,7 +1854,12 @@ uint8_t ucProtocol;
|
||||
}
|
||||
else if( ucProtocol == ( uint8_t ) ipPROTOCOL_TCP )
|
||||
{
|
||||
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
|
||||
if( uxBufferLength < uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_TCP_HEADER )
|
||||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
|
||||
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
|
||||
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
|
||||
{
|
||||
pcType = "TCP";
|
||||
@ -1777,8 +1869,12 @@ uint8_t ucProtocol;
|
||||
else if( ( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) ||
|
||||
( ucProtocol == ( uint8_t ) ipPROTOCOL_IGMP ) )
|
||||
{
|
||||
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
|
||||
|
||||
if( uxBufferLength < uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_ICMP_HEADER )
|
||||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
|
||||
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
|
||||
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
|
||||
{
|
||||
if( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
|
||||
@ -1798,6 +1894,8 @@ uint8_t ucProtocol;
|
||||
return ipUNHANDLED_PROTOCOL;
|
||||
}
|
||||
|
||||
/* The protocol and checksum field have been identified. Check the direction
|
||||
of the packet. */
|
||||
if( xOutgoingPacket != pdFALSE )
|
||||
{
|
||||
/* This is an outgoing packet. Before calculating the checksum, set it
|
||||
@ -1844,7 +1942,7 @@ uint8_t ucProtocol;
|
||||
/* And then continue at the IPv4 source and destination addresses. */
|
||||
usChecksum = ( uint16_t )
|
||||
( ~usGenerateChecksum( ( uint32_t ) usChecksum, ( uint8_t * )&( pxIPPacket->xIPHeader.ulSourceIPAddress ),
|
||||
( size_t )( 2u * sizeof( pxIPPacket->xIPHeader.ulSourceIPAddress ) + ulLength ) ) );
|
||||
( 2u * sizeof( pxIPPacket->xIPHeader.ulSourceIPAddress ) + ulLength ) ) );
|
||||
|
||||
/* Sum TCP header and data. */
|
||||
}
|
||||
@ -1897,6 +1995,39 @@ uint8_t ucProtocol;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* This method generates a checksum for a given IPv4 header, per RFC791 (page 14).
|
||||
* The checksum algorithm is decribed as:
|
||||
* "[T]he 16 bit one's complement of the one's complement sum of all 16 bit words in the
|
||||
* header. For purposes of computing the checksum, the value of the checksum field is zero."
|
||||
*
|
||||
* In a nutshell, that means that each 16-bit 'word' must be summed, after which
|
||||
* the number of 'carries' (overflows) is added to the result. If that addition
|
||||
* produces an overflow, that 'carry' must also be added to the final result. The final checksum
|
||||
* should be the bitwise 'not' (ones-complement) of the result if the packet is
|
||||
* meant to be transmitted, but this method simply returns the raw value, probably
|
||||
* because when a packet is received, the checksum is verified by checking that
|
||||
* ((received & calculated) == 0) without applying a bitwise 'not' to the 'calculated' checksum.
|
||||
*
|
||||
* This logic is optimized for microcontrollers which have limited resources, so the logic looks odd.
|
||||
* It iterates over the full range of 16-bit words, but it does so by processing several 32-bit
|
||||
* words at once whenever possible. Its first step is to align the memory pointer to a 32-bit boundary,
|
||||
* after which it runs a fast loop to process multiple 32-bit words at once and adding their 'carries'.
|
||||
* Finally, it finishes up by processing any remaining 16-bit words, and adding up all of the 'carries'.
|
||||
* With 32-bit arithmetic, the number of 16-bit 'carries' produced by sequential additions can be found
|
||||
* by looking at the 16 most-significant bits of the 32-bit integer, since a 32-bit int will continue
|
||||
* counting up instead of overflowing after 16 bits. That is why the actual checksum calculations look like:
|
||||
* union.u32 = ( uint32_t ) union.u16[ 0 ] + union.u16[ 1 ];
|
||||
*
|
||||
* Arguments:
|
||||
* ulSum: This argument provides a value to initialize the progressive summation
|
||||
* of the header's values to. It is often 0, but protocols like TCP or UDP
|
||||
* can have pseudo-header fields which need to be included in the checksum.
|
||||
* pucNextData: This argument contains the address of the first byte which this
|
||||
* method should process. The method's memory iterator is initialized to this value.
|
||||
* uxDataLengthBytes: This argument contains the number of bytes that this method
|
||||
* should process.
|
||||
*/
|
||||
uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes )
|
||||
{
|
||||
xUnion32 xSum2, xSum, xTerm;
|
||||
@ -2095,8 +2226,8 @@ uint32_t FreeRTOS_GetNetmask( void )
|
||||
|
||||
void FreeRTOS_UpdateMACAddress( const uint8_t ucMACAddress[ipMAC_ADDRESS_LENGTH_BYTES] )
|
||||
{
|
||||
/* Copy the MAC address at the start of the default packet header fragment. */
|
||||
memcpy( ( void * )ipLOCAL_MAC_ADDRESS, ( void * )ucMACAddress, ( size_t )ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
/* Copy the MAC address at the start of the default packet header fragment. */
|
||||
memcpy( ( void * )ipLOCAL_MAC_ADDRESS, ( void * )ucMACAddress, ( size_t )ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -54,18 +54,16 @@ xBoundUDPSocketsList or xBoundTCPSocketsList */
|
||||
number then, depending on the FreeRTOSIPConfig.h settings, it might be that a
|
||||
port number is automatically generated for the socket. Automatically generated
|
||||
port numbers will be between socketAUTO_PORT_ALLOCATION_START_NUMBER and
|
||||
0xffff. */
|
||||
/* _HT_ thinks that the default of 0xc000 is pretty high */
|
||||
0xffff.
|
||||
|
||||
Per https://tools.ietf.org/html/rfc6056, "the dynamic ports consist of the range
|
||||
49152-65535. However, ephemeral port selection algorithms should use the whole
|
||||
range 1024-65535" excluding those already in use (inbound or outbound). */
|
||||
#if !defined( socketAUTO_PORT_ALLOCATION_START_NUMBER )
|
||||
#define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0xc000 )
|
||||
#define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0x0400 )
|
||||
#endif
|
||||
|
||||
/* When the automatically generated port numbers overflow, the next value used
|
||||
is not set back to socketAUTO_PORT_ALLOCATION_START_NUMBER because it is likely
|
||||
that the first few automatically generated ports will still be in use. Instead
|
||||
it is reset back to the value defined by this constant. */
|
||||
#define socketAUTO_PORT_ALLOCATION_RESET_NUMBER ( ( uint16_t ) 0xc100 )
|
||||
#define socketAUTO_PORT_ALLOCATION_MAX_NUMBER ( ( uint16_t ) 0xff00 )
|
||||
#define socketAUTO_PORT_ALLOCATION_MAX_NUMBER ( ( uint16_t ) 0xffff )
|
||||
|
||||
/* The number of octets that make up an IP address. */
|
||||
#define socketMAX_IP_ADDRESS_OCTETS 4u
|
||||
@ -165,15 +163,6 @@ List_t xBoundUDPSocketsList;
|
||||
List_t xBoundTCPSocketsList;
|
||||
#endif /* ipconfigUSE_TCP == 1 */
|
||||
|
||||
/* Holds the next private port number to use when binding a client socket for
|
||||
UDP, and if ipconfigUSE_TCP is set to 1, also TCP. UDP uses index
|
||||
socketNEXT_UDP_PORT_NUMBER_INDEX and TCP uses index
|
||||
socketNEXT_TCP_PORT_NUMBER_INDEX. The initial value is set to be between
|
||||
socketAUTO_PORT_ALLOCATION_RESET_NUMBER and socketAUTO_PORT_ALLOCATION_MAX_NUMBER
|
||||
when the IP stack is initialised. Note ipconfigRAND32() is used, which must be
|
||||
seeded prior to the IP task being started. */
|
||||
static uint16_t usNextPortToUse[ socketPROTOCOL_COUNT ] = { 0 };
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvValidSocket( FreeRTOS_Socket_t *pxSocket, BaseType_t xProtocol, BaseType_t xIsBound )
|
||||
@ -199,35 +188,17 @@ BaseType_t xReturn = pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vNetworkSocketsInit( void )
|
||||
BaseType_t vNetworkSocketsInit( void )
|
||||
{
|
||||
const uint32_t ulAutoPortRange = socketAUTO_PORT_ALLOCATION_MAX_NUMBER - socketAUTO_PORT_ALLOCATION_RESET_NUMBER;
|
||||
uint32_t ulRandomPort;
|
||||
vListInitialise( &xBoundUDPSocketsList );
|
||||
|
||||
vListInitialise( &xBoundUDPSocketsList );
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
{
|
||||
vListInitialise( &xBoundTCPSocketsList );
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP == 1 */
|
||||
|
||||
/* Determine the first anonymous UDP port number to get assigned. Give it
|
||||
a random value in order to avoid confusion about port numbers being used
|
||||
earlier, before rebooting the device. Start with the first auto port
|
||||
number, then add a random offset up to a maximum of the range of numbers. */
|
||||
ulRandomPort = socketAUTO_PORT_ALLOCATION_START_NUMBER;
|
||||
ulRandomPort += ( ipconfigRAND32() % ulAutoPortRange );
|
||||
usNextPortToUse[ socketNEXT_UDP_PORT_NUMBER_INDEX ] = ( uint16_t ) ulRandomPort;
|
||||
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
{
|
||||
extern uint32_t ulNextInitialSequenceNumber;
|
||||
|
||||
ulNextInitialSequenceNumber = ipconfigRAND32();
|
||||
|
||||
/* Determine the first anonymous TCP port number to get assigned. */
|
||||
ulRandomPort = socketAUTO_PORT_ALLOCATION_START_NUMBER;
|
||||
ulRandomPort += ( ipconfigRAND32() % ulAutoPortRange );
|
||||
usNextPortToUse[ socketNEXT_TCP_PORT_NUMBER_INDEX ] = ( uint16_t ) ulRandomPort;
|
||||
|
||||
vListInitialise( &xBoundTCPSocketsList );
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP == 1 */
|
||||
return pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@ -261,6 +232,7 @@ FreeRTOS_Socket_t *pxSocket;
|
||||
if( xType != FREERTOS_SOCK_DGRAM )
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
configASSERT( xReturn );
|
||||
}
|
||||
/* In case a UDP socket is created, do not allocate space for TCP data. */
|
||||
*pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xUDP );
|
||||
@ -271,6 +243,7 @@ FreeRTOS_Socket_t *pxSocket;
|
||||
if( xType != FREERTOS_SOCK_STREAM )
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
configASSERT( xReturn );
|
||||
}
|
||||
|
||||
*pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xTCP );
|
||||
@ -279,6 +252,7 @@ FreeRTOS_Socket_t *pxSocket;
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
configASSERT( xReturn );
|
||||
}
|
||||
}
|
||||
/* In case configASSERT() is not used */
|
||||
@ -320,7 +294,7 @@ Socket_t xReturn;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the entire space to avoid nulling individual entries. */
|
||||
/* Clear the entire space to avoid nulling individual entries */
|
||||
memset( pxSocket, '\0', uxSocketSize );
|
||||
|
||||
pxSocket->xEventGroup = xEventGroup;
|
||||
@ -1016,14 +990,12 @@ List_t *pxSocketList;
|
||||
#if( ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 )
|
||||
{
|
||||
/* pxAddress will be NULL if sendto() was called on a socket without the
|
||||
socket being bound to an address. In this case, automatically allocate
|
||||
an address to the socket. There is a very tiny chance that the allocated
|
||||
port will already be in use - if that is the case, then the check below
|
||||
[pxListFindListItemWithValue()] will result in an error being returned. */
|
||||
socket being bound to an address. In this case, automatically allocate
|
||||
an address and port to the socket. */
|
||||
if( pxAddress == NULL )
|
||||
{
|
||||
pxAddress = &xAddress;
|
||||
/* For now, put it to zero, will be assigned later */
|
||||
/* Put the port to zero to be assigned later. */
|
||||
pxAddress->sin_port = 0u;
|
||||
}
|
||||
}
|
||||
@ -1037,7 +1009,11 @@ List_t *pxSocketList;
|
||||
{
|
||||
if( pxAddress->sin_port == 0u )
|
||||
{
|
||||
pxAddress->sin_port = prvGetPrivatePortNumber( ( BaseType_t ) pxSocket->ucProtocol );
|
||||
pxAddress->sin_port = prvGetPrivatePortNumber( ( BaseType_t )pxSocket->ucProtocol );
|
||||
if( 0 == pxAddress->sin_port )
|
||||
{
|
||||
return -pdFREERTOS_ERRNO_EADDRNOTAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If vSocketBind() is called from the API FreeRTOS_bind() it has been
|
||||
@ -1524,7 +1500,7 @@ FreeRTOS_Socket_t *pxSocket;
|
||||
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bHasInit != pdFALSE_UNSIGNED )
|
||||
{
|
||||
pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength = pxSocket->u.xTCP.uxRxWinSize * pxSocket->u.xTCP.usInitMSS;
|
||||
pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength = pxSocket->u.xTCP.uxTxWinSize * pxSocket->u.xTCP.usInitMSS;
|
||||
pxSocket->u.xTCP.xTCPWindow.xSize.ulTxWindowLength = pxSocket->u.xTCP.uxTxWinSize * pxSocket->u.xTCP.usInitMSS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1631,54 +1607,77 @@ FreeRTOS_Socket_t *pxSocket;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Get a free private ('anonymous') port number */
|
||||
/* Find an available port number per https://tools.ietf.org/html/rfc6056. */
|
||||
static uint16_t prvGetPrivatePortNumber( BaseType_t xProtocol )
|
||||
{
|
||||
uint16_t usResult;
|
||||
BaseType_t xIndex;
|
||||
const uint16_t usEphemeralPortCount =
|
||||
socketAUTO_PORT_ALLOCATION_MAX_NUMBER - socketAUTO_PORT_ALLOCATION_START_NUMBER + 1;
|
||||
uint16_t usIterations = usEphemeralPortCount;
|
||||
uint32_t ulRandomSeed = 0;
|
||||
uint16_t usResult = 0;
|
||||
BaseType_t xGotZeroOnce = pdFALSE;
|
||||
const List_t *pxList;
|
||||
|
||||
#if ipconfigUSE_TCP == 1
|
||||
if( xProtocol == ( BaseType_t ) FREERTOS_IPPROTO_TCP )
|
||||
{
|
||||
xIndex = socketNEXT_TCP_PORT_NUMBER_INDEX;
|
||||
pxList = &xBoundTCPSocketsList;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
xIndex = socketNEXT_UDP_PORT_NUMBER_INDEX;
|
||||
pxList = &xBoundUDPSocketsList;
|
||||
}
|
||||
|
||||
/* Avoid compiler warnings if ipconfigUSE_TCP is not defined. */
|
||||
( void ) xProtocol;
|
||||
|
||||
/* Assign the next port in the range. Has it overflowed? */
|
||||
/*_RB_ This needs to be randomised rather than sequential. */
|
||||
/* _HT_ Agreed, although many OS's use sequential port numbers, see
|
||||
https://www.cymru.com/jtk/misc/ephemeralports.html */
|
||||
for ( ;; )
|
||||
{
|
||||
++( usNextPortToUse[ xIndex ] );
|
||||
/* Find the next available port using the random seed as a starting
|
||||
point. */
|
||||
do
|
||||
{
|
||||
/* Generate a random seed. */
|
||||
ulRandomSeed = ipconfigRAND32( );
|
||||
|
||||
if( usNextPortToUse[ xIndex ] >= socketAUTO_PORT_ALLOCATION_MAX_NUMBER )
|
||||
{
|
||||
/* Don't go right back to the start of the dynamic/private port
|
||||
range numbers as any persistent sockets are likely to have been
|
||||
create first so the early port numbers may still be in use. */
|
||||
usNextPortToUse[ xIndex ] = socketAUTO_PORT_ALLOCATION_RESET_NUMBER;
|
||||
}
|
||||
/* Only proceed if the random number generator succeeded. */
|
||||
if( 0 == ulRandomSeed )
|
||||
{
|
||||
if( pdFALSE == xGotZeroOnce )
|
||||
{
|
||||
xGotZeroOnce = pdTRUE;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
usResult = FreeRTOS_htons( usNextPortToUse[ xIndex ] );
|
||||
/* Map the random to a candidate port. */
|
||||
usResult =
|
||||
socketAUTO_PORT_ALLOCATION_START_NUMBER +
|
||||
( ( ( uint16_t )ulRandomSeed ) % usEphemeralPortCount );
|
||||
|
||||
if( pxListFindListItemWithValue( pxList, ( TickType_t ) usResult ) == NULL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return usResult;
|
||||
} /* Tested */
|
||||
/* Check if there's already an open socket with the same protocol
|
||||
and port. */
|
||||
if( NULL == pxListFindListItemWithValue(
|
||||
pxList,
|
||||
( TickType_t )FreeRTOS_htons( usResult ) ) )
|
||||
{
|
||||
usResult = FreeRTOS_htons( usResult );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
usResult = 0;
|
||||
}
|
||||
|
||||
usIterations--;
|
||||
}
|
||||
while( usIterations > 0 );
|
||||
|
||||
return usResult;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* pxListFindListItemWithValue: find a list item in a bound socket list
|
||||
@ -1889,7 +1888,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||
/* This define makes it possible for network-card drivers to inspect
|
||||
* UDP message and see if there is any UDP socket bound to a given port
|
||||
* number.
|
||||
* This is probably only useful in systems with a minimum of RAM and
|
||||
* This is probably only usefull in systems with a minimum of RAM and
|
||||
* when lots of anonymous broadcast messages come in
|
||||
*/
|
||||
BaseType_t xPortHasUDPSocket( uint16_t usPortNr )
|
||||
@ -2374,9 +2373,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||
{
|
||||
xResult = -pdFREERTOS_ERRNO_ENOMEM;
|
||||
}
|
||||
else if( ( pxSocket->u.xTCP.ucTCPState == eCLOSED ) ||
|
||||
( pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ) ||
|
||||
( pxSocket->u.xTCP.ucTCPState == eCLOSING ) )
|
||||
else if( pxSocket->u.xTCP.ucTCPState == eCLOSED )
|
||||
{
|
||||
xResult = -pdFREERTOS_ERRNO_ENOTCONN;
|
||||
}
|
||||
@ -2875,7 +2872,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
|
||||
static StreamBuffer_t *prvTCPCreateStream( FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream )
|
||||
static StreamBuffer_t *prvTCPCreateStream ( FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream )
|
||||
{
|
||||
StreamBuffer_t *pxBuffer;
|
||||
size_t uxLength;
|
||||
@ -2885,26 +2882,11 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||
creation, it could still be changed with setsockopt(). */
|
||||
if( xIsInputStream != pdFALSE )
|
||||
{
|
||||
/* Flow control for input streams works with a low- and a high-water mark.
|
||||
1) If the RX-space becomes less than uxLittleSpace, the flag 'bLowWater' will
|
||||
be set, and a TCP window update message will be sent to the peer.
|
||||
2) The data will be read from the socket by recv() and when RX-space becomes
|
||||
larger than or equal to than 'uxEnoughSpace', a new TCP window update
|
||||
message will be sent to the peer, and 'bLowWater' will get cleared again.
|
||||
By default:
|
||||
uxLittleSpace == 1/5 x uxRxStreamSize
|
||||
uxEnoughSpace == 4/5 x uxRxStreamSize
|
||||
How-ever it is very inefficient to make 'uxLittleSpace' smaller than the actual MSS.
|
||||
*/
|
||||
uxLength = pxSocket->u.xTCP.uxRxStreamSize;
|
||||
|
||||
if( pxSocket->u.xTCP.uxLittleSpace == 0ul )
|
||||
{
|
||||
pxSocket->u.xTCP.uxLittleSpace = ( 1ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why divide by 5? Can this be changed to a #define? */
|
||||
if( ( pxSocket->u.xTCP.uxLittleSpace < pxSocket->u.xTCP.usCurMSS ) && ( pxSocket->u.xTCP.uxRxStreamSize >= 2u * pxSocket->u.xTCP.usCurMSS ) )
|
||||
{
|
||||
pxSocket->u.xTCP.uxLittleSpace = pxSocket->u.xTCP.usCurMSS;
|
||||
}
|
||||
}
|
||||
|
||||
if( pxSocket->u.xTCP.uxEnoughSpace == 0ul )
|
||||
@ -3047,10 +3029,8 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||
break;
|
||||
}
|
||||
|
||||
if( pxSocket->u.xTCP.pxHandleReceive( (Socket_t *)pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount ) != pdFALSE )
|
||||
{
|
||||
uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );
|
||||
}
|
||||
pxSocket->u.xTCP.pxHandleReceive( (Socket_t *)pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );
|
||||
uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );
|
||||
}
|
||||
} else
|
||||
#endif /* ipconfigUSE_CALLBACKS */
|
||||
@ -3378,12 +3358,13 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||
char ucChildText[16] = "";
|
||||
if (pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN)
|
||||
{
|
||||
snprintf( ucChildText, sizeof( ucChildText ), " %d/%d",
|
||||
pxSocket->u.xTCP.usChildCount,
|
||||
pxSocket->u.xTCP.usBacklog);
|
||||
const int32_t copied_len = snprintf( ucChildText, sizeof( ucChildText ), " %d/%d",
|
||||
( int ) pxSocket->u.xTCP.usChildCount,
|
||||
( int ) pxSocket->u.xTCP.usBacklog);
|
||||
/* These should never evaluate to false since the buffers are both shorter than 5-6 characters (<=65535) */
|
||||
configASSERT( copied_len >= 0 );
|
||||
configASSERT( copied_len < sizeof( ucChildText ) );
|
||||
}
|
||||
if( age > 999999 )
|
||||
age = 999999;
|
||||
FreeRTOS_printf( ( "TCP %5d %-16lxip:%5d %d/%d %-13.13s %6lu %6u%s\n",
|
||||
pxSocket->usLocalPort, /* Local port on this machine */
|
||||
pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine */
|
||||
@ -3391,7 +3372,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||
pxSocket->u.xTCP.rxStream != NULL,
|
||||
pxSocket->u.xTCP.txStream != NULL,
|
||||
FreeRTOS_GetTCPStateName( pxSocket->u.xTCP.ucTCPState ),
|
||||
age,
|
||||
(age > 999999 ? 999999 : age), /* Format 'age' for printing */
|
||||
pxSocket->u.xTCP.usTimeout,
|
||||
ucChildText ) );
|
||||
/* Remove compiler warnings if FreeRTOS_debug_printf() is not defined. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -61,7 +61,7 @@
|
||||
|
||||
/* This compile-time test was moved to here because some macro's
|
||||
were unknown within 'FreeRTOSIPConfigDefaults.h'. It tests whether
|
||||
the defined MTU size can contain at ;east a complete TCP packet. */
|
||||
the defined MTU size can contain at least a complete TCP packet. */
|
||||
|
||||
#if ( ( ipconfigTCP_MSS + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) > ipconfigNETWORK_MTU )
|
||||
#error The ipconfigTCP_MSS setting in FreeRTOSIPConfig.h is too large.
|
||||
@ -137,13 +137,6 @@ the defined MTU size can contain at ;east a complete TCP packet. */
|
||||
*/
|
||||
#define REDUCED_MSS_THROUGH_INTERNET ( 1400 )
|
||||
|
||||
/*
|
||||
* Each time a new TCP connection is being made, a new Initial Sequence Number shall be used.
|
||||
* The variable 'ulNextInitialSequenceNumber' will be incremented with a recommended value
|
||||
* of 0x102.
|
||||
*/
|
||||
#define INITIAL_SEQUENCE_NUMBER_INCREMENT ( 0x102UL )
|
||||
|
||||
/*
|
||||
* When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
|
||||
* the number 5 (words) in the higher niblle of the TCP-offset byte.
|
||||
@ -269,10 +262,6 @@ static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket );
|
||||
*/
|
||||
static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
|
||||
|
||||
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
|
||||
static UBaseType_t prvTCPSetTimeStamp( BaseType_t lOffset, FreeRTOS_Socket_t *pxSocket, TCPHeader_t *pxTCPHeader );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Called from prvTCPHandleState(). Find the TCP payload data and check and
|
||||
* return its length.
|
||||
@ -360,12 +349,14 @@ static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocke
|
||||
static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket );
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Initial Sequence Number, i.e. the next initial sequence number that will be
|
||||
used when a new connection is opened. The value should be randomized to prevent
|
||||
attacks from outside (spoofing). */
|
||||
uint32_t ulNextInitialSequenceNumber = 0ul;
|
||||
/*
|
||||
* Generate a randomized TCP Initial Sequence Number per RFC.
|
||||
*/
|
||||
extern uint32_t ulApplicationGetNextSequenceNumber(
|
||||
uint32_t ulSourceAddress,
|
||||
uint16_t usSourcePort,
|
||||
uint32_t ulDestinationAddress,
|
||||
uint16_t usDestinationPort );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@ -480,11 +471,11 @@ BaseType_t xReady = pdFALSE;
|
||||
if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.txStream != NULL ) )
|
||||
{
|
||||
/* The API FreeRTOS_send() might have added data to the TX stream. Add
|
||||
this data to the windowing system so it can be transmitted. */
|
||||
this data to the windowing system to it can be transmitted. */
|
||||
prvTCPAddTxData( pxSocket );
|
||||
}
|
||||
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
#if ipconfigUSE_TCP_WIN == 1
|
||||
{
|
||||
if( pxSocket->u.xTCP.pxAckMessage != NULL )
|
||||
{
|
||||
@ -577,7 +568,7 @@ NetworkBufferDescriptor_t *pxNetworkBuffer;
|
||||
|
||||
if( pxSocket->u.xTCP.ucTCPState != eCONNECT_SYN )
|
||||
{
|
||||
/* The connection is in a state other than SYN. */
|
||||
/* The connection is in s state other than SYN. */
|
||||
pxNetworkBuffer = NULL;
|
||||
|
||||
/* prvTCPSendRepeated() will only create a network buffer if necessary,
|
||||
@ -609,18 +600,6 @@ NetworkBufferDescriptor_t *pxNetworkBuffer;
|
||||
the Ethernet address of the peer or the gateway is found. */
|
||||
pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
||||
|
||||
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
|
||||
{
|
||||
/* When TCP time stamps are enabled, but they will only be applied
|
||||
if the peer is outside the netmask, usually on the internet.
|
||||
Packages sent on a LAN are usually too big to carry time stamps. */
|
||||
if( ( ( pxSocket->u.xTCP.ulRemoteIP ^ FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) ) & xNetworkAddressing.ulNetMask ) != 0ul )
|
||||
{
|
||||
pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps = pdTRUE_UNSIGNED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* About to send a SYN packet. Call prvSetSynAckOptions() to set
|
||||
the proper options: The size of MSS and whether SACK's are
|
||||
allowed. */
|
||||
@ -707,12 +686,15 @@ NetworkBufferDescriptor_t xTempBuffer;
|
||||
|
||||
if( pxNetworkBuffer == NULL )
|
||||
{
|
||||
memset( &xTempBuffer, '\0', sizeof( xTempBuffer ) );
|
||||
pxNetworkBuffer = &xTempBuffer;
|
||||
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
xTempBuffer.pxNextBuffer = NULL;
|
||||
}
|
||||
#endif
|
||||
xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
||||
xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
|
||||
/* A pseudo network buffer can not be released. */
|
||||
xReleaseAfterSend = pdFALSE;
|
||||
}
|
||||
|
||||
@ -903,7 +885,7 @@ NetworkBufferDescriptor_t xTempBuffer;
|
||||
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
|
||||
|
||||
/* calculate the TCP checksum for an outgoing packet. */
|
||||
usGenerateProtocolChecksum( (uint8_t*)pxTCPPacket, pdTRUE );
|
||||
usGenerateProtocolChecksum( (uint8_t*)pxTCPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
|
||||
|
||||
/* A calculated checksum of 0 must be inverted as 0 means the checksum
|
||||
is disabled. */
|
||||
@ -914,11 +896,9 @@ NetworkBufferDescriptor_t xTempBuffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
pxNetworkBuffer->pxNextBuffer = NULL;
|
||||
}
|
||||
#endif
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
pxNetworkBuffer->pxNextBuffer = NULL;
|
||||
#endif
|
||||
|
||||
/* Important: tell NIC driver how many bytes must be sent. */
|
||||
pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
|
||||
@ -928,7 +908,7 @@ NetworkBufferDescriptor_t xTempBuffer;
|
||||
sizeof( pxEthernetHeader->xDestinationAddress ) );
|
||||
|
||||
/* The source MAC addresses is fixed to 'ipLOCAL_MAC_ADDRESS'. */
|
||||
memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress ), ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress) , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
|
||||
#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
|
||||
{
|
||||
@ -1002,6 +982,7 @@ eARPLookupResult_t eReturned;
|
||||
uint32_t ulRemoteIP;
|
||||
MACAddress_t xEthAddress;
|
||||
BaseType_t xReturn = pdTRUE;
|
||||
uint32_t ulInitialSequenceNumber = 0;
|
||||
|
||||
#if( ipconfigHAS_PRINTF != 0 )
|
||||
{
|
||||
@ -1017,32 +998,47 @@ BaseType_t xReturn = pdTRUE;
|
||||
|
||||
switch( eReturned )
|
||||
{
|
||||
case eARPCacheHit: /* An ARP table lookup found a valid entry. */
|
||||
break; /* We can now prepare the SYN packet. */
|
||||
case eARPCacheMiss: /* An ARP table lookup did not find a valid entry. */
|
||||
case eCantSendPacket: /* There is no IP address, or an ARP is still in progress. */
|
||||
default:
|
||||
/* Count the number of times it couldn't find the ARP address. */
|
||||
pxSocket->u.xTCP.ucRepCount++;
|
||||
case eARPCacheHit: /* An ARP table lookup found a valid entry. */
|
||||
break; /* We can now prepare the SYN packet. */
|
||||
case eARPCacheMiss: /* An ARP table lookup did not find a valid entry. */
|
||||
case eCantSendPacket: /* There is no IP address, or an ARP is still in progress. */
|
||||
default:
|
||||
/* Count the number of times it couldn't find the ARP address. */
|
||||
pxSocket->u.xTCP.ucRepCount++;
|
||||
|
||||
FreeRTOS_debug_printf( ( "ARP for %lxip (using %lxip): rc=%d %02X:%02X:%02X %02X:%02X:%02X\n",
|
||||
pxSocket->u.xTCP.ulRemoteIP,
|
||||
FreeRTOS_htonl( ulRemoteIP ),
|
||||
eReturned,
|
||||
xEthAddress.ucBytes[ 0 ],
|
||||
xEthAddress.ucBytes[ 1 ],
|
||||
xEthAddress.ucBytes[ 2 ],
|
||||
xEthAddress.ucBytes[ 3 ],
|
||||
xEthAddress.ucBytes[ 4 ],
|
||||
xEthAddress.ucBytes[ 5 ] ) );
|
||||
FreeRTOS_debug_printf( ( "ARP for %lxip (using %lxip): rc=%d %02X:%02X:%02X %02X:%02X:%02X\n",
|
||||
pxSocket->u.xTCP.ulRemoteIP,
|
||||
FreeRTOS_htonl( ulRemoteIP ),
|
||||
eReturned,
|
||||
xEthAddress.ucBytes[ 0 ],
|
||||
xEthAddress.ucBytes[ 1 ],
|
||||
xEthAddress.ucBytes[ 2 ],
|
||||
xEthAddress.ucBytes[ 3 ],
|
||||
xEthAddress.ucBytes[ 4 ],
|
||||
xEthAddress.ucBytes[ 5 ] ) );
|
||||
|
||||
/* And issue a (new) ARP request */
|
||||
FreeRTOS_OutputARPRequest( ulRemoteIP );
|
||||
/* And issue a (new) ARP request */
|
||||
FreeRTOS_OutputARPRequest( ulRemoteIP );
|
||||
|
||||
xReturn = pdFALSE;
|
||||
break;
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
if( xReturn != pdFALSE )
|
||||
{
|
||||
/* Get a difficult-to-predict initial sequence number for this 4-tuple. */
|
||||
ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber(
|
||||
*ipLOCAL_IP_ADDRESS_POINTER,
|
||||
pxSocket->usLocalPort,
|
||||
pxSocket->u.xTCP.ulRemoteIP,
|
||||
pxSocket->u.xTCP.usRemotePort );
|
||||
|
||||
/* Check for a random number generation error. */
|
||||
if( 0 == ulInitialSequenceNumber )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if( xReturn != pdFALSE )
|
||||
{
|
||||
/* The MAC-address of the peer (or gateway) has been found,
|
||||
@ -1050,10 +1046,10 @@ BaseType_t xReturn = pdTRUE;
|
||||
pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
||||
pxIPHeader = &pxTCPPacket->xIPHeader;
|
||||
|
||||
/* Reset the retry counter to zero... */
|
||||
/* reset the retry counter to zero. */
|
||||
pxSocket->u.xTCP.ucRepCount = 0u;
|
||||
|
||||
/* ...and remember that the connect/SYN data are prepared. */
|
||||
/* And remember that the connect/SYN data are prepared. */
|
||||
pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE_UNSIGNED;
|
||||
|
||||
/* Now that the Ethernet address is known, the initial packet can be
|
||||
@ -1086,11 +1082,7 @@ BaseType_t xReturn = pdTRUE;
|
||||
pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 0ul;
|
||||
|
||||
/* Start with ISN (Initial Sequence Number). */
|
||||
pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulNextInitialSequenceNumber;
|
||||
|
||||
/* And increment it with 268 for the next new connection, which is
|
||||
recommended value. */
|
||||
ulNextInitialSequenceNumber += 0x102UL;
|
||||
pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
|
||||
|
||||
/* The TCP header size is 20 bytes, divided by 4 equals 5, which is put in
|
||||
the high nibble of the TCP offset field. */
|
||||
@ -1160,38 +1152,73 @@ UBaseType_t uxNewMSS;
|
||||
pucLast = pucPtr + (((pxTCPHeader->ucTCPOffset >> 4) - 5) << 2);
|
||||
pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
|
||||
|
||||
/* Validate options size calculation. */
|
||||
if( pucLast > ( pxNetworkBuffer->pucEthernetBuffer + pxNetworkBuffer->xDataLength ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* The comparison with pucLast is only necessary in case the option data are
|
||||
corrupted, we don't like to run into invalid memory and crash. */
|
||||
while( pucPtr < pucLast )
|
||||
{
|
||||
UBaseType_t xRemainingOptionsBytes = pucLast - pucPtr;
|
||||
|
||||
if( pucPtr[ 0 ] == TCP_OPT_END )
|
||||
{
|
||||
/* End of options. */
|
||||
return;
|
||||
break;
|
||||
}
|
||||
if( pucPtr[ 0 ] == TCP_OPT_NOOP)
|
||||
{
|
||||
pucPtr++;
|
||||
|
||||
/* NOP option, inserted to make the length a multiple of 4. */
|
||||
/* NOP option, inserted to make the length a multiple of 4. */
|
||||
pucPtr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Any other well-formed option must be at least two bytes: the option
|
||||
type byte followed by a length byte. */
|
||||
if( xRemainingOptionsBytes < 2 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
#if( ipconfigUSE_TCP_WIN != 0 )
|
||||
else if( ( pucPtr[ 0 ] == TCP_OPT_WSOPT ) && ( pucPtr[ 1 ] == TCP_OPT_WSOPT_LEN ) )
|
||||
else if( pucPtr[ 0 ] == TCP_OPT_WSOPT )
|
||||
{
|
||||
/* Confirm that the option fits in the remaining buffer space. */
|
||||
if( xRemainingOptionsBytes < TCP_OPT_WSOPT_LEN ||
|
||||
pucPtr[ 1 ] != TCP_OPT_WSOPT_LEN )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ];
|
||||
pxSocket->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
|
||||
pucPtr += TCP_OPT_WSOPT_LEN;
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP_WIN */
|
||||
else if( ( pucPtr[ 0 ] == TCP_OPT_MSS ) && ( pucPtr[ 1 ] == TCP_OPT_MSS_LEN ) )
|
||||
else if( pucPtr[ 0 ] == TCP_OPT_MSS )
|
||||
{
|
||||
/* An MSS option with the correct option length. FreeRTOS_htons()
|
||||
/* Confirm that the option fits in the remaining buffer space. */
|
||||
if( xRemainingOptionsBytes < TCP_OPT_MSS_LEN ||
|
||||
pucPtr[ 1 ] != TCP_OPT_MSS_LEN )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* An MSS option with the correct option length. FreeRTOS_htons()
|
||||
is not needed here because usChar2u16() already returns a host
|
||||
endian number. */
|
||||
uxNewMSS = usChar2u16( pucPtr + 2 );
|
||||
|
||||
if( pxSocket->u.xTCP.usInitMSS != uxNewMSS )
|
||||
{
|
||||
/* Perform a basic check on the the new MSS. */
|
||||
if( uxNewMSS == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", pxSocket->u.xTCP.usInitMSS, uxNewMSS ) );
|
||||
}
|
||||
|
||||
@ -1225,11 +1252,11 @@ UBaseType_t uxNewMSS;
|
||||
{
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
int len = ( int )pucPtr[ 1 ];
|
||||
if( len == 0 )
|
||||
unsigned char len = pucPtr[ 1 ];
|
||||
if( len < 2 || len > xRemainingOptionsBytes )
|
||||
{
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
/* If the length field is too small or too big, the options are malformed.
|
||||
Don't process them further. */
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1284,16 +1311,6 @@ UBaseType_t uxNewMSS;
|
||||
}
|
||||
/* len should be 0 by now. */
|
||||
}
|
||||
#if ipconfigUSE_TCP_TIMESTAMPS == 1
|
||||
else if( pucPtr[0] == TCP_OPT_TIMESTAMP )
|
||||
{
|
||||
len -= 2; /* Skip option and length byte. */
|
||||
pucPtr += 2;
|
||||
pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps = pdTRUE_UNSIGNED;
|
||||
pxSocket->u.xTCP.xTCPWindow.rx.ulTimeStamp = ulChar2u32( pucPtr );
|
||||
pxSocket->u.xTCP.xTCPWindow.tx.ulTimeStamp = ulChar2u32( pucPtr + 4 );
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP_TIMESTAMPS == 1 */
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP_WIN == 1 */
|
||||
|
||||
@ -1371,24 +1388,13 @@ UBaseType_t uxOptionsLength;
|
||||
}
|
||||
#else
|
||||
{
|
||||
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
|
||||
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps )
|
||||
{
|
||||
uxOptionsLength += prvTCPSetTimeStamp( uxOptionsLength, pxSocket, &pxTCPPacket->xTCPHeader );
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = 2u;
|
||||
uxOptionsLength += 2u;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_NOOP;
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = TCP_OPT_NOOP;
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 2 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 3 ] = 2; /* 2: length of this option. */
|
||||
uxOptionsLength += 4u;
|
||||
}
|
||||
return uxOptionsLength; /* bytes, not words. */
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_NOOP;
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = TCP_OPT_NOOP;
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 2 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
|
||||
pxTCPHeader->ucOptdata[ uxOptionsLength + 3 ] = 2; /* 2: length of this option. */
|
||||
uxOptionsLength += 4u;
|
||||
|
||||
return uxOptionsLength; /* bytes, not words. */
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP_WIN == 0 */
|
||||
}
|
||||
@ -1566,7 +1572,7 @@ BaseType_t bAfter = ( BaseType_t ) NOW_CONNECTED( eTCPState ); /* Is it co
|
||||
/* Fill in the new state. */
|
||||
pxSocket->u.xTCP.ucTCPState = ( uint8_t ) eTCPState;
|
||||
|
||||
/* Touch the alive timers because moving to another state. */
|
||||
/* touch the alive timers because moving to another state. */
|
||||
prvTCPTouchSocket( pxSocket );
|
||||
|
||||
#if( ipconfigHAS_DEBUG_PRINTF == 1 )
|
||||
@ -1621,14 +1627,7 @@ BaseType_t xResize;
|
||||
( int32_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen );
|
||||
/* In case we were called from a TCP timer event, a buffer must be
|
||||
created. Otherwise, test 'xDataLength' of the provided buffer. */
|
||||
if( ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded ) )
|
||||
{
|
||||
xResize = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xResize = pdFALSE;
|
||||
}
|
||||
xResize = ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded );
|
||||
}
|
||||
|
||||
if( xResize != pdFALSE )
|
||||
@ -1640,6 +1639,9 @@ BaseType_t xResize;
|
||||
|
||||
if( pxReturn != NULL )
|
||||
{
|
||||
/* Set the actual packet size, in case the returned buffer is larger. */
|
||||
pxReturn->xDataLength = lNeeded;
|
||||
|
||||
/* Copy the existing data to the new created buffer. */
|
||||
if( pxNetworkBuffer )
|
||||
{
|
||||
@ -1695,8 +1697,8 @@ int32_t lStreamPos;
|
||||
pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
|
||||
}
|
||||
|
||||
pxTCPPacket = ( TCPPacket_t * ) pucEthernetBuffer;
|
||||
pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
||||
pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
|
||||
pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
|
||||
lDataLen = 0;
|
||||
lStreamPos = 0;
|
||||
pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_ACK;
|
||||
@ -1848,19 +1850,6 @@ int32_t lStreamPos;
|
||||
pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_PSH;
|
||||
}
|
||||
|
||||
#if ipconfigUSE_TCP_TIMESTAMPS == 1
|
||||
{
|
||||
if( uxOptionsLength == 0u )
|
||||
{
|
||||
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps )
|
||||
{
|
||||
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
|
||||
uxOptionsLength = prvTCPSetTimeStamp( 0, pxSocket, &pxTCPPacket->xTCPHeader );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lDataLen += ( int32_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
|
||||
}
|
||||
|
||||
@ -1941,9 +1930,9 @@ int32_t lCount, lLength;
|
||||
/* A txStream has been created already, see if the socket has new data for
|
||||
the sliding window.
|
||||
|
||||
uxStreamBufferMidSpace() returns the distance between rxHead and rxMid. It
|
||||
contains new Tx data which has not been passed to the sliding window yet.
|
||||
The oldest data not-yet-confirmed can be found at rxTail. */
|
||||
uxStreamBufferMidSpace() returns the distance between rxHead and rxMid. It contains new
|
||||
Tx data which has not been passed to the sliding window yet. The oldest
|
||||
data not-yet-confirmed can be found at rxTail. */
|
||||
lLength = ( int32_t ) uxStreamBufferMidSpace( pxSocket->u.xTCP.txStream );
|
||||
|
||||
if( lLength > 0 )
|
||||
@ -2064,29 +2053,6 @@ uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ipconfigUSE_TCP_TIMESTAMPS == 1
|
||||
|
||||
static UBaseType_t prvTCPSetTimeStamp( BaseType_t lOffset, FreeRTOS_Socket_t *pxSocket, TCPHeader_t *pxTCPHeader )
|
||||
{
|
||||
uint32_t ulTimes[2];
|
||||
uint8_t *ucOptdata = &( pxTCPHeader->ucOptdata[ lOffset ] );
|
||||
|
||||
ulTimes[0] = ( xTaskGetTickCount ( ) * 1000u ) / configTICK_RATE_HZ;
|
||||
ulTimes[0] = FreeRTOS_htonl( ulTimes[0] );
|
||||
ulTimes[1] = FreeRTOS_htonl( pxSocket->u.xTCP.xTCPWindow.rx.ulTimeStamp );
|
||||
ucOptdata[0] = ( uint8_t ) TCP_OPT_TIMESTAMP;
|
||||
ucOptdata[1] = ( uint8_t ) TCP_OPT_TIMESTAMP_LEN;
|
||||
memcpy( &(ucOptdata[2] ), ulTimes, 8u );
|
||||
ucOptdata[10] = ( uint8_t ) TCP_OPT_NOOP;
|
||||
ucOptdata[11] = ( uint8_t ) TCP_OPT_NOOP;
|
||||
/* Do not return the same timestamps 2 times. */
|
||||
pxSocket->u.xTCP.xTCPWindow.rx.ulTimeStamp = 0ul;
|
||||
return 12u;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* prvCheckRxData(): called from prvTCPHandleState()
|
||||
*
|
||||
@ -2279,15 +2245,6 @@ UBaseType_t uxOptionsLength = pxTCPWindow->ucOptionLength;
|
||||
pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
|
||||
}
|
||||
|
||||
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
|
||||
{
|
||||
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps )
|
||||
{
|
||||
uxOptionsLength += prvTCPSetTimeStamp( uxOptionsLength, pxSocket, pxTCPHeader );
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP_TIMESTAMPS == 1 */
|
||||
|
||||
return uxOptionsLength;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@ -2941,16 +2898,31 @@ BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer
|
||||
{
|
||||
FreeRTOS_Socket_t *pxSocket;
|
||||
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
|
||||
uint16_t ucTCPFlags = pxTCPPacket->xTCPHeader.ucTCPFlags;
|
||||
uint32_t ulLocalIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulDestinationIPAddress );
|
||||
uint16_t xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
|
||||
uint32_t ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
|
||||
uint16_t xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
|
||||
uint16_t ucTCPFlags;
|
||||
uint32_t ulLocalIP;
|
||||
uint16_t xLocalPort;
|
||||
uint32_t ulRemoteIP;
|
||||
uint16_t xRemotePort;
|
||||
BaseType_t xResult = pdPASS;
|
||||
|
||||
/* Find the destination socket, and if not found: return a socket listing to
|
||||
the destination PORT. */
|
||||
pxSocket = ( FreeRTOS_Socket_t * ) pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort );
|
||||
/* Check for a minimum packet size. */
|
||||
if( pxNetworkBuffer->xDataLength >=
|
||||
ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER )
|
||||
{
|
||||
ucTCPFlags = pxTCPPacket->xTCPHeader.ucTCPFlags;
|
||||
ulLocalIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulDestinationIPAddress );
|
||||
xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
|
||||
ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
|
||||
xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
|
||||
|
||||
/* Find the destination socket, and if not found: return a socket listing to
|
||||
the destination PORT. */
|
||||
pxSocket = ( FreeRTOS_Socket_t * )pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort );
|
||||
}
|
||||
else
|
||||
{
|
||||
return pdFAIL;
|
||||
}
|
||||
|
||||
if( ( pxSocket == NULL ) || ( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE ) )
|
||||
{
|
||||
@ -3111,59 +3083,71 @@ BaseType_t xResult = pdPASS;
|
||||
static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
|
||||
FreeRTOS_Socket_t *pxReturn;
|
||||
FreeRTOS_Socket_t *pxReturn = NULL;
|
||||
uint32_t ulInitialSequenceNumber;
|
||||
|
||||
/* Assume that a new Initial Sequence Number will be required. Request
|
||||
it now in order to fail out if necessary. */
|
||||
ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber(
|
||||
*ipLOCAL_IP_ADDRESS_POINTER,
|
||||
pxSocket->usLocalPort,
|
||||
pxTCPPacket->xIPHeader.ulSourceIPAddress,
|
||||
pxTCPPacket->xTCPHeader.usSourcePort );
|
||||
|
||||
/* A pure SYN (without ACK) has come in, create a new socket to answer
|
||||
it. */
|
||||
if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
|
||||
{
|
||||
/* The flag bReuseSocket indicates that the same instance of the
|
||||
listening socket should be used for the connection. */
|
||||
pxReturn = pxSocket;
|
||||
pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
|
||||
pxSocket->u.xTCP.pxPeerSocket = pxSocket;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The socket does not have the bReuseSocket flag set meaning create a
|
||||
new socket when a connection comes in. */
|
||||
pxReturn = NULL;
|
||||
if( 0 != ulInitialSequenceNumber )
|
||||
{
|
||||
if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
|
||||
{
|
||||
/* The flag bReuseSocket indicates that the same instance of the
|
||||
listening socket should be used for the connection. */
|
||||
pxReturn = pxSocket;
|
||||
pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
|
||||
pxSocket->u.xTCP.pxPeerSocket = pxSocket;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The socket does not have the bReuseSocket flag set meaning create a
|
||||
new socket when a connection comes in. */
|
||||
pxReturn = NULL;
|
||||
|
||||
if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog )
|
||||
{
|
||||
FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n",
|
||||
pxSocket->usLocalPort,
|
||||
pxSocket->u.xTCP.usChildCount,
|
||||
pxSocket->u.xTCP.usBacklog,
|
||||
pxSocket->u.xTCP.usChildCount == 1 ? "" : "ren" ) );
|
||||
prvTCPSendReset( pxNetworkBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_Socket_t *pxNewSocket = (FreeRTOS_Socket_t *)
|
||||
FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog )
|
||||
{
|
||||
FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n",
|
||||
pxSocket->usLocalPort,
|
||||
pxSocket->u.xTCP.usChildCount,
|
||||
pxSocket->u.xTCP.usBacklog,
|
||||
pxSocket->u.xTCP.usChildCount == 1 ? "" : "ren" ) );
|
||||
prvTCPSendReset( pxNetworkBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_Socket_t *pxNewSocket = ( FreeRTOS_Socket_t * )
|
||||
FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
|
||||
if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) )
|
||||
{
|
||||
FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) );
|
||||
prvTCPSendReset( pxNetworkBuffer );
|
||||
}
|
||||
else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE )
|
||||
{
|
||||
/* The socket will be connected immediately, no time for the
|
||||
owner to setsockopt's, therefore copy properties of the server
|
||||
socket to the new socket. Only the binding might fail (due to
|
||||
lack of resources). */
|
||||
pxReturn = pxNewSocket;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) )
|
||||
{
|
||||
FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) );
|
||||
prvTCPSendReset( pxNetworkBuffer );
|
||||
}
|
||||
else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE )
|
||||
{
|
||||
/* The socket will be connected immediately, no time for the
|
||||
owner to setsockopt's, therefore copy properties of the server
|
||||
socket to the new socket. Only the binding might fail (due to
|
||||
lack of resources). */
|
||||
pxReturn = pxNewSocket;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pxReturn != NULL )
|
||||
if( 0 != ulInitialSequenceNumber && pxReturn != NULL )
|
||||
{
|
||||
pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
|
||||
pxReturn->u.xTCP.ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
|
||||
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulNextInitialSequenceNumber;
|
||||
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
|
||||
|
||||
/* Here is the SYN action. */
|
||||
pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
|
||||
@ -3171,9 +3155,6 @@ FreeRTOS_Socket_t *pxReturn;
|
||||
|
||||
prvTCPCreateWindow( pxReturn );
|
||||
|
||||
/* It is recommended to increase the ISS for each new connection with a value of 0x102. */
|
||||
ulNextInitialSequenceNumber += INITIAL_SEQUENCE_NUMBER_INCREMENT;
|
||||
|
||||
vTCPStateChange( pxReturn, eSYN_FIRST );
|
||||
|
||||
/* Make a copy of the header up to the TCP header. It is needed later
|
||||
@ -3248,7 +3229,7 @@ struct freertos_sockaddr xAddress;
|
||||
/* A reference to the new socket may be stored and the socket is marked
|
||||
as 'passable'. */
|
||||
|
||||
/* When bPassAccept is true, this socket may be returned in a call to
|
||||
/* When bPassAccept is pdTRUE_UNSIGNED this socket may be returned in a call to
|
||||
accept(). */
|
||||
pxNewSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
|
||||
if(pxSocket->u.xTCP.pxPeerSocket == NULL )
|
||||
@ -3327,3 +3308,7 @@ BaseType_t xResult = pdFALSE;
|
||||
|
||||
#endif /* ipconfigUSE_TCP == 1 */
|
||||
|
||||
/* Provide access to private members for testing. */
|
||||
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
|
||||
#include "aws_freertos_tcp_test_access_tcp_define.h"
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -199,7 +199,7 @@ extern void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewL
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* TCP segment pool. */
|
||||
/* TCP segement pool. */
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
static TCPSegment_t *xTCPSegments = NULL;
|
||||
#endif /* ipconfigUSE_TCP_WIN == 1 */
|
||||
@ -292,7 +292,7 @@ void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem
|
||||
pxWhere->pxPrevious = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
pxNewListItem->pvContainer = ( void * ) pxList; /* If this line fails to build then ensure configENABLE_BACKWARD_COMPATIBILITY is set to 1 in FreeRTOSConfig.h. */
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
@ -597,12 +597,12 @@ void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
|
||||
prvCreateSectors();
|
||||
}
|
||||
|
||||
vListInitialise( &( pxWindow->xTxSegments ) );
|
||||
vListInitialise( &( pxWindow->xRxSegments ) );
|
||||
vListInitialise( &pxWindow->xTxSegments );
|
||||
vListInitialise( &pxWindow->xRxSegments );
|
||||
|
||||
vListInitialise( &( pxWindow->xPriorityQueue ) ); /* Priority queue: segments which must be sent immediately */
|
||||
vListInitialise( &( pxWindow->xTxQueue ) ); /* Transmit queue: segments queued for transmission */
|
||||
vListInitialise( &( pxWindow->xWaitQueue ) ); /* Waiting queue: outstanding segments */
|
||||
vListInitialise( &pxWindow->xPriorityQueue ); /* Priority queue: segments which must be sent immediately */
|
||||
vListInitialise( &pxWindow->xTxQueue ); /* Transmit queue: segments queued for transmission */
|
||||
vListInitialise( &pxWindow->xWaitQueue ); /* Waiting queue: outstanding segments */
|
||||
}
|
||||
#endif /* ipconfigUSE_TCP_WIN == 1 */
|
||||
|
||||
@ -788,23 +788,20 @@ const int32_t l500ms = 500;
|
||||
{
|
||||
ulSavedSequenceNumber = ulCurrentSequenceNumber;
|
||||
|
||||
/* Clean up all sequence received between ulSequenceNumber
|
||||
and ulSequenceNumber + ulLength since they are duplicated.
|
||||
If the server is forced to retransmit packets several time
|
||||
in a row it might send a batch of concatenated packet for
|
||||
speed. So we cannot rely on the packets between
|
||||
ulSequenceNumber and ulSequenceNumber + ulLength to be
|
||||
sequential and it is better to just clean them out. */
|
||||
do
|
||||
{
|
||||
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
|
||||
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
|
||||
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
|
||||
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
|
||||
clean them out. */
|
||||
do
|
||||
{
|
||||
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
|
||||
|
||||
if ( pxFound != NULL )
|
||||
{
|
||||
/* Remove it because it will be passed to user directly. */
|
||||
vTCPWindowFree( pxFound );
|
||||
}
|
||||
} while ( pxFound );
|
||||
if ( pxFound != NULL )
|
||||
{
|
||||
/* Remove it because it will be passed to user directly. */
|
||||
vTCPWindowFree( pxFound );
|
||||
}
|
||||
} while ( pxFound );
|
||||
|
||||
/* Check for following segments that are already in the
|
||||
queue and increment ulCurrentSequenceNumber. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -128,15 +128,16 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
|
||||
and
|
||||
xIPHeader.usHeaderChecksum
|
||||
*/
|
||||
|
||||
/* Save options now, as they will be overwritten by memcpy */
|
||||
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
|
||||
{
|
||||
ucSocketOptions = pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ];
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy( ( void *) &( pxUDPPacket->xEthernetHeader.xSourceAddress ), ( void * ) xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );
|
||||
/*
|
||||
* Offset the memcpy by the size of a MAC address to start at the packet's
|
||||
* Ethernet header 'source' MAC address; the preceding 'destination' should not be altered.
|
||||
*/
|
||||
char *pxUdpSrcAddrOffset = ( char *) pxUDPPacket + sizeof( MACAddress_t );
|
||||
memcpy( pxUdpSrcAddrOffset, xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
|
||||
@ -153,6 +154,7 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
|
||||
/* The total transmit size adds on the Ethernet header. */
|
||||
pxNetworkBuffer->xDataLength = pxIPHeader->usLength + sizeof( EthernetHeader_t );
|
||||
pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
|
||||
/* HT:endian: changed back to network endian */
|
||||
pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
@ -174,7 +176,7 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
|
||||
|
||||
if( ( ucSocketOptions & ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT ) != 0u )
|
||||
{
|
||||
usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pdTRUE );
|
||||
usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -241,7 +243,8 @@ FreeRTOS_Socket_t *pxSocket;
|
||||
|
||||
UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
|
||||
|
||||
pxSocket = pxUDPSocketLookup( usPort );
|
||||
/* Caller must check for minimum packet size. */
|
||||
pxSocket = pxUDPSocketLookup( usPort );
|
||||
|
||||
if( pxSocket )
|
||||
{
|
||||
@ -265,9 +268,9 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
|
||||
destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
|
||||
|
||||
if( xHandler( ( Socket_t * ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
|
||||
&xSourceAddress, &destinationAddress ) != pdFALSE )
|
||||
&xSourceAddress, &destinationAddress ) )
|
||||
{
|
||||
xReturn = pdFAIL; /* xHandler has consumed the data, do not add it to .xWaitingPacketsList'. */
|
||||
xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -344,21 +347,8 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
|
||||
/* There is no socket listening to the target port, but still it might
|
||||
be for this node. */
|
||||
|
||||
#if( ipconfigUSE_DNS == 1 )
|
||||
/* A DNS reply, check for the source port. Although the DNS client
|
||||
does open a UDP socket to send a messages, this socket will be
|
||||
closed after a short timeout. Messages that come late (after the
|
||||
socket is closed) will be treated here. */
|
||||
if( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usSourcePort ) == ipDNS_PORT )
|
||||
{
|
||||
vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
/* An LLMNR request, check for the destination port. */
|
||||
/* a LLMNR request, check for the destination port. */
|
||||
if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||
|
||||
( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) )
|
||||
{
|
||||
|
@ -1,4 +1,11 @@
|
||||
Changes since V2.0.0 release
|
||||
Changes between 160919 and 180821 releases:
|
||||
|
||||
+ Multiple security improvements and fixes in packet parsing routines, DNS
|
||||
caching, and TCP sequence number and ID generation.
|
||||
+ Disable NBNS and LLMNR by default.
|
||||
+ Add TCP hang protection by default.
|
||||
|
||||
We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
|
||||
|
||||
+ Update FreeRTOS_gethostbyname() to allow an IP address to be passed in -
|
||||
in which case it is just returned as a uint32_t.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -389,11 +389,13 @@ from the FreeRTOSIPConfig.h configuration header file. */
|
||||
|
||||
#if( ipconfigUSE_DNS_CACHE != 0 )
|
||||
#ifndef ipconfigDNS_CACHE_NAME_LENGTH
|
||||
#define ipconfigDNS_CACHE_NAME_LENGTH ( 16 )
|
||||
/* Per https://tools.ietf.org/html/rfc1035, 253 is the maximum string length
|
||||
of a DNS name. The following default accounts for a null terminator. */
|
||||
#define ipconfigDNS_CACHE_NAME_LENGTH 254
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDNS_CACHE_ENTRIES
|
||||
#define ipconfigDNS_CACHE_ENTRIES 0
|
||||
#define ipconfigDNS_CACHE_ENTRIES 1
|
||||
#endif
|
||||
#endif /* ipconfigUSE_DNS_CACHE != 0 */
|
||||
|
||||
@ -510,7 +512,7 @@ from the FreeRTOSIPConfig.h configuration header file. */
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_KEEP_ALIVE
|
||||
#define ipconfigTCP_KEEP_ALIVE 1
|
||||
#define ipconfigTCP_KEEP_ALIVE 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDNS_USE_CALLBACKS
|
||||
@ -525,10 +527,17 @@ from the FreeRTOSIPConfig.h configuration header file. */
|
||||
#define ipconfigUSE_NBNS 0
|
||||
#endif
|
||||
|
||||
/* As an attack surface reduction for ports that listen for inbound
|
||||
connections, hang protection can help reduce the impact of SYN floods. */
|
||||
#ifndef ipconfigTCP_HANG_PROTECTION
|
||||
#define ipconfigTCP_HANG_PROTECTION 1
|
||||
#endif
|
||||
|
||||
/* Non-activity timeout is expressed in seconds. */
|
||||
#ifndef ipconfigTCP_HANG_PROTECTION_TIME
|
||||
#define ipconfigTCP_HANG_PROTECTION_TIME 30
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_IP_SANITY
|
||||
#define ipconfigTCP_IP_SANITY 0
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -436,8 +436,18 @@ eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucE
|
||||
uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes );
|
||||
|
||||
/* Socket related private functions. */
|
||||
|
||||
/*
|
||||
* The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
|
||||
* payload size (excluding packet headers) and that the packet in pucEthernetBuffer
|
||||
* is at least the size of UDPPacket_t.
|
||||
*/
|
||||
BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort );
|
||||
void vNetworkSocketsInit( void );
|
||||
|
||||
/*
|
||||
* Initialize the socket list data structures for TCP and UDP.
|
||||
*/
|
||||
BaseType_t vNetworkSocketsInit( void );
|
||||
|
||||
/*
|
||||
* Returns pdTRUE if the IP task has been created and is initialised. Otherwise
|
||||
@ -671,7 +681,7 @@ void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuff
|
||||
* bOut = false: checksum will be calculated for incoming packets
|
||||
* returning 0xffff means: checksum was correct
|
||||
*/
|
||||
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, BaseType_t xOutgoingPacket );
|
||||
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket );
|
||||
|
||||
/*
|
||||
* An Ethernet frame has been updated (maybe it was an ARP request or a PING
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -80,17 +80,9 @@ typedef struct xTCP_WINSIZE
|
||||
*/
|
||||
/* Keep this as a multiple of 4 */
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
|
||||
#define ipSIZE_TCP_OPTIONS ( 16u + 12u )
|
||||
#else
|
||||
#define ipSIZE_TCP_OPTIONS 16u
|
||||
#endif
|
||||
#define ipSIZE_TCP_OPTIONS 16u
|
||||
#else
|
||||
#if ipconfigUSE_TCP_TIMESTAMPS == 1
|
||||
#define ipSIZE_TCP_OPTIONS ( 12u + 12u )
|
||||
#else
|
||||
#define ipSIZE_TCP_OPTIONS 12u
|
||||
#endif
|
||||
#define ipSIZE_TCP_OPTIONS 12u
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -120,9 +112,6 @@ typedef struct xTCP_WINDOW
|
||||
* In other words: the sequence number of the left side of the sliding window */
|
||||
uint32_t ulFINSequenceNumber; /* The sequence number which carried the FIN flag */
|
||||
uint32_t ulHighestSequenceNumber;/* Sequence number of the right-most byte + 1 */
|
||||
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
|
||||
uint32_t ulTimeStamp; /* The value of the TCP timestamp, transmitted or received */
|
||||
#endif
|
||||
} rx, tx;
|
||||
uint32_t ulOurSequenceNumber; /* The SEQ number we're sending out */
|
||||
uint32_t ulUserDataLength; /* Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@ -226,7 +225,7 @@ UBaseType_t uxCount;
|
||||
available. */
|
||||
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
|
||||
{
|
||||
/* Protect the structure as it is accessed from tasks and
|
||||
/* Protect the structure as they are accessed from tasks and
|
||||
interrupts. */
|
||||
ipconfigBUFFER_ALLOC_LOCK();
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* 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
|
||||
@ -19,11 +19,12 @@
|
||||
* 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
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* See the following web page for essential buffer allocation scheme usage and
|
||||
@ -323,12 +324,21 @@ BaseType_t xListItemAlreadyInFreeList;
|
||||
}
|
||||
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 )
|
||||
{
|
||||
xSemaphoreGive( xNetworkBufferSemaphore );
|
||||
if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
|
||||
{
|
||||
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
|
||||
}
|
||||
|
||||
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
@ -787,16 +787,11 @@ uint8_t *pucBuffer;
|
||||
}
|
||||
|
||||
/* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
|
||||
|
||||
/* get received frame */
|
||||
if( xReceivedLength > 0ul )
|
||||
/* In order to make the code easier and faster, only packets in a single buffer
|
||||
will be accepted. This can be done by making the buffers large enough to
|
||||
hold a complete Ethernet packet (1536 bytes). */
|
||||
if( xReceivedLength > 0ul && xReceivedLength < ETH_RX_BUF_SIZE )
|
||||
{
|
||||
/* In order to make the code easier and faster, only packets in a single buffer
|
||||
will be accepted. This can be done by making the buffers large enough to
|
||||
hold a complete Ethernet packet (1536 bytes).
|
||||
Therefore, two sanity checks: */
|
||||
configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
|
||||
|
||||
if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
|
||||
{
|
||||
/* Not an Ethernet frame-type or a checmsum error. */
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/* WinPCap includes. */
|
||||
#define HAVE_REMOTE
|
||||
@ -80,7 +79,7 @@ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
|
||||
* by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
|
||||
*/
|
||||
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
|
||||
static void prvOpenInterface( const char *pucName );
|
||||
static int prvOpenInterface( const char *pucName );
|
||||
|
||||
/*
|
||||
* Configure the capture filter to allow blocking reads, and to filter out
|
||||
@ -275,7 +274,7 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
|
||||
printf( "\r\nThe interface that will be opened is set by " );
|
||||
printf( "\"configNETWORK_INTERFACE_TO_USE\", which\r\nshould be defined in FreeRTOSConfig.h\r\n" );
|
||||
|
||||
if( ( xConfigNextworkInterfaceToUse < 1L ) || ( xConfigNextworkInterfaceToUse >= lInterfaceNumber ) )
|
||||
if( ( xConfigNextworkInterfaceToUse < 0L ) || ( xConfigNextworkInterfaceToUse >= lInterfaceNumber ) )
|
||||
{
|
||||
printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNextworkInterfaceToUse );
|
||||
printf( "Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above,\r\n" );
|
||||
@ -300,7 +299,7 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvOpenInterface( const char *pucName )
|
||||
static int prvOpenInterface( const char *pucName )
|
||||
{
|
||||
static char pucInterfaceName[ 256 ];
|
||||
|
||||
@ -326,6 +325,7 @@ static char pucInterfaceName[ 256 ];
|
||||
if ( pxOpenedInterfaceHandle == NULL )
|
||||
{
|
||||
printf( "\n%s is not supported by WinPcap and cannot be opened\n", pucInterfaceName );
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -333,6 +333,7 @@ static char pucInterfaceName[ 256 ];
|
||||
out packets that are not of interest to this demo. */
|
||||
prvConfigureCaptureBehaviour();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@ -343,13 +344,22 @@ int32_t x;
|
||||
|
||||
/* Walk the list of devices until the selected device is located. */
|
||||
xInterface = pxAllNetworkInterfaces;
|
||||
for( x = 0L; x < ( xConfigNextworkInterfaceToUse - 1L ); x++ )
|
||||
{
|
||||
xInterface = xInterface->next;
|
||||
if (0 == xConfigNextworkInterfaceToUse) {
|
||||
while (NULL != xInterface) {
|
||||
xInterface = xInterface->next;
|
||||
if (0 == prvOpenInterface(xInterface->name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (x = 1L; x < xConfigNextworkInterfaceToUse; x++)
|
||||
{
|
||||
xInterface = xInterface->next;
|
||||
}
|
||||
/* Open the selected interface. */
|
||||
(void) prvOpenInterface(xInterface->name);
|
||||
}
|
||||
|
||||
/* Open the selected interface. */
|
||||
prvOpenInterface( xInterface->name );
|
||||
|
||||
/* The device list is no longer required. */
|
||||
pcap_freealldevs( pxAllNetworkInterfaces );
|
||||
@ -514,7 +524,16 @@ eFrameProcessingResult_t eResult;
|
||||
|
||||
iptraceNETWORK_INTERFACE_RECEIVE();
|
||||
|
||||
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
|
||||
/* Check for minimal size. */
|
||||
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
|
||||
{
|
||||
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
|
||||
}
|
||||
else
|
||||
{
|
||||
eResult = eReleaseBuffer;
|
||||
}
|
||||
|
||||
if( eResult == eProcessBuffer )
|
||||
{
|
||||
/* Will the data fit into the frame buffer? */
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
@ -1,27 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
#include "Zynq/x_topology.h"
|
||||
|
@ -1,28 +1,27 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
FreeRTOS+TCP V2.0.7
|
||||
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
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
@ -1,353 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_TCP_server.h"
|
||||
#include "FreeRTOS_server_private.h"
|
||||
|
||||
/* Remove the entire file if TCP is not being used. */
|
||||
#if( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) )
|
||||
|
||||
#if !defined( ARRAY_SIZE )
|
||||
#define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] )
|
||||
#endif
|
||||
|
||||
|
||||
static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket );
|
||||
static char *strnew( const char *pcString );
|
||||
/* Remove slashes at the end of a path. */
|
||||
static void prvRemoveSlash( char *pcDir );
|
||||
|
||||
TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount )
|
||||
{
|
||||
TCPServer_t *pxServer;
|
||||
SocketSet_t xSocketSet;
|
||||
|
||||
/* Create a new server.
|
||||
xPort / xPortAlt : Make the service available on 1 or 2 public port numbers. */
|
||||
xSocketSet = FreeRTOS_CreateSocketSet();
|
||||
|
||||
if( xSocketSet != NULL )
|
||||
{
|
||||
BaseType_t xSize;
|
||||
|
||||
xSize = sizeof( *pxServer ) - sizeof( pxServer->xServers ) + xCount * sizeof( pxServer->xServers[ 0 ] );
|
||||
|
||||
pxServer = ( TCPServer_t * ) pvPortMallocLarge( xSize );
|
||||
if( pxServer != NULL )
|
||||
{
|
||||
struct freertos_sockaddr xAddress;
|
||||
BaseType_t xNoTimeout = 0;
|
||||
BaseType_t xIndex;
|
||||
|
||||
memset( pxServer, '\0', xSize );
|
||||
pxServer->xServerCount = xCount;
|
||||
pxServer->xSocketSet = xSocketSet;
|
||||
|
||||
for( xIndex = 0; xIndex < xCount; xIndex++ )
|
||||
{
|
||||
BaseType_t xPortNumber = pxConfigs[ xIndex ].xPortNumber;
|
||||
|
||||
if( xPortNumber > 0 )
|
||||
{
|
||||
Socket_t xSocket;
|
||||
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
FreeRTOS_printf( ( "TCP socket on port %d\n", ( int )xPortNumber ) );
|
||||
|
||||
if( xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
xAddress.sin_addr = FreeRTOS_GetIPAddress(); // Single NIC, currently not used
|
||||
xAddress.sin_port = FreeRTOS_htons( xPortNumber );
|
||||
|
||||
FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xSocket, pxConfigs[ xIndex ].xBackLog );
|
||||
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );
|
||||
|
||||
#if( ipconfigHTTP_RX_BUFSIZE > 0 )
|
||||
{
|
||||
if( pxConfigs[ xIndex ].eType == eSERVER_HTTP )
|
||||
{
|
||||
WinProperties_t xWinProps;
|
||||
|
||||
memset( &xWinProps, '\0', sizeof( xWinProps ) );
|
||||
/* The parent socket itself won't get connected. The properties below
|
||||
will be inherited by each new child socket. */
|
||||
xWinProps.lTxBufSize = ipconfigHTTP_TX_BUFSIZE;
|
||||
xWinProps.lTxWinSize = ipconfigHTTP_TX_WINSIZE;
|
||||
xWinProps.lRxBufSize = ipconfigHTTP_RX_BUFSIZE;
|
||||
xWinProps.lRxWinSize = ipconfigHTTP_RX_WINSIZE;
|
||||
|
||||
/* Set the window and buffer sizes. */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
FreeRTOS_FD_SET( xSocket, xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
|
||||
pxServer->xServers[ xIndex ].xSocket = xSocket;
|
||||
pxServer->xServers[ xIndex ].eType = pxConfigs[ xIndex ].eType;
|
||||
pxServer->xServers[ xIndex ].pcRootDir = strnew( pxConfigs[ xIndex ].pcRootDir );
|
||||
prvRemoveSlash( ( char * ) pxServer->xServers[ xIndex ].pcRootDir );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Could not allocate the server, delete the socket set */
|
||||
FreeRTOS_DeleteSocketSet( xSocketSet );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Could not create a socket set, return NULL */
|
||||
pxServer = NULL;
|
||||
}
|
||||
|
||||
return pxServer;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket )
|
||||
{
|
||||
TCPClient_t *pxClient = NULL;
|
||||
BaseType_t xSize = 0;
|
||||
FTCPWorkFunction fWorkFunc = NULL;
|
||||
FTCPDeleteFunction fDeleteFunc = NULL;
|
||||
const char *pcType = "Unknown";
|
||||
|
||||
/*_RB_ Can the work and delete functions be part of the xSERVER_CONFIG structure
|
||||
becomes generic, with no pre-processing required? */
|
||||
#if( ipconfigUSE_HTTP != 0 )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].eType == eSERVER_HTTP )
|
||||
{
|
||||
xSize = sizeof( HTTPClient_t );
|
||||
fWorkFunc = xHTTPClientWork;
|
||||
fDeleteFunc = vHTTPClientDelete;
|
||||
pcType = "HTTP";
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_HTTP != 0 */
|
||||
|
||||
#if( ipconfigUSE_FTP != 0 )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].eType == eSERVER_FTP )
|
||||
{
|
||||
xSize = sizeof( FTPClient_t );
|
||||
fWorkFunc = xFTPClientWork;
|
||||
fDeleteFunc = vFTPClientDelete;
|
||||
pcType = "FTP";
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_FTP != 0 */
|
||||
|
||||
/* Malloc enough space for a new HTTP-client */
|
||||
if( xSize )
|
||||
{
|
||||
pxClient = ( TCPClient_t* ) pvPortMallocLarge( xSize );
|
||||
}
|
||||
|
||||
if( pxClient != NULL )
|
||||
{
|
||||
memset( pxClient, '\0', xSize );
|
||||
|
||||
/* Put the new client in front of the list. */
|
||||
pxClient->eType = pxServer->xServers[ xIndex ].eType;
|
||||
pxClient->pcRootDir = pxServer->xServers[ xIndex ].pcRootDir;
|
||||
pxClient->pxParent = pxServer;
|
||||
pxClient->xSocket = xNexSocket;
|
||||
pxClient->pxNextClient = pxServer->pxClients;
|
||||
pxClient->fWorkFunction = fWorkFunc;
|
||||
pxClient->fDeleteFunction = fDeleteFunc;
|
||||
pxServer->pxClients = pxClient;
|
||||
|
||||
FreeRTOS_FD_SET( xNexSocket, pxServer->xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
|
||||
}
|
||||
else
|
||||
{
|
||||
pcType = "closed";
|
||||
FreeRTOS_closesocket( xNexSocket );
|
||||
}
|
||||
{
|
||||
struct freertos_sockaddr xRemoteAddress;
|
||||
FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress );
|
||||
FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, (unsigned)FreeRTOS_ntohl( xRemoteAddress.sin_addr ) ) );
|
||||
}
|
||||
|
||||
/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
|
||||
( void ) pcType;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime )
|
||||
{
|
||||
TCPClient_t **ppxClient;
|
||||
BaseType_t xIndex;
|
||||
BaseType_t xRc;
|
||||
|
||||
/* Let the server do one working cycle */
|
||||
xRc = FreeRTOS_select( pxServer->xSocketSet, xBlockingTime );
|
||||
|
||||
if( xRc != 0 )
|
||||
{
|
||||
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
|
||||
{
|
||||
struct freertos_sockaddr xAddress;
|
||||
Socket_t xNexSocket;
|
||||
socklen_t xSocketLength;
|
||||
|
||||
if( pxServer->xServers[ xIndex ].xSocket == FREERTOS_NO_SOCKET )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
xSocketLength = sizeof( xAddress );
|
||||
xNexSocket = FreeRTOS_accept( pxServer->xServers[ xIndex ].xSocket, &xAddress, &xSocketLength);
|
||||
|
||||
if( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) )
|
||||
{
|
||||
prvReceiveNewClient( pxServer, xIndex, xNexSocket );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ppxClient = &pxServer->pxClients;
|
||||
|
||||
while( ( * ppxClient ) != NULL )
|
||||
{
|
||||
TCPClient_t *pxThis = *ppxClient;
|
||||
|
||||
/* Almost C++ */
|
||||
xRc = pxThis->fWorkFunction( pxThis );
|
||||
|
||||
if (xRc < 0 )
|
||||
{
|
||||
*ppxClient = pxThis->pxNextClient;
|
||||
/* Close handles, resources */
|
||||
pxThis->fDeleteFunction( pxThis );
|
||||
/* Free the space */
|
||||
vPortFreeLarge( pxThis );
|
||||
}
|
||||
else
|
||||
{
|
||||
ppxClient = &( pxThis->pxNextClient );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static char *strnew( const char *pcString )
|
||||
{
|
||||
BaseType_t xLength;
|
||||
char *pxBuffer;
|
||||
|
||||
xLength = strlen( pcString ) + 1;
|
||||
pxBuffer = ( char * ) pvPortMalloc( xLength );
|
||||
if( pxBuffer != NULL )
|
||||
{
|
||||
memcpy( pxBuffer, pcString, xLength );
|
||||
}
|
||||
|
||||
return pxBuffer;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvRemoveSlash( char *pcDir )
|
||||
{
|
||||
BaseType_t xLength = strlen( pcDir );
|
||||
|
||||
while( ( xLength > 0 ) && ( pcDir[ xLength - 1 ] == '/' ) )
|
||||
{
|
||||
pcDir[ --xLength ] = '\0';
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigSUPPORT_SIGNALS != 0 )
|
||||
|
||||
/* FreeRTOS_TCPServerWork() calls select().
|
||||
The two functions below provide a possibility to interrupt
|
||||
the call to select(). After the interruption, resume
|
||||
by calling FreeRTOS_TCPServerWork() again. */
|
||||
BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
BaseType_t xResult = pdFALSE;
|
||||
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
FreeRTOS_SignalSocket( pxServer->xServers[ xIndex ].xSocket );
|
||||
xResult = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
|
||||
#endif /* ipconfigSUPPORT_SIGNALS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigSUPPORT_SIGNALS != 0 )
|
||||
|
||||
/* Same as above: this function may be called from an ISR,
|
||||
for instance a GPIO interrupt. */
|
||||
BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
BaseType_t xResult = pdFALSE;
|
||||
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
FreeRTOS_SignalSocketFromISR( pxServer->xServers[ xIndex ].xSocket, pxHigherPriorityTaskWoken );
|
||||
xResult = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
#endif /* ipconfigSUPPORT_SIGNALS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) */
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_FTP_commands.h"
|
||||
|
||||
const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ] =
|
||||
{
|
||||
/* cmdLen cmdName[7] cmdType checkLogin checkNullArg */
|
||||
{ 4, "USER", ECMD_USER, pdFALSE, pdFALSE },
|
||||
{ 4, "PASS", ECMD_PASS, pdFALSE, pdFALSE },
|
||||
{ 4, "ACCT", ECMD_ACCT, pdTRUE, pdFALSE },
|
||||
{ 3, "CWD", ECMD_CWD, pdTRUE, pdTRUE },
|
||||
{ 4, "CDUP", ECMD_CDUP, pdTRUE, pdFALSE },
|
||||
{ 4, "SMNT", ECMD_SMNT, pdTRUE, pdFALSE },
|
||||
{ 4, "QUIT", ECMD_QUIT, pdTRUE, pdFALSE },
|
||||
{ 4, "REIN", ECMD_REIN, pdTRUE, pdFALSE },
|
||||
{ 4, "PORT", ECMD_PORT, pdTRUE, pdFALSE },
|
||||
{ 4, "PASV", ECMD_PASV, pdTRUE, pdFALSE },
|
||||
{ 4, "TYPE", ECMD_TYPE, pdTRUE, pdFALSE },
|
||||
{ 4, "STRU", ECMD_STRU, pdTRUE, pdFALSE },
|
||||
{ 4, "MODE", ECMD_MODE, pdTRUE, pdFALSE },
|
||||
{ 4, "RETR", ECMD_RETR, pdTRUE, pdTRUE },
|
||||
{ 4, "STOR", ECMD_STOR, pdTRUE, pdTRUE },
|
||||
{ 4, "STOU", ECMD_STOU, pdTRUE, pdFALSE },
|
||||
{ 4, "APPE", ECMD_APPE, pdTRUE, pdFALSE },
|
||||
{ 4, "ALLO", ECMD_ALLO, pdTRUE, pdFALSE },
|
||||
{ 4, "REST", ECMD_REST, pdTRUE, pdFALSE },
|
||||
{ 4, "RNFR", ECMD_RNFR, pdTRUE, pdTRUE },
|
||||
{ 4, "RNTO", ECMD_RNTO, pdTRUE, pdTRUE },
|
||||
{ 4, "ABOR", ECMD_ABOR, pdTRUE, pdFALSE },
|
||||
{ 4, "SIZE", ECMD_SIZE, pdTRUE, pdTRUE },
|
||||
{ 4, "MDTM", ECMD_MDTM, pdTRUE, pdTRUE },
|
||||
{ 4, "DELE", ECMD_DELE, pdTRUE, pdTRUE },
|
||||
{ 3, "RMD", ECMD_RMD, pdTRUE, pdTRUE },
|
||||
{ 3, "MKD", ECMD_MKD, pdTRUE, pdTRUE },
|
||||
{ 3, "PWD", ECMD_PWD, pdTRUE, pdFALSE },
|
||||
{ 4, "LIST", ECMD_LIST, pdTRUE, pdFALSE },
|
||||
{ 4, "NLST", ECMD_NLST, pdTRUE, pdFALSE },
|
||||
{ 4, "SITE", ECMD_SITE, pdTRUE, pdFALSE },
|
||||
{ 4, "SYST", ECMD_SYST, pdFALSE, pdFALSE },
|
||||
{ 4, "FEAT", ECMD_FEAT, pdFALSE, pdFALSE },
|
||||
{ 4, "STAT", ECMD_STAT, pdTRUE, pdFALSE },
|
||||
{ 4, "HELP", ECMD_HELP, pdFALSE, pdFALSE },
|
||||
{ 4, "NOOP", ECMD_NOOP, pdFALSE, pdFALSE },
|
||||
{ 4, "EMPT", ECMD_EMPTY, pdFALSE, pdFALSE },
|
||||
{ 4, "CLOS", ECMD_CLOSE, pdTRUE, pdFALSE },
|
||||
{ 4, "UNKN", ECMD_UNKNOWN, pdFALSE, pdFALSE },
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "FreeRTOS_HTTP_commands.h"
|
||||
|
||||
const struct xWEB_COMMAND xWebCommands[ WEB_CMD_COUNT ] =
|
||||
{
|
||||
{ 3, "GET", ECMD_GET },
|
||||
{ 4, "HEAD", ECMD_HEAD },
|
||||
{ 4, "POST", ECMD_POST },
|
||||
{ 3, "PUT", ECMD_PUT },
|
||||
{ 6, "DELETE", ECMD_DELETE },
|
||||
{ 5, "TRACE", ECMD_TRACE },
|
||||
{ 7, "OPTIONS", ECMD_OPTIONS },
|
||||
{ 7, "CONNECT", ECMD_CONNECT },
|
||||
{ 5, "PATCH", ECMD_PATCH },
|
||||
{ 4, "UNKN", ECMD_UNK },
|
||||
};
|
||||
|
||||
const char *webCodename (int aCode)
|
||||
{
|
||||
switch (aCode) {
|
||||
case WEB_REPLY_OK: // = 200,
|
||||
return "OK";
|
||||
case WEB_NO_CONTENT: // 204
|
||||
return "No content";
|
||||
case WEB_BAD_REQUEST: // = 400,
|
||||
return "Bad request";
|
||||
case WEB_UNAUTHORIZED: // = 401,
|
||||
return "Authorization Required";
|
||||
case WEB_NOT_FOUND: // = 404,
|
||||
return "Not Found";
|
||||
case WEB_GONE: // = 410,
|
||||
return "Done";
|
||||
case WEB_PRECONDITION_FAILED: // = 412,
|
||||
return "Precondition Failed";
|
||||
case WEB_INTERNAL_SERVER_ERROR: // = 500,
|
||||
return "Internal Server Error";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
@ -1,428 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
|
||||
/* FreeRTOS Protocol includes. */
|
||||
#include "FreeRTOS_HTTP_commands.h"
|
||||
#include "FreeRTOS_TCP_server.h"
|
||||
#include "FreeRTOS_server_private.h"
|
||||
|
||||
/* Remove the whole file if HTTP is not supported. */
|
||||
#if( ipconfigUSE_HTTP == 1 )
|
||||
|
||||
/* FreeRTOS+FAT includes. */
|
||||
#include "ff_stdio.h"
|
||||
|
||||
#ifndef HTTP_SERVER_BACKLOG
|
||||
#define HTTP_SERVER_BACKLOG ( 12 )
|
||||
#endif
|
||||
|
||||
#ifndef USE_HTML_CHUNKS
|
||||
#define USE_HTML_CHUNKS ( 0 )
|
||||
#endif
|
||||
|
||||
#if !defined( ARRAY_SIZE )
|
||||
#define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] )
|
||||
#endif
|
||||
|
||||
/* Some defines to make the code more readbale */
|
||||
#define pcCOMMAND_BUFFER pxClient->pxParent->pcCommandBuffer
|
||||
#define pcNEW_DIR pxClient->pxParent->pcNewDir
|
||||
#define pcFILE_BUFFER pxClient->pxParent->pcFileBuffer
|
||||
|
||||
#ifndef ipconfigHTTP_REQUEST_CHARACTER
|
||||
#define ipconfigHTTP_REQUEST_CHARACTER '?'
|
||||
#endif
|
||||
|
||||
/*_RB_ Need comment block, although fairly self evident. */
|
||||
static void prvFileClose( HTTPClient_t *pxClient );
|
||||
static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex );
|
||||
static const char *pcGetContentsType( const char *apFname );
|
||||
static BaseType_t prvOpenURL( HTTPClient_t *pxClient );
|
||||
static BaseType_t prvSendFile( HTTPClient_t *pxClient );
|
||||
static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode );
|
||||
|
||||
static const char pcEmptyString[1] = { '\0' };
|
||||
|
||||
typedef struct xTYPE_COUPLE
|
||||
{
|
||||
const char *pcExtension;
|
||||
const char *pcType;
|
||||
} TypeCouple_t;
|
||||
|
||||
static TypeCouple_t pxTypeCouples[ ] =
|
||||
{
|
||||
{ "html", "text/html" },
|
||||
{ "css", "text/css" },
|
||||
{ "js", "text/javascript" },
|
||||
{ "png", "image/png" },
|
||||
{ "jpg", "image/jpeg" },
|
||||
{ "gif", "image/gif" },
|
||||
{ "txt", "text/plain" },
|
||||
{ "mp3", "audio/mpeg3" },
|
||||
{ "wav", "audio/wav" },
|
||||
{ "flac", "audio/ogg" },
|
||||
{ "pdf", "application/pdf" },
|
||||
{ "ttf", "application/x-font-ttf" },
|
||||
{ "ttc", "application/x-font-ttf" }
|
||||
};
|
||||
|
||||
void vHTTPClientDelete( TCPClient_t *pxTCPClient )
|
||||
{
|
||||
HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient;
|
||||
|
||||
/* This HTTP client stops, close / release all resources. */
|
||||
if( pxClient->xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL );
|
||||
FreeRTOS_closesocket( pxClient->xSocket );
|
||||
pxClient->xSocket = FREERTOS_NO_SOCKET;
|
||||
}
|
||||
prvFileClose( pxClient );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvFileClose( HTTPClient_t *pxClient )
|
||||
{
|
||||
if( pxClient->pxFileHandle != NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "Closing file: %s\n", pxClient->pcCurrentFilename ) );
|
||||
ff_fclose( pxClient->pxFileHandle );
|
||||
pxClient->pxFileHandle = NULL;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode )
|
||||
{
|
||||
struct xTCP_SERVER *pxParent = pxClient->pxParent;
|
||||
BaseType_t xRc;
|
||||
|
||||
/* A normal command reply on the main socket (port 21). */
|
||||
char *pcBuffer = pxParent->pcFileBuffer;
|
||||
|
||||
xRc = snprintf( pcBuffer, sizeof( pxParent->pcFileBuffer ),
|
||||
"HTTP/1.1 %d %s\r\n"
|
||||
#if USE_HTML_CHUNKS
|
||||
"Transfer-Encoding: chunked\r\n"
|
||||
#endif
|
||||
"Content-Type: %s\r\n"
|
||||
"Connection: keep-alive\r\n"
|
||||
"%s\r\n",
|
||||
( int ) xCode,
|
||||
webCodename (xCode),
|
||||
pxParent->pcContentsType[0] ? pxParent->pcContentsType : "text/html",
|
||||
pxParent->pcExtraContents );
|
||||
|
||||
pxParent->pcContentsType[0] = '\0';
|
||||
pxParent->pcExtraContents[0] = '\0';
|
||||
|
||||
xRc = FreeRTOS_send( pxClient->xSocket, ( const void * ) pcBuffer, xRc, 0 );
|
||||
pxClient->bits.bReplySent = pdTRUE_UNSIGNED;
|
||||
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvSendFile( HTTPClient_t *pxClient )
|
||||
{
|
||||
size_t uxSpace;
|
||||
size_t uxCount;
|
||||
BaseType_t xRc = 0;
|
||||
|
||||
if( pxClient->bits.bReplySent == pdFALSE_UNSIGNED )
|
||||
{
|
||||
pxClient->bits.bReplySent = pdTRUE_UNSIGNED;
|
||||
|
||||
strcpy( pxClient->pxParent->pcContentsType, pcGetContentsType( pxClient->pcCurrentFilename ) );
|
||||
snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
|
||||
"Content-Length: %d\r\n", ( int ) pxClient->uxBytesLeft );
|
||||
|
||||
/* "Requested file action OK". */
|
||||
xRc = prvSendReply( pxClient, WEB_REPLY_OK );
|
||||
}
|
||||
|
||||
if( xRc >= 0 ) do
|
||||
{
|
||||
uxSpace = FreeRTOS_tx_space( pxClient->xSocket );
|
||||
|
||||
if( pxClient->uxBytesLeft < uxSpace )
|
||||
{
|
||||
uxCount = pxClient->uxBytesLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCount = uxSpace;
|
||||
}
|
||||
|
||||
if( uxCount > 0u )
|
||||
{
|
||||
if( uxCount > sizeof( pxClient->pxParent->pcFileBuffer ) )
|
||||
{
|
||||
uxCount = sizeof( pxClient->pxParent->pcFileBuffer );
|
||||
}
|
||||
ff_fread( pxClient->pxParent->pcFileBuffer, 1, uxCount, pxClient->pxFileHandle );
|
||||
pxClient->uxBytesLeft -= uxCount;
|
||||
|
||||
xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pxParent->pcFileBuffer, uxCount, 0 );
|
||||
if( xRc < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while( uxCount > 0u );
|
||||
|
||||
if( pxClient->uxBytesLeft == 0u )
|
||||
{
|
||||
/* Writing is ready, no need for further 'eSELECT_WRITE' events. */
|
||||
FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
|
||||
prvFileClose( pxClient );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wake up the TCP task as soon as this socket may be written to. */
|
||||
FreeRTOS_FD_SET( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
|
||||
}
|
||||
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvOpenURL( HTTPClient_t *pxClient )
|
||||
{
|
||||
BaseType_t xRc;
|
||||
char pcSlash[ 2 ];
|
||||
|
||||
pxClient->bits.ulFlags = 0;
|
||||
|
||||
#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
|
||||
{
|
||||
if( strchr( pxClient->pcUrlData, ipconfigHTTP_REQUEST_CHARACTER ) != NULL )
|
||||
{
|
||||
size_t xResult;
|
||||
|
||||
xResult = uxApplicationHTTPHandleRequestHook( pxClient->pcUrlData, pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ) );
|
||||
if( xResult > 0 )
|
||||
{
|
||||
strcpy( pxClient->pxParent->pcContentsType, "text/html" );
|
||||
snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
|
||||
"Content-Length: %d\r\n", ( int ) xResult );
|
||||
xRc = prvSendReply( pxClient, WEB_REPLY_OK ); /* "Requested file action OK" */
|
||||
if( xRc > 0 )
|
||||
{
|
||||
xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pcCurrentFilename, xResult, 0 );
|
||||
}
|
||||
/* Although against the coding standard of FreeRTOS, a return is
|
||||
done here to simplify this conditional code. */
|
||||
return xRc;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */
|
||||
|
||||
if( pxClient->pcUrlData[ 0 ] != '/' )
|
||||
{
|
||||
/* Insert a slash before the file name. */
|
||||
pcSlash[ 0 ] = '/';
|
||||
pcSlash[ 1 ] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The browser provided a starting '/' already. */
|
||||
pcSlash[ 0 ] = '\0';
|
||||
}
|
||||
snprintf( pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ), "%s%s%s",
|
||||
pxClient->pcRootDir,
|
||||
pcSlash,
|
||||
pxClient->pcUrlData);
|
||||
|
||||
pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" );
|
||||
|
||||
FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename,
|
||||
pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) );
|
||||
|
||||
if( pxClient->pxFileHandle == NULL )
|
||||
{
|
||||
/* "404 File not found". */
|
||||
xRc = prvSendReply( pxClient, WEB_NOT_FOUND );
|
||||
}
|
||||
else
|
||||
{
|
||||
pxClient->uxBytesLeft = ( size_t ) pxClient->pxFileHandle->ulFileSize;
|
||||
xRc = prvSendFile( pxClient );
|
||||
}
|
||||
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex )
|
||||
{
|
||||
BaseType_t xResult = 0;
|
||||
|
||||
/* A new command has been received. Process it. */
|
||||
switch( xIndex )
|
||||
{
|
||||
case ECMD_GET:
|
||||
xResult = prvOpenURL( pxClient );
|
||||
break;
|
||||
|
||||
case ECMD_HEAD:
|
||||
case ECMD_POST:
|
||||
case ECMD_PUT:
|
||||
case ECMD_DELETE:
|
||||
case ECMD_TRACE:
|
||||
case ECMD_OPTIONS:
|
||||
case ECMD_CONNECT:
|
||||
case ECMD_PATCH:
|
||||
case ECMD_UNK:
|
||||
{
|
||||
FreeRTOS_printf( ( "prvProcessCmd: Not implemented: %s\n",
|
||||
xWebCommands[xIndex].pcCommandName ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xHTTPClientWork( TCPClient_t *pxTCPClient )
|
||||
{
|
||||
BaseType_t xRc;
|
||||
HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient;
|
||||
|
||||
if( pxClient->pxFileHandle != NULL )
|
||||
{
|
||||
prvSendFile( pxClient );
|
||||
}
|
||||
|
||||
xRc = FreeRTOS_recv( pxClient->xSocket, ( void * )pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 );
|
||||
|
||||
if( xRc > 0 )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
const char *pcEndOfCmd;
|
||||
const struct xWEB_COMMAND *curCmd;
|
||||
char *pcBuffer = pcCOMMAND_BUFFER;
|
||||
|
||||
if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) )
|
||||
{
|
||||
pcBuffer[ xRc ] = '\0';
|
||||
}
|
||||
while( xRc && ( pcBuffer[ xRc - 1 ] == 13 || pcBuffer[ xRc - 1 ] == 10 ) )
|
||||
{
|
||||
pcBuffer[ --xRc ] = '\0';
|
||||
}
|
||||
pcEndOfCmd = pcBuffer + xRc;
|
||||
|
||||
curCmd = xWebCommands;
|
||||
|
||||
/* Pointing to "/index.html HTTP/1.1". */
|
||||
pxClient->pcUrlData = pcBuffer;
|
||||
|
||||
/* Pointing to "HTTP/1.1". */
|
||||
pxClient->pcRestData = pcEmptyString;
|
||||
|
||||
/* Last entry is "ECMD_UNK". */
|
||||
for( xIndex = 0; xIndex < WEB_CMD_COUNT - 1; xIndex++, curCmd++ )
|
||||
{
|
||||
BaseType_t xLength;
|
||||
|
||||
xLength = curCmd->xCommandLength;
|
||||
if( ( xRc >= xLength ) && ( memcmp( curCmd->pcCommandName, pcBuffer, xLength ) == 0 ) )
|
||||
{
|
||||
char *pcLastPtr;
|
||||
|
||||
pxClient->pcUrlData += xLength + 1;
|
||||
for( pcLastPtr = (char *)pxClient->pcUrlData; pcLastPtr < pcEndOfCmd; pcLastPtr++ )
|
||||
{
|
||||
char ch = *pcLastPtr;
|
||||
if( ( ch == '\0' ) || ( strchr( "\n\r \t", ch ) != NULL ) )
|
||||
{
|
||||
*pcLastPtr = '\0';
|
||||
pxClient->pcRestData = pcLastPtr + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( xIndex < ( WEB_CMD_COUNT - 1 ) )
|
||||
{
|
||||
xRc = prvProcessCmd( pxClient, xIndex );
|
||||
}
|
||||
}
|
||||
else if( xRc < 0 )
|
||||
{
|
||||
/* The connection will be closed and the client will be deleted. */
|
||||
FreeRTOS_printf( ( "xHTTPClientWork: rc = %ld\n", xRc ) );
|
||||
}
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static const char *pcGetContentsType (const char *apFname)
|
||||
{
|
||||
const char *slash = NULL;
|
||||
const char *dot = NULL;
|
||||
const char *ptr;
|
||||
const char *pcResult = "text/html";
|
||||
BaseType_t x;
|
||||
|
||||
for( ptr = apFname; *ptr; ptr++ )
|
||||
{
|
||||
if (*ptr == '.') dot = ptr;
|
||||
if (*ptr == '/') slash = ptr;
|
||||
}
|
||||
if( dot > slash )
|
||||
{
|
||||
dot++;
|
||||
for( x = 0; x < ARRAY_SIZE( pxTypeCouples ); x++ )
|
||||
{
|
||||
if( strcasecmp( dot, pxTypeCouples[ x ].pcExtension ) == 0 )
|
||||
{
|
||||
pcResult = pxTypeCouples[ x ].pcType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pcResult;
|
||||
}
|
||||
|
||||
#endif /* ipconfigUSE_HTTP */
|
||||
|
@ -1,440 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* NTPDemo.c
|
||||
*
|
||||
* An example of how to lookup a domain using DNS
|
||||
* And also how to send and receive UDP messages to get the NTP time
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
|
||||
/* Use the date & time functions from +FAT. */
|
||||
#include "ff_time.h"
|
||||
|
||||
#include "NTPDemo.h"
|
||||
#include "ntpClient.h"
|
||||
|
||||
#include "date_and_time.h"
|
||||
|
||||
enum EStatus {
|
||||
EStatusLookup,
|
||||
EStatusAsking,
|
||||
EStatusPause,
|
||||
EStatusFailed,
|
||||
};
|
||||
|
||||
static struct SNtpPacket xNTPPacket;
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS == 0 )
|
||||
static char cRecvBuffer[ sizeof( struct SNtpPacket ) + 64 ];
|
||||
#endif
|
||||
|
||||
static enum EStatus xStatus = EStatusLookup;
|
||||
|
||||
static const char *pcTimeServers[] = {
|
||||
"0.asia.pool.ntp.org",
|
||||
"0.europe.pool.ntp.org",
|
||||
"0.id.pool.ntp.org",
|
||||
"0.south-america.pool.ntp.org",
|
||||
"0.oceania.pool.ntp.org",
|
||||
"0.north-america.pool.ntp.org"
|
||||
};
|
||||
|
||||
static SemaphoreHandle_t xNTPWakeupSem = NULL;
|
||||
static uint32_t ulIPAddressFound;
|
||||
static Socket_t xUDPSocket = NULL;
|
||||
static TaskHandle_t xNTPTaskhandle = NULL;
|
||||
static TickType_t uxSendTime;
|
||||
|
||||
static void prvNTPTask( void *pvParameters );
|
||||
|
||||
static void vSignalTask( void )
|
||||
{
|
||||
#if( ipconfigUSE_CALLBACKS == 0 )
|
||||
if( xUDPSocket != NULL )
|
||||
{
|
||||
/* Send a signal to the socket so that the
|
||||
FreeRTOS_recvfrom will get interrupted. */
|
||||
FreeRTOS_SignalSocket( xUDPSocket );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( xNTPWakeupSem != NULL )
|
||||
{
|
||||
xSemaphoreGive( xNTPWakeupSem );
|
||||
}
|
||||
}
|
||||
|
||||
void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority )
|
||||
{
|
||||
/* The only public function in this module: start a task to contact
|
||||
some NTP server. */
|
||||
|
||||
if( xNTPTaskhandle != NULL )
|
||||
{
|
||||
switch( xStatus )
|
||||
{
|
||||
case EStatusPause:
|
||||
xStatus = EStatusAsking;
|
||||
vSignalTask();
|
||||
break;
|
||||
case EStatusLookup:
|
||||
FreeRTOS_printf( ( "NTP looking up server\n" ) );
|
||||
break;
|
||||
case EStatusAsking:
|
||||
FreeRTOS_printf( ( "NTP still asking\n" ) );
|
||||
break;
|
||||
case EStatusFailed:
|
||||
FreeRTOS_printf( ( "NTP failed somehow\n" ) );
|
||||
ulIPAddressFound = 0ul;
|
||||
xStatus = EStatusLookup;
|
||||
vSignalTask();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xUDPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
|
||||
if( xUDPSocket != NULL )
|
||||
{
|
||||
struct freertos_sockaddr xAddress;
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 0 );
|
||||
#else
|
||||
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
|
||||
#endif
|
||||
|
||||
xAddress.sin_addr = 0ul;
|
||||
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
|
||||
|
||||
FreeRTOS_bind( xUDPSocket, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
xTaskCreate( prvNTPTask, /* The function that implements the task. */
|
||||
( const char * ) "NTP client", /* Just a text name for the task to aid debugging. */
|
||||
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
|
||||
NULL, /* The task parameter, not used in this case. */
|
||||
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
|
||||
&xNTPTaskhandle ); /* The task handle. */
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_printf( ( "Creating socket failed\n" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vDNS_callback( const char *pcName, void *pvSearchID, uint32_t ulIPAddress )
|
||||
{
|
||||
char pcBuf[16];
|
||||
|
||||
/* The DNS lookup has a result, or it has reached the time-out. */
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
|
||||
FreeRTOS_printf( ( "IP address of %s found: %s\n", pcName, pcBuf ) );
|
||||
if( ulIPAddressFound == 0ul )
|
||||
{
|
||||
ulIPAddressFound = ulIPAddress;
|
||||
}
|
||||
/* For testing: in case DNS doen't respond, still try some NTP server
|
||||
with a known IP-address. */
|
||||
if( ulIPAddressFound == 0ul )
|
||||
{
|
||||
ulIPAddressFound = FreeRTOS_inet_addr_quick( 184, 105, 182, 7 );
|
||||
/* ulIPAddressFound = FreeRTOS_inet_addr_quick( 103, 242, 70, 4 ); */
|
||||
}
|
||||
xStatus = EStatusAsking;
|
||||
|
||||
vSignalTask();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSwapFields( struct SNtpPacket *pxPacket)
|
||||
{
|
||||
/* NTP messages are big-endian */
|
||||
pxPacket->rootDelay = FreeRTOS_htonl( pxPacket->rootDelay );
|
||||
pxPacket->rootDispersion = FreeRTOS_htonl( pxPacket->rootDispersion );
|
||||
|
||||
pxPacket->referenceTimestamp.seconds = FreeRTOS_htonl( pxPacket->referenceTimestamp.seconds );
|
||||
pxPacket->referenceTimestamp.fraction = FreeRTOS_htonl( pxPacket->referenceTimestamp.fraction );
|
||||
|
||||
pxPacket->originateTimestamp.seconds = FreeRTOS_htonl( pxPacket->originateTimestamp.seconds );
|
||||
pxPacket->originateTimestamp.fraction = FreeRTOS_htonl( pxPacket->originateTimestamp.fraction );
|
||||
|
||||
pxPacket->receiveTimestamp.seconds = FreeRTOS_htonl( pxPacket->receiveTimestamp.seconds );
|
||||
pxPacket->receiveTimestamp.fraction = FreeRTOS_htonl( pxPacket->receiveTimestamp.fraction );
|
||||
|
||||
pxPacket->transmitTimestamp.seconds = FreeRTOS_htonl( pxPacket->transmitTimestamp.seconds );
|
||||
pxPacket->transmitTimestamp.fraction = FreeRTOS_htonl( pxPacket->transmitTimestamp.fraction );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvNTPPacketInit( )
|
||||
{
|
||||
memset (&xNTPPacket, '\0', sizeof( xNTPPacket ) );
|
||||
|
||||
xNTPPacket.flags = 0xDB; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */
|
||||
xNTPPacket.poll = 10; /* 10 means 1 << 10 = 1024 seconds */
|
||||
xNTPPacket.precision = 0xFA; /* = 250 = 0.015625 seconds */
|
||||
xNTPPacket.rootDelay = 0x5D2E; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */
|
||||
xNTPPacket.rootDispersion = 0x0008CAC8; /* 0x0008CAC8 = 8.7912 seconds */
|
||||
|
||||
/* use the recorded NTP time */
|
||||
time_t uxSecs = FreeRTOS_time( NULL );/* apTime may be NULL, returns seconds */
|
||||
|
||||
xNTPPacket.referenceTimestamp.seconds = uxSecs; /* Current time */
|
||||
xNTPPacket.transmitTimestamp.seconds = uxSecs + 3;
|
||||
|
||||
/* Transform the contents of the fields from native to big endian. */
|
||||
prvSwapFields( &xNTPPacket );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvReadTime( struct SNtpPacket * pxPacket )
|
||||
{
|
||||
FF_TimeStruct_t xTimeStruct;
|
||||
time_t uxPreviousSeconds;
|
||||
time_t uxPreviousMS;
|
||||
|
||||
time_t uxCurrentSeconds;
|
||||
time_t uxCurrentMS;
|
||||
|
||||
const char *pcTimeUnit;
|
||||
int32_t ilDiff;
|
||||
TickType_t uxTravelTime;
|
||||
|
||||
uxTravelTime = xTaskGetTickCount() - uxSendTime;
|
||||
|
||||
/* Transform the contents of the fields from big to native endian. */
|
||||
prvSwapFields( pxPacket );
|
||||
|
||||
uxCurrentSeconds = pxPacket->receiveTimestamp.seconds - TIME1970;
|
||||
uxCurrentMS = pxPacket->receiveTimestamp.fraction / 4294967;
|
||||
uxCurrentSeconds += uxCurrentMS / 1000;
|
||||
uxCurrentMS = uxCurrentMS % 1000;
|
||||
|
||||
// Get the last time recorded
|
||||
uxPreviousSeconds = FreeRTOS_get_secs_msec( &uxPreviousMS );
|
||||
|
||||
// Set the new time with precision in msec. */
|
||||
FreeRTOS_set_secs_msec( &uxCurrentSeconds, &uxCurrentMS );
|
||||
|
||||
if( uxCurrentSeconds >= uxPreviousSeconds )
|
||||
{
|
||||
ilDiff = ( int32_t ) ( uxCurrentSeconds - uxPreviousSeconds );
|
||||
}
|
||||
else
|
||||
{
|
||||
ilDiff = 0 - ( int32_t ) ( uxPreviousSeconds - uxCurrentSeconds );
|
||||
}
|
||||
|
||||
if( ( ilDiff < -5 ) || ( ilDiff > 5 ) )
|
||||
{
|
||||
/* More than 5 seconds difference. */
|
||||
pcTimeUnit = "sec";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Less than or equal to 5 second difference. */
|
||||
pcTimeUnit = "ms";
|
||||
uint32_t ulLowest = ( uxCurrentSeconds <= uxPreviousSeconds ) ? uxCurrentSeconds : uxPreviousSeconds;
|
||||
int32_t iCurMS = 1000 * ( uxCurrentSeconds - ulLowest ) + uxCurrentMS;
|
||||
int32_t iPrevMS = 1000 * ( uxPreviousSeconds - ulLowest ) + uxPreviousMS;
|
||||
ilDiff = iCurMS - iPrevMS;
|
||||
}
|
||||
uxCurrentSeconds -= iTimeZone;
|
||||
|
||||
FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct );
|
||||
|
||||
/*
|
||||
378.067 [NTP client] NTP time: 9/11/2015 16:11:19.559 Diff -20 ms (289 ms)
|
||||
379.441 [NTP client] NTP time: 9/11/2015 16:11:20.933 Diff 0 ms (263 ms)
|
||||
*/
|
||||
|
||||
FreeRTOS_printf( ("NTP time: %d/%d/%02d %2d:%02d:%02d.%03u Diff %d %s (%lu ms)\n",
|
||||
xTimeStruct.tm_mday,
|
||||
xTimeStruct.tm_mon + 1,
|
||||
xTimeStruct.tm_year + 1900,
|
||||
xTimeStruct.tm_hour,
|
||||
xTimeStruct.tm_min,
|
||||
xTimeStruct.tm_sec,
|
||||
( unsigned )uxCurrentMS,
|
||||
( unsigned )ilDiff,
|
||||
pcTimeUnit,
|
||||
uxTravelTime ) );
|
||||
|
||||
/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
|
||||
( void ) pcTimeUnit;
|
||||
( void ) uxTravelTime;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
|
||||
static BaseType_t xOnUDPReceive( Socket_t xSocket, void * pvData, size_t xLength,
|
||||
const struct freertos_sockaddr *pxFrom, const struct freertos_sockaddr *pxDest )
|
||||
{
|
||||
if( xLength >= sizeof( xNTPPacket ) )
|
||||
{
|
||||
prvReadTime( ( struct SNtpPacket *)pvData );
|
||||
if( xStatus != EStatusPause )
|
||||
{
|
||||
xStatus = EStatusPause;
|
||||
}
|
||||
}
|
||||
vSignalTask();
|
||||
/* Tell the driver not to store the RX data */
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ipconfigUSE_CALLBACKS != 0 */
|
||||
|
||||
static void prvNTPTask( void *pvParameters )
|
||||
{
|
||||
BaseType_t xServerIndex = 3;
|
||||
struct freertos_sockaddr xAddress;
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
F_TCP_UDP_Handler_t xHandler;
|
||||
#endif /* ipconfigUSE_CALLBACKS != 0 */
|
||||
|
||||
xStatus = EStatusLookup;
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
xNTPWakeupSem = xSemaphoreCreateBinary();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
memset( &xHandler, '\0', sizeof( xHandler ) );
|
||||
xHandler.pxOnUDPReceive = xOnUDPReceive;
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) );
|
||||
}
|
||||
#endif
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
|
||||
{
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) );
|
||||
}
|
||||
#endif
|
||||
for( ; ; )
|
||||
{
|
||||
switch( xStatus )
|
||||
{
|
||||
case EStatusLookup:
|
||||
if( ( ulIPAddressFound == 0ul ) || ( ulIPAddressFound == ~0ul ) )
|
||||
{
|
||||
if( ++xServerIndex == sizeof( pcTimeServers ) / sizeof( pcTimeServers[ 0 ] ) )
|
||||
{
|
||||
xServerIndex = 0;
|
||||
}
|
||||
FreeRTOS_printf( ( "Looking up server '%s'\n", pcTimeServers[ xServerIndex ] ) );
|
||||
FreeRTOS_gethostbyname_a( pcTimeServers[ xServerIndex ], vDNS_callback, (void *)NULL, 1200 );
|
||||
}
|
||||
else
|
||||
{
|
||||
xStatus = EStatusAsking;
|
||||
}
|
||||
break;
|
||||
|
||||
case EStatusAsking:
|
||||
{
|
||||
char pcBuf[16];
|
||||
|
||||
prvNTPPacketInit( );
|
||||
xAddress.sin_addr = ulIPAddressFound;
|
||||
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
|
||||
|
||||
FreeRTOS_inet_ntoa( xAddress.sin_addr, pcBuf );
|
||||
FreeRTOS_printf( ( "Sending UDP message to %s:%u\n",
|
||||
pcBuf,
|
||||
FreeRTOS_ntohs( xAddress.sin_port ) ) );
|
||||
|
||||
uxSendTime = xTaskGetTickCount( );
|
||||
FreeRTOS_sendto( xUDPSocket, ( void * )&xNTPPacket, sizeof( xNTPPacket ), 0, &xAddress, sizeof( xAddress ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case EStatusPause:
|
||||
break;
|
||||
|
||||
case EStatusFailed:
|
||||
break;
|
||||
}
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
xSemaphoreTake( xNTPWakeupSem, 5000 );
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint32_t xAddressSize;
|
||||
BaseType_t xReturned;
|
||||
|
||||
xAddressSize = sizeof( xAddress );
|
||||
xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize );
|
||||
switch( xReturned )
|
||||
{
|
||||
case 0:
|
||||
case -pdFREERTOS_ERRNO_EAGAIN:
|
||||
case -pdFREERTOS_ERRNO_EINTR:
|
||||
break;
|
||||
default:
|
||||
if( xReturned < sizeof( xNTPPacket ) )
|
||||
{
|
||||
FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
prvReadTime( ( struct SNtpPacket *)cRecvBuffer );
|
||||
if( xStatus != EStatusPause )
|
||||
{
|
||||
xStatus = EStatusPause;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.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
|
||||
*/
|
||||
|
||||
#ifndef __FTPCMD_H__
|
||||
|
||||
#define __FTPCMD_H__
|
||||
|
||||
#define REPL_110 "110 Restart marker reply.\r\n"
|
||||
#define REPL_120 "120 Try again in 2 minutes.\r\n"
|
||||
#define REPL_125 "125 Data connection already open; transfer starting.\r\n"
|
||||
#define REPL_150 "150 File status okay; about to open data connection.\r\n"
|
||||
#define REPL_200 "200 NOOP command successful.\r\n"
|
||||
#define REPL_200_PROGRESS "200 NOOP: data transfer in progress.\r\n"
|
||||
#define REPL_202 "202 Command not implemented, superfluous at this site.\r\n"
|
||||
#define REPL_211 "221 System status, or system help reply.\r\n"
|
||||
#define REPL_211_STATUS "221-status of %s.\r\n"
|
||||
#define REPL_211_END "221 End of status.\r\n"
|
||||
#define REPL_212 "212 Directory status.\r\n"
|
||||
#define REPL_213 "213 File status.\r\n"
|
||||
#define REPL_214 "214 Help message.\r\n"
|
||||
#define REPL_214_END "214 End Help message.\r\n"
|
||||
#define REPL_215 "215 %s system type.\r\n"
|
||||
#define REPL_220 "220 Service ready for new user.\r\n"
|
||||
#define REPL_221 "221 Service closing control connection.\r\n"
|
||||
#define REPL_225 "225 Data connection open; no transfer in progress.\r\n"
|
||||
#define REPL_226 "226 Closing data connection.\r\n"
|
||||
#define REPL_227 "227 Entering Passive Mode (%s,%s,%s,%s,%s,%s).\r\n"
|
||||
#define REPL_227_D "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u).\r\n"
|
||||
#define REPL_230 "230 User logged in, proceed.\r\n"
|
||||
#define REPL_250 "250 Requested file action okay, completed.\r\n"
|
||||
#define REPL_257 "257 %s created.\r\n"
|
||||
// #define REPL_257_PWD "257 \"%s\" is current working dir.\r\n"
|
||||
#define REPL_257_PWD "257 \"%s\"\r\n"
|
||||
#define REPL_331 "331 Only anonymous user is accepted.\r\n"
|
||||
#define REPL_331_ANON "331 Anonymous login okay\r\n"
|
||||
#define REPL_332 "332 Need account for login.\r\n"
|
||||
#define REPL_350 "350 Requested file action pending further information.\r\n"
|
||||
#define REPL_421 "421 Service not available, closing control connection.\r\n"
|
||||
#define REPL_425 "425 Can't open data connection.\r\n"
|
||||
#define REPL_426 "426 Connection closed; transfer aborted.\r\n"
|
||||
#define REPL_450 "450 Requested file action not taken.\r\n"
|
||||
#define REPL_451 "451 Requested action aborted. Local error in processing.\r\n"
|
||||
#define REPL_452 "452 Requested action not taken.\r\n"
|
||||
#define REPL_500 "500 Syntax error, command unrecognized.\r\n"
|
||||
#define REPL_501 "501 Syntax error in parameters or arguments.\r\n"
|
||||
#define REPL_502 "502 Command not implemented.\r\n"
|
||||
#define REPL_503 "503 Bad sequence of commands.\r\n"
|
||||
#define REPL_504 "504 Command not implemented for that parameter.\r\n"
|
||||
#define REPL_530 "530 Not logged in.\r\n"
|
||||
#define REPL_532 "532 Need account for storing files.\r\n"
|
||||
#define REPL_550 "550 Requested action not taken.\r\n"
|
||||
#define REPL_551 "551 Requested action aborted. Page type unknown.\r\n"
|
||||
#define REPL_552 "552 Requested file action aborted.\r\n"
|
||||
#define REPL_553 "553 Requested action not taken.\r\n"
|
||||
#define REPL_553_READ_ONLY "553 Read-only file-system.\r\n"
|
||||
|
||||
enum EFTPCommand {
|
||||
ECMD_USER,
|
||||
ECMD_PASS,
|
||||
ECMD_ACCT,
|
||||
ECMD_CWD,
|
||||
ECMD_CDUP,
|
||||
ECMD_SMNT,
|
||||
ECMD_QUIT,
|
||||
ECMD_REIN,
|
||||
ECMD_PORT,
|
||||
ECMD_PASV,
|
||||
ECMD_TYPE,
|
||||
ECMD_STRU,
|
||||
ECMD_MODE,
|
||||
ECMD_RETR,
|
||||
ECMD_STOR,
|
||||
ECMD_STOU,
|
||||
ECMD_APPE,
|
||||
ECMD_ALLO,
|
||||
ECMD_REST,
|
||||
ECMD_RNFR,
|
||||
ECMD_RNTO,
|
||||
ECMD_ABOR,
|
||||
ECMD_SIZE,
|
||||
ECMD_MDTM,
|
||||
ECMD_DELE,
|
||||
ECMD_RMD,
|
||||
ECMD_MKD,
|
||||
ECMD_PWD,
|
||||
ECMD_LIST,
|
||||
ECMD_NLST,
|
||||
ECMD_SITE,
|
||||
ECMD_SYST,
|
||||
ECMD_FEAT,
|
||||
ECMD_STAT,
|
||||
ECMD_HELP,
|
||||
ECMD_NOOP,
|
||||
ECMD_EMPTY,
|
||||
ECMD_CLOSE,
|
||||
ECMD_UNKNOWN,
|
||||
};
|
||||
|
||||
typedef struct xFTP_COMMAND {
|
||||
BaseType_t xCommandLength;
|
||||
const char pcCommandName[7];
|
||||
const unsigned char ucCommandType;
|
||||
const unsigned char checkLogin;
|
||||
const unsigned char checkNullArg;
|
||||
} FTPCommand_t;
|
||||
|
||||
#define FTP_CMD_COUNT (ECMD_UNKNOWN+1)
|
||||
|
||||
extern const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ];
|
||||
|
||||
#endif // __FTPCMD_H__
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
#ifndef FREERTOS_HTTP_COMMANDS_H
|
||||
#define FREERTOS_HTTP_COMMANDS_H
|
||||
|
||||
enum {
|
||||
WEB_REPLY_OK = 200,
|
||||
WEB_NO_CONTENT = 204,
|
||||
WEB_BAD_REQUEST = 400,
|
||||
WEB_UNAUTHORIZED = 401,
|
||||
WEB_NOT_FOUND = 404,
|
||||
WEB_GONE = 410,
|
||||
WEB_PRECONDITION_FAILED = 412,
|
||||
WEB_INTERNAL_SERVER_ERROR = 500,
|
||||
};
|
||||
|
||||
enum EWebCommand {
|
||||
ECMD_GET,
|
||||
ECMD_HEAD,
|
||||
ECMD_POST,
|
||||
ECMD_PUT,
|
||||
ECMD_DELETE,
|
||||
ECMD_TRACE,
|
||||
ECMD_OPTIONS,
|
||||
ECMD_CONNECT,
|
||||
ECMD_PATCH,
|
||||
ECMD_UNK,
|
||||
};
|
||||
|
||||
struct xWEB_COMMAND
|
||||
{
|
||||
BaseType_t xCommandLength;
|
||||
const char *pcCommandName;
|
||||
const unsigned char ucCommandType;
|
||||
};
|
||||
|
||||
#define WEB_CMD_COUNT (ECMD_UNK+1)
|
||||
|
||||
extern const struct xWEB_COMMAND xWebCommands[WEB_CMD_COUNT];
|
||||
|
||||
extern const char *webCodename (int aCode);
|
||||
|
||||
#endif /* FREERTOS_HTTP_COMMANDS_H */
|
||||
|
||||
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
Some code which is common to TCP servers like HTTP en FTP
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TCP_SERVER_H
|
||||
#define FREERTOS_TCP_SERVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef FTP_SERVER_USES_RELATIVE_DIRECTORY
|
||||
#define FTP_SERVER_USES_RELATIVE_DIRECTORY 0
|
||||
#endif
|
||||
|
||||
enum eSERVER_TYPE
|
||||
{
|
||||
eSERVER_NONE,
|
||||
eSERVER_HTTP,
|
||||
eSERVER_FTP,
|
||||
};
|
||||
|
||||
struct xFTP_CLIENT;
|
||||
|
||||
#if( ipconfigFTP_HAS_RECEIVED_HOOK != 0 )
|
||||
extern void vApplicationFTPReceivedHook( const char *pcFileName, uint32_t ulSize, struct xFTP_CLIENT *pxFTPClient );
|
||||
extern void vFTPReplyMessage( struct xFTP_CLIENT *pxFTPClient, const char *pcMessage );
|
||||
#endif /* ipconfigFTP_HAS_RECEIVED_HOOK != 0 */
|
||||
|
||||
#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 )
|
||||
/*
|
||||
* Function is called when a user name has been submitted.
|
||||
* The function may return a string such as: "331 Please enter your password"
|
||||
* or return NULL to use the default reply.
|
||||
*/
|
||||
extern const char *pcApplicationFTPUserHook( const char *pcUserName );
|
||||
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
|
||||
|
||||
#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 )
|
||||
/*
|
||||
* Function is called when a password was received.
|
||||
* Return positive value to allow the user
|
||||
*/
|
||||
extern BaseType_t xApplicationFTPPasswordHook( const char *pcUserName, const char *pcPassword );
|
||||
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
|
||||
|
||||
#if( ipconfigFTP_HAS_USER_PROPERTIES_HOOK != 0 )
|
||||
/*
|
||||
* The FTP server is asking for user-specific properties
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t usPortNumber; /* For reference only. Host-endian. */
|
||||
const char *pcRootDir;
|
||||
BaseType_t xReadOnly;
|
||||
}
|
||||
FTPUserProperties_t;
|
||||
extern void vApplicationFTPUserPropertiesHook( const char *pcUserName, FTPUserProperties_t *pxProperties );
|
||||
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
|
||||
|
||||
#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
|
||||
/*
|
||||
* A GET request is received containing a special character,
|
||||
* usually a question mark.
|
||||
* const char *pcURLData; // A request, e.g. "/request?limit=75"
|
||||
* char *pcBuffer; // Here the answer can be written
|
||||
* size_t uxBufferLength; // Size of the buffer
|
||||
*
|
||||
*/
|
||||
extern size_t uxApplicationHTTPHandleRequestHook( const char *pcURLData, char *pcBuffer, size_t uxBufferLength );
|
||||
#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */
|
||||
|
||||
struct xSERVER_CONFIG
|
||||
{
|
||||
enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */
|
||||
BaseType_t xPortNumber; /* e.g. 80, 8080, 21 */
|
||||
BaseType_t xBackLog; /* e.g. 10, maximum number of connected TCP clients */
|
||||
const char * const pcRootDir; /* Treat this directory as the root directory */
|
||||
};
|
||||
|
||||
struct xTCP_SERVER;
|
||||
typedef struct xTCP_SERVER TCPServer_t;
|
||||
|
||||
TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount );
|
||||
void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime );
|
||||
|
||||
#if( ipconfigSUPPORT_SIGNALS != 0 )
|
||||
/* FreeRTOS_TCPServerWork() calls select().
|
||||
The two functions below provide a possibility to interrupt
|
||||
the call to select(). After the interruption, resume
|
||||
by calling FreeRTOS_TCPServerWork() again. */
|
||||
BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer );
|
||||
BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_TCP_SERVER_H */
|
@ -1,185 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
Some code which is common to TCP servers like HTTP and FTP
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_SERVER_PRIVATE_H
|
||||
#define FREERTOS_SERVER_PRIVATE_H
|
||||
|
||||
#define FREERTOS_NO_SOCKET NULL
|
||||
|
||||
/* FreeRTOS+FAT */
|
||||
#include "ff_stdio.h"
|
||||
|
||||
/* Each HTTP server has 1, at most 2 sockets */
|
||||
#define HTTP_SOCKET_COUNT 2
|
||||
|
||||
/*
|
||||
* ipconfigTCP_COMMAND_BUFFER_SIZE sets the size of:
|
||||
* pcCommandBuffer': a buffer to receive and send TCP commands
|
||||
*
|
||||
* ipconfigTCP_FILE_BUFFER_SIZE sets the size of:
|
||||
* pcFileBuffer' : a buffer to access the file system: read or write data.
|
||||
*
|
||||
* The buffers are both used for FTP as well as HTTP.
|
||||
*/
|
||||
|
||||
#ifndef ipconfigTCP_COMMAND_BUFFER_SIZE
|
||||
#define ipconfigTCP_COMMAND_BUFFER_SIZE ( 2048 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_FILE_BUFFER_SIZE
|
||||
#define ipconfigTCP_FILE_BUFFER_SIZE ( 2048 )
|
||||
#endif
|
||||
|
||||
struct xTCP_CLIENT;
|
||||
|
||||
typedef BaseType_t ( * FTCPWorkFunction ) ( struct xTCP_CLIENT * /* pxClient */ );
|
||||
typedef void ( * FTCPDeleteFunction ) ( struct xTCP_CLIENT * /* pxClient */ );
|
||||
|
||||
#define TCP_CLIENT_FIELDS \
|
||||
enum eSERVER_TYPE eType; \
|
||||
struct xTCP_SERVER *pxParent; \
|
||||
Socket_t xSocket; \
|
||||
const char *pcRootDir; \
|
||||
FTCPWorkFunction fWorkFunction; \
|
||||
FTCPDeleteFunction fDeleteFunction; \
|
||||
struct xTCP_CLIENT *pxNextClient
|
||||
|
||||
typedef struct xTCP_CLIENT
|
||||
{
|
||||
/* This define contains fields which must come first within each of the client structs */
|
||||
TCP_CLIENT_FIELDS;
|
||||
/* --- Keep at the top --- */
|
||||
|
||||
} TCPClient_t;
|
||||
|
||||
struct xHTTP_CLIENT
|
||||
{
|
||||
/* This define contains fields which must come first within each of the client structs */
|
||||
TCP_CLIENT_FIELDS;
|
||||
/* --- Keep at the top --- */
|
||||
|
||||
const char *pcUrlData;
|
||||
const char *pcRestData;
|
||||
char pcCurrentFilename[ ffconfigMAX_FILENAME ];
|
||||
size_t uxBytesLeft;
|
||||
FF_FILE *pxFileHandle;
|
||||
union {
|
||||
struct {
|
||||
uint32_t
|
||||
bReplySent : 1;
|
||||
};
|
||||
uint32_t ulFlags;
|
||||
} bits;
|
||||
};
|
||||
|
||||
typedef struct xHTTP_CLIENT HTTPClient_t;
|
||||
|
||||
struct xFTP_CLIENT
|
||||
{
|
||||
/* This define contains fields which must come first within each of the client structs */
|
||||
TCP_CLIENT_FIELDS;
|
||||
/* --- Keep at the top --- */
|
||||
|
||||
uint32_t ulRestartOffset;
|
||||
uint32_t ulRecvBytes;
|
||||
size_t uxBytesLeft; /* Bytes left to send */
|
||||
uint32_t ulClientIP;
|
||||
TickType_t xStartTime;
|
||||
uint16_t usClientPort;
|
||||
Socket_t xTransferSocket;
|
||||
BaseType_t xTransType;
|
||||
BaseType_t xDirCount;
|
||||
FF_FindData_t xFindData;
|
||||
FF_FILE *pxReadHandle;
|
||||
FF_FILE *pxWriteHandle;
|
||||
char pcCurrentDir[ ffconfigMAX_FILENAME ];
|
||||
char pcFileName[ ffconfigMAX_FILENAME ];
|
||||
char pcConnectionAck[ 128 ];
|
||||
char pcClientAck[ 128 ];
|
||||
union {
|
||||
struct {
|
||||
uint32_t
|
||||
bHelloSent : 1,
|
||||
bLoggedIn : 1,
|
||||
bStatusUser : 1,
|
||||
bInRename : 1,
|
||||
bReadOnly : 1;
|
||||
};
|
||||
uint32_t ulFTPFlags;
|
||||
} bits;
|
||||
union {
|
||||
struct {
|
||||
uint32_t
|
||||
bIsListen : 1, /* pdTRUE for passive data connections (using list()). */
|
||||
bDirHasEntry : 1, /* pdTRUE if ff_findfirst() was successful. */
|
||||
bClientConnected : 1, /* pdTRUE after connect() or accept() has succeeded. */
|
||||
bEmptyFile : 1, /* pdTRUE if a connection-without-data was received. */
|
||||
bHadError : 1; /* pdTRUE if a transfer got aborted because of an error. */
|
||||
};
|
||||
uint32_t ulConnFlags;
|
||||
} bits1;
|
||||
};
|
||||
|
||||
typedef struct xFTP_CLIENT FTPClient_t;
|
||||
|
||||
BaseType_t xHTTPClientWork( TCPClient_t *pxClient );
|
||||
BaseType_t xFTPClientWork( TCPClient_t *pxClient );
|
||||
|
||||
void vHTTPClientDelete( TCPClient_t *pxClient );
|
||||
void vFTPClientDelete( TCPClient_t *pxClient );
|
||||
|
||||
BaseType_t xMakeAbsolute( struct xFTP_CLIENT *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName );
|
||||
BaseType_t xMakeRelative( FTPClient_t *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName );
|
||||
|
||||
struct xTCP_SERVER
|
||||
{
|
||||
SocketSet_t xSocketSet;
|
||||
/* A buffer to receive and send TCP commands, either HTTP of FTP. */
|
||||
char pcCommandBuffer[ ipconfigTCP_COMMAND_BUFFER_SIZE ];
|
||||
/* A buffer to access the file system: read or write data. */
|
||||
char pcFileBuffer[ ipconfigTCP_FILE_BUFFER_SIZE ];
|
||||
|
||||
#if( ipconfigUSE_FTP != 0 )
|
||||
char pcNewDir[ ffconfigMAX_FILENAME ];
|
||||
#endif
|
||||
#if( ipconfigUSE_HTTP != 0 )
|
||||
char pcContentsType[40]; /* Space for the msg: "text/javascript" */
|
||||
char pcExtraContents[40]; /* Space for the msg: "Content-Length: 346500" */
|
||||
#endif
|
||||
BaseType_t xServerCount;
|
||||
TCPClient_t *pxClients;
|
||||
struct xSERVER
|
||||
{
|
||||
enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */
|
||||
const char *pcRootDir;
|
||||
Socket_t xSocket;
|
||||
} xServers[ 1 ];
|
||||
};
|
||||
|
||||
#endif /* FREERTOS_SERVER_PRIVATE_H */
|
@ -1,71 +0,0 @@
|
||||
//
|
||||
// ntpClient.h
|
||||
//
|
||||
|
||||
#ifndef __NTPCLIENT_H__
|
||||
|
||||
#define __NTPCLIENT_H__
|
||||
|
||||
#define NTP_PORT 123
|
||||
|
||||
typedef uint32_t quint32;
|
||||
typedef int32_t qint32;
|
||||
typedef uint8_t quint8;
|
||||
typedef int8_t qint8;
|
||||
|
||||
typedef union _SNtpFlags SNtpFlags;
|
||||
|
||||
/**
|
||||
* 64-bit NTP timestamp.
|
||||
*/
|
||||
struct __attribute__ ((__packed__)) _SNtpTimestamp {
|
||||
/** Number of seconds passed since Jan 1 1900, in big-endian format. */
|
||||
quint32 seconds;
|
||||
|
||||
/** Fractional time part, in <tt>1/0xFFFFFFFF</tt>s of a second. */
|
||||
quint32 fraction;
|
||||
};
|
||||
|
||||
typedef struct _SNtpTimestamp SNtpTimestamp;
|
||||
/**
|
||||
* Mandatory part of an NTP packet
|
||||
*/
|
||||
struct SNtpPacket {
|
||||
/** Flags. */
|
||||
unsigned char flags; // value 0xDB : mode 3 (client), version 3, leap indicator unknown 3
|
||||
|
||||
/** Stratum of the clock. */
|
||||
quint8 stratum; // value 0 : unspecified
|
||||
|
||||
/** Maximum interval between successive messages, in log2 seconds. Note that the value is signed. */
|
||||
qint8 poll; // 10 means 1 << 10 = 1024 seconds
|
||||
|
||||
/** Precision of the clock, in log2 seconds. Note that the value is signed. */
|
||||
qint8 precision; // 0xFA = 250 = 0.015625 seconds
|
||||
|
||||
/** Round trip time to the primary reference source, in NTP short format. */
|
||||
qint32 rootDelay; // 0x5D2E = 23854 or (23854/65535)= 0.3640 sec
|
||||
|
||||
/** Nominal error relative to the primary reference source. */
|
||||
qint32 rootDispersion; // 0x0008 CAC8 = 8.7912 seconds
|
||||
|
||||
/** Reference identifier (either a 4 character string or an IP address). */
|
||||
qint8 referenceID[4]; // or just 0000
|
||||
|
||||
/** The time at which the clock was last set or corrected. */
|
||||
SNtpTimestamp referenceTimestamp; // Current time
|
||||
|
||||
/** The time at which the request departed the client for the server. */
|
||||
SNtpTimestamp originateTimestamp; // Keep 0
|
||||
|
||||
/** The time at which the request arrived at the server. */
|
||||
SNtpTimestamp receiveTimestamp; // Keep 0
|
||||
|
||||
/** The time at which the reply departed the server for client. */
|
||||
SNtpTimestamp transmitTimestamp;
|
||||
};
|
||||
|
||||
/* Add this number to get secs since 1-1-1900 */
|
||||
#define TIME1970 2208988800UL
|
||||
|
||||
#endif // __NTPCLIENT_H__
|
@ -1,11 +0,0 @@
|
||||
/*
|
||||
* A simple demo for NTP using FreeRTOS+TCP
|
||||
*/
|
||||
|
||||
#ifndef NTPDEMO_H
|
||||
|
||||
#define NTPDEMO_H
|
||||
|
||||
void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority );
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user