Add Pairing support in existing ble_app_uart_c

Hello All,

SDK version: 15.1.0 (nRF5SDK1510a8c0c4d)

We are having BLE nRf52840 connected with processor over UART. As of now nRf52840 is running modified ble_app_uart_c example and we are able to get the beacon data as well as able to connect to various BLE based sensor to read characteristics data in below fashion:

1> Beacon based data:

     We have modified SDK's API nrf_ble_scan_on_ble_evt() by adding parsing logic of various sensor which send data over beacon and we are then sending it to processor over uart.

2> Connection based data:

     We are using Name/MAC based filter to connect to BLE temperature sensor and get hold on connection handles by parsing its services/characteristics so that we can Read/Write from/to BLE temperature sensor and eventually send data to processor over uart.

our nRf52840 is getting installed with merged .hex file of DFU+SOFT_DEVICE+APP_uart_c in factory and on field we only updates BLE applications with the help of nrfutil. 

Now, We have installed BLE pressure sensor on field which is only allowing characteristic/data read if it is paired (with key:123456) and we got to know that NUS's ble_app_uart_c doesn't support pairing. 

So, I am welcoming all suggestions for:

1> What is the best way to handle this? since we have did changes in files ble_nus_c.c, nrf_ble_scan.c, ble_db_discovery.c in SDK codes along with ble_app_uart_c.c

2> Is there any other example which supports both pairing and UART? 

3> Is there any reference available for merging pairing based example with NUS's app_uart_c? basically we want our BLE to connect with normal sensor as well as pairing based sensors and send received data from  sensor to processor over UART

4> Will the new application with pairing support needs reflash DFU or SOFT_DEVICE? or application/example.hex should be enough?

Thanks in Advance,

Ankit

Parents
  • Hi,

    1> What is the best way to handle this? since we have did changes in files ble_nus_c.c, nrf_ble_scan.c, ble_db_discovery.c in SDK codes along with ble_app_uart_c.c

    You are right that the ble_app_uart_c example does not support bonding, but that can be added. Generally, pairing and bonding is handled by the peer manager library, which use FDS for storing the data. So you need to add this libraries to your application.

    Pairing and bonding is mostly the same for peripherals and centrals, but if you want a  central example to refer to, you can take a look at examples/ble_central/ble_app_hrs_c/. This does not include passkey entry, though, which requiers a few more lines. Specifically, after adding support for pairing/bonding, make sure you handle the BLE_GAP_EVT_AUTH_KEY_REQUEST event and reply to it with a call to sd_ble_gap_auth_key_reply().

    2> Is there any other example which supports both pairing and UART? 

    Not officially (unless you mean UART for logging and not NUS in this context). However, the pairing part is independent of most other things, so any example that includes pairing/bonding should work as a reference (regardless of it using NUS or not).

    3> Is there any reference available for merging pairing based example with NUS's app_uart_c? basically we want our BLE to connect with normal sensor as well as pairing based sensors and send received data from  sensor to processor over UART

    There is an old description here, but that is for SDK 12.3.0 and is not entirely up to date with what you need for later SDK versions. But the main things are the same. Generally, take an example as reference and:

    • Copy over any pairing/bonding related code
    • Update your project to include needed libraries and include paths (starting with the peer manager and FDS)
    • Update sdk_config.h to enable relevant features like FDS and the peer manager

    There are quite a few things to remember so I expect things will fail initially, by building and resolving errors one by one you will get it included. This is generally how you add new features and libraries (add what you know you need, then add dependencies as you find it is needed).

    4> Will the new application with pairing support needs reflash DFU or SOFT_DEVICE? or application/example.hex should be enough?

    There is no need to update the bootloader or SoftDevice just because you are introducing pairing or bonding.

  • Hello  

    Thank you for your last prompt response. It was really helpful and I could able to integrate peer_manager service in examples/ble_central/ble_app_uart_c and resolve all the compilation and linking issues.

    Now, I am getting BLE radio crash as soon as I try connecting the BLE sensor which supports pairing. I am yet to deep down line by line debugging from Segger Embedded Studio over Jlink but, 

    Any hint or guidance will be appreciated. 

    Below is the reference for how we have make sure the pairing is handled:

    #define STATIC_PASSKEY    "111111" 
    static ble_opt_t    m_static_pin_option;
    uint8_t passkey[] = STATIC_PASSKEY; 
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context){
    ...
            case BLE_GAP_EVT_AUTH_KEY_REQUEST:
                    err_code = sd_ble_gap_auth_key_reply(p_gap_evt->conn_handle, BLE_GAP_AUTH_KEY_TYPE_PASSKEY, &passkey[0]);
                    asm("nop");
                    APP_ERROR_CHECK(err_code);
                break;
    }

  • Hello  

    ble_nus_c_init() was not removed but it was due to the wrong sequence of init APIs after integrating peer_manager... 

    Old Init Sequence:
    ble_stack_init();
    nus_c_init(6);
    scan_init(6);
    peer_manager_init(erase_bonds);
    gatt_init();
    db_discovery_init();
    scan_start();

    Updated Init Sequence:
    ble_stack_init();
    peer_manager_init(erase_bonds);
    gatt_init();
    db_discovery_init();
    nus_c_init();
    scan_init();
    scan_start();

    If I use BLE_GAP_IO_CAPS_NONE instead of BLE_GAP_IO_CAPS_KEYBOARD_ONLY as SEC_PARAM_IO_CAPABILITIES and flash the application into the nrf BLE, it stop giving responce on UART command which we have wrote (i.e. echo "version" > /dev/ttymxc1 should reach to NRF BLE and it should printf("version:%s\n",APP_VERSION). also, even if I try to attach a debugger from Segger embedded studio it does not give any debug print (i.e. NRF_LOG_INFO()) on the Debug Terminal and that way it stops interacting with Segger embedded studio or UART until I reflash it with combined.hex (boot loader + Soft uart + old application) which we have generated to flash only at the manufacturing facility.


    btw I'm able to proceed further with your hint by Updated init sequence and after resolving a few issues now I'm stuck with the NRF_ERROR_CONN_COUNT error mentioned below:

    #LINE & CODE reference
    515:static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    516:{
    517:    ret_code_t err_code;
    518:
    519:    switch(p_scan_evt->scan_evt_id)
    520:    {
    521:         case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
    522:         {
    523:              err_code = p_scan_evt->params.connecting_err.err_code;
    524:              APP_ERROR_CHECK(err_code);
    525:         } break;
    
    # DEBUG TERMINAL LOGS
    <info> app: BLE NUS UUID: set HB service UUID
    <info> ble_nus_c: Init sensor:6 BLE NUS UUID Type:2
    <debug> ble_scan: Filter set on address type 1, address 0x
    <debug> ble_scan: 40
    <debug> ble_scan: 8A
    <debug> ble_scan: 67
    <debug> ble_scan: 90
    <debug> ble_scan: B1
    <debug> ble_scan: C5
    <debug> ble_scan: 
    <debug> ble_scan: Connecting
    <debug> ble_scan: Connection status: 0
    <info> app: BLE connected: Conected to Target MAC: 408A6790B1C5
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
    <debug> ble_db_disc: Starting discovery of service with UUID 0x3FB7 on connection handle 0x0.
    <info> app: 
    ******* BLE got Disconnected. conn_handle: 0x0, reason: 0x5 *********
    
    <debug> ble_scan: Connecting
    <debug> ble_scan: Connection status: 0
    <info> app: BLE connected: Conected to Target MAC: 408A6790B1C5
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
    <debug> ble_db_disc: Starting discovery of service with UUID 0x3FB7 on connection handle 0x0.
    <debug> nrf_ble_gatt: ATT MTU updated to 156 bytes on connection 0x0 (response).
    <debug> ble_db_disc: Starting discovery of service with UUID 0x3FB7 on connection handle 0x0.
    <debug> nrf_ble_gatt: Data length updated to 251 on connection 0x0.
    <debug> ble_scan: Connecting
    <debug> ble_scan: Connection status: 18
    <error> app: ERROR 18 [NRF_ERROR_CONN_COUNT] at /*/examples/ble_central/ble_app_uart_c/main.c:524
    PC at: 0x0002DD0D
    <error> app: End of error report

    fyi: I am connecting only one sensor (MAC:408A6790B1C5)  and below are MACRO defined in sdk_config.h...

    #define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 0
    #define NRF_SDH_BLE_CENTRAL_LINK_COUNT 1
    #define NRF_SDH_BLE_TOTAL_LINK_COUNT 1

    Also If I try increasing the above count for debugging to resolve the mentioned issue, I get the below error on the Debug Terminal:

    <info> app: Flash: Initialise nrf_fstorage_sd implementation
    <info> app: ========| flash info |========
    <info> app: erase unit: 	4096 bytes
    <info> app: program unit: 	4 bytes
    <info> app: ==============================
    <info> app: Flash:Sucess Read:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
    
    <info> app: Flash:Sucess Read:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
    
    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
    <warning> nrf_sdh_ble: Change the RAM start location from 0x200029E0 to 0x20003980.
    80.

  •  

    We are able to resolve ERROR 18 [NRF_ERROR_CONN_COUNT] by not initiating the scan_start() after a successful connection with one sensor... We will initiate the scan_start() if we receive a disconnection event to resume the connection. 

    case NRF_BLE_SCAN_EVT_CONNECTED:
        nrf_ble_scan_stop();
        //scan_start();


    We are still blocked with the error "Insufficient RAM allocated for the SoftDevice" which is getting introduced if we increase BLE_PERIPHERAL_LINK_COUNT or BLE_CENTRAL_LINK_COUNT. We want to support multiple simultaneous connections (at least 7-8 BLE pressure sensors) with our ble_app_uart_c + integrated peer_manager codebase. 

    Any input or suggestions will be a great help Slight smile

  • Hi,

    When you do configuration changes that makes the SoftDevice need more memory (like including the link count), you need to adjust the application RAM start address (leaving more available to the SoftDevice). Adjustment of RAM and Flash memory gives a good description on how do that.

  • Hello  ,

    Thank you.

    With your valuable Inputs and Support, we are able to pair and read data from the sensor's different service's and characteristics.

    Would you mind sharing your thoughts on below queries?

    1> Now since we have integrated pairing in ble_app_uart_c, how can we add support to connect multiple such BLE sensors (say 4 sensor with different MAC address) at a same time?

      For now we are connecting one BLE sensor with MAC based filter with below API

      uint8_t bd_addr[6] = { 0 };

      // fill bd_addr with right address

      err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, bd_addr);
      APP_ERROR_CHECK(err_code);
      err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ALL_FILTER, false);
      APP_ERROR_CHECK(err_code);

    2> How to get the MAC address for which sensor we are getting/reading the data in API ble_evt_handler() which getting BLE_GATTC_EVT_READ_RSP event?

    The idea is that when we will have multiple sensor of same type are connected, we will have to distinguish from which sensor or which MAC address the data is received as BLE_GATTC_EVT_READ_RSP event

  • Hi,

    You can refer to the BLE Multi-link Example to see an example of a central that maintains a connection to several peripherals concurrently.

    Each connection gets a unique connection handle, that is used in the API. Any events or API calls that relate to a connection will include this handle. When you get the BLE_GAP_EVT_CONNECTED this contains the address, but not later. So if you need to keep the address for later, you should maintain your own mapping between connection handle and the address.

Reply Children
No Data
Related