peer_manager.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  1. /**
  2. * Copyright (c) 2015 - 2018, 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 ID Manager module.
  235. * This function is registered in the ID Manager.
  236. *
  237. * @param[in] p_im_evt The incoming ID Manager event.
  238. */
  239. void pm_im_evt_handler(pm_evt_t * p_im_evt)
  240. {
  241. // Forward the event to all registered Peer Manager event handlers.
  242. evt_send(p_im_evt);
  243. }
  244. /**
  245. * @brief Function for handling BLE events.
  246. *
  247. * @param[in] p_ble_evt Event received from the BLE stack.
  248. * @param[in] p_context Context.
  249. */
  250. static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
  251. {
  252. VERIFY_MODULE_INITIALIZED_VOID();
  253. im_ble_evt_handler(p_ble_evt);
  254. sm_ble_evt_handler(p_ble_evt);
  255. gcm_ble_evt_handler(p_ble_evt);
  256. }
  257. NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, PM_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
  258. /**@brief Function for resetting the internal state of this module.
  259. */
  260. static void internal_state_reset()
  261. {
  262. m_highest_ranked_peer = PM_PEER_ID_INVALID;
  263. m_peer_rank_token = PM_STORE_TOKEN_INVALID;
  264. }
  265. ret_code_t pm_init(void)
  266. {
  267. ret_code_t err_code;
  268. err_code = pds_init();
  269. if (err_code != NRF_SUCCESS)
  270. {
  271. NRF_LOG_ERROR("%s failed because pds_init() returned %s.", __func__, nrf_strerror_get(err_code));
  272. return NRF_ERROR_INTERNAL;
  273. }
  274. err_code = pdb_init();
  275. if (err_code != NRF_SUCCESS)
  276. {
  277. NRF_LOG_ERROR("%s failed because pdb_init() returned %s.", __func__, nrf_strerror_get(err_code));
  278. return NRF_ERROR_INTERNAL;
  279. }
  280. err_code = sm_init();
  281. if (err_code != NRF_SUCCESS)
  282. {
  283. NRF_LOG_ERROR("%s failed because sm_init() returned %s.", __func__, nrf_strerror_get(err_code));
  284. return NRF_ERROR_INTERNAL;
  285. }
  286. err_code = smd_init();
  287. if (err_code != NRF_SUCCESS)
  288. {
  289. NRF_LOG_ERROR("%s failed because smd_init() returned %s.", __func__, nrf_strerror_get(err_code));
  290. return NRF_ERROR_INTERNAL;
  291. }
  292. err_code = gcm_init();
  293. if (err_code != NRF_SUCCESS)
  294. {
  295. NRF_LOG_ERROR("%s failed because gcm_init() returned %s.", __func__, nrf_strerror_get(err_code));
  296. return NRF_ERROR_INTERNAL;
  297. }
  298. err_code = gscm_init();
  299. if (err_code != NRF_SUCCESS)
  300. {
  301. NRF_LOG_ERROR("%s failed because gscm_init() returned %s.", __func__, nrf_strerror_get(err_code));
  302. return NRF_ERROR_INTERNAL;
  303. }
  304. internal_state_reset();
  305. m_peer_rank_initialized = false;
  306. m_module_initialized = true;
  307. // If PM_PEER_RANKS_ENABLED is 0, these variables are unused.
  308. UNUSED_VARIABLE(m_peer_rank_initialized);
  309. UNUSED_VARIABLE(m_peer_rank_token);
  310. UNUSED_VARIABLE(m_current_highest_peer_rank);
  311. UNUSED_VARIABLE(m_highest_ranked_peer);
  312. return NRF_SUCCESS;
  313. }
  314. ret_code_t pm_register(pm_evt_handler_t event_handler)
  315. {
  316. VERIFY_MODULE_INITIALIZED();
  317. if (m_n_registrants >= PM_MAX_REGISTRANTS)
  318. {
  319. return NRF_ERROR_NO_MEM;
  320. }
  321. m_evt_handlers[m_n_registrants] = event_handler;
  322. m_n_registrants += 1;
  323. return NRF_SUCCESS;
  324. }
  325. ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params)
  326. {
  327. VERIFY_MODULE_INITIALIZED();
  328. ret_code_t err_code;
  329. err_code = sm_sec_params_set(p_sec_params);
  330. // NRF_ERROR_INVALID_PARAM if parameters are invalid,
  331. // NRF_SUCCESS otherwise.
  332. return err_code;
  333. }
  334. ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing)
  335. {
  336. VERIFY_MODULE_INITIALIZED();
  337. ret_code_t err_code;
  338. err_code = sm_link_secure(conn_handle, force_repairing);
  339. if (err_code == NRF_ERROR_INVALID_STATE)
  340. {
  341. err_code = NRF_ERROR_BUSY;
  342. }
  343. return err_code;
  344. }
  345. void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config)
  346. {
  347. if (p_conn_sec_config != NULL)
  348. {
  349. sm_conn_sec_config_reply(conn_handle, p_conn_sec_config);
  350. }
  351. }
  352. ret_code_t pm_conn_sec_params_reply(uint16_t conn_handle,
  353. ble_gap_sec_params_t * p_sec_params,
  354. void const * p_context)
  355. {
  356. VERIFY_MODULE_INITIALIZED();
  357. return sm_sec_params_reply(conn_handle, p_sec_params, p_context);
  358. }
  359. void pm_local_database_has_changed(void)
  360. {
  361. #if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
  362. VERIFY_MODULE_INITIALIZED_VOID();
  363. gcm_local_database_has_changed();
  364. #endif
  365. }
  366. ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr)
  367. {
  368. VERIFY_MODULE_INITIALIZED();
  369. return im_id_addr_set(p_addr);
  370. }
  371. ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr)
  372. {
  373. VERIFY_MODULE_INITIALIZED();
  374. VERIFY_PARAM_NOT_NULL(p_addr);
  375. return im_id_addr_get(p_addr);
  376. }
  377. ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params)
  378. {
  379. VERIFY_MODULE_INITIALIZED();
  380. VERIFY_PARAM_NOT_NULL(p_privacy_params);
  381. return im_privacy_set(p_privacy_params);
  382. }
  383. ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params)
  384. {
  385. VERIFY_MODULE_INITIALIZED();
  386. VERIFY_PARAM_NOT_NULL(p_privacy_params);
  387. VERIFY_PARAM_NOT_NULL(p_privacy_params->p_device_irk);
  388. return im_privacy_get(p_privacy_params);
  389. }
  390. bool pm_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
  391. {
  392. VERIFY_MODULE_INITIALIZED();
  393. if ((p_addr == NULL) || (p_irk == NULL))
  394. {
  395. return false;
  396. }
  397. else
  398. {
  399. return im_address_resolve(p_addr, p_irk);
  400. }
  401. }
  402. ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers,
  403. uint32_t peer_cnt)
  404. {
  405. VERIFY_MODULE_INITIALIZED();
  406. return im_whitelist_set(p_peers, peer_cnt);
  407. }
  408. ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs,
  409. uint32_t * p_addr_cnt,
  410. ble_gap_irk_t * p_irks,
  411. uint32_t * p_irk_cnt)
  412. {
  413. VERIFY_MODULE_INITIALIZED();
  414. if (((p_addrs == NULL) && (p_irks == NULL)) ||
  415. ((p_addrs != NULL) && (p_addr_cnt == NULL)) ||
  416. ((p_irks != NULL) && (p_irk_cnt == NULL)))
  417. {
  418. // The buffers can't be both NULL, and if a buffer is provided its size must be specified.
  419. return NRF_ERROR_NULL;
  420. }
  421. return im_whitelist_get(p_addrs, p_addr_cnt, p_irks, p_irk_cnt);
  422. }
  423. ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers,
  424. uint32_t peer_cnt)
  425. {
  426. VERIFY_MODULE_INITIALIZED();
  427. return im_device_identities_list_set(p_peers, peer_cnt);
  428. }
  429. ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status)
  430. {
  431. VERIFY_MODULE_INITIALIZED();
  432. VERIFY_PARAM_NOT_NULL(p_conn_sec_status);
  433. ble_conn_state_status_t status = ble_conn_state_status(conn_handle);
  434. if (status == BLE_CONN_STATUS_INVALID)
  435. {
  436. return BLE_ERROR_INVALID_CONN_HANDLE;
  437. }
  438. p_conn_sec_status->connected = (status == BLE_CONN_STATUS_CONNECTED);
  439. p_conn_sec_status->bonded = (im_peer_id_get_by_conn_handle(conn_handle) != PM_PEER_ID_INVALID);
  440. p_conn_sec_status->encrypted = ble_conn_state_encrypted(conn_handle);
  441. p_conn_sec_status->mitm_protected = ble_conn_state_mitm_protected(conn_handle);
  442. return NRF_SUCCESS;
  443. }
  444. ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key)
  445. {
  446. VERIFY_MODULE_INITIALIZED();
  447. return sm_lesc_public_key_set(p_public_key);
  448. }
  449. ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle)
  450. {
  451. VERIFY_MODULE_INITIALIZED();
  452. VERIFY_PARAM_NOT_NULL(p_conn_handle);
  453. *p_conn_handle = im_conn_handle_get(peer_id);
  454. return NRF_SUCCESS;
  455. }
  456. ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id)
  457. {
  458. VERIFY_MODULE_INITIALIZED();
  459. VERIFY_PARAM_NOT_NULL(p_peer_id);
  460. *p_peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  461. return NRF_SUCCESS;
  462. }
  463. uint32_t pm_peer_count(void)
  464. {
  465. if (!MODULE_INITIALIZED)
  466. {
  467. return 0;
  468. }
  469. return pds_peer_count_get();
  470. }
  471. pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id)
  472. {
  473. pm_peer_id_t next_peer_id = prev_peer_id;
  474. if (!MODULE_INITIALIZED)
  475. {
  476. return PM_PEER_ID_INVALID;
  477. }
  478. do
  479. {
  480. next_peer_id = pds_next_peer_id_get(next_peer_id);
  481. } while (pds_peer_id_is_deleted(next_peer_id));
  482. return next_peer_id;
  483. }
  484. /**@brief Function for checking if the peer has a valid Identity Resolving Key.
  485. *
  486. * @param[in] p_irk Pointer to the Identity Resolving Key.
  487. */
  488. static bool peer_is_irk(ble_gap_irk_t const * const p_irk)
  489. {
  490. for (uint32_t i = 0; i < ARRAY_SIZE(p_irk->irk); i++)
  491. {
  492. if (p_irk->irk[i] != 0)
  493. {
  494. return true;
  495. }
  496. }
  497. return false;
  498. }
  499. ret_code_t pm_peer_id_list(pm_peer_id_t * p_peer_list,
  500. uint32_t * const p_list_size,
  501. pm_peer_id_t first_peer_id,
  502. pm_peer_id_list_skip_t skip_id)
  503. {
  504. VERIFY_MODULE_INITIALIZED();
  505. VERIFY_PARAM_NOT_NULL(p_list_size);
  506. VERIFY_PARAM_NOT_NULL(p_peer_list);
  507. ret_code_t err_code;
  508. uint32_t size = *p_list_size;
  509. uint32_t current_size = 0;
  510. pm_peer_data_t pm_car_data;
  511. pm_peer_data_t pm_bond_data;
  512. pm_peer_id_t current_peer_id = first_peer_id;
  513. ble_gap_addr_t const * p_gap_addr;
  514. bool skip_no_addr = skip_id & PM_PEER_ID_LIST_SKIP_NO_ID_ADDR;
  515. bool skip_no_irk = skip_id & PM_PEER_ID_LIST_SKIP_NO_IRK;
  516. bool skip_no_car = skip_id & PM_PEER_ID_LIST_SKIP_NO_CAR;
  517. //lint -save -e685
  518. if ((*p_list_size < 1) ||
  519. (skip_id > (PM_PEER_ID_LIST_SKIP_NO_ID_ADDR | PM_PEER_ID_LIST_SKIP_ALL)))
  520. {
  521. return NRF_ERROR_INVALID_PARAM;
  522. }
  523. //lint -restore
  524. *p_list_size = 0;
  525. if (current_peer_id == PM_PEER_ID_INVALID)
  526. {
  527. current_peer_id = pm_next_peer_id_get(current_peer_id);
  528. if (current_peer_id == PM_PEER_ID_INVALID)
  529. {
  530. return NRF_SUCCESS;
  531. }
  532. }
  533. memset(&pm_car_data, 0, sizeof(pm_peer_data_t));
  534. memset(&pm_bond_data, 0, sizeof(pm_peer_data_t));
  535. while (current_peer_id != PM_PEER_ID_INVALID)
  536. {
  537. bool skip = false;
  538. if (skip_no_addr || skip_no_irk)
  539. {
  540. // Get data
  541. pm_bond_data.p_bonding_data = NULL;
  542. err_code = pds_peer_data_read(current_peer_id,
  543. PM_PEER_DATA_ID_BONDING,
  544. &pm_bond_data,
  545. NULL);
  546. if (err_code == NRF_ERROR_NOT_FOUND)
  547. {
  548. skip = true;
  549. }
  550. else
  551. {
  552. VERIFY_SUCCESS(err_code);
  553. }
  554. // Check data
  555. if (skip_no_addr)
  556. {
  557. p_gap_addr = &pm_bond_data.p_bonding_data->peer_ble_id.id_addr_info;
  558. if ((p_gap_addr->addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) &&
  559. (p_gap_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC))
  560. {
  561. skip = true;
  562. }
  563. }
  564. if (skip_no_irk)
  565. {
  566. if (!peer_is_irk(&pm_bond_data.p_bonding_data->peer_ble_id.id_info))
  567. {
  568. skip = true;
  569. }
  570. }
  571. }
  572. if (skip_no_car)
  573. {
  574. // Get data
  575. pm_car_data.p_central_addr_res = NULL;
  576. err_code = pds_peer_data_read(current_peer_id,
  577. PM_PEER_DATA_ID_CENTRAL_ADDR_RES,
  578. &pm_car_data,
  579. NULL);
  580. if (err_code == NRF_ERROR_NOT_FOUND)
  581. {
  582. skip = true;
  583. }
  584. else
  585. {
  586. VERIFY_SUCCESS(err_code);
  587. }
  588. // Check data
  589. if (*pm_car_data.p_central_addr_res == 0)
  590. {
  591. skip = true;
  592. }
  593. }
  594. if (!skip)
  595. {
  596. p_peer_list[current_size++] = current_peer_id;
  597. if (current_size >= size)
  598. {
  599. break;
  600. }
  601. }
  602. current_peer_id = pm_next_peer_id_get(current_peer_id);
  603. }
  604. *p_list_size = current_size;
  605. return NRF_SUCCESS;
  606. }
  607. ret_code_t pm_peer_data_load(pm_peer_id_t peer_id,
  608. pm_peer_data_id_t data_id,
  609. void * p_data,
  610. uint16_t * p_length)
  611. {
  612. VERIFY_MODULE_INITIALIZED();
  613. VERIFY_PARAM_NOT_NULL(p_data);
  614. VERIFY_PARAM_NOT_NULL(p_length);
  615. pm_peer_data_t peer_data;
  616. memset(&peer_data, 0, sizeof(peer_data));
  617. peer_data.p_all_data = p_data;
  618. return pds_peer_data_read(peer_id, data_id, &peer_data, p_length);
  619. }
  620. ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id,
  621. pm_peer_data_bonding_t * p_data)
  622. {
  623. uint16_t length = sizeof(pm_peer_data_bonding_t);
  624. return pm_peer_data_load(peer_id,
  625. PM_PEER_DATA_ID_BONDING,
  626. p_data,
  627. &length);
  628. }
  629. ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id,
  630. ble_gatt_db_srv_t * p_data,
  631. uint16_t * p_length)
  632. {
  633. return pm_peer_data_load(peer_id,
  634. PM_PEER_DATA_ID_GATT_REMOTE,
  635. p_data,
  636. p_length);
  637. }
  638. ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id,
  639. void * p_data,
  640. uint16_t * p_length)
  641. {
  642. return pm_peer_data_load(peer_id,
  643. PM_PEER_DATA_ID_APPLICATION,
  644. p_data,
  645. p_length);
  646. }
  647. ret_code_t pm_peer_data_store(pm_peer_id_t peer_id,
  648. pm_peer_data_id_t data_id,
  649. void const * p_data,
  650. uint16_t length,
  651. pm_store_token_t * p_token)
  652. {
  653. VERIFY_MODULE_INITIALIZED();
  654. VERIFY_PARAM_NOT_NULL(p_data);
  655. if (ALIGN_NUM(4, length) != length)
  656. {
  657. return NRF_ERROR_INVALID_PARAM;
  658. }
  659. if (data_id == PM_PEER_DATA_ID_BONDING)
  660. {
  661. pm_peer_id_t dupl_peer_id;
  662. dupl_peer_id = im_find_duplicate_bonding_data((pm_peer_data_bonding_t *) p_data, peer_id);
  663. if (dupl_peer_id != PM_PEER_ID_INVALID)
  664. {
  665. return NRF_ERROR_FORBIDDEN;
  666. }
  667. }
  668. pm_peer_data_flash_t peer_data;
  669. memset(&peer_data, 0, sizeof(peer_data));
  670. peer_data.length_words = BYTES_TO_WORDS(length);
  671. peer_data.data_id = data_id;
  672. peer_data.p_all_data = p_data;
  673. return pds_peer_data_store(peer_id, &peer_data, p_token);
  674. }
  675. ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id,
  676. pm_peer_data_bonding_t const * p_data,
  677. pm_store_token_t * p_token)
  678. {
  679. return pm_peer_data_store(peer_id,
  680. PM_PEER_DATA_ID_BONDING,
  681. p_data,
  682. ALIGN_NUM(4, sizeof(pm_peer_data_bonding_t)),
  683. p_token);
  684. }
  685. ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id,
  686. ble_gatt_db_srv_t const * p_data,
  687. uint16_t length,
  688. pm_store_token_t * p_token)
  689. {
  690. return pm_peer_data_store(peer_id,
  691. PM_PEER_DATA_ID_GATT_REMOTE,
  692. p_data,
  693. length,
  694. p_token);
  695. }
  696. ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id,
  697. void const * p_data,
  698. uint16_t length,
  699. pm_store_token_t * p_token)
  700. {
  701. return pm_peer_data_store(peer_id,
  702. PM_PEER_DATA_ID_APPLICATION,
  703. p_data,
  704. length,
  705. p_token);
  706. }
  707. ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
  708. {
  709. VERIFY_MODULE_INITIALIZED();
  710. if (data_id == PM_PEER_DATA_ID_BONDING)
  711. {
  712. return NRF_ERROR_INVALID_PARAM;
  713. }
  714. return pds_peer_data_delete(peer_id, data_id);
  715. }
  716. ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id,
  717. pm_peer_data_bonding_t * p_bonding_data,
  718. pm_store_token_t * p_token)
  719. {
  720. ret_code_t err_code;
  721. pm_peer_id_t peer_id;
  722. pm_peer_data_flash_t peer_data;
  723. VERIFY_MODULE_INITIALIZED();
  724. VERIFY_PARAM_NOT_NULL(p_bonding_data);
  725. VERIFY_PARAM_NOT_NULL(p_new_peer_id);
  726. memset(&peer_data, 0, sizeof(pm_peer_data_flash_t));
  727. // Search through existing bonds to look for a duplicate.
  728. pds_peer_data_iterate_prepare();
  729. // @note This check is not thread safe since data is not copied while iterating.
  730. while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
  731. {
  732. if (im_is_duplicate_bonding_data(p_bonding_data, peer_data.p_bonding_data))
  733. {
  734. *p_new_peer_id = peer_id;
  735. return NRF_SUCCESS;
  736. }
  737. }
  738. // If no duplicate data is found, prepare to write a new bond to flash.
  739. *p_new_peer_id = pds_peer_id_allocate();
  740. if (*p_new_peer_id == PM_PEER_ID_INVALID)
  741. {
  742. return NRF_ERROR_NO_MEM;
  743. }
  744. memset(&peer_data, 0, sizeof(pm_peer_data_flash_t));
  745. peer_data.data_id = PM_PEER_DATA_ID_BONDING;
  746. peer_data.p_bonding_data = p_bonding_data;
  747. peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t));
  748. err_code = pds_peer_data_store(*p_new_peer_id, &peer_data, p_token);
  749. if (err_code != NRF_SUCCESS)
  750. {
  751. ret_code_t err_code_free = im_peer_free(*p_new_peer_id);
  752. if (err_code_free != NRF_SUCCESS)
  753. {
  754. NRF_LOG_ERROR("Fatal error during cleanup of a failed call to %s. im_peer_free() "\
  755. "returned %s. peer_id: %d",
  756. __func__,
  757. nrf_strerror_get(err_code_free),
  758. *p_new_peer_id);
  759. return NRF_ERROR_INTERNAL;
  760. }
  761. // NRF_ERROR_STORAGE_FULL, if no space in flash.
  762. // NRF_ERROR_BUSY, if flash filesystem was busy.
  763. // NRF_ERROR_INTENRAL, on internal error.
  764. return err_code;
  765. }
  766. return NRF_SUCCESS;
  767. }
  768. ret_code_t pm_peer_delete(pm_peer_id_t peer_id)
  769. {
  770. VERIFY_MODULE_INITIALIZED();
  771. return im_peer_free(peer_id);
  772. }
  773. ret_code_t pm_peers_delete(void)
  774. {
  775. VERIFY_MODULE_INITIALIZED();
  776. m_deleting_all = true;
  777. pm_peer_id_t current_peer_id = pds_next_peer_id_get(PM_PEER_ID_INVALID);
  778. if (current_peer_id == PM_PEER_ID_INVALID)
  779. {
  780. // No peers bonded.
  781. m_deleting_all = false;
  782. pm_evt_t pm_delete_all_evt;
  783. memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
  784. pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED;
  785. pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
  786. pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
  787. evt_send(&pm_delete_all_evt);
  788. }
  789. while (current_peer_id != PM_PEER_ID_INVALID)
  790. {
  791. ret_code_t err_code = pm_peer_delete(current_peer_id);
  792. if (err_code != NRF_SUCCESS)
  793. {
  794. NRF_LOG_ERROR("%s() failed because a call to pm_peer_delete() returned %s. peer_id: %d",
  795. __func__,
  796. nrf_strerror_get(err_code),
  797. current_peer_id);
  798. return NRF_ERROR_INTERNAL;
  799. }
  800. current_peer_id = pds_next_peer_id_get(current_peer_id);
  801. }
  802. return NRF_SUCCESS;
  803. }
  804. ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer,
  805. uint32_t * p_highest_rank,
  806. pm_peer_id_t * p_lowest_ranked_peer,
  807. uint32_t * p_lowest_rank)
  808. {
  809. #if PM_PEER_RANKS_ENABLED == 0
  810. return NRF_ERROR_NOT_SUPPORTED;
  811. #else
  812. VERIFY_MODULE_INITIALIZED();
  813. pm_peer_id_t peer_id = pds_next_peer_id_get(PM_PEER_ID_INVALID);
  814. uint32_t peer_rank = 0;
  815. //lint -save -e65 -e64
  816. uint16_t length = sizeof(peer_rank);
  817. pm_peer_data_t peer_data = {.p_peer_rank = &peer_rank};
  818. //lint -restore
  819. ret_code_t err_code = pds_peer_data_read(peer_id,
  820. PM_PEER_DATA_ID_PEER_RANK,
  821. &peer_data,
  822. &length);
  823. uint32_t highest_rank = 0;
  824. uint32_t lowest_rank = 0xFFFFFFFF;
  825. pm_peer_id_t highest_ranked_peer = PM_PEER_ID_INVALID;
  826. pm_peer_id_t lowest_ranked_peer = PM_PEER_ID_INVALID;
  827. if (err_code == NRF_ERROR_INVALID_PARAM)
  828. {
  829. // No peer IDs exist.
  830. return NRF_ERROR_NOT_FOUND;
  831. }
  832. while ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND))
  833. {
  834. if (err_code == NRF_SUCCESS)
  835. {
  836. if (peer_rank >= highest_rank)
  837. {
  838. highest_rank = peer_rank;
  839. highest_ranked_peer = peer_id;
  840. }
  841. if (peer_rank < lowest_rank)
  842. {
  843. lowest_rank = peer_rank;
  844. lowest_ranked_peer = peer_id;
  845. }
  846. }
  847. peer_id = pds_next_peer_id_get(peer_id);
  848. err_code = pds_peer_data_read(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data, &length);
  849. }
  850. if (peer_id == PM_PEER_ID_INVALID)
  851. {
  852. if ((highest_ranked_peer == PM_PEER_ID_INVALID) || (lowest_ranked_peer == PM_PEER_ID_INVALID))
  853. {
  854. err_code = NRF_ERROR_NOT_FOUND;
  855. }
  856. else
  857. {
  858. err_code = NRF_SUCCESS;
  859. }
  860. if (p_highest_ranked_peer != NULL)
  861. {
  862. *p_highest_ranked_peer = highest_ranked_peer;
  863. }
  864. if (p_highest_rank != NULL)
  865. {
  866. *p_highest_rank = highest_rank;
  867. }
  868. if (p_lowest_ranked_peer != NULL)
  869. {
  870. *p_lowest_ranked_peer = lowest_ranked_peer;
  871. }
  872. if (p_lowest_rank != NULL)
  873. {
  874. *p_lowest_rank = lowest_rank;
  875. }
  876. }
  877. else
  878. {
  879. NRF_LOG_ERROR("Could not retreive ranks. pdb_peer_data_load() returned %s. peer_id: %d",
  880. nrf_strerror_get(err_code),
  881. peer_id);
  882. err_code = NRF_ERROR_INTERNAL;
  883. }
  884. return err_code;
  885. #endif
  886. }
  887. #if PM_PEER_RANKS_ENABLED == 1
  888. /**@brief Function for initializing peer rank functionality.
  889. */
  890. static void rank_init(void)
  891. {
  892. rank_vars_update();
  893. }
  894. #endif
  895. ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id)
  896. {
  897. #if PM_PEER_RANKS_ENABLED == 0
  898. return NRF_ERROR_NOT_SUPPORTED;
  899. #else
  900. VERIFY_MODULE_INITIALIZED();
  901. ret_code_t err_code;
  902. //lint -save -e65 -e64
  903. pm_peer_data_flash_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(m_current_highest_peer_rank)),
  904. .data_id = PM_PEER_DATA_ID_PEER_RANK,
  905. .p_peer_rank = &m_current_highest_peer_rank};
  906. //lint -restore
  907. if (!m_peer_rank_initialized)
  908. {
  909. rank_init();
  910. }
  911. if (!m_peer_rank_initialized || (m_peer_rank_token != PM_STORE_TOKEN_INVALID))
  912. {
  913. err_code = NRF_ERROR_BUSY;
  914. }
  915. else
  916. {
  917. if ((peer_id == m_highest_ranked_peer) && (m_current_highest_peer_rank > 0))
  918. {
  919. pm_evt_t pm_evt;
  920. // The reported peer is already regarded as highest (provided it has an index at all)
  921. err_code = NRF_SUCCESS;
  922. memset(&pm_evt, 0, sizeof(pm_evt));
  923. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  924. pm_evt.conn_handle = im_conn_handle_get(peer_id);
  925. pm_evt.peer_id = peer_id;
  926. pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_PEER_RANK;
  927. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  928. pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  929. pm_evt.params.peer_data_update_succeeded.flash_changed = false;
  930. evt_send(&pm_evt);
  931. }
  932. else
  933. {
  934. if (m_current_highest_peer_rank == UINT32_MAX)
  935. {
  936. err_code = NRF_ERROR_RESOURCES;
  937. }
  938. else
  939. {
  940. m_current_highest_peer_rank += 1;
  941. err_code = pds_peer_data_store(peer_id, &peer_data, &m_peer_rank_token);
  942. if (err_code != NRF_SUCCESS)
  943. {
  944. m_peer_rank_token = PM_STORE_TOKEN_INVALID;
  945. m_current_highest_peer_rank -= 1;
  946. if ((err_code != NRF_ERROR_BUSY) &&
  947. (err_code != NRF_ERROR_STORAGE_FULL) &&
  948. (err_code != NRF_ERROR_INVALID_PARAM)) // Assume INVALID_PARAM refers to peer_id, not data_id.
  949. {
  950. NRF_LOG_ERROR("Could not update rank. pdb_raw_store() returned %s. "\
  951. "peer_id: %d",
  952. nrf_strerror_get(err_code),
  953. peer_id);
  954. err_code = NRF_ERROR_INTERNAL;
  955. }
  956. }
  957. }
  958. }
  959. }
  960. return err_code;
  961. #endif
  962. }
  963. #endif // NRF_MODULE_ENABLED(PEER_MANAGER)