static void HandleBootstrapResponse(void * ctxt, AddressType* address, const char * responsePath, int responseCode, AwaContentType contentType, char * payload, size_t payloadLen)
{
    Lwm2mContextType * context = ctxt;

    if (responseCode == AwaResult_SuccessChanged)
    {
        Lwm2m_Info("Waiting for bootstrap to finish\n");
        Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_BootStrapFinishPending);
        Lwm2mCore_SetLastBootStrapUpdate(context, Lwm2mCore_GetTickCountMs());
    }
    else
    {
        Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_BootStrapFailed);
    }
}
/* The LWM2M Client MUST follow the procedure specified as below when attempting to bootstrap a LWM2M Device:
 * 1. If the LWM2M Device has Smartcard, the LWM2M Client tries to obtain Bootstrap Information
 *    from the Smartcard using the Bootstrap from Smartcard mode.
 * 2. If the LWM2M Client is not configured using the Bootstrap from Smartcard mode, the LWM2M
 *    Client tries to obtain the Bootstrap Information by using Factory Bootstrap mode.
 * 3. If the LWM2M Client has any LWM2M Server Object Instances from the previous steps, the LWM2M
 *    Client tries to register to the LWM2M Server(s) configured in the LWM2M Server Object Instance(s).
 * 4. If LWM2M Client fails to register to all the LWM2M Servers or the Client doesn’t have any
 *    LWM2M Server Object Instances, and the LWM2M Client hasn’t received a Server Initiated Bootstrap
 *    within the ClientHoldOffTime, the LWM2M Client performs the Client Initiated Bootstrap.
 */
void Lwm2m_UpdateBootStrapState(Lwm2mContextType * context)
{
    uint32_t now = Lwm2mCore_GetTickCountMs();
    uint32_t clientHoldOff;
    enum { SERVER_BOOTSTRAP = 0 };

    switch (Lwm2mCore_GetBootstrapState(context))
    {
        case Lwm2mBootStrapState_NotBootStrapped:

            // First attempt smart card bootstrap.
            if (BootStrapFromSmartCard(context))
            {
                Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_BootStrapped);
            }
            // If that fails try and use the factory information.
            else if (BootStrapFromFactory(context))
            {
                Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_BootStrapped);
            }
            // If that fails wait for the client hold off time, for a server initiated bootstrap.
            else
            {
                Lwm2m_Info("Try existing server entries\n");
                Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_CheckExisting);
            }
            Lwm2mCore_UpdateAllServers(context, Lwm2mRegistrationState_Register);
            Lwm2mCore_SetLastBootStrapUpdate(context, now);
            break;

        case Lwm2mBootStrapState_CheckExisting:
            // Pass control to Registration process, if this fails then we will
            // drop into the ClientHoldOff State
            break;

        case Lwm2mBootStrapState_ClientHoldOff:
            // Wait for server initiated bootstrap.
            // Only one bootstrap server is supported.

            // If the hold off timer has expired, then request a boot strap.
            Lwm2m_GetClientHoldOff(context, SERVER_BOOTSTRAP, &clientHoldOff);

            if (now - Lwm2mCore_GetLastBootStrapUpdate(context) >= (clientHoldOff * 1000))
            {
                Lwm2m_Info("Hold Off expired - attempt client-initiated bootstrap\n");
                Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_BootStrapPending);
                SendBootStrapRequest(context, SERVER_BOOTSTRAP);
                Lwm2mCore_SetLastBootStrapUpdate(context, now);
            }
            break;

        case Lwm2mBootStrapState_BootStrapPending:

            if (now - Lwm2mCore_GetLastBootStrapUpdate(context) >= BOOTSTRAP_TIMEOUT)
            {
                Lwm2m_Error("No response to client initiated bootstrap\n");
                Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_BootStrapFailed);
                Lwm2mCore_SetLastBootStrapUpdate(context, now);
            }

            break;

        case Lwm2mBootStrapState_BootStrapFinishPending:
            // The 2015/07/07 LWM2M draft requires that the server sends a bootstrap finished to the clients /bs endpoint,
            // however for now lets just wait up to 15 seconds and then move to BootStrapped state.
            if (now - Lwm2mCore_GetLastBootStrapUpdate(context) >= BOOTSTRAP_FINISHED_TIMEOUT)
            {
                Lwm2m_Warning("No bootstrap finished after 15 seconds, retrying...\n");
                Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_BootStrapFailed);
            }
            break;

        case Lwm2mBootStrapState_BootStrapped:
            break;

        case Lwm2mBootStrapState_BootStrapFailed:

            // If the hold off timer has expired, then request a boot strap.
            Lwm2m_GetClientHoldOff(context, SERVER_BOOTSTRAP, &clientHoldOff);

            if (now - Lwm2mCore_GetLastBootStrapUpdate(context) >= (clientHoldOff * 1000))
            {
                Lwm2m_Warning("HoldOff Expired - Re-attempt bootstrap\n");
                Lwm2mCore_SetBootstrapState(context, Lwm2mBootStrapState_NotBootStrapped);
            }
            break;

        default:
            Lwm2m_Error("Unhandled bootstrap state %d\n", Lwm2mCore_GetBootstrapState(context));
    }
}