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

Legacy Pairing/Bonding problem, pc-ble-driver, NRF52, central

I currently need to solve pairing/bonding to be able to implement DFU with the buttonless bonded bootloader. So I need to handle bonding/pairing from my central device, controlled using pc-ble-driver (and connectivity firmware SD 140, v6.1.1). The project is at a late stage. Scanning, connecting, discovering and using characteristics is already really stable and works as expected.

Just a side note: The peripheral firmware seems to be correct, as I'm able to do DFU from a mobile application running on Android!

What already works:
After a connection to an unbonded peripheral is established (just before discovering services), I call sd_ble_gap_authenticate() with:

const ble_gap_sec_params_t SecurityParams = {
1, // Bond
0,
0,
0,
BLE_GAP_IO_CAPS_NONE,
0,
7,
16,
{ 1, 1, 0, 0 },
{ 1, 1, 0, 0 }
};

which responds with BLE_GAP_EVT_SEC_PARAMS_REQUEST. I answer this by calling sd_ble_gap_sec_params_reply(sec_status=0, p_sec_params=NULL, keySet), where keySet is just an empty buffer. This call fills the own/p_id_key with key data, which I store in a file. I than got BLE_GAP_EVT_AUTH_STATUS with bonded=true and auth_status=0 (SUCCESS).

At this point, I'm able to subscribe to BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID's indication, so I assume bonding was successful. I can repeat this by resetting the bonding information in the peripheral.

What does not work:
I'm not able to recreate this state if the peripheral holds the bonding information. After the connection has been established I directly got BLE_GAP_EVT_SEC_REQUEST. Upon receiving this event, I call sd_ble_gap_authenticate() using the parameters above (tested with bond=0 and bond=1). I've also tested calling sd_ble_gap_authenticate() a second time after handling BLE_GAP_EVT_SEC_REQUEST. Either case, I always receive BLE_GAP_EVT_AUTH_STATUS with bonded=false and auth_status=133 (BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP). So I neither got BLE_GAP_EVT_SEC_PARAMS_REQUEST to supply my stored keys to the central.

I've tried to understand how pc-nrfutil handles this, but looking into github.com/.../dfu_transport_ble.py , def bond(), seems to do it this way too. I've no idea what I do wrong.

What's the correct way to connect / pair / (reestablish-)bond to an already bonded peripheral?

A second question: Does the connectivity firmware store the bonding keys on device site too? This question is centered about the usability. If I connect my central device to a different host PC and try to connect to an already bonded peripheral, does the central know the bonding keys (e.g. stored in flash) or do I have to copy my host site keystore to the new host (and supply them when receiving BLE_GAP_EVT_SEC_REQUEST)?

Many thanks,
Thomas

Parents
  • Hello Thomas,

    The peer manager on the peripheral will by default reject bonding requests from a previously bonded peer, so this is likely why you get the BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP status in response to your request. I explained how you can configure the Peer manager to accept bond updates in my post here: https://devzone.nordicsemi.com/f/nordic-q-a/51965/pairing-and-bonding-after-deleting-synchronization/208927#208927. The other option is to delete the bond on the DFU target before you initiate DFU.

    A second question: Does the connectivity firmware store the bonding keys on device site too? This question is centered about the usability. If I connect my central device to a different host PC and try to connect to an already bonded peripheral, does the central know the bonding keys (e.g. stored in flash) or do I have to copy my host site keystore to the new host (and supply them when receiving BLE_GAP_EVT_SEC_REQUEST)?

    The host (pc-ble-driver app in this case) is responsible for the key storage. The connectivity FW does not store anything to flash.

    If anything is unclear, let me know.

    Best regards,

    Vidar

  • Hello Vidar,

    thanks for your fast response.

    Not sure, but I assume you talk about a different topic. My goal is not re-bonding using a new set of keys. I need a valid connection to be able to subscribe to the mentioned characteristic.

    After closing the connection (with the initial bond) and connecting again (with just sd_ble_gap_connect()), my subscription fails. I didn't get any event to supply my previously stored key. So I assume I miss something to call after the connection is established.

    My (simplified) call order (with initial bonding):

    • sd_ble_gap_connect() .. wait for event.
    • sd_ble_gap_authenticate(bond) .. wait for event.
    • sd_ble_gap_sec_params_reply() .. wait for event, got bonding keys, store them
    • [discover services, characteristics, desciptors ] ..
    • subscribe to BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID -> success.
    • ..
    • close connection

    Do the same while without removing previous bonding information:

    • sd_ble_gap_connect() .. wait for event.
    • Got async BLE_GAP_EVT_SEC_REQUEST, how to respond?
    • ?What to do at this point? How to supply my stored key? Calls to sd_ble_gap_authenticate() fail, so I assume they are wrong here, but I don't wan't to re-bond, just get a 'bonded' connection as required by this characteristic -> https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/service_dfu.html.
    • [discover services, characteristics, desciptors ] ..
    • subscribe to BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID -> fails. Bonding/Pairing not active?

    I hope you understand my problem.

    Thank you again,

    Thomas

  • Hello,

    Sorry, I misread your description. My answer was based on the assumption that you also got the error on the first connection, even though you were pretty clear on this.

    What you want to do on re-connect is to secure the connection with the previously exchanged encryption key by calling sd_ble_gap_encrypt() , not send a new bond request. 

    This procedure to encrypt the connection with an existing key is illustrated by the message sequence chart here: Encryption Establishment using stored keys

    Best regards,

    Vidar

Reply
  • Hello,

    Sorry, I misread your description. My answer was based on the assumption that you also got the error on the first connection, even though you were pretty clear on this.

    What you want to do on re-connect is to secure the connection with the previously exchanged encryption key by calling sd_ble_gap_encrypt() , not send a new bond request. 

    This procedure to encrypt the connection with an existing key is illustrated by the message sequence chart here: Encryption Establishment using stored keys

    Best regards,

    Vidar

Children
No Data
Related