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

nRF52840 bonded devices

Good morning,

I have my BLE application developed on the nRF52840 and S140.

My application is perfectly working and I'm able to bond (pin required) any Android smartphone.

At this point I have two questions:

1.- Is there any limit regarding the number of smartphones I can bond to a device? If yes, how can I manage this?

2.- When doing same operation with an Apple device, Smartphone is never asking for a pin code. Why? Is there any different setting for this?

Dani.

Parents
  • In general you may find documentation useful:
    https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__peer__manager.html

    There is no specific limit to the number of bonds that the peer manager can handle. So typically you can call pm_peer_count(), use pm_next_peer_id_get() to for instance call pm_peer_delete() if you exceed the number of bonds you want to support.

    For instance to loop through stored bonds you can call the following in a while()-loop:
    
    pm_peer_id_t peer_id;
    peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);        
    
    while ((peer_id != PM_PEER_ID_INVALID))
    {
        // You can delete the bond if you like by calling pm_peer_delete(peer_id)
        
        peer_id = pm_next_peer_id_get(peer_id);
    }
    

    Typically you can include pm_handler_flash_clean() in pm_evt_handler(), such that if flash storage is full, it will delete the oldest bond that have not been used.

    I do not understand why Apple does not display a pin code, are you sure you have configured characteristics which require MITM security level?

  • Hi Kenneth,

    Thank you for the bonding inputs. In what regards this: I'm already calling 'pm_handelr_flash_clean()' in pm_evt_handler. Should it be enough to be sure bonding space will not be full? Should I also call 'pm_handler_flash_clean_on_return' when NRF_ERROR_STORAGE_FULL event is given? And I guess, that using this fucntions, it is not necessary to call pm_peer_delete(), right?

    In what regards connection with Apple device: by using nRFConnect app, I'm able to read data that my device is sending without being asked for a passkey. If I want to send some data, then I'm asked for the passkey. But, as in Android, I should be asked for a passkey when connecting to device.

    In what regards services and characterisitics: for each service, I have one characteristic to send data (like button example) and another one to received data (like LED example).

    In what regards 'button example', when adding the characteristic:

    ......

    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t attr_char_value;
    ble_uuid_t ble_uuid;
    ble_gatts_attr_md_t attr_md;

    memset(&cccd_md, 0, sizeof(cccd_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    //BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cccd_md.write_perm);

    cccd_md.vloc = BLE_GATTS_VLOC_STACK;

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read = 1;
    char_md.char_props.notify = 1;
    char_md.p_char_user_desc = NULL;
    char_md.p_char_pf = NULL;
    char_md.p_user_desc_md = NULL;
    char_md.p_cccd_md = &cccd_md;
    char_md.p_sccd_md = NULL;

    ble_uuid.type = p_lbs->uuid_type;
    ble_uuid.uuid = FABRICA_UUID_TX_CHAR;

    memset(&attr_md, 0, sizeof(attr_md));


    BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);


    attr_md.vloc = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth = 0;
    attr_md.wr_auth = 0;
    attr_md.vlen = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len = sizeof(u8);
    attr_char_value.init_offs = 0;
    attr_char_value.max_len = BLE_TAMANY_FABRICA_RX_TX_CHAR;
    attr_char_value.p_value = NULL;

    return sd_ble_gatts_characteristic_add(p_lbs->service_handle, &char_md,
    &attr_char_value,
    &p_lbs->tx_char_handles);

    ....

    And in what regards 'LED example':

    ....

    u32 err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t attr_char_value;
    ble_uuid_t ble_uuid;
    ble_gatts_attr_md_t attr_md;


    //Metadata Structure for the Characteristic, which has info about properties available (read, write, notification,...)
    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read = 1;
    char_md.char_props.write = 1;
    char_md.p_char_user_desc = NULL;
    char_md.p_char_pf = NULL;
    char_md.p_user_desc_md = NULL;
    char_md.p_cccd_md = NULL;
    char_md.p_sccd_md = NULL;

    ble_uuid.type=p_lbs->uuid_type;
    ble_uuid.uuid=FABRICA_UUID_RX_CHAR;

    //attr_md: Description of the value attribute
    memset(&attr_md, 0, sizeof(attr_md));

    BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.write_perm);


    attr_md.vloc = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth = 0;
    attr_md.wr_auth = 0;
    attr_md.vlen = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_offs = 0;
    attr_char_value.max_len = BLE_TAMANY_FABRICA_RX_TX_CHAR;
    attr_char_value.p_value = NULL;

    err_code = sd_ble_gatts_characteristic_add(p_lbs->service_handle, &char_md,
    &attr_char_value,
    &p_lbs->rx_char_handles);
    if (err_code != NRF_SUCCESS)
    {
    return err_code;
    }

    return NRF_SUCCESS;

    ....

    This is perfectly working on Android. Which is the difference with Apple?

    Dani

  • Dani said:
    Thank you for the bonding inputs. In what regards this: I'm already calling 'pm_handelr_flash_clean()' in pm_evt_handler. Should it be enough to be sure bonding space will not be full? Should I also call 'pm_handler_flash_clean_on_return' when NRF_ERROR_STORAGE_FULL event is given? And I guess, that using this fucntions, it is not necessary to call pm_peer_delete(), right?

    It should be sufficient to call pm_handler_flash_clean() in pm_evt_handler(). You can find for instance that pm_handler_flash_clean() will already handle PM_EVT_STORAGE_FULL.

    It's not necessary to delete bonds no, but I think it may be a good idea to limit the number of bonds overall (to avoid potentially old peers to connect).

    You can for instance in beginning of main() call pm_peer_count() to find the numbers of peer bonded, and if you have more than 5 peers bonded you can call pm_peer_ranks_get() to get the 'p_lowest_ranked_peer' and delete it by calling pm_peer_delete(lowest_ranked_peer).

    I do not understand why Apple don't trigger passkey here no, do you have an on-air sniffer log (e.g. nRF Sniffer)? For comparison you may try take a look at the code inside the glucose application example in the SDK. This example implements LESC bonding with passkey. This example can be found in folder \examples\ble_peripheral\ble_app_gls and the documentation from the infocenter is found here.

    Kenneth

  • You said "You can for instance in beginning of main() call pm_peer_count() to find the numbers of peer bonded, and if you have more than 5 peers bonded you can call pm_peer_ranks_get() to get the 'p_lowest_ranked_peer' and delete it by calling pm_peer_delete(lowest_ranked_peer)."

    I suppose you mean to call pm_peer_count() in while() loop (main). And in what regards call to pm_peer_ranks_get and pm_peer_delete: which is the best place to implement them? In the same while loop or inside a certain event in pm_evt_handler? And, it is necessary to call pm_peer_rang_highest() when the event PM_EVT_BONDED_PEER_CONNECTED is given?

    On the other side, I will compare my application with the one you suggested in order to make my application working with IoS devices. I will keep you informed.

    Dani

  • In what regards connection with IoS: I have followed the example you have suggested and now IoS is requesting me the passkey. Nevertheless, when I write the passkey, the PM_EVT_CONN_SEC_FAILED event is received. Which can be the reason? For clarification: I'm using a 8-digit passkey.

    Dani

Reply Children
No Data
Related