static void events_send_from_err_code(uint16_t conn_handle, ret_code_t err_code) { if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) { sm_evt_t evt = { .conn_handle = conn_handle, .params = {.error_unexpected = { .error = err_code }} }; if (err_code == NRF_ERROR_TIMEOUT) { evt.evt_id = SM_EVT_ERROR_SMP_TIMEOUT; } else if (err_code == NRF_ERROR_NO_MEM) { evt.evt_id = SM_EVT_ERROR_NO_MEM; } else { evt.evt_id = SM_EVT_ERROR_UNEXPECTED; } evt_send(&evt); }
ret_code_t pm_peers_delete(void) { VERIFY_MODULE_INITIALIZED(); m_deleting_all = true; pm_peer_id_t current_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); if (current_peer_id == PM_PEER_ID_INVALID) { // No peers bonded. m_deleting_all = false; pm_evt_t pm_delete_all_evt; memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED; pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; evt_send(&pm_delete_all_evt); } while (current_peer_id != PM_PEER_ID_INVALID) { ret_code_t err_code = pm_peer_delete(current_peer_id); if (err_code != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } current_peer_id = pdb_next_peer_id_get(current_peer_id); } return NRF_SUCCESS; }
ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id) { VERIFY_MODULE_INITIALIZED(); ret_code_t err_code; //lint -save -e65 -e64 pm_peer_data_flash_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(m_current_highest_peer_rank)), .data_id = PM_PEER_DATA_ID_PEER_RANK, .p_peer_rank = &m_current_highest_peer_rank}; //lint -restore if (!m_peer_rank_initialized) { rank_init(); } if (!m_peer_rank_initialized || (m_peer_rank_token != PM_STORE_TOKEN_INVALID)) { err_code = NRF_ERROR_BUSY; } else { if ((peer_id == m_highest_ranked_peer) && (m_current_highest_peer_rank > 0)) { pm_evt_t pm_evt; // The reported peer is already regarded as highest (provided it has an index at all) err_code = NRF_SUCCESS; memset(&pm_evt, 0, sizeof(pm_evt)); pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.conn_handle = im_conn_handle_get(peer_id); pm_evt.peer_id = peer_id; pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_PEER_RANK; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; pm_evt.params.peer_data_update_succeeded.flash_changed = false; evt_send(&pm_evt); } else { m_current_highest_peer_rank += 1; err_code = pdb_raw_store(peer_id, &peer_data, &m_peer_rank_token); if (err_code != NRF_SUCCESS) { m_peer_rank_token = PM_STORE_TOKEN_INVALID; m_current_highest_peer_rank -= 1; { if ((err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_STORAGE_FULL)) err_code = NRF_ERROR_INTERNAL; } } } } return err_code; }
/**@brief Event handler for events from the Peer Database module. * This function is extern in Peer Database. * * @param[in] p_event The event that has happend with peer id and flags. */ void im_pdb_evt_handler(pdb_evt_t const * p_event) { ret_code_t ret; pm_peer_id_t peer_id; pm_peer_data_flash_t peer_data; pm_peer_data_flash_t peer_data_duplicate; NRF_PM_DEBUG_CHECK(m_module_initialized); NRF_PM_DEBUG_CHECK(p_event != NULL); if ((p_event->evt_id != PDB_EVT_WRITE_BUF_STORED) || (p_event->data_id != PM_PEER_DATA_ID_BONDING)) { return; } // If new data about peer id has been stored it is compared to other peers peer ids in // search of duplicates. ret = pdb_peer_data_ptr_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &peer_data); if (ret != NRF_SUCCESS) { // @note emdi: this shouldn't happen, since the data was just stored, right? NRF_PM_DEBUG_CHECK(false); return; } pds_peer_data_iterate_prepare(); while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data_duplicate)) { if (p_event->peer_id == peer_id) { // Skip the iteration if the bonding data retrieved is for a peer // with the same ID as the one contained in the event. continue; } if (im_is_duplicate_bonding_data(peer_data.p_bonding_data, peer_data_duplicate.p_bonding_data)) { im_evt_t im_evt; im_evt.conn_handle = im_conn_handle_get(p_event->peer_id); im_evt.evt_id = IM_EVT_DUPLICATE_ID; im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id; im_evt.params.duplicate_id.peer_id_2 = peer_id; evt_send(&im_evt); break; } } }
void im_evt_handler(im_evt_t const * p_evt) { pm_evt_t pm_evt; switch (p_evt->evt_id) { case IM_EVT_DUPLICATE_ID: // Delete the duplicate data to free space and avoid finding old data when scanning in the future pm_peer_delete(p_evt->params.duplicate_id.peer_id_2); break; case IM_EVT_BONDED_PEER_CONNECTED: ble_conn_state_user_flag_set(p_evt->conn_handle, m_pm.bonding_flag_id, true); memset(&pm_evt, 0, sizeof(pm_evt_t)); pm_evt.conn_handle = p_evt->conn_handle; pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_evt->conn_handle); pm_evt.evt_id = PM_EVT_BONDED_PEER_CONNECTED; evt_send(&pm_evt); break; } }
/**@brief Event handler for events from the peer_database module. * * @param[in] p_event The event that has happend with peer id and flags. */ static void pdb_evt_handler(pdb_evt_t const * p_event) { ret_code_t err_code; if ((p_event != NULL) && (p_event->evt_id == PDB_EVT_WRITE_BUF_STORED)) { // If new data about peer id has been stored it is compared to other peers peer ids in // search of duplicates. if (p_event->data_id == PM_PEER_DATA_ID_BONDING) { pm_peer_data_flash_t written_data; err_code = pdb_read_buf_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &written_data, NULL); if (err_code == NRF_SUCCESS) { pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); while (compared_peer_id != PM_PEER_ID_INVALID) { pm_peer_data_flash_t compared_data; err_code = pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL); if ( err_code == NRF_SUCCESS && p_event->peer_id != compared_peer_id && is_duplicate_bonding_data(written_data.p_bonding_data, compared_data.p_bonding_data) ) { im_evt_t im_evt; im_evt.conn_handle = im_conn_handle_get(p_event->peer_id); im_evt.evt_id = IM_EVT_DUPLICATE_ID; im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id; im_evt.params.duplicate_id.peer_id_2 = compared_peer_id; evt_send(&im_evt); } compared_peer_id = pdb_next_peer_id_get(compared_peer_id); } } } } }
void im_ble_evt_handler(ble_evt_t * ble_evt) { ble_gap_evt_t gap_evt; pm_peer_id_t bonded_matching_peer_id; NRF_PM_DEBUG_CHECK(m_module_initialized); if (ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED) { // Nothing to do. return; } gap_evt = ble_evt->evt.gap_evt; bonded_matching_peer_id = PM_PEER_ID_INVALID; if ( gap_evt.params.connected.peer_addr.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) { /* Search the database for bonding data matching the one that triggered the event. * Public and static addresses can be matched on address alone, while resolvable * random addresses can be resolved agains known IRKs. Non-resolvable random addresses * are never matching because they are not longterm form of identification. */ pm_peer_id_t peer_id; pm_peer_data_flash_t peer_data; pds_peer_data_iterate_prepare(); switch (gap_evt.params.connected.peer_addr.addr_type) { case BLE_GAP_ADDR_TYPE_PUBLIC: case BLE_GAP_ADDR_TYPE_RANDOM_STATIC: { while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) { if (addr_compare(&gap_evt.params.connected.peer_addr, &peer_data.p_bonding_data->peer_id.id_addr_info)) { bonded_matching_peer_id = peer_id; break; } } } break; case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE: { while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) { if (im_address_resolve(&gap_evt.params.connected.peer_addr, &peer_data.p_bonding_data->peer_id.id_info)) { bonded_matching_peer_id = peer_id; break; } } } break; default: NRF_PM_DEBUG_CHECK(false); break; } } uint8_t new_index = new_connection(gap_evt.conn_handle, &gap_evt.params.connected.peer_addr); UNUSED_VARIABLE(new_index); if (bonded_matching_peer_id != PM_PEER_ID_INVALID) { im_new_peer_id(gap_evt.conn_handle, bonded_matching_peer_id); // Send a bonded peer event im_evt_t im_evt; im_evt.conn_handle = gap_evt.conn_handle; im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED; evt_send(&im_evt); } }
__IRAM_CODE void btn_processPress(int val) { int btn; struct evt_t evt; for(btn=0;btn<NB_BUTTONS;btn++) { if(BTN_NOT_PRESSED(val,btn)) /* the btn is NOT pressed */ { nb_pressed[btn]=0; /* reset nb_pressed */ mx_press[btn] = current_repeatParam->init_delay; press_step[btn] = 0; /*if(btn==BTN_OFF) nb_off_press=0; */ /* if off btn released -> reset nb_off_press */ } else /* the btn i is pressed */ { /*if(btn==BTN_OFF) */ /* OFF btn pressed => check if we have to halt */ /*{ nb_off_press++; if(nb_off_press>MAX_OFF) { printk("[OFF button] => halt\n"); halt_device(); } }*/ if(nb_pressed[btn]==0) { #ifdef HAVE_FM_REMOTE if(!inHold) { #endif switch(press_step[btn]) { case 0: press_step[btn] = 1; nb_pressed[btn] = current_repeatParam->init_delay; break; case 1: press_step[btn] = 2; nb_pressed[btn] = current_repeatParam->second_delay; mx_press[btn] = current_repeatParam->second_delay; break; case 2: mx_press[btn] -= current_repeatParam->dec_value; if(mx_press[btn]<current_repeatParam->min_delay) mx_press[btn]=current_repeatParam->min_delay; nb_pressed[btn] = mx_press[btn]; break; default: press_step[btn] = 0; mx_press[btn] = current_repeatParam->init_delay; } #if 0 if(lcd_get_state()==0) { /* the lcd is off => turn on and discard the event */ lcd_keyPress(); break; } else lcd_launchTimer(); /* postpone the lcd timer */ halt_launchTimer(); /* postpone the poweroff timer */ #endif if(!con_screenIsVisible()) { if (val&BTMASK_F1 && btn+1==BTN_ON) con_screenSwitch(); // post the event evt.evt=btn+1; evt.evt_class=BTN_CLASS; evt.data=(void*)mx_press[btn]; evt_send(&evt); } else { switch(btn+1) { case BTN_ON: con_screenSwitch(); break; case BTN_OFF: con_clear(); break; case BTN_UP: con_screenScroll(-1); break; case BTN_DOWN: con_screenScroll(1); break; } } //printk("BTN %d pressed\n",btn); #ifdef HAVE_FM_REMOTE } else { //FM_putTmpText("** HOLD **",30); printk("** HOLD **\n"); } #endif } else nb_pressed[btn]--; } } }
/**@brief Event handler for events from the Peer Database module. * This handler is extern in the Peer Database module. * * @param[in] p_pdb_evt The incoming Peer Database event. */ void pm_pdb_evt_handler(pdb_evt_t const * p_pdb_evt) { bool send_evt = true; pm_evt_t pm_evt; memset(&pm_evt, 0, sizeof(pm_evt_t)); pm_evt.peer_id = p_pdb_evt->peer_id; pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id); switch (p_pdb_evt->evt_id) { case PDB_EVT_WRITE_BUF_STORED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; pm_evt.params.peer_data_update_succeeded.flash_changed = true; break; case PDB_EVT_RAW_STORED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_succeeded.token = p_pdb_evt->params.raw_stored_evt.store_token; pm_evt.params.peer_data_update_succeeded.flash_changed = true; if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID) && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token)) { m_peer_rank_token = PM_STORE_TOKEN_INVALID; m_highest_ranked_peer = pm_evt.peer_id; pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; } break; case PDB_EVT_RAW_STORE_FAILED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id; pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_failed.token = p_pdb_evt->params.error_raw_store_evt.store_token; pm_evt.params.peer_data_update_failed.error = p_pdb_evt->params.error_raw_store_evt.err_code; if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID) && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token)) { m_peer_rank_token = PM_STORE_TOKEN_INVALID; m_current_highest_peer_rank -= 1; pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; } break; case PDB_EVT_CLEARED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_DELETE; pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; break; case PDB_EVT_CLEAR_FAILED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id; pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_DELETE; pm_evt.params.peer_data_update_failed.error = p_pdb_evt->params.clear_failed_evt.err_code; break; case PDB_EVT_PEER_FREED: pm_evt.evt_id = PM_EVT_PEER_DELETE_SUCCEEDED; // Check that no peers marked for deletion are left. if (m_deleting_all && (pdb_next_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID) && (pdb_next_deleted_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID)) { // pm_peers_delete() has been called and this is the last peer to be deleted. m_deleting_all = false; pm_evt_t pm_delete_all_evt; memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED; pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; evt_send(&pm_delete_all_evt); } break; case PDB_EVT_PEER_FREE_FAILED: pm_evt.evt_id = PM_EVT_PEER_DELETE_FAILED; pm_evt.params.peer_delete_failed.error = p_pdb_evt->params.peer_free_failed_evt.err_code; if (m_deleting_all) { // pm_peers_delete() has been called and has thus failed. m_deleting_all = false; pm_evt_t pm_delete_all_evt; memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_FAILED; pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; pm_delete_all_evt.params.peers_delete_failed_evt.error = p_pdb_evt->params.peer_free_failed_evt.err_code; evt_send(&pm_delete_all_evt); } break; case PDB_EVT_COMPRESSED: send_evt = false; // Do nothing break; case PDB_EVT_ERROR_NO_MEM: pm_evt.evt_id = PM_EVT_STORAGE_FULL; break; case PDB_EVT_ERROR_UNEXPECTED: pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; break; default: send_evt = false; break; } if (send_evt) { evt_send(&pm_evt); } }
/**@brief Event handler for events from the GATT Cache Manager module. * This handler is extern in GATT Cache Manager. * * @param[in] p_gcm_evt The incoming GATT Cache Manager event. */ void pm_gcm_evt_handler(gcm_evt_t const * p_gcm_evt) { bool send_evt = true; pm_evt_t pm_evt; memset(&pm_evt, 0, sizeof(pm_evt_t)); pm_evt.peer_id = p_gcm_evt->peer_id; pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id); switch (p_gcm_evt->evt_id) { case GCM_EVT_LOCAL_DB_CACHE_STORED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL; break; case GCM_EVT_LOCAL_DB_CACHE_UPDATED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL; break; case GCM_EVT_LOCAL_DB_CACHE_APPLIED: pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLIED; break; case GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY: pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED; break; case GCM_EVT_REMOTE_DB_CACHE_UPDATED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_REMOTE; break; case GCM_EVT_SERVICE_CHANGED_IND_SENT: pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_SENT; break; case GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED: pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_CONFIRMED; break; case GCM_EVT_ERROR_DATA_SIZE: send_evt = false; break; case GCM_EVT_ERROR_STORAGE_FULL: pm_evt.evt_id = PM_EVT_STORAGE_FULL; break; case GCM_EVT_ERROR_UNEXPECTED: pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; pm_evt.params.error_unexpected.error = p_gcm_evt->params.error_unexpected.error; pm_evt.conn_handle = p_gcm_evt->params.error_unexpected.conn_handle; break; } if (send_evt) { evt_send(&pm_evt); } }
/**@brief Event handler for events from the Security Manager module. * This handler is extern in the Security Manager module. * * @param[in] p_sm_evt The incoming Security Manager event. */ void pm_sm_evt_handler(sm_evt_t const * p_sm_evt) { bool find_peer_id = true; bool send_evt = true; pm_evt_t pm_evt; memset(&pm_evt, 0, sizeof(pm_evt_t)); pm_evt.conn_handle = p_sm_evt->conn_handle; switch (p_sm_evt->evt_id) { case SM_EVT_SLAVE_SECURITY_REQ: find_peer_id = false; send_evt = false; break; case SM_EVT_SEC_PROCEDURE_START: { pm_evt.evt_id = PM_EVT_CONN_SEC_START; bool pairing = p_sm_evt->params.sec_procedure_start.procedure != PM_LINK_SECURED_PROCEDURE_ENCRYPTION; bool bonding = p_sm_evt->params.sec_procedure_start.procedure == PM_LINK_SECURED_PROCEDURE_BONDING; ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, pairing); ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_bonding_flag_id, bonding); break; } case SM_EVT_PAIRING_SUCCESS: pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED; pm_evt.params.conn_sec_succeeded.procedure = p_sm_evt->params.pairing_success.bonded ? PM_LINK_SECURED_PROCEDURE_BONDING : PM_LINK_SECURED_PROCEDURE_PAIRING; ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, true); ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_bonding_flag_id, p_sm_evt->params.pairing_success.bonded ); break; case SM_EVT_PAIRING_FAIL: pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; pm_evt.params.conn_sec_failed.procedure = ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id) ? PM_LINK_SECURED_PROCEDURE_BONDING : PM_LINK_SECURED_PROCEDURE_PAIRING; pm_evt.params.conn_sec_failed.error_src = p_sm_evt->params.pairing_failed.error_src; pm_evt.params.conn_sec_failed.error = p_sm_evt->params.pairing_failed.error; break; case SM_EVT_LINK_ENCRYPTION_UPDATE: if (!ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pairing_flag_id)) { pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED; pm_evt.params.conn_sec_succeeded.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; } else { find_peer_id = false; send_evt = false; } break; case SM_EVT_LINK_ENCRYPTION_FAILED: pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; pm_evt.params.conn_sec_failed.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; pm_evt.params.conn_sec_failed.error_src = p_sm_evt->params.link_encryption_failed.error_src; pm_evt.params.conn_sec_failed.error = p_sm_evt->params.link_encryption_failed.error; break; case SM_EVT_BONDING_INFO_STORED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.peer_id = p_sm_evt->params.bonding_info_stored.peer_id; pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_BONDING; pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; find_peer_id = false; break; case SM_EVT_ERROR_BONDING_INFO: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; pm_evt.peer_id = p_sm_evt->params.error_bonding_info.peer_id; pm_evt.params.peer_data_update_failed.data_id = PM_PEER_DATA_ID_BONDING; pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE; pm_evt.params.peer_data_update_failed.error = p_sm_evt->params.error_bonding_info.error; find_peer_id = false; break; case SM_EVT_ERROR_UNEXPECTED: pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; pm_evt.params.error_unexpected.error = p_sm_evt->params.error_unexpected.error; break; case SM_EVT_ERROR_NO_MEM: pm_evt.evt_id = PM_EVT_STORAGE_FULL; break; case SM_EVT_ERROR_SMP_TIMEOUT: pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; pm_evt.params.conn_sec_failed.procedure = ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id) ? PM_LINK_SECURED_PROCEDURE_BONDING : PM_LINK_SECURED_PROCEDURE_PAIRING; pm_evt.params.conn_sec_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL; pm_evt.params.conn_sec_failed.error = PM_CONN_SEC_ERROR_SMP_TIMEOUT; break; case SM_EVT_CONN_SEC_CONFIG_REQ: pm_evt.evt_id = PM_EVT_CONN_SEC_CONFIG_REQ; break; default: send_evt = false; break; } if (find_peer_id) { pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_sm_evt->conn_handle); } if (send_evt) { evt_send(&pm_evt); } }
void im_ble_evt_handler(ble_evt_t * ble_evt) { ret_code_t err_code; switch (ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: { pm_peer_id_t bonded_matching_peer_id = PM_PEER_ID_INVALID; if (ble_evt->evt.gap_evt.params.connected.irk_match == 1) { // The peer was matched using a whitelist. bonded_matching_peer_id = m_im.irk_whitelist_peer_ids[ble_evt->evt.gap_evt.params.connected.irk_match_idx]; } else if ( ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) { /* Search the database for bonding data matching the one that triggered the event. * Public and static addresses can be matched on address alone, while resolvable * random addresses can be resolved agains known IRKs. Non-resolvable random addresses * are never matching because they are not longterm form of identification. */ pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); while ( (compared_peer_id != PM_PEER_ID_INVALID) && (bonded_matching_peer_id == PM_PEER_ID_INVALID)) { pm_peer_data_flash_t compared_data; switch (ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type) { case BLE_GAP_ADDR_TYPE_PUBLIC: /* fall-through */ case BLE_GAP_ADDR_TYPE_RANDOM_STATIC: err_code = pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL); if ((err_code == NRF_SUCCESS) && addr_compare(&ble_evt->evt.gap_evt.params.connected.peer_addr, &compared_data.p_bonding_data->peer_id.id_addr_info) ) { bonded_matching_peer_id = compared_peer_id; } break; case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE: err_code = pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL); if (err_code == NRF_SUCCESS && im_address_resolve(&ble_evt->evt.gap_evt.params.connected.peer_addr, &compared_data.p_bonding_data->peer_id.id_info) ) { bonded_matching_peer_id = compared_peer_id; } break; case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE: // Should not happen. break; default: break; } compared_peer_id = pdb_next_peer_id_get(compared_peer_id); } } uint8_t new_index = new_connection(ble_evt->evt.gap_evt.conn_handle, &ble_evt->evt.gap_evt.params.connected.peer_addr); UNUSED_VARIABLE(new_index); if (bonded_matching_peer_id != PM_PEER_ID_INVALID) { im_new_peer_id(ble_evt->evt.gap_evt.conn_handle, bonded_matching_peer_id); // Send a bonded peer event im_evt_t im_evt; im_evt.conn_handle = ble_evt->evt.gap_evt.conn_handle; im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED; evt_send(&im_evt); } } } }
void pdb_evt_handler(pdb_evt_t const * p_evt) { bool send_evt = true; pm_evt_t pm_evt; memset(&pm_evt, 0, sizeof(pm_evt_t)); pm_evt.peer_id = p_evt->peer_id; pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id); switch (p_evt->evt_id) { case PDB_EVT_WRITE_BUF_STORED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id; pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; break; case PDB_EVT_RAW_STORED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id; pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; break; case PDB_EVT_RAW_STORE_FAILED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; pm_evt.params.peer_data_update_failed_evt.data_id = p_evt->data_id; pm_evt.params.peer_data_update_failed_evt.action = PM_PEER_DATA_ACTION_UPDATE; pm_evt.params.peer_data_update_failed_evt.error = NRF_ERROR_INTERNAL; break; case PDB_EVT_CLEARED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id; pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_CLEAR; break; case PDB_EVT_CLEAR_FAILED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; pm_evt.params.peer_data_update_failed_evt.data_id = p_evt->data_id; pm_evt.params.peer_data_update_failed_evt.action = PM_PEER_DATA_ACTION_CLEAR; pm_evt.params.peer_data_update_failed_evt.error = NRF_ERROR_INTERNAL; break; case PDB_EVT_COMPRESSED: send_evt = false; // Do nothing break; case PDB_EVT_ERROR_NO_MEM: pm_evt.evt_id = PM_EVT_STORAGE_FULL; break; case PDB_EVT_ERROR_UNEXPECTED: pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; break; default: /* No implementation necessary. */ break; } if (send_evt) { evt_send(&pm_evt); } }
void evt_timer_action(void) { evt_send(&evt); evt_timer.expires = tick + EVT_DELAY; /* 1s timer */ tmr_start(&evt_timer); }