Hello Aniruddha,
Thanks for replying. I have gone through the path that code follows. DHCP hook is enabled and xApplicationDHCPHook is returning the eReturn = eDHCPContinue; .
xApplicationDHCPHook is called from case : eWaitingSendFirstDiscover
and case : eWaitingOffer inside vDHCPProcessEndPoint() function
- When xApplicationDHCPHook is called from case : eWaitingSendFirstDiscover it returns eReturn = eDHCPContinue
case eWaitingSendFirstDiscover :
/* Ask the user if a DHCP discovery is required. */
#if( ipconfigUSE_DHCP_HOOK != 0 )
**eAnswer = xApplicationDHCPHook( eDHCPPhasePreDiscover, pxEndPoint->ulDefaultIPAddress );**
if( eAnswer == eDHCPContinue )
#endif /* ipconfigUSE_DHCP_HOOK */
{
/* Initial state. Create the DHCP socket, timer, etc. if they
have not already been created. */
prvInitialiseDHCP( pxEndPoint );
/* Put 'ulIPAddress' to zero to indicate that the end-point is down. */
pxEndPoint->ulIPAddress = 0UL;
/* Send the first discover request. */
if( xDHCPSocket != NULL )
{
pxEndPoint->xDHCPData.xDHCPTxTime = xTaskGetTickCount();
prvSendDHCPDiscover( pxEndPoint );
pxEndPoint->xDHCPData.eDHCPState = eWaitingOffer;
}
}
#if( ipconfigUSE_DHCP_HOOK != 0 )
else
{
if( eAnswer == eDHCPUseDefaults )
{
memcpy( &xNetworkAddressing, &xDefaultAddressing, sizeof( xNetworkAddressing ) );
}
/* The user indicates that the DHCP process does not continue. */
xGivingUp = pdTRUE;
}
#endif /* ipconfigUSE_DHCP_HOOK */
break;
- After that it changes its state from eWaitingSendFirstDiscover to eWaitingOffer and now after it goes in case : eWaitingOffer the following if condition is not executed. Due to which the xApplicationDHCPHook is not called again as it stucks there and execute the else if part mentioned below.
if( ( xDoCheck != pdFALSE ) && ( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_OFFER, pxEndPoint ) == pdPASS ) )
case eWaitingOffer :
xGivingUp = pdFALSE;
/* Look for offers coming in. */
if( ( xDoCheck != pdFALSE ) && ( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_OFFER, pxEndPoint ) == pdPASS ) )
{
#if( ipconfigUSE_DHCP_HOOK != 0 )
/* Ask the user if a DHCP request is required. */
eAnswer = xApplicationDHCPHook( eDHCPPhasePreRequest, pxEndPoint->xDHCPData.ulOfferedIPAddress );
if( eAnswer == eDHCPContinue )
#endif /* ipconfigUSE_DHCP_HOOK */
{
/* An offer has been made, the user wants to continue,
generate the request. */
pxEndPoint->xDHCPData.xDHCPTxTime = xTaskGetTickCount();
pxEndPoint->xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
prvSendDHCPRequest( pxEndPoint );
pxEndPoint->xDHCPData.eDHCPState = eWaitingAcknowledge;
break;
}
#if( ipconfigUSE_DHCP_HOOK != 0 )
if( eAnswer == eDHCPUseDefaults )
{
memcpy( &xNetworkAddressing, &xDefaultAddressing, sizeof( xNetworkAddressing ) );
pxEndPoint->ulIPAddress = pxEndPoint->ulDefaultIPAddress; /* Use this address in case DHCP has failed. */
}
/* The user indicates that the DHCP process does not continue. */
xGivingUp = pdTRUE;
#endif /* ipconfigUSE_DHCP_HOOK */
}
/* Is it time to send another Discover? */
**else if( ( xTaskGetTickCount() - pxEndPoint->xDHCPData.xDHCPTxTime ) > pxEndPoint->xDHCPData.xDHCPTxPeriod )**
{
/* Increase the time period, and if it has not got to the
point of giving up - send another discovery. */
pxEndPoint->xDHCPData.xDHCPTxPeriod <<= 1;
if( pxEndPoint->xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
{
pxEndPoint->xDHCPData.ulTransactionId++;
pxEndPoint->xDHCPData.xDHCPTxTime = xTaskGetTickCount();
pxEndPoint->xDHCPData.xUseBroadcast = !pxEndPoint->xDHCPData.xUseBroadcast;
prvSendDHCPDiscover( pxEndPoint );
FreeRTOS_printf( ( "vDHCPProcess[%02x-%02x]: timeout %lu ticks\n",
pxEndPoint->xMACAddress.ucBytes[ 4 ],
pxEndPoint->xMACAddress.ucBytes[ 5 ],
pxEndPoint->xDHCPData.xDHCPTxPeriod ) );
}
else
{
FreeRTOS_printf( ( "vDHCPProcess[%02x-%02x]: giving up %lu > %lu ticks\n",
pxEndPoint->xMACAddress.ucBytes[ 4 ],
pxEndPoint->xMACAddress.ucBytes[ 5 ],
pxEndPoint->xDHCPData.xDHCPTxPeriod, ipconfigMAXIMUM_DISCOVER_TX_PERIOD ) );
#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
{
/* Only use a fake Ack if the default IP address == 0x00
and the link local addressing is used. Start searching
a free LinkLayer IP-address. Next state will be
'eGetLinkLayerAddress'. */
prvPrepareLinkLayerIPLookUp();
/* Setting an IP address manually so set to not using
leased address mode. */
pxEndPoint->xDHCPData.eDHCPState = eGetLinkLayerAddress;
}
#else
{
xGivingUp = pdTRUE;
}
#endif /* ipconfigDHCP_FALL_BACK_AUTO_IP */
}
}
break;
- Now I have observed that in vDHCPProcess() function the lBytes is calculated from FreeRTOS_recvfrom() function and then the condition ( lBytes <= 0 ) is checked. Here the value of lBytes is always -11 i.e
pdFREERTOS_ERRNO_EWOULDBLOCK. So it never complete the for loop and break from the condition ( lBytes <= 0 ).
void vDHCPProcess( BaseType_t xReset, NetworkEndPoint_t *pxEndPoint )
{
/* If there is a socket, check for incoming messasges first. */
if( xDHCPSocket != NULL )
{
uint8_t *pucUDPPayload;
DHCPMessage_IPv4_t *pxDHCPMessage;
BaseType_t lBytes;
for( ;; )
{
NetworkEndPoint_t *pxIterator = NULL;
/* Peek the next UDP message. */
lBytes = FreeRTOS_recvfrom( xDHCPSocket, ( void * ) &pucUDPPayload, 0, FREERTOS_ZERO_COPY | FREERTOS_MSG_PEEK, NULL, NULL );
if( lBytes <= 0 )
{
if( ( lBytes < 0 ) && ( lBytes != -pdFREERTOS_ERRNO_EAGAIN ) )
{
FreeRTOS_printf( ( "vDHCPProcess: FreeRTOS_recvfrom returns %d\n", lBytes ) );
}
break;
}
/* Map a DHCP structure onto the received data. */
pxDHCPMessage = ( DHCPMessage_IPv4_t * ) ( pucUDPPayload );
/* Sanity check. */
if( ( pxDHCPMessage->ulDHCPCookie == dhcpCOOKIE ) && ( pxDHCPMessage->ucOpcode == dhcpREPLY_OPCODE ) )
{
pxIterator = pxNetworkEndPoints;
/* Find the end-point with given transaction ID. */
while( pxIterator != NULL )
{
if( pxDHCPMessage->ulTransactionID == FreeRTOS_htonl( pxIterator->xDHCPData.ulTransactionId ) )
{
break;
}
pxIterator = pxIterator->pxNext;
}
}
if( ( pxIterator != NULL ) && ( pxIterator->xDHCPData.eDHCPState == eLeasedAddress ) )
{
pxIterator = NULL;
}
if( pxIterator != NULL )
{
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
{
FreeRTOS_debug_printf( ( "vDHCPProcess[%02x-%02x] ID %04X: state %s found xReset %d\n",
pxIterator->xMACAddress.ucBytes[ 4 ],
pxIterator->xMACAddress.ucBytes[ 5 ],
pxIterator->xDHCPData.ulTransactionId,
pcDHCPStateName( pxIterator->xDHCPData.eDHCPState ) ) );
}
#endif /* ipconfigHAS_DEBUG_PRINTF */
/* The second parameter pdTRUE tells to check for a UDP message. */
vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxIterator );
if( pxEndPoint == pxIterator )
{
pxEndPoint = NULL;
}
}
else
{
/* Target not found, fetch the message and delete it. */
lBytes = FreeRTOS_recvfrom( xDHCPSocket, ( void * ) &pucUDPPayload, 0, FREERTOS_ZERO_COPY, NULL, NULL );
if( lBytes > 0 )
{
/* Remove it now, destination not found. */
FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );
FreeRTOS_printf( ( "vDHCPProcess: Removed a %d-byte message: target not found\n", lBytes ) );
}
}
}
}
if( pxEndPoint != NULL )
{
vDHCPProcessEndPoint( xReset, pdFALSE, pxEndPoint );
}
}
I will also debug further and will let you know the observation.
Thanks
Prince Tripathi