I am currently using nrf52840, nRF5_SDK_17.1.0_ddde560, and the ble_app_multirole_lesc example file.
I have successfully removed the HRS and button Bluetooth connections from the example file.
However, I encountered errors when adding NUS to the program.
Below are the programs I have added or modified, as well as the error information.
#include "ble_nus.h" #define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */ BLE_NUS_DEF(m_nus, NRF_SDH_BLE_PERIPHERAL_LINK_COUNT); /**< BLE NUS service instance. */ NRF_BLE_QWR_DEF(m_qwr); /**< Context for the Queued Write module.*/ static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ uint8_t data_buffer[242]; static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */ { {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE} }; static void on_conn_params_evt(ble_conn_params_evt_t * p_evt) { uint32_t err_code; if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); APP_ERROR_CHECK(err_code); } } static void multi_qwr_conn_handle_assign(uint16_t conn_handle) { if (m_qwr.conn_handle == BLE_CONN_HANDLE_INVALID) { ret_code_t err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, conn_handle); APP_ERROR_CHECK(err_code); } } static void on_ble_evt(uint16_t conn_handle, ble_evt_t const * p_ble_evt) { char passkey[BLE_GAP_PASSKEY_LEN + 1]; uint16_t role = ble_conn_state_role(conn_handle); ret_code_t err_code; pm_handler_secure_on_connection(p_ble_evt); switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: m_connected_peers[conn_handle].is_connected = true; m_connected_peers[conn_handle].address = p_ble_evt->evt.gap_evt.params.connected.peer_addr; // multi_qwr_conn_handle_assign(conn_handle); 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); break; case BLE_GAP_EVT_DISCONNECTED: memset(&m_connected_peers[conn_handle], 0x00, sizeof(m_connected_peers[0])); m_conn_handle = BLE_CONN_HANDLE_INVALID; break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: NRF_LOG_INFO("%s: BLE_GAP_EVT_SEC_PARAMS_REQUEST", nrf_log_push(roles_str[role])); // Pairing not supported err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_PASSKEY_DISPLAY: memcpy(passkey, p_ble_evt->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN); passkey[BLE_GAP_PASSKEY_LEN] = 0x00; NRF_LOG_INFO("%s: BLE_GAP_EVT_PASSKEY_DISPLAY: passkey=%s match_req=%d", nrf_log_push(roles_str[role]), nrf_log_push(passkey), p_ble_evt->evt.gap_evt.params.passkey_display.match_request); if (p_ble_evt->evt.gap_evt.params.passkey_display.match_request) { on_match_request(conn_handle, role); } break; case BLE_GAP_EVT_AUTH_KEY_REQUEST: NRF_LOG_INFO("%s: BLE_GAP_EVT_AUTH_KEY_REQUEST", nrf_log_push(roles_str[role])); break; case BLE_GAP_EVT_LESC_DHKEY_REQUEST: NRF_LOG_INFO("%s: BLE_GAP_EVT_LESC_DHKEY_REQUEST", nrf_log_push(roles_str[role])); break; case BLE_GAP_EVT_AUTH_STATUS: NRF_LOG_INFO("%s: BLE_GAP_EVT_AUTH_STATUS: status=0x%x bond=0x%x lv4: %d kdist_own:0x%x kdist_peer:0x%x", nrf_log_push(roles_str[role]), p_ble_evt->evt.gap_evt.params.auth_status.auth_status, p_ble_evt->evt.gap_evt.params.auth_status.bonded, p_ble_evt->evt.gap_evt.params.auth_status.sm1_levels.lv4, *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_own), *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer)); break; case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { NRF_LOG_DEBUG("PHY update request."); ble_gap_phys_t const phys = { .rx_phys = BLE_GAP_PHY_AUTO, .tx_phys = BLE_GAP_PHY_AUTO, }; ret_code_t err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } } static void on_ble_peripheral_evt(ble_evt_t const * p_ble_evt) { ret_code_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: NRF_LOG_INFO("PERIPHERAL: Connected, handle %d.", p_ble_evt->evt.gap_evt.conn_handle); // bsp_board_led_off(PERIPHERAL_ADVERTISING_LED); // bsp_board_led_on(PERIPHERAL_CONNECTED_LED); 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); break; case BLE_GAP_EVT_DISCONNECTED: NRF_LOG_INFO("PERIPHERAL: Disconnected, handle %d, reason 0x%x.", p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.disconnected.reason); // LED indication will be changed when advertising starts. m_conn_handle = BLE_CONN_HANDLE_INVALID; break; case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. NRF_LOG_DEBUG("PERIPHERAL: GATT Client 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: // Disconnect on GATT Server timeout event. NRF_LOG_DEBUG("PERIPHERAL: GATT Server 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; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; default: // No implementation needed. break; } } static void bsp_event_handler(bsp_event_t event) { ret_code_t err_code; switch (event) { case BSP_EVENT_DISCONNECT: err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } break; case BSP_EVENT_WHITELIST_OFF: if (m_conn_handle == BLE_CONN_HANDLE_INVALID) { err_code = ble_advertising_restart_without_whitelist(&m_advertising); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } } break; default: break; } } void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt) { if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) { m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len); } NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x", p_gatt->att_mtu_desired_central, p_gatt->att_mtu_desired_periph); } static void gatt_init(void) { ret_code_t 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); } static void nus_data_handler(ble_nus_evt_t * p_evt) { if (p_evt->type == BLE_NUS_EVT_RX_DATA) { NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART."); NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length); } } static void services_init(void) { uint32_t err_code; ble_nus_init_t nus_init; nrf_ble_qwr_init_t qwr_init = {0}; // Initialize Queued Write Module. qwr_init.error_handler = nrf_qwr_error_handler; err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init); APP_ERROR_CHECK(err_code); // Initialize NUS. memset(&nus_init, 0, sizeof(nus_init)); nus_init.data_handler = nus_data_handler; err_code = ble_nus_init(&m_nus, &nus_init); APP_ERROR_CHECK(err_code); } int main(void) { services_init(); for (;;) { data_buffer[0] = 0x0A; data_buffer[1] = 0x0B; data_buffer[2] = 0x0C; uint16_t length = 242; uint32_t err_code = ble_nus_data_send(&m_nus, (uint8_t *)data_buffer, &length, m_conn_handle); APP_ERROR_CHECK(err_code); // ..\..\..\main.c:1407 idle_state_handle(); } }
Error:
<error> app: ERROR 5 [NRF_ERROR_NOT_FOUND] at ..\..\..\main.c:1407
PC at: 0x000332C1
<error> app: End of error report