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

checking if connection is bonded in multiperipheral device

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

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

My aim is to disconnect central devices that are not bonded within 10 seconds.

uint16_t uptime[NRF_SDH_BLE_PERIPHERAL_LINK_COUNT];
bool f_link_bonded[NRF_SDH_BLE_PERIPHERAL_LINK_COUNT];

NRF_BLE_QWRS_DEF(m_qwr, NRF_SDH_BLE_TOTAL_LINK_COUNT);

...

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
  switch (p_ble_evt->header.evt_id)
  {
    case BLE_GAP_EVT_CONNECTED:
    {
      NRF_LOG_INFO("peer %u connected", p_ble_evt->conn_handle);
      uptime[p_ble_evt->conn_handle] = 0;

      // Assign connection handle to available instance of QWR module.
      for (uint8_t i = 0; i < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT; i++)
      {
        if (m_qwr[i].conn_handle == BLE_CONN_HANDLE_INVALID)
        {
          ret_val = nrf_ble_qwr_conn_handle_assign(&m_qwr[i], p_ble_evt->conn_handle);
          APP_ERROR_CHECK(ret_val);
         break;
        }
      }
      break;
    }

    case BLE_GAP_EVT_DISCONNECTED:
    {
      f_link_bonded[p_evt->conn_handle] = false;
      break;
    }

    ...
  }
}


static void pm_evt_handler(pm_evt_t const * p_evt)
{
  switch (p_evt->evt_id)
  {
    case PM_EVT_BONDED_PEER_CONNECTED:
    {
      NRF_LOG_INFO("peer %u bonded", p_evt->conn_handle);
      f_link_bonded[p_evt->conn_handle] = true;
      break;
    }

    case PM_EVT_CONN_SEC_SUCCEEDED:
    {
      NRF_LOG_INFO("peer %u bonded", p_evt->conn_handle);
      f_link_bonded[p_evt->conn_handle] = true;
      break;
    }

...

  }
}


main()
{
  while(true)
  {
    ...

    // every second
    for (uint8_t i = 0; i < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT; i++)
    {
      if (m_qwr[i].conn_handle != BLE_CONN_HANDLE_INVALID) { uptime++; }
    }
  }
}

A connected central device gets a specific connection number in ble_evt_handler. This connection number  is assigned to m_qwr[i]. But in pm_evt_handler p_evt->conn_handle can have a different value.

As a result it is not possible to figure out if a specific peer is bonded or not.

if ((uptime[3] >= 10) && (f_link_bonded[3])) { disconnect(); }

This command does not work all time because uptime[3] and f_link_bonded[3] could be assigned to different peers.

Any idea how I could check if a specific peer is bonded after a certain time?

Parents
  • Hi,

    I am not following exactly how you organize the connection handles. Essentially you just need to store them somehow for later use. The connection handle does not change for the duration of a connection, so as long as there has not been any disconnect it will stay the same and represent the same peer. (I do not see any reason for mixing with the QWR module, it could be kept separate.)

    I suggest something like the following:

    1. When a device connections the applications gets a BLE_GAP_EVT_CONNECTED event, which includes the connection handle.
    2. Store the connection handle somewhere and start a single shot app timer with 10 seconds timeout.
    3. If the connection is terminated before the timer expires, stop the app timer so that nothing more happens.
    4. When the timeout occurs, check if the connection handle represents a bonded device using pm_peer_id_get().
    5. If not bonded, disconnect by calling sd_ble_gap_disconnect().

    The above method is a bit simplistic as it does not handle a second connection within the 10 second before checking if it has bonded so it needs a bit expansion to be complete, but it demonstrates how it can be done.

  • Meanwhile I found the mistake (misunderstanding) in my firmware. I mixed the address (i) and the value of the array m_qwr[i].conn_handle.

Reply Children
No Data
Related