Hello @epopov,
As usual, I try to keep it short
At this moment, FreeRTOS_FillEndPoint()
will call FreeRTOS_AddEndPoint()
, which has a problem. I discovered and solved it this week in PR #1020.
Also FreeRTOS_AddNetworkInterface()
will need a small change.
Important to know: when xApplicationDHCPHook_Multi()
is called, the code is running from the IP-task, so it is safe to make changes to the ipv4_defaults
of the endpoint.
Here is an example that I just tested. Note that it is a quick sketch, just to explain and explore ideas.
First I have started the endpoint with these properties:
===> Interface 'eth0' endpoint '0.0.0.0' is up
IPv4 address = 0.0.0.0
IP-address : 0.0.0.0
End-point : up = yes method static
Net mask : 255.255.255.0
GW : 0.0.0.0
DNS-0 : 0.0.0.0
DNS-1 : 0.0.0.0
Broadcast : 0.0.0.255
MAC address: 00-11-22-33-44-41
After 3 seconds I want to start DHCP:
static BaseType_t bDHCP_started = pdFALSE;
/* Only do this once, after running 3 seconds. */
if( ( bDHCP_started == pdFALSE ) &&
( xTaskGetTickCount () > pdMS_TO_TICKS( 3000U ) ) )
{
/* Remember that DHCP was started. */
bDHCP_started = pdTRUE;
/* Set the DHCP bit. */
xEndPoints[0].bits.bWantDHCP = pdTRUE;
/* Put the endpoint in the down state. */
// vApplicationIPNetworkEventHook_Multi( eNetworkDown, &( xEndPoints[ 0 ] ) );
/* Try this in stead: */
xEndPoints[ 0 ].bits.bEndPointUp = pdFALSE_UNSIGNED;
EDIT : probably not a good idea to call the network event hook from the application.
Actually I was looking for a function that brings a single endpoint in the eNetworkDown
state.
/* Tell the IP-task that DHCP must be re-started. */
xSendDHCPEvent( &( xEndPoints[ 0 ] ) );
}
You may wat to stop the scheduler temporarily while running the above code.
Now I see that DHCP negotiation is starting again and my DHCP application hook is called:
eDHCPCallbackAnswer_t xApplicationDHCPHook_Multi( eDHCPCallbackPhase_t eDHCPPhase,
struct xNetworkEndPoint * pxEndPoint,
IP_Address_t * pxIPAddress )
{
eDHCPCallbackAnswer_t aAnswer = eDHCPContinue;
if( pxEndPoint->bits.bIPv6 == pdTRUE_UNSIGNED )
{
FreeRTOS_printf( ("DHCP[%d] IP %pip\n",
( int ) eDHCPPhase, pxIPAddress->xIP_IPv6.ucBytes) );
}
else
{
if( ( bEnableDHCP == pdFALSE ) && ( eDHCPPhase == eDHCPPhasePreDiscover ) )
{
/* Use a static address 192.168.2.199. */
uint32_t ulIPAddress;
FreeRTOS_inet_pton4( "192.168.2.199", ( void* )&ulIPAddress );
uint8_t * pucIPAddress = (uint8_t * )&ulIPAddress;
FreeRTOS_FillEndPoint( &(xInterfaces[0]),
&(xEndPoints[0]),
pucIPAddress,
ucNetMask,
ucGatewayAddress,
ucDNSServerAddress,
ucMACAddress );
/* Just to make clear that DHCP was cancelled. */
pxEndPoint->bits.bWantDHCP = pdFALSE;
aAnswer = eDHCPUseDefaults;
}
FreeRTOS_printf( ("DHCP[%d] IP %xip\n",
( int ) eDHCPPhase, FreeRTOS_ntohl( pxIPAddress->ulIP_IPv4 ) ) );
}
return aAnswer;
}
My vApplicationIPNetworkEventHook_Multi()
is called again when DHCP is ready or in case I stopped DHCP.
These are the new properties of the endpoint:
===> Interface 'eth0' endpoint '192.168.2.199' is up
uxNetworkisUp = 5 expected 5
IPv4 address = 192.168.2.199
End-point : up = yes method static
Net mask : 255.255.255.0
GW : 192.168.2.1
DNS-0 : 118.98.44.100
DNS-1 : 0.0.0.0
Broadcast : 192.168.2.255
MAC address: 00-11-22-33-44-41
But once again: the FreeRTOS_FillEndPoint()
can be called once for every endpoint until PR #1020 is applyied.