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

how to make pairing mandatory

Module: ilumi H52 BLE module (nRF52832)
SDK: nRF5_SDK_15.2.0_9412b96
Softdevice: 132_nrf52_6.1.0_softdevice.hex
Compiler: gcc version 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907] (15:7-2018-q2-4)

Hello,

I'm working with ble multiperipheral / app_UART (NUS) examples.

Since UART (NUS) example doesn't support pairing, I had to implement pairing manually.
Pairing works now. But central devices can still connect to the peripheral without pairing. Requirement is that only bonded devices are able to use the UART service. How can this be accomplished? How to force pairing / bonding for all connecting devices?

Parents
  • You should use Peer Manager module. After initialization it with pm_init()  set security params using pm_sec_params_set().

    After peripheral device is connected, call pm_conn_secure() to initiate bonding.

    You might want to check ble_app_hrs_c, where it's implemented.

  • Thank you for your message. But as I wrote, I'm working with the multiperipheral example. So I'm using a peripheral device, not a central device. All incoming connections from central devices should be forced to pair with the peripheral device.

  • You can initiate pm_conn_secure() in peripheral role as well like this:

    void onPeerManagerBlePeripheralEvent(ble_evt_t const* bleEvent) {
        switch (bleEvent->header.evt_id) {
            case BLE_GAP_EVT_CONNECTED: {
                pm_conn_secure(bleEvent->evt.gap_evt.conn_handle, false);
                break;
            }
        }
    }

    Also keep in mind that NUS service in the SDK has open read and write characteristics (their read and write access is set to SEC_OPEN). If you want the characteristics to be secure, you might want to set mitm option in security params to 1. and also change NUS read and write characteristics security access like this:

    add_char_params.read_access  = SEC_MITM;
    add_char_params.write_access = SEC_MITM;

    This way only paired devices would be able to use your NUS characteristics

  • pm_conn_secure basically works in our peripheral device, provided the connecting central device is not already bonded.

    <info> app: Multiperipheral example started.
    <info> app: Client requested that all bonds be deleted
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 82 bytes on connection 0x0.
    <debug> nrf_ble_gatt: Updating data length to 83 on connection 0x0.
    <debug> nrf_ble_gatt: ATT MTU updated to 82 bytes on connection 0x0 (response).
    <info> app: Data len is set to 0x4F(79)
    <debug> app: ATT MTU exchange completed. central 0x52 peripheral 0x52
    <debug> nrf_ble_gatt: Data length updated to 83 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 83
    <debug> nrf_ble_gatt: max_tx_octets: 83
    <debug> nrf_ble_gatt: max_rx_time: 1096
    <debug> nrf_ble_gatt: max_tx_time: 1096
    <debug> app: ATT MTU exchange completed. central 0x52 peripheral 0x52
    <debug> app: BLE_GAP_EVT_SEC_PARAMS_REQUEST
    <info> peer_manager_handler: Connection secured: role: Peripheral, conn_handle: 0, procedure: Bonding
    <info> app: Connection with link 0x0 established.
    <info> app: BLE_GAP_EVT_AUTH_STATUS: status=0x0 bond=0x1 lv4: 0 kdist_own:0x3 kdist_peer:0x3

    If the central device disconnects and connects again, pm_conn_secure is executed again an an error occurs:

    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 82 bytes on connection 0x1.
    <debug> nrf_ble_gatt: Updating data length to 83 on connection 0x1.
    <info> app: PM_EVT_BONDED_PEER_CONNECTED
    <error> app: ERROR 17 [NRF_ERROR_BUSY] at .//main.c:993
    PC at: 0x0002DC97
    <error> app: End of error report

    Line 993 in main.c is the result of APP_ERROR_CHECK after executing pm_conn_secure.

    My question: How can we check if the connecting device is already bonded before executing pm_conn_secure in case BLE_GAP_EVT_CONNECTED)?

  • Hi, 

    Usually it's not suggested to call pm_conn_secure() when you are a peripheral (Apple BLE guideline doesn't suggest this, same on Android). If you are a peripheral, usually you let the central device to trigger pairing and re-pairing. 

    If you still want to trigger pairing from the peripheral side, you can add code to skip calling pm_conn_secure() if PM_EVT_BONDED_PEER_CONNECTED is received. 

     

Reply
  • Hi, 

    Usually it's not suggested to call pm_conn_secure() when you are a peripheral (Apple BLE guideline doesn't suggest this, same on Android). If you are a peripheral, usually you let the central device to trigger pairing and re-pairing. 

    If you still want to trigger pairing from the peripheral side, you can add code to skip calling pm_conn_secure() if PM_EVT_BONDED_PEER_CONNECTED is received. 

     

Children
  • Hello Hung, Thank you for your message.

    Usually it's not suggested to call pm_conn_secure() when you are a peripheral (Apple BLE guideline doesn't suggest this, same on Android). If you are a peripheral, usually you let the central device to trigger pairing and re-pairing.

    But that is what CodeLoader recommended. Otherwise let's go back to my origin question: "how to make pairing mandatory" if pairing has to be initiated by central? (Please keep in mind: we are programming the peripheral part)

    If you still want to trigger pairing from the peripheral side, you can add code to skip calling pm_conn_secure() if PM_EVT_BONDED_PEER_CONNECTED is received.

    Unfortunately pm_conn_secure is called in case BLE_GAP_EVT_CONNECTED, before PM_EVT_BONDED_PEER_CONNECTED is received. So how should code work?

  • Maybe my intention is a little misleading.

    In other words:

    We want that only paired (and bonded) central devices are able to work with the peripheral device. Not paired central devices should be forced to pair. Otherwise they should be disconnected.

  • Again, you don't have to call pm_conn_secure () to enforce pairing. If your attributes (service and characteristic) require encryption, the peer device need to trigger a bonding or it won't be able to access those attribute. 

    I'm not familiar with CodeLoader, what is that? 

    If you have a look at the guide line here by Apple at section 11.10 you can find the recommendation from apple that peripheral should not request pairing. 

    If you want to disconnect those peer devices that don't start pairing, you can add a timer in your application. You start the timer when you are connected and after a certain time, you can disconnect if the bonded event is not arrived. 

  • Again, you don't have to call pm_conn_secure () to enforce pairing. If your attributes (service and characteristic) require encryption, the peer device need to trigger a bonding or it won't be able to access those attribute.

    If I understand right the peer device (central device) will trigger a bonding automatically if an attribute like encryption is required. And to achieve this, the NUS UUID characteristics have to be changed to require encryption, right? How does the UUID have to be changed?...

    I'm not familiar with CodeLoader, what is that?

    "CodeLoader" is one of the writers or the previous messages.

    If you want to disconnect those peer devices that don't start pairing, you can add a timer in your application. You start the timer when you are connected and after a certain time, you can disconnect if the bonded event is not arrived. 

    I would use that as a workaround if there's no avail to a better solution.

  • Yes, it's correct. It's how usually things work on BLE. The central read/write the characteristic to find out if encryption is required or not and then start the pairing bonding if needed. 

    You would need to change the permission, not the UUID. Please study the ble_app_proximity example. For example, take a look at the tps_init() function. You need to choose SEC_JUST_WORKS or SEC_MITM instead of SEC_OPEN.

Related