eclipse-threadx / netxduo

Eclipse ThreadX - NetXDuo is an advanced, industrial-grade TCP/IP network stack designed specifically for deeply embedded real-time and IoT applications
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/netx-duo/index.md
MIT License
230 stars 131 forks source link

ADU on IoT Hub stuck "In Progress" or "Failed" even when firmware successfully was updated OTA #120

Closed t-tbrown closed 1 year ago

t-tbrown commented 1 year ago

Hello,

I am using ADU with the SAME54 board, using the MPLAB sample here

I followed the steps in the documentation to set up the device and the updates are being triggered successfully from IoT Hub.

IoT Hub is failing to recognize the update went through to the device, and constantly get stuck in either "In Progress" or "Failed". However, for each of these in progress and failed deployments, as reported from IoT Hub, I can verify with a serial terminal that the board is indeed receiving, downloading, and applying the firmware update successfully. image

I'm not sure how to troubleshoot this further, so any advice is welcome. Thanks!

bo-ms commented 1 year ago

Hi @t-tbrown Thanks for reporting this issue. Device reports the old version before reporting new version to service after reboot/apply, device has already updated the new firmware and there is no real issue, but "Failed" shown up since the order of reported version is incorrect. For public preview or the project you are using, could you replace the function nx_azure_iot_adu_agent_reported_properties_send() as below and try again?

FYI: We already fixed this issue for GA and will release it in October.


static UINT nx_azure_iot_adu_agent_reported_properties_send(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, UINT wait_option)
{

NX_PACKET *packet_ptr;
NX_AZURE_IOT_JSON_WRITER json_writer;
NX_AZURE_IOT_ADU_AGENT_DEVICE_PROPERTIES *device_properties = &(adu_agent_ptr -> nx_azure_iot_adu_agent_device_properties);
NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_CONTENT *manifest_content = &(adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content);
UINT status;
UINT response_status;
UINT request_id;
ULONG reported_property_version;
UINT result_code;
UINT i;
CHAR step_property_name[8] = "step_";
UINT step_size = sizeof("step_") - 1;
UINT step_property_name_size;
UINT update_id_length;

    /* Create json writer for client reported property.  */
    status = nx_azure_iot_hub_client_reported_properties_create(adu_agent_ptr -> nx_azure_iot_hub_client_ptr, &packet_ptr, wait_option);
    if (status)
    {
        return(status);
    }

    /* Init json writer.  */
    status = nx_azure_iot_json_writer_init(&json_writer, packet_ptr, wait_option);
    if (status)
    {
        nx_packet_release(packet_ptr);
        return(status);
    }

    /* Append begin object.  */
    if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    /* Fill the ADU agent component name.  */
    status = nx_azure_iot_hub_client_reported_properties_component_begin(adu_agent_ptr -> nx_azure_iot_hub_client_ptr,
                                                                         &json_writer, 
                                                                         (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME,
                                                                         sizeof(NX_AZURE_IOT_ADU_AGENT_COMPONENT_NAME) - 1);
    if (status)
    {
        nx_packet_release(packet_ptr);
        return(status);
    }

    /* Fill the agent property name.  */
    if (nx_azure_iot_json_writer_append_property_name(&json_writer,
                                                      (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_AGENT,
                                                      sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_AGENT) - 1))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    /* Start to fill agent property value.   */
    if (nx_azure_iot_json_writer_append_begin_object(&json_writer))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    /* Fill the deviceProperties.  */
    if ((nx_azure_iot_json_writer_append_property_name(&json_writer,
                                                        (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_DEVICEPROPERTIES,
                                                        sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_DEVICEPROPERTIES) - 1)) ||
        (nx_azure_iot_json_writer_append_begin_object(&json_writer)) ||
        (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                    (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANUFACTURER,
                                                                    sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MANUFACTURER) - 1,
                                                                    device_properties -> manufacturer, device_properties -> manufacturer_length)) ||
        (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                    (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MODEL,
                                                                    sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_MODEL) - 1,
                                                                    device_properties -> model, device_properties -> model_length)) ||
        (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                    (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INTERFACE_ID,
                                                                    sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INTERFACE_ID) - 1,
                                                                    (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_INTERFACE_ID,
                                                                    sizeof(NX_AZURE_IOT_ADU_AGENT_INTERFACE_ID) - 1)) ||
        (nx_azure_iot_json_writer_append_end_object(&json_writer)))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    /* Fill the comatability property.  */
    if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                   (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_COMPAT_PROPERTY_NAMES,
                                                                   sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_COMPAT_PROPERTY_NAMES) - 1,
                                                                   (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_COMPATIBILITY,
                                                                   sizeof(NX_AZURE_IOT_ADU_AGENT_COMPATIBILITY) - 1))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    if (adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content.steps_count)
    {

        /* Fill the state.   */
        if (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
                                                                      (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STATE,
                                                                      sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STATE) - 1,
                                                                      (INT)adu_agent_ptr -> nx_azure_iot_adu_agent_state))
        {
            nx_packet_release(packet_ptr);
            return(NX_NOT_SUCCESSFUL);
        }

        /* Fill the workflow.  */
        if (adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id_length)
        {
            if (nx_azure_iot_json_writer_append_property_name(&json_writer,
                                                                (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW,
                                                                sizeof (NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_WORKFLOW) - 1) ||
                nx_azure_iot_json_writer_append_begin_object(&json_writer) ||
                nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
                                                                          (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION,
                                                                          sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ACTION) - 1,
                                                                          (INT)adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.action) ||
                nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                           (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID,
                                                                           sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_ID) - 1,
                                                                           adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id,
                                                                           adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.id_length))
            {
                nx_packet_release(packet_ptr);
                return (NX_NOT_SUCCESSFUL);
            }

            /* End workflow object.  */
            if (nx_azure_iot_json_writer_append_end_object(&json_writer))
            {
                nx_packet_release(packet_ptr);
                return(NX_NOT_SUCCESSFUL);
            }
        }

        /* Append retry timestamp in workflow if existed.  */
        if (adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp_length)
        {
            if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                           (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP,
                                                                           sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RETRY_TIMESTAMP) - 1,
                                                                           adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp,
                                                                           adu_agent_ptr -> nx_azure_iot_adu_agent_workflow.retry_timestamp_length))
            {
                nx_packet_release(packet_ptr);
                return (NX_NOT_SUCCESSFUL);
            }
        }

        /* Fill installed update id.  */
        if (adu_agent_ptr -> nx_azure_iot_adu_agent_state == NX_AZURE_IOT_ADU_AGENT_STATE_IDLE)
        {

            /* Use nx_azure_iot_adu_agent_update_manifest as temporary buffer to encode the update id as string.*/
            update_id_length = (UINT)snprintf((CHAR *)adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
                                              NX_AZURE_IOT_ADU_AGENT_UPDATE_MANIFEST_SIZE,
                                              "{\"%.*s\":\"%.*s\",\"%.*s\":\"%.*s\",\"%.*s\":\"%.*s\"}",
                                              sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_PROVIDER) - 1,
                                              NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_PROVIDER,
                                              manifest_content -> update_id.provider_length, manifest_content -> update_id.provider, 
                                              sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_NAME) - 1,
                                              NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_NAME,
                                              manifest_content -> update_id.name_length, manifest_content -> update_id.name,
                                              sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_VERSION) - 1,
                                              NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_VERSION,
                                              manifest_content -> update_id.version_length, manifest_content -> update_id.version);

            if (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                           (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTALLED_CONTENT_ID,
                                                                           sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_INSTALLED_CONTENT_ID) - 1,
                                                                           adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest,
                                                                           update_id_length))
            {
                nx_packet_release(packet_ptr);
                return (NX_NOT_SUCCESSFUL);
            }
        }

        /* Fill the last install result.  */
        if (adu_agent_ptr -> nx_azure_iot_adu_agent_state != NX_AZURE_IOT_ADU_AGENT_STATE_DEPLOYMENT_IN_PROGRESS)
        {

            /* Check the state.  */
            if (adu_agent_ptr -> nx_azure_iot_adu_agent_state == NX_AZURE_IOT_ADU_AGENT_STATE_IDLE)
            {
                result_code = NX_AZURE_IOT_ADU_AGENT_RESULT_CODE_APPLY_SUCCESS;
            }
            else
            {
                result_code = NX_AZURE_IOT_ADU_AGENT_RESULT_CODE_FAILURE;
            }

            if ((nx_azure_iot_json_writer_append_property_name(&json_writer,
                                                               (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_LAST_INSTALL_RESULT,
                                                               sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_LAST_INSTALL_RESULT) - 1)) ||
                (nx_azure_iot_json_writer_append_begin_object(&json_writer)) ||
                (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
                                                                           (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE,
                                                                           sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE) - 1,
                                                                           (int32_t)result_code)) ||
                (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
                                                                           (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE,
                                                                           sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE) - 1,
                                                                           0)) ||
                (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                           (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS,
                                                                           sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS) - 1,
                                                                           NX_NULL, 0)) ||
                (nx_azure_iot_json_writer_append_property_name(&json_writer,
                                                               (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STEP_RESULTS,
                                                               sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_STEP_RESULTS) - 1)) ||
                (nx_azure_iot_json_writer_append_begin_object(&json_writer)))
            {
                nx_packet_release(packet_ptr);
                return(NX_NOT_SUCCESSFUL);
            }

            /* Loop to fill the step results.  */
            for (i = 0; i < adu_agent_ptr -> nx_azure_iot_adu_agent_update_manifest_content.steps_count; i++)
            {
                if ((step_property_name_size = _nx_utility_uint_to_string(i, 10, &step_property_name[step_size], 8 - step_size)) == 0)
                {
                    nx_packet_release(packet_ptr);
                    return(NX_NOT_SUCCESSFUL);
                }
                step_property_name_size += step_size;

                if ((nx_azure_iot_json_writer_append_property_name(&json_writer,
                                                                   (const UCHAR *)step_property_name,
                                                                   step_property_name_size)) ||
                    (nx_azure_iot_json_writer_append_begin_object(&json_writer)) ||
                    (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
                                                                               (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE,
                                                                               sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_CODE) - 1,
                                                                               (int32_t)result_code)) ||
                    (nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer,
                                                                               (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE,
                                                                               sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_EXTENDED_RESULT_CODE) - 1,
                                                                               0)) ||
                    (nx_azure_iot_json_writer_append_property_with_string_value(&json_writer,
                                                                               (const UCHAR *)NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS,
                                                                               sizeof(NX_AZURE_IOT_ADU_AGENT_PROPERTY_NAME_RESULT_DETAILS) - 1,
                                                                               NX_NULL, 0)) ||
                    (nx_azure_iot_json_writer_append_end_object(&json_writer)))
                {
                    nx_packet_release(packet_ptr);
                    return(NX_NOT_SUCCESSFUL);
                }
            }

            if ((nx_azure_iot_json_writer_append_end_object(&json_writer)) ||
                (nx_azure_iot_json_writer_append_end_object(&json_writer)))
            {
                nx_packet_release(packet_ptr);
                return(NX_NOT_SUCCESSFUL);
            }
        }
    }

    /* End the client property value.  */
    if (nx_azure_iot_json_writer_append_end_object(&json_writer))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    /* End ADU agent component.  */
    if (nx_azure_iot_hub_client_reported_properties_component_end(adu_agent_ptr -> nx_azure_iot_hub_client_ptr, &json_writer))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    /* End json object.  */
    if (nx_azure_iot_json_writer_append_end_object(&json_writer))
    {
        nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }

    /* Send device info reported properties message to IoT Hub.  */
    status = nx_azure_iot_hub_client_reported_properties_send(adu_agent_ptr -> nx_azure_iot_hub_client_ptr,
                                                              packet_ptr,
                                                              &request_id, &response_status,
                                                              &reported_property_version, wait_option);
    if (status)
    {
        nx_packet_release(packet_ptr);
        return(status);
    }

    /* Check the response statue for blocking.  */
    if (wait_option)
    {
        if ((response_status < 200) || (response_status >= 300))
        {
            return(NX_NOT_SUCCESSFUL);
        }
    }

    return(NX_AZURE_IOT_SUCCESS);
}
bo-ms commented 1 year ago

Closing, no further response.