I'm using a nRF52840 configured as Central and Peripheral, with nRF5_SDK 17.1.0 (I'm Not using Zephyr) for reading the Device Name from the Generic Service of a beacon.
I'm already able to connect to the beacon GAP, discover the characteristic I need and read the device name. Up to this point everything is fine.
But when my beacon terminates the connection or when I try to finish it by calling sd_ble_gap_disconnect(...), my nRF52840 reboots.
Since I'm not using a development kit (I'm using a final product that has the nRF52840 as microcontroller) the only way I can debug is via a serial port the product has. But although I've put a lot of "printf like" calls to try to track where the reset is comming from, I wasn't able to find it. My serial debug goes all fine until I call the sd_ble_gap_disconnect or until the beacon shuts off the connection.
Does anyone have an idea of what can be happening and how can I solve it?
#define BEACON_GAP_UUID 0xFEAA #define APP_BLE_CONN_CFG_TAG 1 #define APP_BLE_OBSERVER_PRIO 3 uint8_t BufferDataRead[30]; uint16_t myConnHandle; BLE_DB_DISCOVERY_DEF(m_db_disc); NRF_BLE_GQ_DEF(m_ble_gatt_queue, NRF_SDH_BLE_CENTRAL_LINK_COUNT, NRF_BLE_GQ_QUEUE_SIZE); NRF_BLE_SCAN_DEF(m_scan); //========== MAIN ========== int main(void) { err_code = nrf_sdh_enable_request(); APP_ERROR_CHECK(err_code); ble_stack_init(); gatt_init(); beacon_db_discovery_init(); beacon_scan_init(); beacon_scan_start(); //starts scanning //... rest of the program's logic //... } //========================== void gatt_init(void) { ret_code_t err_code; err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler); APP_ERROR_CHECK(err_code); err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); APP_ERROR_CHECK(err_code); err_code = nrf_ble_gatt_att_mtu_central_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); APP_ERROR_CHECK(err_code); } static void ble_stack_init(void) { ret_code_t err_code; uint32_t ram_start = 0; err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start); APP_ERROR_CHECK(err_code); err_code = nrf_sdh_ble_enable(&ram_start); APP_ERROR_CHECK(err_code); NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL); } static void db_disc_handler(ble_db_discovery_evt_t * p_evt) { uint16_t att_handle; ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics; if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) { if (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_GAP && p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) { for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++) { if (p_chars[i].characteristic.uuid.uuid == BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME) { att_handle = p_chars[i].characteristic.handle_value; sd_ble_gattc_read(p_evt->conn_handle, att_handle, 0); } } } } } void beacon_db_discovery_init(void) { ble_db_discovery_init_t db_init; memset(&db_init, 0, sizeof(ble_db_discovery_init_t)); db_init.evt_handler = db_disc_handler; db_init.p_gatt_queue = &m_ble_gatt_queue; ret_code_t err_code = ble_db_discovery_init(&db_init); APP_ERROR_CHECK(err_code); } void beacon_scan_start(void) { ret_code_t err_code; err_code = nrf_ble_scan_start(&m_scan); APP_ERROR_CHECK(err_code); } static void scan_evt_handler(scan_evt_t const * p_scan_evt) { ret_code_t err_code; switch(p_scan_evt->scan_evt_id) { case NRF_BLE_SCAN_EVT_CONNECTED: sd_ble_gap_scan_stop(); break; } } void beacon_scan_init(void) { ret_code_t err_code; nrf_ble_scan_init_t init_scan; static ble_uuid_t beacon_uuid_generic; beacon_uuid_generic.type = BLE_UUID_TYPE_BLE; beacon_uuid_generic.uuid = BLE_UUID_GAP; ble_uuid_t beacon_uuid = { .type = BLE_UUID_TYPE_BLE, .uuid = BEACON_GAP_UUID, }; memset(&init_scan, 0, sizeof(init_scan)); init_scan.connect_if_match = true; init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG; ble_db_discovery_evt_register(&beacon_uuid_generic); err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler); APP_ERROR_CHECK(err_code); err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &beacon_uuid); APP_ERROR_CHECK(err_code); err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false); APP_ERROR_CHECK(err_code); } static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) { ret_code_t err_code; ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt; switch(p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: { myConnHandle = p_ble_evt->evt.gattc_evt.conn_handle; err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle); APP_ERROR_CHECK(err_code); break; } case BLE_GATTC_EVT_READ_RSP: { uint8_t lengthDataRead = p_ble_evt->evt.gattc_evt.params.read_rsp.len; memcpy(BufferDataRead, p_ble_evt->evt.gattc_evt.params.read_rsp.data, lengthDataRead); //EVERYTHING GOES FINE UNTIL HERE //BUT WHEN I TRY DO DISCONNECT IT, uC REBOOTS sd_ble_gap_disconnect(myConnHandle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); break; } case BLE_GAP_EVT_SEC_PARAMS_REQUEST: { err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); APP_ERROR_CHECK(err_code); break; } case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update_request.conn_params); APP_ERROR_CHECK(err_code); break; } case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { ble_gap_phys_t const phys = { .rx_phys = BLE_GAP_PHY_AUTO, .tx_phys = BLE_GAP_PHY_AUTO, }; err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); APP_ERROR_CHECK(err_code); break; } case BLE_GATTC_EVT_TIMEOUT: { err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; } case BLE_GATTS_EVT_TIMEOUT: { err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; } } }