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.

  • 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. 

     

  • 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.

Reply
  • 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.

Children
  • 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.

  • Thanks. That helped me. Now pairing works automatically.

    I enabled SEC_PARAM_LESC in main.c and changed the file components/ble/ble_services/ble_nus/ble_nus.c

        // Add the RX Characteristic.
        memset(&add_char_params, 0, sizeof(add_char_params));
        add_char_params.uuid                     = BLE_UUID_NUS_RX_CHARACTERISTIC;
        add_char_params.uuid_type                = p_nus->uuid_type;
        add_char_params.max_len                  = BLE_NUS_MAX_RX_CHAR_LEN;
        add_char_params.init_len                 = sizeof(uint8_t);
        add_char_params.is_var_len               = true;
        add_char_params.char_props.write         = 1;
        add_char_params.char_props.write_wo_resp = 1;
    
    //    add_char_params.read_access  = SEC_OPEN;
    //    add_char_params.write_access = SEC_OPEN;
        add_char_params.read_access  = SEC_JUST_WORKS;
        add_char_params.write_access = SEC_JUST_WORKS;
    
        err_code = characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->rx_handles);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        // Add the TX Characteristic.
        /**@snippet [Adding proprietary characteristic to the SoftDevice] */
        memset(&add_char_params, 0, sizeof(add_char_params));
        add_char_params.uuid              = BLE_UUID_NUS_TX_CHARACTERISTIC;
        add_char_params.uuid_type         = p_nus->uuid_type;
        add_char_params.max_len           = BLE_NUS_MAX_TX_CHAR_LEN;
        add_char_params.init_len          = sizeof(uint8_t);
        add_char_params.is_var_len        = true;
        add_char_params.char_props.notify = 1;
    
    //    add_char_params.read_access       = SEC_OPEN;
    //    add_char_params.write_access      = SEC_OPEN;
    //    add_char_params.cccd_write_access = SEC_OPEN;
        add_char_params.read_access       = SEC_JUST_WORKS;
        add_char_params.write_access      = SEC_JUST_WORKS;
        add_char_params.cccd_write_access = SEC_JUST_WORKS;
    
        return characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->tx_handles);

    Unfortunately I was not able to change permissions afterwards in main.c, so I had to change the ble_nus.c from nordic SDK.

Related