Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

fatal error in the BLE observers

Hello, new-to-this platform dev here!

I am implementing BLE bonding on my nRF52840 DK, which uses the S140 Softdevice. The DK is a peripheral and I'm using version 17.1 of the SDK. I adapted most of the peer_manager/whitelist code from the ble_peripheral hci keyboard sample. However, I'd like to implement some special logic to allow only the first device to be bonded with my nRF52840 to talk to it, and to reject pairing/bonding attempts from other devices. 

I implemented this logic in the ble_evt_handler, where I intercept LE_GAP_EVT_CONNECTED events and apply my go/no go logic. If the connection request falls into the "no go" category, I call sd_ble_gap_disconnect function. This returns an err_code of 0x0. But the next thing that happens is nrf_sdh_ble_evts_poll tries to forward  the event to BLE observers (line 300 of nrf_sdh_ble.c), and that's where I hit the fatal error. In the debugger, it looks like the sdh_ble_observer items point to valid addresses, but that's about as far as I can get on this.

Can anyone see where I am going wrong? Or know a better way to accomplish my goal?

Code from my BLE event handler:

    case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("ble_evt_handler: connected event ");

            pm_peer_id_t peer_id;
            err_code = pm_peer_id_get(p_ble_evt->evt.gattc_evt.conn_handle,&peer_id);
            APP_ERROR_CHECK(err_code);
            NRF_LOG_INFO("ble_evt_handler: conn handle 0x%x peer lookup returns %d", p_ble_evt->evt.gattc_evt.conn_handle,peer_id);
            NRF_LOG_INFO("current peer_cnt %d", pm_peer_count());

            // if this connection isn't already a peer and we already have a peer, reject it
            if ( peer_id == PM_PEER_ID_INVALID && pm_peer_count() > 0 )
            {
              NRF_LOG_INFO("ble_evt_handler: going to reject this");
              // according to message sequence charts at https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s140.api.v7.3.0/group___b_l_e___g_a_p___m_s_c.html,
               // I should send an sd_ble_gap_disconnect message here.
              // according to function docs at https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s140.api.v6.0.0%2Fgroup___b_l_e___g_a_p___f_u_n_c_t_i_o_n_s.html,
              // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and BLE_HCI_CONN_INTERVAL_UNACCEPTABLE are the only valid reason codes to use.
              // both return 0x0 in the err_code, but lead to a fatal error on line 300 of nrf_sdh_ble.c.
              //err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
              err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
              NRF_LOG_INFO("ble_evt_handler: disc error code %d",err_code)
              APP_ERROR_CHECK(err_code);
            }
            else
            {
              NRF_LOG_INFO("ble_evt_handler: going to set up connection");
              err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
              APP_ERROR_CHECK(err_code);
              m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
              err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
              APP_ERROR_CHECK(err_code);
              err_code = pm_conn_secure(p_ble_evt->evt.gap_evt.conn_handle, false);
              if (err_code != NRF_ERROR_BUSY)
              {
                APP_ERROR_CHECK(err_code);
              }
            }
            break;

    case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected, reason %d.", p_ble_evt->evt.gap_evt.params.disconnected.reason);
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;

Parents
  • I seem to have gotten rid of my APP_ERROR. But I am still having problems detecting when I've already entered a central device to the whitelist at the BLE connected event message level.

    I take the address in p_ble_evt->evt.gap_evt.params.connected.peer_addr and check it against the contents of the whitelist_addrs returned by pm_whitelist_get(). My central device sends the same peer_addr every time, but that's not what I see in the whitelist.

    I set the whitelist with the results of a call to pm_peer_id_list()  in the PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event. The peer_id is a unsigned 16-bit number.

    How can I take a ble_gap_add_t and map it to whatever is in the whitelist?

Reply
  • I seem to have gotten rid of my APP_ERROR. But I am still having problems detecting when I've already entered a central device to the whitelist at the BLE connected event message level.

    I take the address in p_ble_evt->evt.gap_evt.params.connected.peer_addr and check it against the contents of the whitelist_addrs returned by pm_whitelist_get(). My central device sends the same peer_addr every time, but that's not what I see in the whitelist.

    I set the whitelist with the results of a call to pm_peer_id_list()  in the PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event. The peer_id is a unsigned 16-bit number.

    How can I take a ble_gap_add_t and map it to whatever is in the whitelist?

Children
No Data
Related