This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Init Packet

I'm referring this

https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.2.0%2Flib_dfu_transport_ble.html

which states that when in bootloader mode, I've to send the init packet first & then the firmware image.

So what happens after I send 06 01 command. What is init packet? How do I create one? The response received for each command - is it written over a characteristic or a descriptor inside characteristic? My understanding is DFU Control Point & DFU Packet characteristics do not support read property. So where can I see the response received for every command sent by host to BLE device?

Sorry I could not understand a thing from the sniffer trace which I captured while executing the actual DFU procedure listed on Nordic Infocenter. I'm using SDK 15.2 & nrf52832.

5875.original.pcapng

Parents
  • Hi Sonal, 

    What is init packet? How do I create one?

    the Init packet is part of the DFU firmware image that you create using nrfutil, see https://github.com/NordicSemiconductor/pc-nrfutil

    The response received for each command - is it written over a characteristic or a descriptor inside characteristic? My understanding is DFU Control Point & DFU Packet characteristics do not support read property. So where can I see the response received for every command sent by host to BLE device?

     The response is a characteristic notification from the BLE peripheral to the BLE Central. 

    Best regards

    Bjørn

  • Thanks Bjorn! How can I read this response? On which characteristic is this response sent? 

  • As show in the Transfer of an init packet MSC, its the DFU Control Point characteristic that Notifies the DFU controller. In order to receive notifications you will have to enable Notifications by writting to the CCCD of the DFU Control Point characteristic. 

    Bjørn

  • Ok. Where in the secure bootloader code is this response being sent?

  • It is done in the request handler module of the bootloader , see on_data_obj_select_request in nrf_dfu_req_handler.c (nRF5_SDK_15.2.0_9412b96\components\libraries\bootloader\dfu\nrf_dfu_req_handler.c)

    static void on_data_obj_select_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
    {
        NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_SELECT (data)");
    
        p_res->select.crc    = s_dfu_settings.progress.firmware_image_crc;
        p_res->select.offset = s_dfu_settings.progress.firmware_image_offset;
    
        p_res->select.max_size = DATA_OBJECT_MAX_SIZE;
    
        NRF_LOG_DEBUG("crc = 0x%x, offset = 0x%x, max_size = 0x%x",
                      p_res->select.crc,
                      p_res->select.offset,
                      p_res->select.max_size);
    }

  • Is the init packet generated from the zip package? - .dat file? 

    I think the responses below are incorrect except the first two. What am I doing wrong?

    HOST -> BLE DEVICE BLE DEVICE -> HOST
    06 01 60-06-01-00-01-00-00-00-00-00-00-00-00-00-00
    01 01 8E 00 00 00 60-01-01
       
    12 8b 01 0a 45 08 01 12 41 08 90 4e 10 34 1a 02 af 01 20 00  60-12-02
    28 00 30 00 38 b0 8e 03 42 24 08 03 12 20 01 91 8e 46 bb 14  60-28-02
    fc b6 37 95 6d dd d4 34 40 a4 60 ab ec 76 57 8f 9c 72 e6 b5  60-FC-02
    8a 62 c7 9b b3 df 48 00 52 04 08 01 12 00 10 00 1a 40 9d 86 60-8A-02
    94 d0 23 bd 0e db 03 47 26 f9 4d 27 77 4c 4b 04 8e de 75 79  60-94-02
    bf d4 b5 1a df 0f 5a 39 f0 b1 5b 44 bc 12 bf 16 87 99 6d c8  60-BF-02
    e2 a7 aa 4e 62 c4 ad 68 55 2f b1 8c a4 27 1e bc 07 65 5a 0f  60-E2-02
    28 a3 60-28-02
       
    3 60-03-01-00-00-00-00-00-00-00-00
    4 60-04-08
  • bscdb said:
    Is the init packet generated from the zip package? - .dat file? 

    Yes, the init packet is the .dat file in the zip package. 

    bscdb said:
    I think the responses below are incorrect except the first two. What am I doing wrong?


    The first request from the host is the select command, where the control point replies with 60-06-01-00-01-00-00-00-00-00-00-00-00-00-00, which means that the Select command was successful, i.e. 60-06-01, then you have the max size of the init packet 00-01-00-00, the offset 00-00-00-00 and the CRC32 00-00-00-00. 

    The second request is a Create request from the host, i.e. 01 01, where it informs the Control Point that the size of the init packet is 8E 00 00 00.

    The Control point should not respond to the data packets after the Control Point has replied with Create Success, i.e. 60-01-01.

    The two last operations consists of the following:

    Opcode 3 is a CRC request from the host. The control point replies with 60-03-01-00-00-00-00-00-00-00-00, which is means NRF_SUCESS, but the offset and the current CRC is zero.

    Opcode 4 is an Execute request from the host. The control point replies replies with 60-04-08, which means NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED. 

    I would recommend to debug the bootloader when you transfer the init packet and set breakpoints at the following locations in the bootloader code.

    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_validation.c:ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;

    You should hit one of them and then hopefully get an indication to why the bootloader does not permit the init packet. 

    Best regards

    Bjørn

     

     

Reply
  • bscdb said:
    Is the init packet generated from the zip package? - .dat file? 

    Yes, the init packet is the .dat file in the zip package. 

    bscdb said:
    I think the responses below are incorrect except the first two. What am I doing wrong?


    The first request from the host is the select command, where the control point replies with 60-06-01-00-01-00-00-00-00-00-00-00-00-00-00, which means that the Select command was successful, i.e. 60-06-01, then you have the max size of the init packet 00-01-00-00, the offset 00-00-00-00 and the CRC32 00-00-00-00. 

    The second request is a Create request from the host, i.e. 01 01, where it informs the Control Point that the size of the init packet is 8E 00 00 00.

    The Control point should not respond to the data packets after the Control Point has replied with Create Success, i.e. 60-01-01.

    The two last operations consists of the following:

    Opcode 3 is a CRC request from the host. The control point replies with 60-03-01-00-00-00-00-00-00-00-00, which is means NRF_SUCESS, but the offset and the current CRC is zero.

    Opcode 4 is an Execute request from the host. The control point replies replies with 60-04-08, which means NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED. 

    I would recommend to debug the bootloader when you transfer the init packet and set breakpoints at the following locations in the bootloader code.

    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
    nRF5_SDK_15.2.0_9412b96/components/libraries/bootloader/dfu/nrf_dfu_validation.c:ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;

    You should hit one of them and then hopefully get an indication to why the bootloader does not permit the init packet. 

    Best regards

    Bjørn

     

     

Children
  • My nrf log file which I captured using RTT viewer - 

    00> <info> app: Inside main
    00> <debug> app: In nrf_bootloader_init
    00> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    00> <debug> nrf_dfu_settings: Settings OK
    00> <debug> app: Enter nrf_bootloader_fw_activate
    00> <info> app: No firmware to activate.
    00> <debug> app: Enter nrf_dfu_app_is_valid
    00> <debug> app: No valid app to boot.
    00> <debug> app: DFU mode because app is not valid.
    00> <info> nrf_bootloader_wdt: WDT is not enabled
    00> <debug> app: in weak nrf_dfu_init_user
    00> <debug> app: timer_stop (0x200057D0)
    00> <debug> app: timer_activate (0x200057D0)
    00> <info> app: Entering DFU mode.
    00> <debug> app: Initializing transports (found: 1)
    00> <debug> nrf_dfu_ble: Initializing BLE DFU transport
    00> <debug> nrf_dfu_ble: Setting up vector table: 0x00072000
    00> <debug> nrf_dfu_ble: Enabling SoftDevice.
    00> <debug> nrf_dfu_ble: Configuring BLE stack.
    00> <debug> nrf_dfu_ble: Enabling the BLE stack.
    00> <debug> nrf_dfu_ble: No advertising name found
    00> <debug> nrf_dfu_ble: Using default advertising name
    00> <debug> nrf_dfu_ble: Advertising...
    00> <debug> nrf_dfu_ble: BLE DFU transport initialized.
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_sd backend.
    00> <debug> app: Enter main loop
    00> <debug> nrf_dfu_ble: Connected
    00> <debug> nrf_dfu_ble: Received BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST (request: 527, reply: 247).
    00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (command)
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    00> <debug> app: Shutting down transports (found: 1)
    00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (command)
    00> <debug> app: timer_stop (0x200057D0)
    00> <debug> app: timer_activate (0x200057D0)
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0x12.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 18 failed with error: 0x2
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0x28.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 40 failed with error: 0x2
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0xFC.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 252 failed with error: 0x2
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0x8A.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 138 failed with error: 0x2
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0x94.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 148 failed with error: 0x2
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0xBF.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 191 failed with error: 0x2
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0xE2.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 226 failed with error: 0x2
    00> <info> nrf_dfu_req_handler: Invalid opcode received: 0x28.
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x2
    00> <warning> nrf_dfu_ble: DFU request 40 failed with error: 0x2
    00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (command)
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    00> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (command)
    00> <error> nrf_dfu_validation: Execute with faulty offset
    00> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x8
    00> <warning> nrf_dfu_ble: DFUrequest 4 failed with error: 0x8
    00> <debug> nrf_dfu_ble: Received BLE_GAP_EVT_CONN_PARAM_UPDATE
    00> <debug> nrf_dfu_ble: max_conn_interval: 12
    00> <debug> nrf_dfu_ble: min_conn_interval: 12
    00> <debug> nrf_dfu_ble: slave_latency: 0
    00> <debug> nrf_dfu_ble: conn_sup_timeout: 600

    Whats missing?

  • HI Sonal, 

    It looks like you are writting the date of the init packet to the Control Point Characteristic and not the DFU Packet characteristic. You see that you get a lot of invalid opcode respones. Try writting the data to the DFU packet characteristic instead. 

    Best regards 

    Bjørn

  • Thanks Bjorn, I could successfully send the init packet with your help! Can you tell me how is the CRC32 response calculated?

  • HI Sonal, 

    Happy to hear that you're able to send the init packet successfully now. The CRC32 request is handled by the on_data_obj_crc_request() callback in nrf_dfu_req_handler.c. It simply retrieves the CRC stored on the bootloader settings page, see snippet below

    static void on_data_obj_crc_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
    {
        NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (data)");
        NRF_LOG_DEBUG("Offset:%d, CRC:0x%08x",
                     s_dfu_settings.progress.firmware_image_offset,
                     s_dfu_settings.progress.firmware_image_crc);
    
        p_res->crc.crc    = s_dfu_settings.progress.firmware_image_crc;
        p_res->crc.offset = s_dfu_settings.progress.firmware_image_offset;
    }

    The CRC value is updated on every write request to the DFU packet characteristic, which is handled by the  on_data_obj_write_request() callback

    static void on_data_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
    {
        NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (data)");
    
        if (!nrf_dfu_validation_init_cmd_present())
        {
            /* Can't accept data because DFU isn't initialized by init command. */
            p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
            return;
        }
    
        uint32_t const data_object_offset = s_dfu_settings.progress.firmware_image_offset -
                                            s_dfu_settings.progress.firmware_image_offset_last;
    
        if ((p_req->write.len + data_object_offset) > s_dfu_settings.progress.data_object_size)
        {
            /* Can't accept data because too much data has been received. */
            NRF_LOG_ERROR("Write request too long");
            p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
            return;
        }
    
        uint32_t const write_addr = m_firmware_start_addr + s_dfu_settings.write_offset;
        /* CRC must be calculated before handing off the data to fstorage because the data is
         * freed on write completion.
         */
        uint32_t const next_crc =
            crc32_compute(p_req->write.p_data, p_req->write.len, &s_dfu_settings.progress.firmware_image_crc);
    
        ASSERT(p_req->callback.write);
    
        ret_code_t ret =
            nrf_dfu_flash_store(write_addr, p_req->write.p_data, p_req->write.len, p_req->callback.write);
    
        if (ret != NRF_SUCCESS)
        {
            /* When nrf_dfu_flash_store() fails because there is no space in the queue,
             * stop processing the request so that the peer can detect a CRC error
             * and retransmit this object. Remember to manually free the buffer !
             */
            p_req->callback.write((void*)p_req->write.p_data);
            return;
        }
    
        /* Update the CRC of the firmware image. */
        s_dfu_settings.write_offset                   += p_req->write.len;
        s_dfu_settings.progress.firmware_image_offset += p_req->write.len;
        s_dfu_settings.progress.firmware_image_crc     = next_crc;
    
        /* This is only used when the PRN is triggered and the 'write' message
         * is answered with a CRC message and these field are copied into the response.
         */
        p_res->write.crc    = s_dfu_settings.progress.firmware_image_crc;
        p_res->write.offset = s_dfu_settings.progress.firmware_image_offset;
    }

    It calls crc32_compute to compute the CRC.

    Best regards

    Bjørn

  • Thanks!! I'm facing problems sending the firmware image. After I send 06 02, I receive 60-06-01-00-10-00-00-00-00-00-00-00-00-00-00. Does that mean each data object can only be 0x1000 bytes long? Can you please tell me the sequence of commands to send the firmware image? Should I send create command, CRC command & execute command separately for every data object or do I send it just once?

    Also I never really get this response for both init packet & firmware image.

Related