Android asking for pairing after DFU

Using SDK 15.3 on the embedded side and Android 10 I think it is on the mobile side.

We've implemented whitelists and hanging onto the bonding information on the embedded side.  The idea is that once the mobile side is talking to us we only want to talk to that particular device until we explicitly change to another one.

This works fine across power cycles on both sides.  Once paired and bonded and everything, the mobile side and embedded side exist in married bliss.

Now, pull up nRF connect and run a DFU on the embedded side. Once the embedded side comes back (and it is keeping all the bonding information and whitelists and all that across this as far as I can tell), Android wants to pair again...

I just don't understand why this is.  We've got the bonding information both sides as far as I know. Why does the Android side really want to pair again?  Am I missing something on the embedded side?

Parents
  • Hello,

    So it is after the update is complete, and you try to connect to it again like it was before (in the married bliss) that it wants to pair again, is that correct? 

    Do you see whether the peripheral device has changed anything? Or did you try to debug the applciation? Is the bonding data still present on the peripheral? Does the peripheral use the same Bluetooth LE address as before the DFU update took place?

    Best regards,

    Edvin

  • yes, after the DFU has completed. Everything should be the same as before the update as all that information is being saved as far as I know...  Power cycles of either side of that prior to DFU does not cause this repairing request so I'm pretty sure it's being saved.

    Android itself is popping a "you want to pair?" message.

  • Ok, so one of your devices has probably lost the bonding data, if your peripheral hasn't changed address.

    There is a setting in the sdk_config.h of your bootloader to determine how many FDS pages your bootloader should preserve through a DFU. How many FDS pages is your application using? And what does the setting say in your sdk_config.h of your bootloader?

    You can also make your application to tell you how many peers that are stored in the beginning of your application, to verify that it is in fact the nRF that has lost the bonding data. What does it say?

    Best regards,

    Edvin

  • I used to know the variables involved in this in the sdk_config.h files but I can't find them just now... what variable names are you after in particular here?

    We only allow exactly one connection/pairing/bonding at a time enforced through the whitelist stored in FDS and some interaction with things.... 

    I remember I had quite a fight months ago keeping FDS over a DFU but don't recall what I had to set to do it...

Reply
  • I used to know the variables involved in this in the sdk_config.h files but I can't find them just now... what variable names are you after in particular here?

    We only allow exactly one connection/pairing/bonding at a time enforced through the whitelist stored in FDS and some interaction with things.... 

    I remember I had quite a fight months ago keeping FDS over a DFU but don't recall what I had to set to do it...

Children
  • It is the one called NRF_DFU_APP_DATA_AREA_SIZE in SDK15.3.0. By default this is set to 12288, which equals 3 flash pages (3 * 1024 words = 3*1024*4).

    So in your application's sdk_config.h file, how many flash pages does your application use? (what is FDS_VIRTUAL_PAGES and FDS_VIRTUAL_PAGE_SIZE in sdk_config.h?)

  • Bootloader has that set to default size of 12288

    application has

    #define FDS_VIRTUAL_PAGES 3

    #define FDS_VIRTUAL_PAGE_SIZE 1024

  • Ok. Then you need to start investigating the other things that I have mentioned:

    Edvin said:
    Do you see whether the peripheral device has changed anything? Or did you try to debug the applciation? Is the bonding data still present on the peripheral? Does the peripheral use the same Bluetooth LE address as before the DFU update took place?

    Edvin said:
    You can also make your application to tell you how many peers that are stored in the beginning of your application, to verify that it is in fact the nRF that has lost the bonding data. What does it say?

    And also, what does the log from your application say? Please copy paste the log from before you DFU, i.e. when you don't have to pair again and when you do have to pair again. Do they look the same?

    Does this only happen on Android? Did you try with iOS?

    BR,

    Edvin

  • And also, what does the log from your application say?

    Attached is the log from nRFconnect on Android.  This has a complicated connection scheme so I have not attempted this on iOS to see if there is a difference in it.

    1. Once the device is paired and bonded through our application, close the application and then connect back up with nRFconnect (this bypasses all the oddities of our application
    2. Then put the device into DFU mode via struct command 0x0000000007 in nRF Connect (line 53). This causes the device to change to bootloader mode.  In this mode, we aren't using the whitelists and such...
    3. run DFU
    4. Allow reconnect of nRFconnect when done (line 985- ~994)
    5. Android asks pairing again (starting at line 995 or so)...

    I'll be looking at the embedded side to answer some questions a bit later (this is going to take awhile to do here so you'll have to bear with me please)

    Thank you for your help so far in this.

    Log 6.txt

  • Hello,

    Edvin said:
    And also, what does the log from your application say? Please copy paste the log from before you DFU, i.e. when you don't have to pair again and when you do have to pair again. Do they look the same?

    I was actually thinking of the log from the nRF chip, if you have any.

    I see from the log 6.txt that it receives a pairing request. The address of the nRF chip is the same before and after the DFU (I 13:14:35.703 Connected to DF:A0:E4:ED:42:5C), so that should not be the issue. Perhaps the the nRF doesn't have the bonding data after the DFU process.

    Please check that delete_bonds() is not called after the DFU. Try setting a breakpoint or add some logging in the delete_bonds() function to see whether this is triggered.

    Also, you can add this before you start advertising:

    static void check_bonds(void)
    {
        ret_code_t err_code;
        uint32_t peer_count;
        pm_peer_id_t peer_id = PM_PEER_ID_INVALID;
        pm_peer_data_bonding_t peer_data;
        
        peer_count = pm_peer_count();
        NRF_LOG_INFO("peer_count: %d", peer_count);
        
        peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
        if (peer_id != PM_PEER_ID_INVALID)
        {
            while (peer_id != PM_PEER_ID_INVALID)
            {
                NRF_LOG_INFO("peer id %d is valid", peer_id);
                err_code = pm_peer_data_bonding_load(peer_id, &peer_data);
                APP_ERROR_CHECK(err_code);
                NRF_LOG_INFO("peer address: %02x:%02x:%02x:%02x:%02x:%02x", peer_data.peer_ble_id.id_addr_info.addr[5],
                                                                            peer_data.peer_ble_id.id_addr_info.addr[4],
                                                                            peer_data.peer_ble_id.id_addr_info.addr[3],
                                                                            peer_data.peer_ble_id.id_addr_info.addr[2],
                                                                            peer_data.peer_ble_id.id_addr_info.addr[1],
                                                                            peer_data.peer_ble_id.id_addr_info.addr[0]);
                
                peer_id = pm_next_peer_id_get(peer_id);
            }
        }
        else 
        {
            NRF_LOG_INFO("no valid peers");
        }
    }

    It will print the address of all the peers that are bonded with the nRF. Add it right before you start advertising.

    BR,
    Edvin

Related