FreeRTOS+TCP 4.0.0 What is the "proper" way to change end-point settings

Thanks @Shub and @ActoryOu

I’m not trying to add an endpoint. I’m trying to modify it’s settings.

About the idea of creating 2 IPv4 endpoints and leaving one at 0.0.0.0 Well that doesn’t really help. I don’t need 2 endpoints. One issue is that at the very early stages of booting I don’t know my IP settings but I still want to be able to receive a type of magic packet that causes the device to revert back to safe functional firmware. At that stage I don’t want to have any IP because I don’t want any chance of a duplicate IP on the network where devices from multiple vendors are present. At this stage, a second endpoint is not helping because I still don’t know what settings to apply to it. After those couple of seconds I mount the FS and read my settings. At this point, I don’t need an endpoint with 0.0.0.0 because I now know my final settings. So you see how I just need to modify and endpoint, not add/remove them and having 2 doesn’t really help me in any way.

OK, since there is no proper, official, or well established way to modify endpoints after the stack has been initialized, here’s my quick and dirty solution in case someone else needs to do this. Please feel free to criticize and advise if you think I’m doing something wrong.

To recap: I need to modify an endpoint’s settings way after +TCP is initialized and up and running.

// Note: all parameters in network byte order
void ApplyNetworkSettings( NetworkEndPoint_t * pxEndPoint, uint8_t bEnableDHCP, uint32_t uiIPAddress_NBO, uint32_t uiNetMask_NBO, uint32_t uiGateway_NBO, uint32_t uiDNS_NBO )
{
    // We are about change endpoint data and the global prvDHCP_Enabled flag from a task that is different than the TCP task.
    vTaskSuspendAll();
    {
        pxEndPoint->ipv4_settings.ulNetMask = uiNetMask_NBO;
        pxEndPoint->ipv4_settings.ulGatewayAddress = uiGateway_NBO;
        pxEndPoint->ipv4_settings.ulDNSServerAddresses[ 0 ] = uiDNS_NBO;
        pxEndPoint->ipv4_settings.ulBroadcastAddress = uiNetMask_NBO | ~( pxEndPoint->ipv4_settings.ulNetMask );
        // Copy the current values to the default values.
        ( void ) memcpy( &( pxEndPoint->ipv4_defaults ), &( pxEndPoint->ipv4_settings ), sizeof( pxEndPoint->ipv4_defaults ) );
        // The default IP-address will be used in case DHCP fails with IPv4LL disabled, or if the user callback chooses to use the default IP-address.
        pxEndPoint->ipv4_defaults.ulIPAddress = uiIPAddress_NBO;

        pxEndPoint->bits.bWantDHCP = bEnableDHCP;
    }
    xTaskResumeAll();

    // Force the TCP stack to re-init.
    FreeRTOS_NetworkDown( pxEndPoint->pxNetworkInterface );
}

Note 1: The vTaskSuspendAll() / xTaskResumeAll(); is a bit heavy-handed and one will probably be OK without it but it’s cheap insurance in a function that should be called extremely rarely.

Note 2: @Shub in the past when I tried using pxEndPoint->bits.bWantDHCP I ran into issues. Therefore I initialized all end-points with bWantDHCP set to pdTRUE. This forced +TCP to call my DHCP callback all the time and I used that callback and a global flag to allow/deny DHCP. Today, I’m realizing that those issues were not with the bWandDHCP flag itself, but were caused by me incorrectly setting either pxEndPoint->ipv4_settings or pxEndPoint->ipv4_defaults but not both. Now that I’ve figured out how to properly update an end-point’s settings, I don’t need that global flag and I’m going back to using pxEndPoint->bits.bWantDHCP as you suggested. I also edited the sample code above to reflect that.