ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id, pm_peer_data_bonding_t * p_bonding_data, pm_store_token_t * p_token) { ret_code_t err_code; pm_peer_id_t peer_id; pm_peer_data_flash_t peer_data; VERIFY_MODULE_INITIALIZED(); VERIFY_PARAM_NOT_NULL(p_bonding_data); VERIFY_PARAM_NOT_NULL(p_new_peer_id); memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); // Search through existing bonds to look for a duplicate. pds_peer_data_iterate_prepare(); // @note emdi: should maybe use a critical section, since data is not copied while iterating. while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) { if (im_is_duplicate_bonding_data(p_bonding_data, peer_data.p_bonding_data)) { *p_new_peer_id = peer_id; return NRF_SUCCESS; } } // If no duplicate data is found, prepare to write a new bond to flash. *p_new_peer_id = pdb_peer_allocate(); if (*p_new_peer_id == PM_PEER_ID_INVALID) { return NRF_ERROR_NO_MEM; } memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); peer_data.data_id = PM_PEER_DATA_ID_BONDING; peer_data.p_bonding_data = p_bonding_data; peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t)); err_code = pdb_raw_store(*p_new_peer_id, &peer_data, p_token); if (err_code != NRF_SUCCESS) { if (im_peer_free(*p_new_peer_id) != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } // NRF_ERROR_STORAGE_FULL, if no space in flash. // NRF_ERROR_BUSY, if flash filesystem was busy. // NRF_ERROR_INTENRAL, on internal error. return err_code; } return NRF_SUCCESS; }
/**@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; } } }