/**@brief Function for handling a Bond Manager error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void bond_manager_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
/**@brief Function for handling a Connection Parameters error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
/**@brief Function for handling a Connection Parameters error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); uart_tx_status_code("nrf error code:", nrf_error, 0); }
void intern_softdevice_events_execute(void) { if (!m_softdevice_enabled) { // SoftDevice not enabled. This can be possible if the SoftDevice was enabled by the // application without using this module's API (i.e softdevice_handler_init) return; } bool no_more_soc_evts = (m_sys_evt_handler == NULL); #ifdef BLE_STACK_SUPPORT_REQD bool no_more_ble_evts = (m_ble_evt_handler == NULL); #endif #ifdef ANT_STACK_SUPPORT_REQD bool no_more_ant_evts = (m_ant_evt_handler == NULL); #endif for (;;) { uint32_t err_code; if (!no_more_soc_evts) { uint32_t evt_id; // Pull event from SOC. err_code = sd_evt_get(&evt_id); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_soc_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's SOC event handler. m_sys_evt_handler(evt_id); } } #ifdef BLE_STACK_SUPPORT_REQD // Fetch BLE Events. if (!no_more_ble_evts) { // Pull event from stack uint16_t evt_len = m_ble_evt_buffer_size; err_code = sd_ble_evt_get(mp_ble_evt_buffer, &evt_len); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_ble_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's BLE stack event handler. m_ble_evt_handler((ble_evt_t *)mp_ble_evt_buffer); } } #endif #ifdef ANT_STACK_SUPPORT_REQD // Fetch ANT Events. if (!no_more_ant_evts) { // Pull event from stack err_code = sd_ant_event_get(&m_ant_evt_buffer.channel, &m_ant_evt_buffer.event, m_ant_evt_buffer.evt_buffer); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_ant_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's ANT stack event handler. m_ant_evt_handler(&m_ant_evt_buffer); } } #endif if (no_more_soc_evts) { // There are no remaining System (SOC) events to be fetched from the SoftDevice. #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD) // Check if there are any remaining BLE and ANT events. if (no_more_ble_evts && no_more_ant_evts) { break; } #elif defined(BLE_STACK_SUPPORT_REQD) // Check if there are any remaining BLE events. if (no_more_ble_evts) { break; } #elif defined(ANT_STACK_SUPPORT_REQD) // Check if there are any remaining ANT events. if (no_more_ant_evts) { break; } #else // No need to check for BLE or ANT events since there is no support for BLE and ANT // required. break; #endif } } }
/**@brief Function for handling Peer Manager events. * * @param[in] p_evt Peer Manager event. */ static void pm_evt_handler(pm_evt_t const * p_evt) { ret_code_t err_code; switch (p_evt->evt_id) { case PM_EVT_BONDED_PEER_CONNECTED: { NRF_LOG_DEBUG("Connected to previously bonded device\r\n"); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } } break; // PM_EVT_BONDED_PEER_CONNECTED case PM_EVT_CONN_SEC_START: break; // PM_EVT_CONN_SEC_START case PM_EVT_CONN_SEC_SUCCEEDED: { NRF_LOG_DEBUG("Link secured. Role: %d. conn_handle: %d, Procedure: %d\r\n", ble_conn_state_role(p_evt->conn_handle), p_evt->conn_handle, p_evt->params.conn_sec_succeeded.procedure); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } } break; // PM_EVT_CONN_SEC_SUCCEEDED case PM_EVT_CONN_SEC_FAILED: { /** In some cases, when securing fails, it can be restarted directly. Sometimes it can * be restarted, but only after changing some Security Parameters. Sometimes, it cannot * be restarted until the link is disconnected and reconnected. Sometimes it is * impossible, to secure the link, or the peer device does not support it. How to * handle this error is highly application dependent. */ switch (p_evt->params.conn_sec_failed.error) { case PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING: // Rebond if one party has lost its keys. err_code = pm_conn_secure(p_evt->conn_handle, true); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } break; // PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING default: break; } } break; // PM_EVT_CONN_SEC_FAILED case PM_EVT_CONN_SEC_CONFIG_REQ: { // Reject pairing request from an already bonded peer. pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false}; pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config); } break; // PM_EVT_CONN_SEC_CONFIG_REQ case PM_EVT_STORAGE_FULL: { // Run garbage collection on the flash. err_code = fds_gc(); if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES) { // Retry. } else { APP_ERROR_CHECK(err_code); } } break; // PM_EVT_STORAGE_FULL case PM_EVT_ERROR_UNEXPECTED: // Assert. APP_ERROR_CHECK(p_evt->params.error_unexpected.error); break; // PM_EVT_ERROR_UNEXPECTED case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED: break; // PM_EVT_PEER_DATA_UPDATE_SUCCEEDED case PM_EVT_PEER_DATA_UPDATE_FAILED: // Assert. APP_ERROR_CHECK_BOOL(false); break; // PM_EVT_PEER_DATA_UPDATE_FAILED case PM_EVT_PEER_DELETE_SUCCEEDED: break; // PM_EVT_PEER_DELETE_SUCCEEDED case PM_EVT_PEER_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error); break; // PM_EVT_PEER_DELETE_FAILED case PM_EVT_PEERS_DELETE_SUCCEEDED: advertising_start(); break; // PM_EVT_PEERS_DELETE_SUCCEEDED case PM_EVT_PEERS_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error); break; // PM_EVT_PEERS_DELETE_FAILED case PM_EVT_LOCAL_DB_CACHE_APPLIED: break; // PM_EVT_LOCAL_DB_CACHE_APPLIED case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED: // The local database has likely changed, send service changed indications. pm_local_database_has_changed(); break; // PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED case PM_EVT_SERVICE_CHANGED_IND_SENT: break; // PM_EVT_SERVICE_CHANGED_IND_SENT case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED: break; // PM_EVT_SERVICE_CHANGED_IND_SENT default: // No implementation needed. break; } } /**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg); err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/**@brief Function for handling Service errors. * * @details A pointer to this function will be passed to each service which may need to inform the * application about an error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void service_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
/**@brief Function for handling Peer Manager events. * * @param[in] p_evt Peer Manager event. */ static void pm_evt_handler(pm_evt_t const * p_evt) { ret_code_t err_code; switch(p_evt->evt_id) { case PM_EVT_BONDED_PEER_CONNECTED: { NRF_LOG_PRINTF_DEBUG("Connected to previously bonded device\r\n"); // Start Security Request timer. err_code = app_timer_start(m_sec_req_timer_id, SECURITY_REQUEST_DELAY, NULL); APP_ERROR_CHECK(err_code); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } }break;//PM_EVT_BONDED_PEER_CONNECTED case PM_EVT_CONN_SEC_START: break;//PM_EVT_CONN_SEC_START case PM_EVT_CONN_SEC_SUCCEEDED: { /*Check if the link is authenticated (meaning at least MITM)*/ pm_conn_sec_status_t conn_sec_status; err_code = pm_conn_sec_status_get(p_evt->conn_handle, &conn_sec_status); APP_ERROR_CHECK(err_code); if (!conn_sec_status.mitm_protected) { APP_LOG("Collector did not use MITM, disconnecting\r\n"); /*The peer did not use MITM, disconnect*/ err_code = pm_peer_id_get(m_conn_handle, &peer_to_be_deleted); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); // m_state = W_ADV_STATE_UNBONDED; } else { NRF_LOG_PRINTF_DEBUG("Link secured. Role: %d. conn_handle: %d, Procedure: %d\r\n", ble_conn_state_role(p_evt->conn_handle), p_evt->conn_handle, p_evt->params.conn_sec_succeeded.procedure); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } // m_state = W_ADV_STATE_BONDED; } }break;//PM_EVT_CONN_SEC_SUCCEEDED case PM_EVT_CONN_SEC_FAILED: { /** In some cases, when securing fails, it can be restarted directly. Sometimes it can * be restarted, but only after changing some Security Parameters. Sometimes, it cannot * be restarted until the link is disconnected and reconnected. Sometimes it is * impossible, to secure the link, or the peer device does not support it. How to * handle this error is highly application dependent. */ APP_LOG("link secure failed! "); switch (p_evt->params.conn_sec_failed.error) { case PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING: NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING"); break;//PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING case PM_CONN_SEC_ERROR_MIC_FAILURE: NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_MIC_FAILURE"); break;//PM_CONN_SEC_ERROR_MIC_FAILURE case PM_CONN_SEC_ERROR_DISCONNECT : NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_DISCONNECT "); break;//PM_CONN_SEC_ERROR_DISCONNECT case PM_CONN_SEC_ERROR_SMP_TIMEOUT: NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_SMP_TIMEOUT"); break;//PM_CONN_SEC_ERROR_SMP_TIMEOUT default: NRF_LOG_DEBUG("unknown error"); break; } APP_LOG("\r\nDisconnecting\r\n"); err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; }break;//PM_EVT_CONN_SEC_FAILED case PM_EVT_CONN_SEC_CONFIG_REQ: { // Reject pairing request from an already bonded peer. pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false}; pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config); }break;//PM_EVT_CONN_SEC_CONFIG_REQ case PM_EVT_STORAGE_FULL: { // Run garbage collection on the flash. err_code = fds_gc(); if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES) { // Retry. } else { APP_ERROR_CHECK(err_code); } }break;//PM_EVT_STORAGE_FULL case PM_EVT_ERROR_UNEXPECTED: // Assert. APP_ERROR_CHECK(p_evt->params.error_unexpected.error); break;//PM_EVT_ERROR_UNEXPECTED case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED: break;//PM_EVT_PEER_DATA_UPDATE_SUCCEEDED case PM_EVT_PEER_DATA_UPDATE_FAILED: // Assert. APP_ERROR_CHECK_BOOL(false); break;//PM_EVT_PEER_DATA_UPDATE_FAILED case PM_EVT_PEER_DELETE_SUCCEEDED: break;//PM_EVT_PEER_DELETE_SUCCEEDED case PM_EVT_PEER_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error); break;//PM_EVT_PEER_DELETE_FAILED case PM_EVT_PEERS_DELETE_SUCCEEDED: NRF_LOG_PRINTF_DEBUG("%s: PM_EVT_PEERS_DELETE_SUCCEEDED\r\n", __func__); // m_erasing_bonds = false; // advertising_init(); // advertising_start(); break; case PM_EVT_PEERS_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error); break;//PM_EVT_PEERS_DELETE_FAILED case PM_EVT_LOCAL_DB_CACHE_APPLIED: break;//PM_EVT_LOCAL_DB_CACHE_APPLIED case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED: // The local database has likely changed, send service changed indications. pm_local_database_has_changed(); break;//PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED case PM_EVT_SERVICE_CHANGED_IND_SENT: break;//PM_EVT_SERVICE_CHANGED_IND_SENT case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED: break;//PM_EVT_SERVICE_CHANGED_IND_CONFIRMED default: // No implementation needed. break; } } /**@brief Function for handling Service errors. * * @details A pointer to this function will be passed to each service which may need to inform the * application about an error. * * @param[in] nrf_error Error code containing information about what went wrong. */ //static void service_error_handler(uint32_t nrf_error) //{ // APP_ERROR_HANDLER(nrf_error); //} /**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; // battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg); battery_level = 37; err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } // if (m_adv_state == W_ADV_STATE_IDLE) { // advertising_init(); // advertising_start(); // } }
/**@brief Function for handling the Apple Notification Service Client errors. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void apple_notification_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
/**@brief Function for processing received profile page events. * * @param[in] p_event_return Profile page event to be processed. */ static __INLINE void profile_event_page_handle(const antplus_event_return_t * const p_event_return) { #if defined(TRACE_DATA_PAGE) const bp_page16_data_t * p_page16_data; const bp_page17_data_t * p_page17_data; const bp_page18_data_t * p_page18_data; const bp_page32_data_t * p_page32_data; const page80_data_t * p_page80_data; const page81_data_t * p_page81_data; #endif // defined(TRACE_DATA_PAGE) #if defined(TRACE_CALIBRATION) const bp_page1_response_data_t * p_page1_general_response_data; #endif // defined(TRACE_CALIBRATION) switch (p_event_return->param1) { case BP_PAGE_1: // Calibration message main data page. #if defined(TRACE_CALIBRATION) p_page1_general_response_data = bp_rx_data_page1_response_get(); printf("page1:calibration_id %#x\n", (uint8_t)p_page1_general_response_data->calibration_id); printf("page1:auto_zero_status %u\n", (uint8_t)p_page1_general_response_data->auto_zero_status); printf("page1:calibration_data %i\n", (uint16_t)p_page1_general_response_data->calibration_data); #endif // defined(TRACE_CALIBRATION) break; case BP_PAGE_16: // Standard power only page. #if defined(TRACE_DATA_PAGE) p_page16_data = bp_rx_data_page16_get(); printf("Page16:event count %u\n", (unsigned int)p_page16_data->event_count); printf("Page16:pedal power %u\n", (unsigned int)p_page16_data->pedal_power); printf("Page16:instantaneous cadence %u\n", (unsigned int)p_page16_data->instantaneous_cadence); printf("Page16:accumulated power %u\n", (unsigned int)p_page16_data->accumulated_power); printf("Page16:instantaneous power %u\n", (unsigned int)p_page16_data->instantaneous_power); #endif // defined(TRACE_DATA_PAGE) break; case BP_PAGE_17: // Wheel Torque (WT) main data page. #if defined(TRACE_DATA_PAGE) p_page17_data = bp_rx_data_page17_get(); printf("Page17:update_event_counter %u\n", (unsigned int)p_page17_data->update_event_counter); printf("Page17:wheel_ticks %u\n", (unsigned int)p_page17_data->wheel_ticks); printf("Page17:instantaneous_cadence %u\n", (unsigned int)p_page17_data->instantaneous_cadence); printf("Page17:accumulated wheel_period %u\n", (unsigned int)p_page17_data->wheel_period); printf("Page17:accumulated_torgue %u\n", (unsigned int)p_page17_data->accumulated_torgue); #endif // defined(TRACE_DATA_PAGE) break; case BP_PAGE_18: // Standard Crank Torque (CT) main data page. #if defined(TRACE_DATA_PAGE) p_page18_data = bp_rx_data_page18_get(); printf("Page18:update_event_counter %u\n", (unsigned int)p_page18_data->update_event_counter); printf("Page18:crank_ticks %u\n", (unsigned int)p_page18_data->crank_ticks); printf("Page18:instantaneous_cadence %u\n", (unsigned int)p_page18_data->instantaneous_cadence); printf("Page18:accumulated crank_period %u\n", (unsigned int)p_page18_data->crank_period); printf("Page18:accumulated_torgue %u\n", (unsigned int)p_page18_data->accumulated_torgue); #endif // defined(TRACE_DATA_PAGE) break; case BP_PAGE_32: // Standard Crank Torque Frequency (CTF) main data page. #if defined(TRACE_DATA_PAGE) p_page32_data = bp_rx_data_page32_get(); printf("Page32:event_counter %u\n", (unsigned int)p_page32_data->update_event_counter); printf("Page32:slope %u\n", (unsigned int)p_page32_data->slope); printf("Page32:time_stamp %u\n", (unsigned int)p_page32_data->time_stamp); printf("Page32:torque_ticks_stamp %u\n", (unsigned int)p_page32_data->torque_ticks_stamp); printf("Page32:average_cadence %u\n", (unsigned int)p_page32_data->average_cadence); #endif // defined(TRACE_DATA_PAGE) break; case COMMON_PAGE_80: // Manufacturer's identification common data page. #if defined(TRACE_DATA_PAGE) p_page80_data = bp_rx_data_page80_get(); printf("Page80:hw_revision %u\n", (unsigned int)p_page80_data->hw_revision); printf("Page80:manufacturing_id %u\n", (unsigned int)p_page80_data->manufacturing_id); printf("Page80:model_number %u\n", (unsigned int)p_page80_data->model_number); #endif // defined(TRACE_DATA_PAGE) break; case COMMON_PAGE_81: // Product information common data page. #if defined(TRACE_DATA_PAGE) p_page81_data = bp_rx_data_page81_get(); printf("Page81:sw_revision %u\n", (unsigned int)p_page81_data->sw_revision); printf("Page81:serial_number %u\n", (unsigned int)p_page81_data->serial_number); #endif // defined(TRACE_DATA_PAGE) break; default: APP_ERROR_HANDLER(p_event_return->param1); break; } }
/**@brief Function for handling a BeaconScanner error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void beacon_scanner_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
/**@brief Function for handling the Current Time Service errors. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void current_time_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
static void uart_event_handle(app_uart_evt_t * p_event) { static uint8_t data_array[BLE_NUS_MAX_DATA_LEN]; static uint8_t index = 0; uint32_t err_code; //uint8_t dbg_idx = 0; //uint8_t nDataLen = 0; switch (p_event->evt_type) { case APP_UART_DATA_READY: UNUSED_VARIABLE(app_uart_get(&data_array[index])); //log_print("0x%02x ", data_array[index]); index++; if ((data_array[index - 1] == 0x03/*'\n'*/) || (index >= (BLE_NUS_MAX_DATA_LEN))) { //err_code = ble_nus_string_send(&m_nus, data_array, index); err_code = ble_uart_send_data(data_array, index); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } index = 0; //nrf_delay_ms(10); } //nDataLen = sizeof(json); #if 0 do { if (nDataLen < BLE_NUS_MAX_DATA_LEN) { ble_uart_send_data((uint8_t *)json+dbg_idx, nDataLen); dbg_idx += nDataLen; nDataLen = 0; } else { ble_uart_send_data((uint8_t *)json+dbg_idx, BLE_NUS_MAX_DATA_LEN); dbg_idx += BLE_NUS_MAX_DATA_LEN; nDataLen -= BLE_NUS_MAX_DATA_LEN; } nrf_delay_ms(10); } while(nDataLen > 0); #endif break; case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER(p_event->data.error_communication); break; case APP_UART_FIFO_ERROR: APP_ERROR_HANDLER(p_event->data.error_code); break; default: break; } }
/**@brief Function for handling slip events. * * @param[in] event The event structure. */ void slip_event_handle(hci_slip_evt_t event) { uint32_t return_code; uint32_t err_code; switch (event.evt_type) { case HCI_SLIP_TX_DONE: tx_sm_event_handle(TX_EVENT_SLIP_TX_DONE); break; case HCI_SLIP_RX_RDY: return_code = packet_type_decode(event.packet, event.packet_length); switch (return_code) { case PKT_TYPE_VENDOR_SPECIFIC: rx_vendor_specific_pkt_type_handle(event.packet, event.packet_length); break; case PKT_TYPE_ACK: if (rx_ack_pkt_type_handle(event.packet)) { // Valid expected acknowledgement packet received: set correct TX done event // callback function result code and execute state change. m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS; tx_sm_event_handle(TX_EVENT_VALID_RX_ACK); } /* fall-through */ default: // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer // overflow. // If existing mem pool produced RX buffer exists reuse that one. If existing // mem pool produced RX buffer does not exist try to produce new one. If // producing fails use the internal acknowledgement buffer. if (mp_slip_used_rx_buffer != NULL) { err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE); APP_ERROR_CHECK(err_code); } else { err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM)); err_code = hci_slip_rx_buffer_register( (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, (err_code == NRF_SUCCESS) ? RX_BUF_SIZE : ACK_BUF_SIZE); APP_ERROR_CHECK(err_code); } break; } break; case HCI_SLIP_RX_OVERFLOW: err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE); APP_ERROR_CHECK(err_code); break; case HCI_SLIP_ERROR: APP_ERROR_HANDLER(event.evt_type); break; default: APP_ERROR_HANDLER(event.evt_type); break; } }
/**@brief Function for handling Peer Manager events. * * @param[in] p_evt Peer Manager event. */ static void pm_evt_handler(pm_evt_t const * p_evt) { ret_code_t err_code; switch(p_evt->evt_id) { case PM_EVT_BONDED_PEER_CONNECTED: { NRF_LOG_PRINTF_DEBUG("Connected to previously bonded device\r\n"); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } }break;//PM_EVT_BONDED_PEER_CONNECTED case PM_EVT_CONN_SEC_START: break;//PM_EVT_CONN_SEC_START case PM_EVT_CONN_SEC_SUCCEEDED: { NRF_LOG_PRINTF("Link secured. Role: %d. conn_handle: %d, Procedure: %d\r\n", ble_conn_state_role(p_evt->conn_handle), p_evt->conn_handle, p_evt->params.conn_sec_succeeded.procedure); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } }break;//PM_EVT_CONN_SEC_SUCCEEDED case PM_EVT_CONN_SEC_FAILED: { /** In some cases, when securing fails, it can be restarted directly. Sometimes it can * be restarted, but only after changing some Security Parameters. Sometimes, it cannot * be restarted until the link is disconnected and reconnected. Sometimes it is * impossible, to secure the link, or the peer device does not support it. How to * handle this error is highly application dependent. */ switch (p_evt->params.conn_sec_failed.error) { case PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING: // Rebond if one party has lost its keys. err_code = pm_conn_secure(p_evt->conn_handle, true); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } break;//PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING default: break; } }break;//PM_EVT_CONN_SEC_FAILED case PM_EVT_CONN_SEC_CONFIG_REQ: { // Reject pairing request from an already bonded peer. pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false}; pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config); }break;//PM_EVT_CONN_SEC_CONFIG_REQ case PM_EVT_STORAGE_FULL: { // Run garbage collection on the flash. err_code = fds_gc(); if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES) { // Retry. } else { APP_ERROR_CHECK(err_code); } }break;//PM_EVT_STORAGE_FULL case PM_EVT_ERROR_UNEXPECTED: // Assert. APP_ERROR_CHECK(p_evt->params.error_unexpected.error); break;//PM_EVT_ERROR_UNEXPECTED case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED: break;//PM_EVT_PEER_DATA_UPDATE_SUCCEEDED case PM_EVT_PEER_DATA_UPDATE_FAILED: // Assert. APP_ERROR_CHECK_BOOL(false); break;//PM_EVT_PEER_DATA_UPDATE_FAILED case PM_EVT_PEER_DELETE_SUCCEEDED: break;//PM_EVT_PEER_DELETE_SUCCEEDED case PM_EVT_PEER_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error); break;//PM_EVT_PEER_DELETE_FAILED case PM_EVT_PEERS_DELETE_SUCCEEDED: adv_scan_start(); break;//PM_EVT_PEERS_DELETE_SUCCEEDED case PM_EVT_PEERS_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error); break;//PM_EVT_PEERS_DELETE_FAILED case PM_EVT_LOCAL_DB_CACHE_APPLIED: break;//PM_EVT_LOCAL_DB_CACHE_APPLIED case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED: // The local database has likely changed, send service changed indications. pm_local_database_has_changed(); break;//PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED case PM_EVT_SERVICE_CHANGED_IND_SENT: break;//PM_EVT_SERVICE_CHANGED_IND_SENT case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED: break;//PM_EVT_SERVICE_CHANGED_IND_CONFIRMED default: // No implementation needed. break; } } /**@brief Handles events coming from the Heart Rate central module. */ static void hrs_c_evt_handler(ble_hrs_c_t * p_hrs_c, ble_hrs_c_evt_t * p_hrs_c_evt) { switch (p_hrs_c_evt->evt_type) { case BLE_HRS_C_EVT_DISCOVERY_COMPLETE: { if (m_conn_handle_hrs_c == BLE_CONN_HANDLE_INVALID) { ret_code_t err_code; m_conn_handle_hrs_c = p_hrs_c_evt->conn_handle; NRF_LOG_PRINTF("HRS discovered on conn_handle 0x%x\r\n", m_conn_handle_hrs_c); err_code = ble_hrs_c_handles_assign(p_hrs_c, m_conn_handle_hrs_c, &p_hrs_c_evt->params.peer_db); APP_ERROR_CHECK(err_code); // Initiate bonding. err_code = pm_conn_secure(m_conn_handle_hrs_c, false); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } // Heart rate service discovered. Enable notification of Heart Rate Measurement. err_code = ble_hrs_c_hrm_notif_enable(p_hrs_c); APP_ERROR_CHECK(err_code); } } break; // BLE_HRS_C_EVT_DISCOVERY_COMPLETE case BLE_HRS_C_EVT_HRM_NOTIFICATION: { ret_code_t err_code; NRF_LOG_PRINTF("Heart Rate = %d\r\n", p_hrs_c_evt->params.hrm.hr_value); err_code = ble_hrs_heart_rate_measurement_send(&m_hrs, p_hrs_c_evt->params.hrm.hr_value); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } } break; // BLE_HRS_C_EVT_HRM_NOTIFICATION default: // No implementation needed. break; } } /**@brief Handles events coming from Running Speed and Cadence central module. */ static void rscs_c_evt_handler(ble_rscs_c_t * p_rscs_c, ble_rscs_c_evt_t * p_rscs_c_evt) { switch (p_rscs_c_evt->evt_type) { case BLE_RSCS_C_EVT_DISCOVERY_COMPLETE: { if (m_conn_handle_rscs_c == BLE_CONN_HANDLE_INVALID) { ret_code_t err_code; m_conn_handle_rscs_c = p_rscs_c_evt->conn_handle; NRF_LOG_PRINTF("Running Speed and Cadence service discovered on conn_handle 0x%x\r\n", m_conn_handle_rscs_c); err_code = ble_rscs_c_handles_assign(p_rscs_c, m_conn_handle_rscs_c, &p_rscs_c_evt->params.rscs_db); APP_ERROR_CHECK(err_code); // Initiate bonding. err_code = pm_conn_secure(m_conn_handle_rscs_c, false); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } // Running speed cadence service discovered. Enable notifications. err_code = ble_rscs_c_rsc_notif_enable(p_rscs_c); APP_ERROR_CHECK(err_code); } } break; // BLE_RSCS_C_EVT_DISCOVERY_COMPLETE: case BLE_RSCS_C_EVT_RSC_NOTIFICATION: { uint32_t err_code; ble_rscs_meas_t rscs_measurment; NRF_LOG_PRINTF("Speed = %d\r\n", p_rscs_c_evt->params.rsc.inst_speed); rscs_measurment.is_running = p_rscs_c_evt->params.rsc.is_running; rscs_measurment.is_inst_stride_len_present = p_rscs_c_evt->params.rsc.is_inst_stride_len_present; rscs_measurment.is_total_distance_present = p_rscs_c_evt->params.rsc.is_total_distance_present; rscs_measurment.inst_stride_length = p_rscs_c_evt->params.rsc.inst_stride_length; rscs_measurment.inst_cadence = p_rscs_c_evt->params.rsc.inst_cadence; rscs_measurment.inst_speed = p_rscs_c_evt->params.rsc.inst_speed; rscs_measurment.total_distance = p_rscs_c_evt->params.rsc.total_distance; err_code = ble_rscs_measurement_send(&m_rscs, &rscs_measurment); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } } break; // BLE_RSCS_C_EVT_RSC_NOTIFICATION default: // No implementation needed. break; } } /**@brief Function for searching a given name in the advertisement packets. * * @details Use this function to parse received advertising data and to find a given * name in them either as 'complete_local_name' or as 'short_local_name'. * * @param[in] p_adv_report advertising data to parse. * @param[in] name_to_find name to search. * @return true if the given name was found, false otherwise. */ static bool find_adv_name(const ble_gap_evt_adv_report_t *p_adv_report, const char * name_to_find) { uint32_t err_code; data_t adv_data; data_t dev_name; // Initialize advertisement report for parsing adv_data.p_data = (uint8_t *)p_adv_report->data; adv_data.data_len = p_adv_report->dlen; //search for advertising names err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, &adv_data, &dev_name); if (err_code == NRF_SUCCESS) { if(memcmp(name_to_find, dev_name.p_data, dev_name.data_len )== 0) { return true; } } else { // Look for the short local name if it was not found as complete err_code = adv_report_parse(BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME, &adv_data, &dev_name); if (err_code != NRF_SUCCESS) { return false; } if(memcmp(m_target_periph_name, dev_name.p_data, dev_name.data_len )== 0) { return true; } } return false; }
/**@brief Function for handling a BeaconAdvertiser error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void beacon_advertiser_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }