ret_code_t im_whitelist_create(pm_peer_id_t * p_peer_ids, uint8_t n_peer_ids, ble_gap_whitelist_t * p_whitelist) { VERIFY_MODULE_INITIALIZED(); VERIFY_PARAM_NOT_NULL(p_whitelist); ret_code_t err_code; p_whitelist->addr_count = 0; p_whitelist->irk_count = 0; m_im.n_irk_whitelist_peer_ids = 0; for (uint32_t peer_index = 0; peer_index < n_peer_ids; peer_index++) { uint16_t conn_handle = im_conn_handle_get(p_peer_ids[peer_index]); if (ble_conn_state_status(conn_handle) != BLE_CONN_STATUS_CONNECTED) { pm_peer_data_flash_t peer_data; err_code = pdb_read_buf_get(p_peer_ids[peer_index], PM_PEER_DATA_ID_BONDING, &peer_data, NULL); if (err_code == NRF_ERROR_INVALID_PARAM || err_code == NRF_ERROR_NOT_FOUND) { return NRF_ERROR_INVALID_PARAM; } if (p_whitelist->pp_addrs != NULL && peer_data.p_bonding_data->peer_id.id_addr_info.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE && peer_data.p_bonding_data->peer_id.id_addr_info.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE ) { memcpy(m_im.whitelist_addrs[peer_index].addr, peer_data.p_bonding_data->peer_id.id_addr_info.addr, BLE_GAP_ADDR_LEN ); m_im.whitelist_addrs[peer_index].addr_type = peer_data.p_bonding_data->peer_id.id_addr_info.addr_type; p_whitelist->pp_addrs[peer_index] = &m_im.whitelist_addrs[peer_index]; p_whitelist->addr_count++; } if (p_whitelist->pp_irks != NULL && is_valid_irk(&(peer_data.p_bonding_data->peer_id.id_info)) ) { memcpy(m_im.whitelist_irks[peer_index].irk, peer_data.p_bonding_data->peer_id.id_info.irk, BLE_GAP_SEC_KEY_LEN ); p_whitelist->pp_irks[peer_index] = &m_im.whitelist_irks[peer_index]; p_whitelist->irk_count++; m_im.irk_whitelist_peer_ids[peer_index] = p_peer_ids[peer_index]; m_im.n_irk_whitelist_peer_ids++; } } } return NRF_SUCCESS; }
/**@brief Function to compare two sets of bonding data to check if they belong to the same device. * @note Invalid irks will never match even though they are identical. * * @param[in] p_bonding_data1 First bonding data for comparison * @param[in] p_bonding_data2 Second bonding data for comparison * * @return True if the input matches, false if it does not. */ bool is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, pm_peer_data_bonding_t const * p_bonding_data2) { bool valid_irk = is_valid_irk(&p_bonding_data1->peer_id.id_info); bool duplicate_irk = valid_irk && (memcmp(p_bonding_data1->peer_id.id_info.irk, p_bonding_data2->peer_id.id_info.irk, BLE_GAP_SEC_KEY_LEN) == 0 ); bool duplicate_addr = addr_compare(&p_bonding_data1->peer_id.id_addr_info, &p_bonding_data2->peer_id.id_addr_info ); return duplicate_irk || duplicate_addr; }
ret_code_t im_whitelist_custom(ble_gap_whitelist_t const * p_whitelist) { ret_code_t err_code; pm_peer_id_t new_irk_whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; uint32_t n_new_irk_whitelist_peer_ids = 0; VERIFY_PARAM_NOT_NULL(p_whitelist); for (uint32_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) { new_irk_whitelist_peer_ids[i] = PM_PEER_ID_INVALID; } 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) { for (uint32_t i = 0; i < p_whitelist->irk_count; i++) { bool valid_irk = is_valid_irk(&compared_data.p_bonding_data->peer_id.id_info); bool duplicate_irk = valid_irk && (memcmp(p_whitelist->pp_irks[i]->irk, compared_data.p_bonding_data->peer_id.id_info.irk, BLE_GAP_SEC_KEY_LEN) == 0 ); if (duplicate_irk) { new_irk_whitelist_peer_ids[i] = compared_peer_id; n_new_irk_whitelist_peer_ids++; } } } compared_peer_id = pdb_next_peer_id_get(compared_peer_id); } if (n_new_irk_whitelist_peer_ids != p_whitelist->irk_count) { return NRF_ERROR_NOT_FOUND; } else { for (uint32_t i = 0; i < n_new_irk_whitelist_peer_ids; i++) { m_im.irk_whitelist_peer_ids[i] = new_irk_whitelist_peer_ids[i]; } m_im.n_irk_whitelist_peer_ids = n_new_irk_whitelist_peer_ids; return NRF_SUCCESS; } }
/**@brief Function to compare two sets of bonding data to check if they belong to the same device. * @note Invalid irks will never match even though they are identical. * * @param[in] p_bonding_data1 First bonding data for comparison * @param[in] p_bonding_data2 Second bonding data for comparison * * @return True if the input matches, false if it does not. */ bool im_is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, pm_peer_data_bonding_t const * p_bonding_data2) { NRF_PM_DEBUG_CHECK(p_bonding_data1 != NULL); NRF_PM_DEBUG_CHECK(p_bonding_data2 != NULL); if (!is_valid_irk(&p_bonding_data1->peer_id.id_info)) { return false; } bool duplicate_irk = (memcmp(p_bonding_data1->peer_id.id_info.irk, p_bonding_data2->peer_id.id_info.irk, BLE_GAP_SEC_KEY_LEN) == 0); bool duplicate_addr = addr_compare(&p_bonding_data1->peer_id.id_addr_info, &p_bonding_data2->peer_id.id_addr_info); return duplicate_irk || duplicate_addr; }