peer_manager.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187
  1. /**
  2. * Copyright (c) 2015 - 2019, 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 "ble_err.h"
  43. #include "peer_manager.h"
  44. #include <string.h>
  45. #include "security_manager.h"
  46. #include "security_dispatcher.h"
  47. #include "gatt_cache_manager.h"
  48. #include "gatts_cache_manager.h"
  49. #include "peer_database.h"
  50. #include "peer_data_storage.h"
  51. #include "id_manager.h"
  52. #include "ble_conn_state.h"
  53. #include "peer_manager_internal.h"
  54. #include "nrf_sdh_ble.h"
  55. #define NRF_LOG_MODULE_NAME peer_manager
  56. #if PM_LOG_ENABLED
  57. #define NRF_LOG_LEVEL PM_LOG_LEVEL
  58. #define NRF_LOG_INFO_COLOR PM_LOG_INFO_COLOR
  59. #define NRF_LOG_DEBUG_COLOR PM_LOG_DEBUG_COLOR
  60. #else
  61. #define NRF_LOG_LEVEL 0
  62. #endif // PM_LOG_ENABLED
  63. #include "nrf_log.h"
  64. #include "nrf_log_ctrl.h"
  65. NRF_LOG_MODULE_REGISTER();
  66. #include "nrf_strerror.h"
  67. #ifndef PM_PEER_RANKS_ENABLED
  68. #define PM_PEER_RANKS_ENABLED 1
  69. #endif
  70. #define MODULE_INITIALIZED (m_module_initialized) /**< Macro indicating whether the module has been initialized properly. */
  71. static bool m_module_initialized; /**< Whether or not @ref pm_init has been called successfully. */
  72. static bool m_peer_rank_initialized; /**< Whether or not @ref rank_init has been called successfully. */
  73. static bool m_deleting_all; /**< True from when @ref pm_peers_delete is called until all peers have been deleted. */
  74. static pm_store_token_t m_peer_rank_token; /**< The store token of an ongoing peer rank update via a call to @ref pm_peer_rank_highest. If @ref PM_STORE_TOKEN_INVALID, there is no ongoing update. */
  75. static uint32_t m_current_highest_peer_rank; /**< The current highest peer rank. Used by @ref pm_peer_rank_highest. */
  76. static pm_peer_id_t m_highest_ranked_peer; /**< The peer with the highest peer rank. Used by @ref pm_peer_rank_highest. */
  77. static pm_evt_handler_t m_evt_handlers[PM_MAX_REGISTRANTS];/**< The subscribers to Peer Manager events, as registered through @ref pm_register. */
  78. static uint8_t m_n_registrants; /**< The number of event handlers registered through @ref pm_register. */
  79. /**@brief Function for sending a Peer Manager event to all subscribers.
  80. *
  81. * @param[in] p_pm_evt The event to send.
  82. */
  83. static void evt_send(pm_evt_t const * p_pm_evt)
  84. {
  85. for (int i = 0; i < m_n_registrants; i++)
  86. {
  87. m_evt_handlers[i](p_pm_evt);
  88. }
  89. }
  90. #if PM_PEER_RANKS_ENABLED == 1
  91. /**@brief Function for initializing peer rank static variables.
  92. */
  93. static void rank_vars_update(void)
  94. {
  95. ret_code_t err_code = pm_peer_ranks_get(&m_highest_ranked_peer,
  96. &m_current_highest_peer_rank,
  97. NULL,
  98. NULL);
  99. m_peer_rank_initialized = ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND));
  100. }
  101. #endif
  102. /**@brief Event handler for events from the Peer Database module.
  103. * This handler is extern in the Peer Database module.
  104. *
  105. * @param[in] p_pdb_evt The incoming Peer Database event.
  106. */
  107. void pm_pdb_evt_handler(pm_evt_t * p_pdb_evt)
  108. {
  109. bool send_evt = true;
  110. p_pdb_evt->conn_handle = im_conn_handle_get(p_pdb_evt->peer_id);
  111. switch (p_pdb_evt->evt_id)
  112. {
  113. #if PM_PEER_RANKS_ENABLED == 1
  114. case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
  115. if (p_pdb_evt->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
  116. {
  117. if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID)
  118. && (m_peer_rank_token == p_pdb_evt->params.peer_data_update_succeeded.token))
  119. {
  120. m_peer_rank_token = PM_STORE_TOKEN_INVALID;
  121. m_highest_ranked_peer = p_pdb_evt->peer_id;
  122. p_pdb_evt->params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  123. }
  124. else if ( m_peer_rank_initialized
  125. && (p_pdb_evt->peer_id == m_highest_ranked_peer)
  126. && (p_pdb_evt->params.peer_data_update_succeeded.data_id
  127. == PM_PEER_DATA_ID_PEER_RANK))
  128. {
  129. // Update peer rank variable if highest ranked peer has changed its rank.
  130. rank_vars_update();
  131. }
  132. }
  133. else if (p_pdb_evt->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_DELETE)
  134. {
  135. if ( m_peer_rank_initialized
  136. && (p_pdb_evt->peer_id == m_highest_ranked_peer)
  137. && (p_pdb_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_PEER_RANK))
  138. {
  139. // Update peer rank variable if highest ranked peer has deleted its rank.
  140. rank_vars_update();
  141. }
  142. }
  143. break;
  144. case PM_EVT_PEER_DATA_UPDATE_FAILED:
  145. if (p_pdb_evt->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
  146. {
  147. if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID)
  148. && (m_peer_rank_token == p_pdb_evt->params.peer_data_update_failed.token))
  149. {
  150. m_peer_rank_token = PM_STORE_TOKEN_INVALID;
  151. m_current_highest_peer_rank -= 1;
  152. p_pdb_evt->params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  153. }
  154. }
  155. break;
  156. #endif
  157. case PM_EVT_PEER_DELETE_SUCCEEDED:
  158. // Check that no peers marked for deletion are left.
  159. if (m_deleting_all
  160. && (pds_next_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID)
  161. && (pds_next_deleted_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID))
  162. {
  163. // pm_peers_delete() has been called and this is the last peer to be deleted.
  164. m_deleting_all = false;
  165. pm_evt_t pm_delete_all_evt;
  166. memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
  167. pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED;
  168. pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
  169. pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
  170. send_evt = false;
  171. // Forward the event to all registered Peer Manager event handlers.
  172. evt_send(p_pdb_evt); // Ensure that PEER_DELETE_SUCCEEDED arrives before PEERS_DELETE_SUCCEEDED.
  173. evt_send(&pm_delete_all_evt);
  174. }
  175. #if PM_PEER_RANKS_ENABLED == 1
  176. if (m_peer_rank_initialized && (p_pdb_evt->peer_id == m_highest_ranked_peer))
  177. {
  178. // Update peer rank variable if highest ranked peer has been deleted.
  179. rank_vars_update();
  180. }
  181. #endif
  182. break;
  183. case PM_EVT_PEER_DELETE_FAILED:
  184. if (m_deleting_all)
  185. {
  186. // pm_peers_delete() was called and has thus failed.
  187. m_deleting_all = false;
  188. pm_evt_t pm_delete_all_evt;
  189. memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
  190. pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_FAILED;
  191. pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
  192. pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
  193. pm_delete_all_evt.params.peers_delete_failed_evt.error
  194. = p_pdb_evt->params.peer_delete_failed.error;
  195. pm_delete_all_evt.params.peers_delete_failed_evt.fds_error
  196. = p_pdb_evt->params.peer_delete_failed.fds_error;
  197. send_evt = false;
  198. // Forward the event to all registered Peer Manager event handlers.
  199. evt_send(p_pdb_evt); // Ensure that PEER_DELETE_FAILED arrives before PEERS_DELETE_FAILED.
  200. evt_send(&pm_delete_all_evt);
  201. }
  202. break;
  203. default:
  204. // Do nothing.
  205. break;
  206. }
  207. if (send_evt)
  208. {
  209. // Forward the event to all registered Peer Manager event handlers.
  210. evt_send(p_pdb_evt);
  211. }
  212. }
  213. /**@brief Event handler for events from the Security Manager module.
  214. * This handler is extern in the Security Manager module.
  215. *
  216. * @param[in] p_sm_evt The incoming Security Manager event.
  217. */
  218. void pm_sm_evt_handler(pm_evt_t * p_sm_evt)
  219. {
  220. VERIFY_PARAM_NOT_NULL_VOID(p_sm_evt);
  221. // Forward the event to all registered Peer Manager event handlers.
  222. evt_send(p_sm_evt);
  223. }
  224. /**@brief Event handler for events from the GATT Cache Manager module.
  225. * This handler is extern in GATT Cache Manager.
  226. *
  227. * @param[in] p_gcm_evt The incoming GATT Cache Manager event.
  228. */
  229. void pm_gcm_evt_handler(pm_evt_t * p_gcm_evt)
  230. {
  231. // Forward the event to all registered Peer Manager event handlers.
  232. evt_send(p_gcm_evt);
  233. }
  234. /**@brief Event handler for events from the GATTS Cache Manager module.
  235. * This handler is extern in GATTS Cache Manager.
  236. *
  237. * @param[in] p_gscm_evt The incoming GATTS Cache Manager event.
  238. */
  239. void pm_gscm_evt_handler(pm_evt_t * p_gscm_evt)
  240. {
  241. // Forward the event to all registered Peer Manager event handlers.
  242. evt_send(p_gscm_evt);
  243. }
  244. /**@brief Event handler for events from the ID Manager module.
  245. * This function is registered in the ID Manager.
  246. *
  247. * @param[in] p_im_evt The incoming ID Manager event.
  248. */
  249. void pm_im_evt_handler(pm_evt_t * p_im_evt)
  250. {
  251. // Forward the event to all registered Peer Manager event handlers.
  252. evt_send(p_im_evt);
  253. }
  254. /**
  255. * @brief Function for handling BLE events.
  256. *
  257. * @param[in] p_ble_evt Event received from the BLE stack.
  258. * @param[in] p_context Context.
  259. */
  260. static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
  261. {
  262. VERIFY_MODULE_INITIALIZED_VOID();
  263. im_ble_evt_handler(p_ble_evt);
  264. sm_ble_evt_handler(p_ble_evt);
  265. gcm_ble_evt_handler(p_ble_evt);
  266. }
  267. NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, PM_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
  268. /**@brief Function for resetting the internal state of this module.
  269. */
  270. static void internal_state_reset()
  271. {
  272. m_highest_ranked_peer = PM_PEER_ID_INVALID;
  273. m_peer_rank_token = PM_STORE_TOKEN_INVALID;
  274. }
  275. ret_code_t pm_init(void)
  276. {
  277. ret_code_t err_code;
  278. err_code = pds_init();
  279. if (err_code != NRF_SUCCESS)
  280. {
  281. NRF_LOG_ERROR("%s failed because pds_init() returned %s.", __func__, nrf_strerror_get(err_code));
  282. return NRF_ERROR_INTERNAL;
  283. }
  284. err_code = pdb_init();
  285. if (err_code != NRF_SUCCESS)
  286. {
  287. NRF_LOG_ERROR("%s failed because pdb_init() returned %s.", __func__, nrf_strerror_get(err_code));
  288. return NRF_ERROR_INTERNAL;
  289. }
  290. err_code = sm_init();
  291. if (err_code != NRF_SUCCESS)
  292. {
  293. NRF_LOG_ERROR("%s failed because sm_init() returned %s.", __func__, nrf_strerror_get(err_code));
  294. return NRF_ERROR_INTERNAL;
  295. }
  296. err_code = smd_init();
  297. if (err_code != NRF_SUCCESS)
  298. {
  299. NRF_LOG_ERROR("%s failed because smd_init() returned %s.", __func__, nrf_strerror_get(err_code));
  300. return NRF_ERROR_INTERNAL;
  301. }
  302. err_code = gcm_init();
  303. if (err_code != NRF_SUCCESS)
  304. {
  305. NRF_LOG_ERROR("%s failed because gcm_init() returned %s.", __func__, nrf_strerror_get(err_code));
  306. return NRF_ERROR_INTERNAL;
  307. }
  308. err_code = gscm_init();
  309. if (err_code != NRF_SUCCESS)
  310. {
  311. NRF_LOG_ERROR("%s failed because gscm_init() returned %s.", __func__, nrf_strerror_get(err_code));
  312. return NRF_ERROR_INTERNAL;
  313. }
  314. internal_state_reset();
  315. m_peer_rank_initialized = false;
  316. m_module_initialized = true;
  317. // If PM_PEER_RANKS_ENABLED is 0, these variables are unused.
  318. UNUSED_VARIABLE(m_peer_rank_initialized);
  319. UNUSED_VARIABLE(m_peer_rank_token);
  320. UNUSED_VARIABLE(m_current_highest_peer_rank);
  321. UNUSED_VARIABLE(m_highest_ranked_peer);
  322. return NRF_SUCCESS;
  323. }
  324. ret_code_t pm_register(pm_evt_handler_t event_handler)
  325. {
  326. VERIFY_MODULE_INITIALIZED();
  327. if (m_n_registrants >= PM_MAX_REGISTRANTS)
  328. {
  329. return NRF_ERROR_NO_MEM;
  330. }
  331. m_evt_handlers[m_n_registrants] = event_handler;
  332. m_n_registrants += 1;
  333. return NRF_SUCCESS;
  334. }
  335. ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params)
  336. {
  337. VERIFY_MODULE_INITIALIZED();
  338. ret_code_t err_code;
  339. err_code = sm_sec_params_set(p_sec_params);
  340. // NRF_ERROR_INVALID_PARAM if parameters are invalid,
  341. // NRF_SUCCESS otherwise.
  342. return err_code;
  343. }
  344. ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing)
  345. {
  346. VERIFY_MODULE_INITIALIZED();
  347. ret_code_t err_code;
  348. err_code = sm_link_secure(conn_handle, force_repairing);
  349. if (err_code == NRF_ERROR_INVALID_STATE)
  350. {
  351. err_code = NRF_ERROR_BUSY;
  352. }
  353. return err_code;
  354. }
  355. void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config)
  356. {
  357. if (p_conn_sec_config != NULL)
  358. {
  359. sm_conn_sec_config_reply(conn_handle, p_conn_sec_config);
  360. }
  361. }
  362. ret_code_t pm_conn_sec_params_reply(uint16_t conn_handle,
  363. ble_gap_sec_params_t * p_sec_params,
  364. void const * p_context)
  365. {
  366. VERIFY_MODULE_INITIALIZED();
  367. return sm_sec_params_reply(conn_handle, p_sec_params, p_context);
  368. }
  369. void pm_local_database_has_changed(void)
  370. {
  371. #if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
  372. VERIFY_MODULE_INITIALIZED_VOID();
  373. gcm_local_database_has_changed();
  374. #endif
  375. }
  376. ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr)
  377. {
  378. VERIFY_MODULE_INITIALIZED();
  379. return im_id_addr_set(p_addr);
  380. }
  381. ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr)
  382. {
  383. VERIFY_MODULE_INITIALIZED();
  384. VERIFY_PARAM_NOT_NULL(p_addr);
  385. return im_id_addr_get(p_addr);
  386. }
  387. ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params)
  388. {
  389. VERIFY_MODULE_INITIALIZED();
  390. VERIFY_PARAM_NOT_NULL(p_privacy_params);
  391. return im_privacy_set(p_privacy_params);
  392. }
  393. ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params)
  394. {
  395. VERIFY_MODULE_INITIALIZED();
  396. VERIFY_PARAM_NOT_NULL(p_privacy_params);
  397. VERIFY_PARAM_NOT_NULL(p_privacy_params->p_device_irk);
  398. return im_privacy_get(p_privacy_params);
  399. }
  400. bool pm_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
  401. {
  402. VERIFY_MODULE_INITIALIZED();
  403. if ((p_addr == NULL) || (p_irk == NULL))
  404. {
  405. return false;
  406. }
  407. else
  408. {
  409. return im_address_resolve(p_addr, p_irk);
  410. }
  411. }
  412. ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers,
  413. uint32_t peer_cnt)
  414. {
  415. VERIFY_MODULE_INITIALIZED();
  416. return im_whitelist_set(p_peers, peer_cnt);
  417. }
  418. ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs,
  419. uint32_t * p_addr_cnt,
  420. ble_gap_irk_t * p_irks,
  421. uint32_t * p_irk_cnt)
  422. {
  423. VERIFY_MODULE_INITIALIZED();
  424. if (((p_addrs == NULL) && (p_irks == NULL)) ||
  425. ((p_addrs != NULL) && (p_addr_cnt == NULL)) ||
  426. ((p_irks != NULL) && (p_irk_cnt == NULL)))
  427. {
  428. // The buffers can't be both NULL, and if a buffer is provided its size must be specified.
  429. return NRF_ERROR_NULL;
  430. }
  431. return im_whitelist_get(p_addrs, p_addr_cnt, p_irks, p_irk_cnt);
  432. }
  433. ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers,
  434. uint32_t peer_cnt)
  435. {
  436. VERIFY_MODULE_INITIALIZED();
  437. return im_device_identities_list_set(p_peers, peer_cnt);
  438. }
  439. ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status)
  440. {
  441. VERIFY_MODULE_INITIALIZED();
  442. VERIFY_PARAM_NOT_NULL(p_conn_sec_status);
  443. ble_conn_state_status_t status = ble_conn_state_status(conn_handle);
  444. if (status == BLE_CONN_STATUS_INVALID)
  445. {
  446. return BLE_ERROR_INVALID_CONN_HANDLE;
  447. }
  448. p_conn_sec_status->connected = (status == BLE_CONN_STATUS_CONNECTED);
  449. p_conn_sec_status->bonded = (im_peer_id_get_by_conn_handle(conn_handle) != PM_PEER_ID_INVALID);
  450. p_conn_sec_status->encrypted = ble_conn_state_encrypted(conn_handle);
  451. p_conn_sec_status->mitm_protected = ble_conn_state_mitm_protected(conn_handle);
  452. return NRF_SUCCESS;
  453. }
  454. ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key)
  455. {
  456. VERIFY_MODULE_INITIALIZED();
  457. return sm_lesc_public_key_set(p_public_key);
  458. }
  459. ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle)
  460. {
  461. VERIFY_MODULE_INITIALIZED();
  462. VERIFY_PARAM_NOT_NULL(p_conn_handle);
  463. *p_conn_handle = im_conn_handle_get(peer_id);
  464. return NRF_SUCCESS;
  465. }
  466. ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id)
  467. {
  468. VERIFY_MODULE_INITIALIZED();
  469. VERIFY_PARAM_NOT_NULL(p_peer_id);
  470. *p_peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  471. return NRF_SUCCESS;
  472. }
  473. uint32_t pm_peer_count(void)
  474. {
  475. if (!MODULE_INITIALIZED)
  476. {
  477. return 0;
  478. }
  479. return pds_peer_count_get();
  480. }
  481. pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id)
  482. {
  483. pm_peer_id_t next_peer_id = prev_peer_id;
  484. if (!MODULE_INITIALIZED)
  485. {
  486. return PM_PEER_ID_INVALID;
  487. }
  488. do
  489. {
  490. next_peer_id = pds_next_peer_id_get(next_peer_id);
  491. } while (pds_peer_id_is_deleted(next_peer_id));
  492. return next_peer_id;
  493. }
  494. /**@brief Function for checking if the peer has a valid Identity Resolving Key.
  495. *
  496. * @param[in] p_irk Pointer to the Identity Resolving Key.
  497. */
  498. static bool peer_is_irk(ble_gap_irk_t const * const p_irk)
  499. {
  500. for (uint32_t i = 0; i < ARRAY_SIZE(p_irk->irk); i++)
  501. {
  502. if (p_irk->irk[i] != 0)
  503. {
  504. return true;
  505. }
  506. }
  507. return false;
  508. }
  509. ret_code_t pm_peer_id_list(pm_peer_id_t * p_peer_list,
  510. uint32_t * const p_list_size,
  511. pm_peer_id_t first_peer_id,
  512. pm_peer_id_list_skip_t skip_id)
  513. {
  514. VERIFY_MODULE_INITIALIZED();
  515. VERIFY_PARAM_NOT_NULL(p_list_size);
  516. VERIFY_PARAM_NOT_NULL(p_peer_list);
  517. ret_code_t err_code;
  518. uint32_t size = *p_list_size;
  519. uint32_t current_size = 0;
  520. pm_peer_data_t pm_car_data;
  521. pm_peer_data_t pm_bond_data;
  522. pm_peer_id_t current_peer_id = first_peer_id;
  523. ble_gap_addr_t const * p_gap_addr;
  524. bool skip_no_addr = skip_id & PM_PEER_ID_LIST_SKIP_NO_ID_ADDR;
  525. bool skip_no_irk = skip_id & PM_PEER_ID_LIST_SKIP_NO_IRK;
  526. bool skip_no_car = skip_id & PM_PEER_ID_LIST_SKIP_NO_CAR;
  527. //lint -save -e685
  528. if ((*p_list_size < 1) ||
  529. (skip_id > (PM_PEER_ID_LIST_SKIP_NO_ID_ADDR | PM_PEER_ID_LIST_SKIP_ALL)))
  530. {
  531. return NRF_ERROR_INVALID_PARAM;
  532. }
  533. //lint -restore
  534. *p_list_size = 0;
  535. if (current_peer_id == PM_PEER_ID_INVALID)
  536. {
  537. current_peer_id = pm_next_peer_id_get(current_peer_id);
  538. if (current_peer_id == PM_PEER_ID_INVALID)
  539. {
  540. return NRF_SUCCESS;
  541. }
  542. }
  543. memset(&pm_car_data, 0, sizeof(pm_peer_data_t));
  544. memset(&pm_bond_data, 0, sizeof(pm_peer_data_t));
  545. while (current_peer_id != PM_PEER_ID_INVALID)
  546. {
  547. bool skip = false;
  548. if (skip_no_addr || skip_no_irk)
  549. {
  550. // Get data
  551. pm_bond_data.p_bonding_data = NULL;
  552. err_code = pds_peer_data_read(current_peer_id,
  553. PM_PEER_DATA_ID_BONDING,
  554. &pm_bond_data,
  555. NULL);
  556. if (err_code == NRF_ERROR_NOT_FOUND)
  557. {
  558. skip = true;
  559. }
  560. else
  561. {
  562. VERIFY_SUCCESS(err_code);
  563. }
  564. // Check data
  565. if (skip_no_addr)
  566. {
  567. p_gap_addr = &pm_bond_data.p_bonding_data->peer_ble_id.id_addr_info;
  568. if ((p_gap_addr->addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) &&
  569. (p_gap_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC))
  570. {
  571. skip = true;
  572. }
  573. }
  574. if (skip_no_irk)
  575. {
  576. if (!peer_is_irk(&pm_bond_data.p_bonding_data->peer_ble_id.id_info))
  577. {
  578. skip = true;
  579. }
  580. }
  581. }
  582. if (skip_no_car)
  583. {
  584. // Get data
  585. pm_car_data.p_central_addr_res = NULL;
  586. err_code = pds_peer_data_read(current_peer_id,
  587. PM_PEER_DATA_ID_CENTRAL_ADDR_RES,
  588. &pm_car_data,
  589. NULL);
  590. if (err_code == NRF_ERROR_NOT_FOUND)
  591. {
  592. skip = true;
  593. }
  594. else
  595. {
  596. VERIFY_SUCCESS(err_code);
  597. }
  598. // Check data
  599. if (*pm_car_data.p_central_addr_res == 0)
  600. {
  601. skip = true;
  602. }
  603. }
  604. if (!skip)
  605. {
  606. p_peer_list[current_size++] = current_peer_id;
  607. if (current_size >= size)
  608. {
  609. break;
  610. }
  611. }
  612. current_peer_id = pm_next_peer_id_get(current_peer_id);
  613. }
  614. *p_list_size = current_size;
  615. return NRF_SUCCESS;
  616. }
  617. ret_code_t pm_peer_data_load(pm_peer_id_t peer_id,
  618. pm_peer_data_id_t data_id,
  619. void * p_data,
  620. uint16_t * p_length)
  621. {
  622. VERIFY_MODULE_INITIALIZED();
  623. VERIFY_PARAM_NOT_NULL(p_data);
  624. VERIFY_PARAM_NOT_NULL(p_length);
  625. pm_peer_data_t peer_data;
  626. memset(&peer_data, 0, sizeof(peer_data));
  627. peer_data.p_all_data = p_data;
  628. return pds_peer_data_read(peer_id, data_id, &peer_data, p_length);
  629. }
  630. ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id,
  631. pm_peer_data_bonding_t * p_data)
  632. {
  633. uint16_t length = sizeof(pm_peer_data_bonding_t);
  634. return pm_peer_data_load(peer_id,
  635. PM_PEER_DATA_ID_BONDING,
  636. p_data,
  637. &length);
  638. }
  639. ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id,
  640. ble_gatt_db_srv_t * p_data,
  641. uint16_t * p_length)
  642. {
  643. return pm_peer_data_load(peer_id,
  644. PM_PEER_DATA_ID_GATT_REMOTE,
  645. p_data,
  646. p_length);
  647. }
  648. ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id,
  649. void * p_data,
  650. uint16_t * p_length)
  651. {
  652. return pm_peer_data_load(peer_id,
  653. PM_PEER_DATA_ID_APPLICATION,
  654. p_data,
  655. p_length);
  656. }
  657. ret_code_t pm_peer_data_store(pm_peer_id_t peer_id,
  658. pm_peer_data_id_t data_id,
  659. void const * p_data,
  660. uint16_t length,
  661. pm_store_token_t * p_token)
  662. {
  663. VERIFY_MODULE_INITIALIZED();
  664. VERIFY_PARAM_NOT_NULL(p_data);
  665. if (ALIGN_NUM(4, length) != length)
  666. {
  667. return NRF_ERROR_INVALID_PARAM;
  668. }
  669. if (data_id == PM_PEER_DATA_ID_BONDING)
  670. {
  671. pm_peer_id_t dupl_peer_id;
  672. dupl_peer_id = im_find_duplicate_bonding_data((pm_peer_data_bonding_t *) p_data, peer_id);
  673. if (dupl_peer_id != PM_PEER_ID_INVALID)
  674. {
  675. return NRF_ERROR_FORBIDDEN;
  676. }
  677. }
  678. pm_peer_data_flash_t peer_data;
  679. memset(&peer_data, 0, sizeof(peer_data));
  680. peer_data.length_words = BYTES_TO_WORDS(length);
  681. peer_data.data_id = data_id;
  682. peer_data.p_all_data = p_data;
  683. return pds_peer_data_store(peer_id, &peer_data, p_token);
  684. }
  685. ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id,
  686. pm_peer_data_bonding_t const * p_data,
  687. pm_store_token_t * p_token)
  688. {
  689. return pm_peer_data_store(peer_id,
  690. PM_PEER_DATA_ID_BONDING,
  691. p_data,
  692. ALIGN_NUM(4, sizeof(pm_peer_data_bonding_t)),
  693. p_token);
  694. }
  695. ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id,
  696. ble_gatt_db_srv_t const * p_data,
  697. uint16_t length,
  698. pm_store_token_t * p_token)
  699. {
  700. return pm_peer_data_store(peer_id,
  701. PM_PEER_DATA_ID_GATT_REMOTE,
  702. p_data,
  703. length,
  704. p_token);
  705. }
  706. ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id,
  707. void const * p_data,
  708. uint16_t length,
  709. pm_store_token_t * p_token)
  710. {
  711. return pm_peer_data_store(peer_id,
  712. PM_PEER_DATA_ID_APPLICATION,
  713. p_data,
  714. length,
  715. p_token);
  716. }
  717. ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
  718. {
  719. VERIFY_MODULE_INITIALIZED();
  720. if (data_id == PM_PEER_DATA_ID_BONDING)
  721. {
  722. return NRF_ERROR_INVALID_PARAM;
  723. }
  724. return pds_peer_data_delete(peer_id, data_id);
  725. }
  726. ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id,
  727. pm_peer_data_bonding_t * p_bonding_data,
  728. pm_store_token_t * p_token)
  729. {
  730. ret_code_t err_code;
  731. pm_peer_id_t peer_id;
  732. pm_peer_data_flash_t peer_data;
  733. VERIFY_MODULE_INITIALIZED();
  734. VERIFY_PARAM_NOT_NULL(p_bonding_data);
  735. VERIFY_PARAM_NOT_NULL(p_new_peer_id);
  736. memset(&peer_data, 0, sizeof(pm_peer_data_flash_t));
  737. // Search through existing bonds to look for a duplicate.
  738. pds_peer_data_iterate_prepare();
  739. // @note This check is not thread safe since data is not copied while iterating.
  740. while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
  741. {
  742. if (im_is_duplicate_bonding_data(p_bonding_data, peer_data.p_bonding_data))
  743. {
  744. *p_new_peer_id = peer_id;
  745. return NRF_SUCCESS;
  746. }
  747. }
  748. // If no duplicate data is found, prepare to write a new bond to flash.
  749. *p_new_peer_id = pds_peer_id_allocate();
  750. if (*p_new_peer_id == PM_PEER_ID_INVALID)
  751. {
  752. return NRF_ERROR_NO_MEM;
  753. }
  754. memset(&peer_data, 0, sizeof(pm_peer_data_flash_t));
  755. peer_data.data_id = PM_PEER_DATA_ID_BONDING;
  756. peer_data.p_bonding_data = p_bonding_data;
  757. peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t));
  758. err_code = pds_peer_data_store(*p_new_peer_id, &peer_data, p_token);
  759. if (err_code != NRF_SUCCESS)
  760. {
  761. ret_code_t err_code_free = im_peer_free(*p_new_peer_id);
  762. if (err_code_free != NRF_SUCCESS)
  763. {
  764. NRF_LOG_ERROR("Fatal error during cleanup of a failed call to %s. im_peer_free() "\
  765. "returned %s. peer_id: %d",
  766. __func__,
  767. nrf_strerror_get(err_code_free),
  768. *p_new_peer_id);
  769. return NRF_ERROR_INTERNAL;
  770. }
  771. // NRF_ERROR_STORAGE_FULL, if no space in flash.
  772. // NRF_ERROR_BUSY, if flash filesystem was busy.
  773. // NRF_ERROR_INTENRAL, on internal error.
  774. return err_code;
  775. }
  776. return NRF_SUCCESS;
  777. }
  778. ret_code_t pm_peer_delete(pm_peer_id_t peer_id)
  779. {
  780. VERIFY_MODULE_INITIALIZED();
  781. return im_peer_free(peer_id);
  782. }
  783. ret_code_t pm_peers_delete(void)
  784. {
  785. VERIFY_MODULE_INITIALIZED();
  786. m_deleting_all = true;
  787. pm_peer_id_t current_peer_id = pds_next_peer_id_get(PM_PEER_ID_INVALID);
  788. if (current_peer_id == PM_PEER_ID_INVALID)
  789. {
  790. // No peers bonded.
  791. m_deleting_all = false;
  792. pm_evt_t pm_delete_all_evt;
  793. memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
  794. pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED;
  795. pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
  796. pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
  797. evt_send(&pm_delete_all_evt);
  798. }
  799. while (current_peer_id != PM_PEER_ID_INVALID)
  800. {
  801. ret_code_t err_code = pm_peer_delete(current_peer_id);
  802. if (err_code != NRF_SUCCESS)
  803. {
  804. NRF_LOG_ERROR("%s() failed because a call to pm_peer_delete() returned %s. peer_id: %d",
  805. __func__,
  806. nrf_strerror_get(err_code),
  807. current_peer_id);
  808. return NRF_ERROR_INTERNAL;
  809. }
  810. current_peer_id = pds_next_peer_id_get(current_peer_id);
  811. }
  812. return NRF_SUCCESS;
  813. }
  814. ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer,
  815. uint32_t * p_highest_rank,
  816. pm_peer_id_t * p_lowest_ranked_peer,
  817. uint32_t * p_lowest_rank)
  818. {
  819. #if PM_PEER_RANKS_ENABLED == 0
  820. return NRF_ERROR_NOT_SUPPORTED;
  821. #else
  822. VERIFY_MODULE_INITIALIZED();
  823. pm_peer_id_t peer_id = pds_next_peer_id_get(PM_PEER_ID_INVALID);
  824. uint32_t peer_rank = 0;
  825. //lint -save -e65 -e64
  826. uint16_t length = sizeof(peer_rank);
  827. pm_peer_data_t peer_data = {.p_peer_rank = &peer_rank};
  828. //lint -restore
  829. ret_code_t err_code = pds_peer_data_read(peer_id,
  830. PM_PEER_DATA_ID_PEER_RANK,
  831. &peer_data,
  832. &length);
  833. uint32_t highest_rank = 0;
  834. uint32_t lowest_rank = 0xFFFFFFFF;
  835. pm_peer_id_t highest_ranked_peer = PM_PEER_ID_INVALID;
  836. pm_peer_id_t lowest_ranked_peer = PM_PEER_ID_INVALID;
  837. if (err_code == NRF_ERROR_INVALID_PARAM)
  838. {
  839. // No peer IDs exist.
  840. return NRF_ERROR_NOT_FOUND;
  841. }
  842. while ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND))
  843. {
  844. if (err_code == NRF_SUCCESS)
  845. {
  846. if (peer_rank >= highest_rank)
  847. {
  848. highest_rank = peer_rank;
  849. highest_ranked_peer = peer_id;
  850. }
  851. if (peer_rank < lowest_rank)
  852. {
  853. lowest_rank = peer_rank;
  854. lowest_ranked_peer = peer_id;
  855. }
  856. }
  857. peer_id = pds_next_peer_id_get(peer_id);
  858. err_code = pds_peer_data_read(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data, &length);
  859. }
  860. if (peer_id == PM_PEER_ID_INVALID)
  861. {
  862. if ((highest_ranked_peer == PM_PEER_ID_INVALID) || (lowest_ranked_peer == PM_PEER_ID_INVALID))
  863. {
  864. err_code = NRF_ERROR_NOT_FOUND;
  865. }
  866. else
  867. {
  868. err_code = NRF_SUCCESS;
  869. }
  870. if (p_highest_ranked_peer != NULL)
  871. {
  872. *p_highest_ranked_peer = highest_ranked_peer;
  873. }
  874. if (p_highest_rank != NULL)
  875. {
  876. *p_highest_rank = highest_rank;
  877. }
  878. if (p_lowest_ranked_peer != NULL)
  879. {
  880. *p_lowest_ranked_peer = lowest_ranked_peer;
  881. }
  882. if (p_lowest_rank != NULL)
  883. {
  884. *p_lowest_rank = lowest_rank;
  885. }
  886. }
  887. else
  888. {
  889. NRF_LOG_ERROR("Could not retreive ranks. pdb_peer_data_load() returned %s. peer_id: %d",
  890. nrf_strerror_get(err_code),
  891. peer_id);
  892. err_code = NRF_ERROR_INTERNAL;
  893. }
  894. return err_code;
  895. #endif
  896. }
  897. #if PM_PEER_RANKS_ENABLED == 1
  898. /**@brief Function for initializing peer rank functionality.
  899. */
  900. static void rank_init(void)
  901. {
  902. rank_vars_update();
  903. }
  904. #endif
  905. ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id)
  906. {
  907. #if PM_PEER_RANKS_ENABLED == 0
  908. return NRF_ERROR_NOT_SUPPORTED;
  909. #else
  910. VERIFY_MODULE_INITIALIZED();
  911. ret_code_t err_code;
  912. //lint -save -e65 -e64
  913. pm_peer_data_flash_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(m_current_highest_peer_rank)),
  914. .data_id = PM_PEER_DATA_ID_PEER_RANK,
  915. .p_peer_rank = &m_current_highest_peer_rank};
  916. //lint -restore
  917. if (!m_peer_rank_initialized)
  918. {
  919. rank_init();
  920. }
  921. if (!m_peer_rank_initialized || (m_peer_rank_token != PM_STORE_TOKEN_INVALID))
  922. {
  923. err_code = NRF_ERROR_BUSY;
  924. }
  925. else
  926. {
  927. if ((peer_id == m_highest_ranked_peer) && (m_current_highest_peer_rank > 0))
  928. {
  929. pm_evt_t pm_evt;
  930. // The reported peer is already regarded as highest (provided it has an index at all)
  931. err_code = NRF_SUCCESS;
  932. memset(&pm_evt, 0, sizeof(pm_evt));
  933. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  934. pm_evt.conn_handle = im_conn_handle_get(peer_id);
  935. pm_evt.peer_id = peer_id;
  936. pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_PEER_RANK;
  937. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  938. pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  939. pm_evt.params.peer_data_update_succeeded.flash_changed = false;
  940. evt_send(&pm_evt);
  941. }
  942. else
  943. {
  944. if (m_current_highest_peer_rank == UINT32_MAX)
  945. {
  946. err_code = NRF_ERROR_RESOURCES;
  947. }
  948. else
  949. {
  950. m_current_highest_peer_rank += 1;
  951. err_code = pds_peer_data_store(peer_id, &peer_data, &m_peer_rank_token);
  952. if (err_code != NRF_SUCCESS)
  953. {
  954. m_peer_rank_token = PM_STORE_TOKEN_INVALID;
  955. m_current_highest_peer_rank -= 1;
  956. if ((err_code != NRF_ERROR_BUSY) &&
  957. (err_code != NRF_ERROR_STORAGE_FULL) &&
  958. (err_code != NRF_ERROR_INVALID_PARAM)) // Assume INVALID_PARAM refers to peer_id, not data_id.
  959. {
  960. NRF_LOG_ERROR("Could not update rank. pdb_raw_store() returned %s. "\
  961. "peer_id: %d",
  962. nrf_strerror_get(err_code),
  963. peer_id);
  964. err_code = NRF_ERROR_INTERNAL;
  965. }
  966. }
  967. }
  968. }
  969. }
  970. return err_code;
  971. #endif
  972. }
  973. #endif // NRF_MODULE_ENABLED(PEER_MANAGER)