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

DFU, caching & iOS

Hi,

I know that this is a known issue, but I'm seeing caching issues often with iOS. I'm using S132 v5.0.0, SDK 14.0 against custom application with iOS DFU SDK and often I'm seeing that my device is unusable after DFU unless I toggle the bluetooth button in the iOS Settings window. If the DFU fails, then the device's displayed name continues to be DfuTarg unless bluetooth is toggled.

I'm using bonded devices, services changed characteristic is enabled in both app and BL.

Any reason why wouldn't the iOS discover the services correctly? Any solution for this issue? Workarounds?

I'll appreciate the help

  • @run_ar, using SDK14 from scratch, gscm_local_database_has_changed is called.

    What are the effects of changing to bondless? Is it still buttonless DFU and no need for app/user intervention to perform DFU? and I'm guess that the link is not encrypted as well to the DFU is exposed.

  • Could it be that the SC indication is sent only to the first peer that ever connected? I'm seeing that the second peer doesn't receive the indication, but the first does

  • Apparently, the code is hitting:

        case PM_EVT_PEER_DATA_UPDATE_FAILED:
        // Failure to update data. Service Changed cannot be sent but DFU mode is still possible
        err_code = ble_dfu_buttonless_bootloader_start_finalize();
        if (err_code != NRF_SUCCESS)
        {
            mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
        }
    
        break;
    

    I'm investigating what's the reason for the failure

  • It passes the fallthrough (by mistake?) in the above code with an event p_evt->evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED and p_evt->params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING.

    It looks like a race to store all of the peers' SC indication status in the flash until the reset to the bootloader. More likely until the 1st peer data is stored.

  • but now there's a race in another place. in ble_dfu_buttonless_bootloader_start_prepare(), there's a connection termination, which didn't actually happen (to some degree). upon receiving callbacks from FDS about successful writes from gscm_local_database_has_changed(), the gatt_cache_manager's service_changed_pending_flags_check() is triggered, then seeing that it needs to send SC indication, but gscm_service_changed_ind_send(x) returns NRF_ERROR_INVALID_STATE since we already disconnected, which then removes the indication request (// CCCDs not enabled. Drop indication.).

    I set a break in this case NRF_ERROR_INVALID_STATE so it doesn't removed the need for indication. Any comment on how would it affect the system? Any suggestion for a better solution?

Related