peer_data_storage.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /**
  2. * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "sdk_common.h"
  41. #if NRF_MODULE_ENABLED(PEER_MANAGER)
  42. #include "peer_data_storage.h"
  43. #include <stdint.h>
  44. #include <string.h>
  45. #include "sdk_errors.h"
  46. #include "peer_manager_types.h"
  47. #include "peer_manager_internal.h"
  48. #include "peer_id.h"
  49. #include "fds.h"
  50. #define NRF_LOG_MODULE_NAME peer_manager_pds
  51. #if PM_LOG_ENABLED
  52. #define NRF_LOG_LEVEL PM_LOG_LEVEL
  53. #define NRF_LOG_INFO_COLOR PM_LOG_INFO_COLOR
  54. #define NRF_LOG_DEBUG_COLOR PM_LOG_DEBUG_COLOR
  55. #else
  56. #define NRF_LOG_LEVEL 0
  57. #endif // PM_LOG_ENABLED
  58. #include "nrf_log.h"
  59. #include "nrf_log_ctrl.h"
  60. NRF_LOG_MODULE_REGISTER();
  61. // Macro for verifying that the peer id is within a valid range.
  62. #define VERIFY_PEER_ID_IN_RANGE(id) VERIFY_FALSE((id >= PM_PEER_ID_N_AVAILABLE_IDS), \
  63. NRF_ERROR_INVALID_PARAM)
  64. // Macro for verifying that the peer data id is withing a valid range.
  65. #define VERIFY_PEER_DATA_ID_IN_RANGE(id) VERIFY_TRUE(peer_data_id_is_valid(id), \
  66. NRF_ERROR_INVALID_PARAM)
  67. // The number of registered event handlers.
  68. #define PDS_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
  69. // Peer Data Storage event handler in Peer Database.
  70. extern void pdb_pds_evt_handler(pm_evt_t *);
  71. // Peer Data Storage events' handlers.
  72. // The number of elements in this array is PDS_EVENT_HANDLERS_CNT.
  73. static pm_evt_handler_internal_t const m_evt_handlers[] =
  74. {
  75. pdb_pds_evt_handler,
  76. };
  77. static bool m_module_initialized = false;
  78. static volatile bool m_peer_delete_deferred = false;
  79. // A token used for Flash Data Storage searches.
  80. static fds_find_token_t m_fds_ftok;
  81. // Function for dispatching events to all registered event handlers.
  82. static void pds_evt_send(pm_evt_t * p_event)
  83. {
  84. p_event->conn_handle = BLE_CONN_HANDLE_INVALID;
  85. for (uint32_t i = 0; i < PDS_EVENT_HANDLERS_CNT; i++)
  86. {
  87. m_evt_handlers[i](p_event);
  88. }
  89. }
  90. // Function to convert peer IDs to file IDs.
  91. static uint16_t peer_id_to_file_id(pm_peer_id_t peer_id)
  92. {
  93. return (uint16_t)(peer_id + PEER_ID_TO_FILE_ID);
  94. }
  95. // Function to convert peer data id to type id.
  96. static pm_peer_id_t file_id_to_peer_id(uint16_t file_id)
  97. {
  98. return (pm_peer_id_t)(file_id + FILE_ID_TO_PEER_ID);
  99. }
  100. // Function to convert peer data IDs to record keys.
  101. static uint16_t peer_data_id_to_record_key(pm_peer_data_id_t peer_data_id)
  102. {
  103. return (uint16_t)(peer_data_id + DATA_ID_TO_RECORD_KEY);
  104. }
  105. // Function to convert record keys to peer data IDs.
  106. static pm_peer_data_id_t record_key_to_peer_data_id(uint16_t record_key)
  107. {
  108. return (pm_peer_data_id_t)(record_key + RECORD_KEY_TO_DATA_ID);
  109. }
  110. // Function for checking whether a file ID is relevant for the Peer Manager.
  111. static bool file_id_within_pm_range(uint16_t file_id)
  112. {
  113. return ((PDS_FIRST_RESERVED_FILE_ID <= file_id)
  114. && (file_id <= PDS_LAST_RESERVED_FILE_ID));
  115. }
  116. // Function for checking whether a record key is relevant for the Peer Manager.
  117. static bool record_key_within_pm_range(uint16_t record_key)
  118. {
  119. return ((PDS_FIRST_RESERVED_RECORD_KEY <= record_key)
  120. && (record_key <= PDS_LAST_RESERVED_RECORD_KEY));
  121. }
  122. static bool peer_data_id_is_valid(pm_peer_data_id_t data_id)
  123. {
  124. return ((data_id == PM_PEER_DATA_ID_BONDING) ||
  125. (data_id == PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING) ||
  126. (data_id == PM_PEER_DATA_ID_GATT_LOCAL) ||
  127. (data_id == PM_PEER_DATA_ID_GATT_REMOTE) ||
  128. (data_id == PM_PEER_DATA_ID_PEER_RANK) ||
  129. (data_id == PM_PEER_DATA_ID_CENTRAL_ADDR_RES) ||
  130. (data_id == PM_PEER_DATA_ID_APPLICATION));
  131. }
  132. /**@brief Function for sending a PM_EVT_ERROR_UNEXPECTED event.
  133. *
  134. * @param[in] peer_id The peer the event pertains to.
  135. * @param[in] err_code The unexpected error that occurred.
  136. */
  137. static void send_unexpected_error(pm_peer_id_t peer_id, ret_code_t err_code)
  138. {
  139. pm_evt_t error_evt =
  140. {
  141. .evt_id = PM_EVT_ERROR_UNEXPECTED,
  142. .peer_id = peer_id,
  143. .params =
  144. {
  145. .error_unexpected =
  146. {
  147. .error = err_code,
  148. }
  149. }
  150. };
  151. pds_evt_send(&error_evt);
  152. }
  153. // Function for deleting all data beloning to a peer.
  154. // These operations will be sent to FDS one at a time.
  155. static void peer_data_delete_process()
  156. {
  157. ret_code_t ret;
  158. pm_peer_id_t peer_id;
  159. uint16_t file_id;
  160. fds_record_desc_t desc;
  161. fds_find_token_t ftok;
  162. m_peer_delete_deferred = false;
  163. memset(&ftok, 0x00, sizeof(fds_find_token_t));
  164. peer_id = peer_id_get_next_deleted(PM_PEER_ID_INVALID);
  165. while ( (peer_id != PM_PEER_ID_INVALID)
  166. && (fds_record_find_in_file(peer_id_to_file_id(peer_id), &desc, &ftok)
  167. == FDS_ERR_NOT_FOUND))
  168. {
  169. peer_id_free(peer_id);
  170. peer_id = peer_id_get_next_deleted(peer_id);
  171. }
  172. if (peer_id != PM_PEER_ID_INVALID)
  173. {
  174. file_id = peer_id_to_file_id(peer_id);
  175. ret = fds_file_delete(file_id);
  176. if (ret == FDS_ERR_NO_SPACE_IN_QUEUES)
  177. {
  178. m_peer_delete_deferred = true;
  179. }
  180. else if (ret != NRF_SUCCESS)
  181. {
  182. NRF_LOG_ERROR("Could not delete peer data. fds_file_delete() returned 0x%x for peer_id: %d",
  183. ret,
  184. peer_id);
  185. send_unexpected_error(peer_id, ret);
  186. }
  187. }
  188. }
  189. static ret_code_t peer_data_find(pm_peer_id_t peer_id,
  190. pm_peer_data_id_t data_id,
  191. fds_record_desc_t * const p_desc)
  192. {
  193. ret_code_t ret;
  194. fds_find_token_t ftok;
  195. NRF_PM_DEBUG_CHECK(peer_id < PM_PEER_ID_N_AVAILABLE_IDS);
  196. NRF_PM_DEBUG_CHECK(peer_data_id_is_valid(data_id));
  197. NRF_PM_DEBUG_CHECK(p_desc != NULL);
  198. memset(&ftok, 0x00, sizeof(fds_find_token_t));
  199. uint16_t file_id = peer_id_to_file_id(peer_id);
  200. uint16_t record_key = peer_data_id_to_record_key(data_id);
  201. ret = fds_record_find(file_id, record_key, p_desc, &ftok);
  202. if (ret != NRF_SUCCESS)
  203. {
  204. return NRF_ERROR_NOT_FOUND;
  205. }
  206. return NRF_SUCCESS;
  207. }
  208. static void peer_ids_load()
  209. {
  210. fds_record_desc_t record_desc;
  211. fds_flash_record_t record;
  212. fds_find_token_t ftok;
  213. memset(&ftok, 0x00, sizeof(fds_find_token_t));
  214. uint16_t const record_key = peer_data_id_to_record_key(PM_PEER_DATA_ID_BONDING);
  215. while (fds_record_find_by_key(record_key, &record_desc, &ftok) == NRF_SUCCESS)
  216. {
  217. pm_peer_id_t peer_id;
  218. // It is safe to ignore the return value since the descriptor was
  219. // just obtained and also 'record' is different from NULL.
  220. (void)fds_record_open(&record_desc, &record);
  221. peer_id = file_id_to_peer_id(record.p_header->file_id);
  222. (void)fds_record_close(&record_desc);
  223. (void)peer_id_allocate(peer_id);
  224. }
  225. }
  226. static void fds_evt_handler(fds_evt_t const * const p_fds_evt)
  227. {
  228. pm_evt_t pds_evt =
  229. {
  230. .peer_id = file_id_to_peer_id(p_fds_evt->write.file_id)
  231. };
  232. switch (p_fds_evt->id)
  233. {
  234. case FDS_EVT_WRITE:
  235. case FDS_EVT_UPDATE:
  236. case FDS_EVT_DEL_RECORD:
  237. if ( file_id_within_pm_range(p_fds_evt->write.file_id)
  238. || record_key_within_pm_range(p_fds_evt->write.record_key))
  239. {
  240. pds_evt.params.peer_data_update_succeeded.data_id
  241. = record_key_to_peer_data_id(p_fds_evt->write.record_key);
  242. pds_evt.params.peer_data_update_succeeded.action
  243. = (p_fds_evt->id == FDS_EVT_DEL_RECORD) ? PM_PEER_DATA_OP_DELETE
  244. : PM_PEER_DATA_OP_UPDATE;
  245. pds_evt.params.peer_data_update_succeeded.token = p_fds_evt->write.record_id;
  246. if (p_fds_evt->result == NRF_SUCCESS)
  247. {
  248. pds_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  249. pds_evt.params.peer_data_update_succeeded.flash_changed = true;
  250. }
  251. else
  252. {
  253. pds_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
  254. pds_evt.params.peer_data_update_failed.error = p_fds_evt->result;
  255. }
  256. pds_evt_send(&pds_evt);
  257. }
  258. break;
  259. case FDS_EVT_DEL_FILE:
  260. if ( file_id_within_pm_range(p_fds_evt->del.file_id)
  261. && (p_fds_evt->del.record_key == FDS_RECORD_KEY_DIRTY))
  262. {
  263. if (p_fds_evt->result == NRF_SUCCESS)
  264. {
  265. pds_evt.evt_id = PM_EVT_PEER_DELETE_SUCCEEDED;
  266. peer_id_free(pds_evt.peer_id);
  267. }
  268. else
  269. {
  270. pds_evt.evt_id = PM_EVT_PEER_DELETE_FAILED;
  271. pds_evt.params.peer_delete_failed.error = p_fds_evt->result;
  272. }
  273. m_peer_delete_deferred = true; // Trigger remaining deletes.
  274. pds_evt_send(&pds_evt);
  275. }
  276. break;
  277. case FDS_EVT_GC:
  278. if (p_fds_evt->result == NRF_SUCCESS)
  279. {
  280. pds_evt.evt_id = PM_EVT_FLASH_GARBAGE_COLLECTED;
  281. }
  282. else
  283. {
  284. pds_evt.evt_id = PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED;
  285. pds_evt.params.garbage_collection_failed.error = p_fds_evt->result;
  286. }
  287. pds_evt.peer_id = PM_PEER_ID_INVALID;
  288. pds_evt_send(&pds_evt);
  289. break;
  290. default:
  291. // No action.
  292. break;
  293. }
  294. if (m_peer_delete_deferred)
  295. {
  296. peer_data_delete_process();
  297. }
  298. }
  299. ret_code_t pds_init()
  300. {
  301. ret_code_t ret;
  302. // Check for re-initialization if debugging.
  303. NRF_PM_DEBUG_CHECK(!m_module_initialized);
  304. ret = fds_register(fds_evt_handler);
  305. if (ret != NRF_SUCCESS)
  306. {
  307. NRF_LOG_ERROR("Could not initialize flash storage. fds_register() returned 0x%x.", ret);
  308. return NRF_ERROR_INTERNAL;
  309. }
  310. ret = fds_init();
  311. if (ret != NRF_SUCCESS)
  312. {
  313. NRF_LOG_ERROR("Could not initialize flash storage. fds_init() returned 0x%x.", ret);
  314. return NRF_ERROR_STORAGE_FULL;
  315. }
  316. peer_id_init();
  317. peer_ids_load();
  318. m_module_initialized = true;
  319. return NRF_SUCCESS;
  320. }
  321. ret_code_t pds_peer_data_read(pm_peer_id_t peer_id,
  322. pm_peer_data_id_t data_id,
  323. pm_peer_data_t * const p_data,
  324. uint32_t const * const p_buf_len)
  325. {
  326. ret_code_t ret;
  327. fds_record_desc_t rec_desc;
  328. fds_flash_record_t rec_flash;
  329. NRF_PM_DEBUG_CHECK(m_module_initialized);
  330. NRF_PM_DEBUG_CHECK(p_data != NULL);
  331. VERIFY_PEER_ID_IN_RANGE(peer_id);
  332. VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
  333. ret = peer_data_find(peer_id, data_id, &rec_desc);
  334. if (ret != NRF_SUCCESS)
  335. {
  336. return NRF_ERROR_NOT_FOUND;
  337. }
  338. // Shouldn't fail, unless the record was deleted in the meanwhile or the CRC check has failed.
  339. ret = fds_record_open(&rec_desc, &rec_flash);
  340. if (ret != NRF_SUCCESS)
  341. {
  342. return NRF_ERROR_NOT_FOUND;
  343. }
  344. p_data->data_id = data_id;
  345. p_data->length_words = rec_flash.p_header->length_words;
  346. // If p_buf_len is NULL, provide a pointer to data in flash, otherwise,
  347. // check that the buffer is large enough and copy the data in flash into the buffer.
  348. if (p_buf_len == NULL)
  349. {
  350. // The cast is necessary because if no buffer is provided, we just copy the pointer,
  351. // but in that case it should be considered a pointer to const data by the caller,
  352. // since it is a pointer to data in flash.
  353. p_data->p_all_data = (void*)rec_flash.p_data;
  354. }
  355. else
  356. {
  357. uint32_t const data_len_bytes = (p_data->length_words * sizeof(uint32_t));
  358. uint32_t const copy_len_bytes = MIN((*p_buf_len), (p_data->length_words * sizeof(uint32_t)));
  359. memcpy(p_data->p_all_data, rec_flash.p_data, copy_len_bytes);
  360. if (copy_len_bytes < data_len_bytes)
  361. {
  362. return NRF_ERROR_DATA_SIZE;
  363. }
  364. }
  365. // Shouldn't fail unless the record was already closed, in which case it can be ignored.
  366. (void)fds_record_close(&rec_desc);
  367. return NRF_SUCCESS;
  368. }
  369. void pds_peer_data_iterate_prepare(void)
  370. {
  371. memset(&m_fds_ftok, 0x00, sizeof(fds_find_token_t));
  372. }
  373. bool pds_peer_data_iterate(pm_peer_data_id_t data_id,
  374. pm_peer_id_t * const p_peer_id,
  375. pm_peer_data_flash_t * const p_data)
  376. {
  377. ret_code_t ret;
  378. uint16_t rec_key;
  379. fds_record_desc_t rec_desc;
  380. fds_flash_record_t rec_flash;
  381. NRF_PM_DEBUG_CHECK(m_module_initialized);
  382. NRF_PM_DEBUG_CHECK(p_peer_id != NULL);
  383. NRF_PM_DEBUG_CHECK(p_data != NULL);
  384. VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
  385. rec_key = peer_data_id_to_record_key(data_id);
  386. if (fds_record_find_by_key(rec_key, &rec_desc, &m_fds_ftok) != NRF_SUCCESS)
  387. {
  388. return false;
  389. }
  390. ret = fds_record_open(&rec_desc, &rec_flash);
  391. if (ret != NRF_SUCCESS)
  392. {
  393. // It can only happen if the record was deleted after the call to fds_record_find_by_key(),
  394. // before we could open it, or if CRC support was enabled in Flash Data Storage at compile
  395. // time and the CRC check failed.
  396. return false;
  397. }
  398. p_data->data_id = data_id;
  399. p_data->length_words = rec_flash.p_header->length_words;
  400. p_data->p_all_data = rec_flash.p_data;
  401. *p_peer_id = file_id_to_peer_id(rec_flash.p_header->file_id);
  402. (void)fds_record_close(&rec_desc);
  403. return true;
  404. }
  405. ret_code_t pds_peer_data_store(pm_peer_id_t peer_id,
  406. pm_peer_data_const_t const * p_peer_data,
  407. pm_store_token_t * p_store_token)
  408. {
  409. ret_code_t ret;
  410. fds_record_t rec;
  411. fds_record_desc_t rec_desc;
  412. NRF_PM_DEBUG_CHECK(m_module_initialized);
  413. NRF_PM_DEBUG_CHECK(p_peer_data != NULL);
  414. VERIFY_PEER_ID_IN_RANGE(peer_id);
  415. VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id);
  416. // Prepare the record to be stored in flash.
  417. rec.file_id = peer_id_to_file_id(peer_id);
  418. rec.key = peer_data_id_to_record_key(p_peer_data->data_id);
  419. rec.data.p_data = (void*)p_peer_data->p_all_data;
  420. rec.data.length_words = p_peer_data->length_words;
  421. ret = peer_data_find(peer_id, p_peer_data->data_id, &rec_desc);
  422. if (ret == NRF_ERROR_NOT_FOUND)
  423. {
  424. ret = fds_record_write(&rec_desc, &rec);
  425. }
  426. else // NRF_SUCCESS
  427. {
  428. // Update existing record.
  429. ret = fds_record_update(&rec_desc, &rec);
  430. }
  431. switch (ret)
  432. {
  433. case NRF_SUCCESS:
  434. if (p_store_token != NULL)
  435. {
  436. // Update the store token.
  437. (void)fds_record_id_from_desc(&rec_desc, (uint32_t*)p_store_token);
  438. }
  439. return NRF_SUCCESS;
  440. case FDS_ERR_BUSY:
  441. case FDS_ERR_NO_SPACE_IN_QUEUES:
  442. return NRF_ERROR_BUSY;
  443. case FDS_ERR_NO_SPACE_IN_FLASH:
  444. return NRF_ERROR_STORAGE_FULL;
  445. case FDS_ERR_UNALIGNED_ADDR:
  446. return NRF_ERROR_INVALID_ADDR;
  447. default:
  448. NRF_LOG_ERROR("Could not write data to flash. fds_record_{write|update}() returned 0x%x. "\
  449. "peer_id: %d",
  450. ret,
  451. peer_id);
  452. return NRF_ERROR_INTERNAL;
  453. }
  454. }
  455. ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
  456. {
  457. ret_code_t ret;
  458. fds_record_desc_t record_desc;
  459. NRF_PM_DEBUG_CHECK(m_module_initialized);
  460. VERIFY_PEER_ID_IN_RANGE(peer_id);
  461. VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
  462. ret = peer_data_find(peer_id, data_id, &record_desc);
  463. if (ret != NRF_SUCCESS)
  464. {
  465. return NRF_ERROR_NOT_FOUND;
  466. }
  467. ret = fds_record_delete(&record_desc);
  468. switch (ret)
  469. {
  470. case NRF_SUCCESS:
  471. return NRF_SUCCESS;
  472. case FDS_ERR_NO_SPACE_IN_QUEUES:
  473. return NRF_ERROR_BUSY;
  474. default:
  475. NRF_LOG_ERROR("Could not delete peer. fds_record_delete() returned 0x%x. peer_id: %d, "\
  476. "data_id: %d.",
  477. ret,
  478. peer_id,
  479. data_id);
  480. return NRF_ERROR_INTERNAL;
  481. }
  482. }
  483. pm_peer_id_t pds_peer_id_allocate(void)
  484. {
  485. NRF_PM_DEBUG_CHECK(m_module_initialized);
  486. return peer_id_allocate(PM_PEER_ID_INVALID);
  487. }
  488. ret_code_t pds_peer_id_free(pm_peer_id_t peer_id)
  489. {
  490. NRF_PM_DEBUG_CHECK(m_module_initialized);
  491. VERIFY_PEER_ID_IN_RANGE(peer_id);
  492. (void)peer_id_delete(peer_id);
  493. peer_data_delete_process();
  494. return NRF_SUCCESS;
  495. }
  496. bool pds_peer_id_is_allocated(pm_peer_id_t peer_id)
  497. {
  498. NRF_PM_DEBUG_CHECK(m_module_initialized);
  499. return peer_id_is_allocated(peer_id);
  500. }
  501. bool pds_peer_id_is_deleted(pm_peer_id_t peer_id)
  502. {
  503. NRF_PM_DEBUG_CHECK(m_module_initialized);
  504. return peer_id_is_deleted(peer_id);
  505. }
  506. pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id)
  507. {
  508. NRF_PM_DEBUG_CHECK(m_module_initialized);
  509. return peer_id_get_next_used(prev_peer_id);
  510. }
  511. pm_peer_id_t pds_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id)
  512. {
  513. NRF_PM_DEBUG_CHECK(m_module_initialized);
  514. return peer_id_get_next_deleted(prev_peer_id);
  515. }
  516. uint32_t pds_peer_count_get(void)
  517. {
  518. NRF_PM_DEBUG_CHECK(m_module_initialized);
  519. return peer_id_n_ids();
  520. }
  521. #endif // NRF_MODULE_ENABLED(PEER_MANAGER)