This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Questions regarding DFU, Bonding and iOS (caching)

Hi,

I have some questions regarding DFU, Bonding and iOS (caching). In my current project I have a DFU bootloader which does not use bonds, however the application uses bonds.

The current setup is that the DFU bootloader uses a different MAC-address than the application, this way iOS will treat the DFU bootloader and the application as two different devices and caching is not an issue. Is this an okay solution or would it be preferable to use bonds in the DFU FW since the application uses it?

If using bonds with the DFU and adding the Services Changed characteristic and the application is it possible to share the bonding information between Application and DFU FWs? Is there any example that uses bonds for both DFU and application? From what I've read the DFU FW does not know where the App stores the bonding information and vice versa.

I've have tried changing the DFU FW to also use bonds, however I run into issues when I try to mergehex the settings file for the application with the hex for SD + APP + Bootloader, I'm assuming this is because there are overlapping memory addresses.

HW: nRF52832

SDK: 15.0

Softdevice: 6.0

Br,
Anton

  • If it was the UUID count then you should have gotten the NRF_ERROR_NO_MEM return value. 

    If you are getting NRF_ERROR_INVALID_STATE, then this suggests that there is some wrong with the service context passed to sd_ble_gatts_characteristic_add()

    NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.

    What service handle is returned by sd_ble_gatts_service_add(), which is called prior to sd_ble_uuid_vs_add() and ble_dfu_buttonless_char_add()?

  • Right.

    I've added some debug logs to ble_dfu, and its seems to be the function ble_dfu_buttonless_backend_init which returns NRF_ERROR_INVALID_STATE.

  • I found the issue, I was looking in the wrong file (ble_dfu_unbonded.c, my ctags took me there instead of ble_dfu_bonded). All that was needed was to move the Peer Manager initialization to before init of ble dfu buttonless service.

    I'm now struggling with entering the bootloader. After I have bonded and try to write to the DFU characteristic I receive this in the logs:

    app: Read/Write Authorization request.
    <info> app: Writing peer data to the bootloader...
    <error> app: Request to enter bootloader mode failed asynchroneously.
    <info> app: Handle Value Confirmation
    

    the issue seems to be that ble_dfu_bonded.c cannot find the bonding information, retrieve_peer_data() returns NRF_ERROR_NOT_FOUND. Not really sure where to go from here.

  • Hi again Björn,

    I've managed to get it all working. I was missing some necessary things such as Service Changed Characterstic in the application and so on. After adding them I can enter the DFU bootloader using the shared bond.

    One thing I've noticed is that when the DFU is complete and I reconnect the DFU services are still there and I have to refresh the services on my Android device. I'm guessing I should call sd_ble_gatts_service_changed() to notify the Central that the services has changed in the application, is there in any specific event that you recommend that I call this function? Like BLE_GAP_EVT_CONNECTED?

    Edit:

    I've found another question here on Devzone where the call to sd_ble_gatts_service_changed() is placed in BLE_GAP_EVT_CONN_SEC_UPDATE. I placed it there and notifications are sent when i disconnect / reconnect. But after DFU I get BLE_ERROR_INVALID_ATTR_HANDLE, I have pretty much copied how I send notifications from nrf_dfu_ble.c

    err_code = sd_ble_gatts_sys_attr_set(
                p_ble_evt->evt.gap_evt.conn_handle,
                sys_serv_attr,
                len,                               
                BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS
            );
    
            if (err_code != NRF_SUCCESS)
            {
                NRF_LOG_INFO("Error setting system attributes!");
            }
    
    
            err_code = sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gap_evt.conn_handle,
                                             NULL,
                                             0,
                                             BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
            if (err_code != NRF_SUCCESS)
            {
                NRF_LOG_INFO("Failed to set system attributes!");
            }
    
            err_code = sd_ble_gatts_service_changed(p_ble_evt->evt.gap_evt.conn_handle, system_service_get_service_handle(), 0xFFFF);
            if (err_code != NRF_SUCCESS)
            {
                NRF_LOG_INFO("Failed to send service changed indication!, err_code: %d", err_code);
            }
            else
            {
                NRF_LOG_INFO("Service changed indication sent!");
            }

  • Hi Anton, 

    I apologize for the late reply, I have been on vacation the past week.  

    What start handle are you passing to sd_ble_gatts_service_changed(), i.e. which handle value is system_service_get_service_handle() returning? Can you post the code for system_service_get_service_handle()?

    Best regards

    Bjørn

Related