peer_manager.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "peer_manager.h"
  13. #include <string.h>
  14. #include "app_util.h"
  15. #include "security_manager.h"
  16. #include "gatt_cache_manager.h"
  17. #include "peer_database.h"
  18. #include "id_manager.h"
  19. #include "ble_conn_state.h"
  20. #include "sdk_common.h"
  21. #include "peer_manager_internal.h"
  22. #define MODULE_INITIALIZED m_pm.initialized
  23. #include "sdk_macros.h"
  24. #define MAX_REGISTRANTS 3 /**< The number of event handlers that can be registered with the module. */
  25. /**@brief Internal state of the module.
  26. */
  27. typedef struct
  28. {
  29. uint8_t initialized : 1; /**< Whether or not @ref pm_init has been called successfully. */
  30. uint8_t peer_rank_initialized : 1; /**< Whether or not @ref rank_init has been called successfully. */
  31. uint8_t deleting_all : 1; /**< True from when @ref pm_peers_delete is called until all peers have been deleted. */
  32. pm_store_token_t 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. */
  33. uint32_t current_highest_peer_rank; /**< The current highest peer rank. Used by @ref pm_peer_rank_highest. */
  34. pm_peer_id_t highest_ranked_peer; /**< The peer with the highest peer rank. Used by @ref pm_peer_rank_highest. */
  35. pm_evt_handler_t evt_handlers[MAX_REGISTRANTS]; /**< The subscribers to Peer Manager events, as registered through @ref pm_register. */
  36. uint8_t n_registrants; /**< The number of event handlers registered through @ref pm_register. */
  37. ble_conn_state_user_flag_id_t pairing_flag_id; /**< The flag ID for which connections are paired. */
  38. ble_conn_state_user_flag_id_t bonding_flag_id; /**< The flag ID for which connections are bonded. */
  39. } pm_t;
  40. /**@brief Instantiation of Peer Manager internal state.
  41. */
  42. static pm_t m_pm =
  43. {
  44. .initialized = 0,
  45. .peer_rank_initialized = 0,
  46. };
  47. /**@brief Function for sending a Peer Manager event to all subscribers.
  48. *
  49. * @param[in] p_pm_evt The event to send.
  50. */
  51. static void evt_send(pm_evt_t * p_pm_evt)
  52. {
  53. for (int i = 0; i < m_pm.n_registrants; i++)
  54. {
  55. m_pm.evt_handlers[i](p_pm_evt);
  56. }
  57. }
  58. /**@brief Event handler for events from the Peer Database module.
  59. *
  60. * @param[in] p_pdb_evt The incoming Peer Database event.
  61. */
  62. static void pdb_evt_handler(pdb_evt_t const * p_pdb_evt)
  63. {
  64. bool send_evt = true;
  65. pm_evt_t pm_evt;
  66. memset(&pm_evt, 0, sizeof(pm_evt_t));
  67. pm_evt.peer_id = p_pdb_evt->peer_id;
  68. pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id);
  69. switch (p_pdb_evt->evt_id)
  70. {
  71. case PDB_EVT_WRITE_BUF_STORED:
  72. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  73. pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id;
  74. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  75. pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  76. pm_evt.params.peer_data_update_succeeded.flash_changed = true;
  77. break;
  78. case PDB_EVT_RAW_STORED:
  79. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  80. pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id;
  81. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  82. pm_evt.params.peer_data_update_succeeded.token
  83. = p_pdb_evt->params.raw_stored_evt.store_token;
  84. pm_evt.params.peer_data_update_succeeded.flash_changed = true;
  85. if( (m_pm.peer_rank_token != PM_STORE_TOKEN_INVALID)
  86. && (m_pm.peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token))
  87. {
  88. m_pm.peer_rank_token = PM_STORE_TOKEN_INVALID;
  89. m_pm.highest_ranked_peer = pm_evt.peer_id;
  90. pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  91. }
  92. break;
  93. case PDB_EVT_RAW_STORE_FAILED:
  94. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
  95. pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id;
  96. pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE;
  97. pm_evt.params.peer_data_update_failed.token
  98. = p_pdb_evt->params.error_raw_store_evt.store_token;
  99. pm_evt.params.peer_data_update_failed.error
  100. = p_pdb_evt->params.error_raw_store_evt.err_code;
  101. if( (m_pm.peer_rank_token != PM_STORE_TOKEN_INVALID)
  102. && (m_pm.peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token))
  103. {
  104. m_pm.peer_rank_token = PM_STORE_TOKEN_INVALID;
  105. m_pm.current_highest_peer_rank -= 1;
  106. pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  107. }
  108. break;
  109. case PDB_EVT_CLEARED:
  110. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  111. pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id;
  112. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_DELETE;
  113. pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  114. break;
  115. case PDB_EVT_CLEAR_FAILED:
  116. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
  117. pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id;
  118. pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_DELETE;
  119. pm_evt.params.peer_data_update_failed.error
  120. = p_pdb_evt->params.clear_failed_evt.err_code;
  121. break;
  122. case PDB_EVT_PEER_FREED:
  123. pm_evt.evt_id = PM_EVT_PEER_DELETE_SUCCEEDED;
  124. if (m_pm.deleting_all && (pdb_next_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID))
  125. {
  126. // pm_peers_delete() has been called and this is the last peer to be deleted.
  127. m_pm.deleting_all = false;
  128. pm_evt_t pm_delete_all_evt;
  129. memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
  130. pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED;
  131. pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
  132. pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
  133. evt_send(&pm_delete_all_evt);
  134. }
  135. break;
  136. case PDB_EVT_PEER_FREE_FAILED:
  137. pm_evt.evt_id = PM_EVT_PEER_DELETE_FAILED;
  138. pm_evt.params.peer_delete_failed.error
  139. = p_pdb_evt->params.peer_free_failed_evt.err_code;
  140. if (m_pm.deleting_all)
  141. {
  142. // pm_peers_delete() has been called and has thus failed.
  143. m_pm.deleting_all = false;
  144. pm_evt_t pm_delete_all_evt;
  145. memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
  146. pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_FAILED;
  147. pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
  148. pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
  149. pm_delete_all_evt.params.peers_delete_failed_evt.error
  150. = p_pdb_evt->params.peer_free_failed_evt.err_code;
  151. evt_send(&pm_delete_all_evt);
  152. }
  153. break;
  154. case PDB_EVT_COMPRESSED:
  155. send_evt = false;
  156. // Do nothing
  157. break;
  158. case PDB_EVT_ERROR_NO_MEM:
  159. pm_evt.evt_id = PM_EVT_STORAGE_FULL;
  160. break;
  161. case PDB_EVT_ERROR_UNEXPECTED:
  162. pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
  163. break;
  164. default:
  165. send_evt = false;
  166. break;
  167. }
  168. if (send_evt)
  169. {
  170. evt_send(&pm_evt);
  171. }
  172. }
  173. /**@brief Event handler for events from the Security Manager module.
  174. *
  175. * @param[in] p_sm_evt The incoming Security Manager event.
  176. */
  177. static void sm_evt_handler(sm_evt_t const * p_sm_evt)
  178. {
  179. bool find_peer_id = true;
  180. bool send_evt = true;
  181. pm_evt_t pm_evt;
  182. memset(&pm_evt, 0, sizeof(pm_evt_t));
  183. pm_evt.conn_handle = p_sm_evt->conn_handle;
  184. switch (p_sm_evt->evt_id)
  185. {
  186. case SM_EVT_SLAVE_SECURITY_REQ:
  187. find_peer_id = false;
  188. send_evt = false;
  189. break;
  190. case SM_EVT_SEC_PROCEDURE_START:
  191. {
  192. pm_evt.evt_id = PM_EVT_CONN_SEC_START;
  193. bool pairing = p_sm_evt->params.sec_procedure_start.procedure
  194. != PM_LINK_SECURED_PROCEDURE_ENCRYPTION;
  195. bool bonding = p_sm_evt->params.sec_procedure_start.procedure
  196. == PM_LINK_SECURED_PROCEDURE_BONDING;
  197. ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pm.pairing_flag_id, pairing);
  198. ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pm.bonding_flag_id, bonding);
  199. break;
  200. }
  201. case SM_EVT_PAIRING_SUCCESS:
  202. pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
  203. pm_evt.params.conn_sec_succeeded.procedure =
  204. p_sm_evt->params.pairing_success.bonded
  205. ? PM_LINK_SECURED_PROCEDURE_BONDING
  206. : PM_LINK_SECURED_PROCEDURE_PAIRING;
  207. ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pm.pairing_flag_id, true);
  208. ble_conn_state_user_flag_set(p_sm_evt->conn_handle,
  209. m_pm.bonding_flag_id,
  210. p_sm_evt->params.pairing_success.bonded
  211. );
  212. break;
  213. case SM_EVT_PAIRING_FAIL:
  214. pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED;
  215. pm_evt.params.conn_sec_failed.procedure =
  216. ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pm.bonding_flag_id)
  217. ? PM_LINK_SECURED_PROCEDURE_BONDING
  218. : PM_LINK_SECURED_PROCEDURE_PAIRING;
  219. pm_evt.params.conn_sec_failed.error_src
  220. = p_sm_evt->params.pairing_failed.error_src;
  221. pm_evt.params.conn_sec_failed.error
  222. = p_sm_evt->params.pairing_failed.error;
  223. break;
  224. case SM_EVT_LINK_ENCRYPTION_UPDATE:
  225. if (!ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pm.pairing_flag_id))
  226. {
  227. pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
  228. pm_evt.params.conn_sec_succeeded.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION;
  229. }
  230. else
  231. {
  232. find_peer_id = false;
  233. send_evt = false;
  234. }
  235. break;
  236. case SM_EVT_LINK_ENCRYPTION_FAILED:
  237. pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED;
  238. pm_evt.params.conn_sec_failed.procedure
  239. = PM_LINK_SECURED_PROCEDURE_ENCRYPTION;
  240. pm_evt.params.conn_sec_failed.error_src
  241. = p_sm_evt->params.link_encryption_failed.error_src;
  242. pm_evt.params.conn_sec_failed.error
  243. = p_sm_evt->params.link_encryption_failed.error;
  244. break;
  245. case SM_EVT_BONDING_INFO_STORED:
  246. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  247. pm_evt.peer_id = p_sm_evt->params.bonding_info_stored.peer_id;
  248. pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_BONDING;
  249. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  250. find_peer_id = false;
  251. break;
  252. case SM_EVT_ERROR_BONDING_INFO:
  253. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
  254. pm_evt.peer_id = p_sm_evt->params.error_bonding_info.peer_id;
  255. pm_evt.params.peer_data_update_failed.data_id = PM_PEER_DATA_ID_BONDING;
  256. pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE;
  257. pm_evt.params.peer_data_update_failed.error
  258. = p_sm_evt->params.error_bonding_info.error;
  259. find_peer_id = false;
  260. break;
  261. case SM_EVT_ERROR_UNEXPECTED:
  262. pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
  263. pm_evt.params.error_unexpected.error = p_sm_evt->params.error_unexpected.error;
  264. break;
  265. case SM_EVT_ERROR_NO_MEM:
  266. pm_evt.evt_id = PM_EVT_STORAGE_FULL;
  267. break;
  268. case SM_EVT_ERROR_SMP_TIMEOUT:
  269. pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED;
  270. pm_evt.params.conn_sec_failed.procedure
  271. = ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pm.bonding_flag_id)
  272. ? PM_LINK_SECURED_PROCEDURE_BONDING
  273. : PM_LINK_SECURED_PROCEDURE_PAIRING;
  274. pm_evt.params.conn_sec_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL;
  275. pm_evt.params.conn_sec_failed.error = PM_CONN_SEC_ERROR_SMP_TIMEOUT;
  276. break;
  277. case SM_EVT_CONN_SEC_CONFIG_REQ:
  278. pm_evt.evt_id = PM_EVT_CONN_SEC_CONFIG_REQ;
  279. break;
  280. default:
  281. send_evt = false;
  282. break;
  283. }
  284. if (find_peer_id)
  285. {
  286. pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_sm_evt->conn_handle);
  287. }
  288. if (send_evt)
  289. {
  290. evt_send(&pm_evt);
  291. }
  292. }
  293. /**@brief Event handler for events from the GATT Cache Manager module.
  294. *
  295. * @param[in] p_gcm_evt The incoming GATT Cache Manager event.
  296. */
  297. static void gcm_evt_handler(gcm_evt_t const * p_gcm_evt)
  298. {
  299. bool send_evt = true;
  300. pm_evt_t pm_evt;
  301. memset(&pm_evt, 0, sizeof(pm_evt_t));
  302. pm_evt.peer_id = p_gcm_evt->peer_id;
  303. pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id);
  304. switch (p_gcm_evt->evt_id)
  305. {
  306. case GCM_EVT_LOCAL_DB_CACHE_STORED:
  307. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  308. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  309. pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL;
  310. break;
  311. case GCM_EVT_LOCAL_DB_CACHE_UPDATED:
  312. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  313. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  314. pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL;
  315. break;
  316. case GCM_EVT_LOCAL_DB_CACHE_APPLIED:
  317. pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLIED;
  318. break;
  319. case GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY:
  320. pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED;
  321. break;
  322. case GCM_EVT_REMOTE_DB_CACHE_UPDATED:
  323. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  324. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  325. pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_REMOTE;
  326. break;
  327. case GCM_EVT_SERVICE_CHANGED_IND_SENT:
  328. pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_SENT;
  329. break;
  330. case GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
  331. pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_CONFIRMED;
  332. break;
  333. case GCM_EVT_ERROR_DATA_SIZE:
  334. send_evt = false;
  335. break;
  336. case GCM_EVT_ERROR_STORAGE_FULL:
  337. pm_evt.evt_id = PM_EVT_STORAGE_FULL;
  338. break;
  339. case GCM_EVT_ERROR_UNEXPECTED:
  340. pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
  341. pm_evt.params.error_unexpected.error = p_gcm_evt->params.error_unexpected.error;
  342. pm_evt.conn_handle = p_gcm_evt->params.error_unexpected.conn_handle;
  343. break;
  344. }
  345. if (send_evt)
  346. {
  347. evt_send(&pm_evt);
  348. }
  349. }
  350. /**@brief Event handler for events from the ID Manager module.
  351. *
  352. * @param[in] p_im_evt The incoming ID Manager event.
  353. */
  354. static void im_evt_handler(im_evt_t const * p_im_evt)
  355. {
  356. pm_evt_t pm_evt;
  357. ret_code_t err_code;
  358. switch (p_im_evt->evt_id)
  359. {
  360. case IM_EVT_DUPLICATE_ID:
  361. // Attempt to delete the duplicate data to free space and avoid finding old data when
  362. // scanning in the future
  363. err_code = pm_peer_delete(p_im_evt->params.duplicate_id.peer_id_2);
  364. UNUSED_VARIABLE(err_code);
  365. break;
  366. case IM_EVT_BONDED_PEER_CONNECTED:
  367. ble_conn_state_user_flag_set(p_im_evt->conn_handle, m_pm.bonding_flag_id, true);
  368. memset(&pm_evt, 0, sizeof(pm_evt_t));
  369. pm_evt.conn_handle = p_im_evt->conn_handle;
  370. pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_im_evt->conn_handle);
  371. pm_evt.evt_id = PM_EVT_BONDED_PEER_CONNECTED;
  372. evt_send(&pm_evt);
  373. break;
  374. }
  375. }
  376. void pm_on_ble_evt(ble_evt_t * p_ble_evt)
  377. {
  378. VERIFY_MODULE_INITIALIZED_VOID();
  379. im_ble_evt_handler(p_ble_evt);
  380. sm_ble_evt_handler(p_ble_evt);
  381. gcm_ble_evt_handler(p_ble_evt);
  382. }
  383. /**@brief Function for resetting the internal state of this module.
  384. */
  385. static void internal_state_reset()
  386. {
  387. memset(&m_pm, 0, sizeof(m_pm));
  388. m_pm.highest_ranked_peer = PM_PEER_ID_INVALID;
  389. m_pm.peer_rank_token = PM_STORE_TOKEN_INVALID;
  390. m_pm.pairing_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID;
  391. m_pm.bonding_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID;
  392. }
  393. ret_code_t pm_init(void)
  394. {
  395. ret_code_t err_code;
  396. err_code = pdb_register(pdb_evt_handler);
  397. if (err_code != NRF_SUCCESS)
  398. {
  399. if (err_code != NRF_ERROR_INVALID_STATE)
  400. {
  401. err_code = NRF_ERROR_INTERNAL;
  402. }
  403. return err_code;
  404. }
  405. err_code = sm_register(sm_evt_handler);
  406. if (err_code != NRF_SUCCESS)
  407. {
  408. return NRF_ERROR_INTERNAL;
  409. }
  410. err_code = gcm_init(gcm_evt_handler);
  411. if (err_code != NRF_SUCCESS)
  412. {
  413. return NRF_ERROR_INTERNAL;
  414. }
  415. err_code = im_register(im_evt_handler);
  416. if (err_code != NRF_SUCCESS)
  417. {
  418. return NRF_ERROR_INTERNAL;
  419. }
  420. internal_state_reset();
  421. m_pm.pairing_flag_id = ble_conn_state_user_flag_acquire();
  422. if (m_pm.pairing_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
  423. {
  424. return NRF_ERROR_INTERNAL;
  425. }
  426. m_pm.bonding_flag_id = ble_conn_state_user_flag_acquire();
  427. if (m_pm.bonding_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
  428. {
  429. return NRF_ERROR_INTERNAL;
  430. }
  431. m_pm.peer_rank_initialized = false;
  432. m_pm.initialized = true;
  433. return NRF_SUCCESS;
  434. }
  435. ret_code_t pm_register(pm_evt_handler_t event_handler)
  436. {
  437. VERIFY_MODULE_INITIALIZED();
  438. if (m_pm.n_registrants >= MAX_REGISTRANTS)
  439. {
  440. return NRF_ERROR_NO_MEM;
  441. }
  442. m_pm.evt_handlers[m_pm.n_registrants] = event_handler;
  443. m_pm.n_registrants += 1;
  444. return NRF_SUCCESS;
  445. }
  446. ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params)
  447. {
  448. VERIFY_MODULE_INITIALIZED();
  449. ret_code_t err_code;
  450. err_code = sm_sec_params_set(p_sec_params);
  451. if (err_code == NRF_ERROR_INVALID_STATE)
  452. {
  453. err_code = NRF_ERROR_INTERNAL;
  454. }
  455. return err_code;
  456. }
  457. ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing)
  458. {
  459. VERIFY_MODULE_INITIALIZED();
  460. ret_code_t err_code;
  461. err_code = sm_link_secure(conn_handle, force_repairing);
  462. return err_code;
  463. }
  464. void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config)
  465. {
  466. sm_conn_sec_config_reply(conn_handle, p_conn_sec_config);
  467. }
  468. ret_code_t pm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params)
  469. {
  470. VERIFY_MODULE_INITIALIZED();
  471. return NRF_SUCCESS;
  472. }
  473. void pm_local_database_has_changed(void)
  474. {
  475. VERIFY_MODULE_INITIALIZED_VOID();
  476. gcm_local_database_has_changed();
  477. }
  478. ret_code_t pm_whitelist_create(pm_peer_id_t * p_peer_ids,
  479. uint8_t n_peer_ids,
  480. ble_gap_whitelist_t * p_whitelist)
  481. {
  482. VERIFY_MODULE_INITIALIZED();
  483. return im_whitelist_create(p_peer_ids, n_peer_ids, p_whitelist);
  484. }
  485. ret_code_t pm_whitelist_custom(ble_gap_whitelist_t * p_whitelist)
  486. {
  487. VERIFY_MODULE_INITIALIZED();
  488. return im_whitelist_custom(p_whitelist);
  489. }
  490. ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status)
  491. {
  492. VERIFY_MODULE_INITIALIZED();
  493. VERIFY_PARAM_NOT_NULL(p_conn_sec_status);
  494. ble_conn_state_status_t status = ble_conn_state_status(conn_handle);
  495. if (status == BLE_CONN_STATUS_INVALID)
  496. {
  497. return BLE_ERROR_INVALID_CONN_HANDLE;
  498. }
  499. p_conn_sec_status->connected = (status == BLE_CONN_STATUS_CONNECTED);
  500. p_conn_sec_status->bonded = ble_conn_state_user_flag_get(conn_handle, m_pm.bonding_flag_id);
  501. p_conn_sec_status->encrypted = ble_conn_state_encrypted(conn_handle);
  502. p_conn_sec_status->mitm_protected = ble_conn_state_mitm_protected(conn_handle);
  503. return NRF_SUCCESS;
  504. }
  505. ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key)
  506. {
  507. VERIFY_MODULE_INITIALIZED();
  508. return sm_lesc_public_key_set(p_public_key);
  509. }
  510. ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle)
  511. {
  512. VERIFY_MODULE_INITIALIZED();
  513. VERIFY_PARAM_NOT_NULL(p_conn_handle);
  514. *p_conn_handle = im_conn_handle_get(peer_id);
  515. return NRF_SUCCESS;
  516. }
  517. ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id)
  518. {
  519. VERIFY_MODULE_INITIALIZED();
  520. VERIFY_PARAM_NOT_NULL(p_peer_id);
  521. *p_peer_id = im_peer_id_get_by_conn_handle(conn_handle);
  522. return NRF_SUCCESS;
  523. }
  524. uint32_t pm_peer_count(void)
  525. {
  526. if (!MODULE_INITIALIZED)
  527. {
  528. return 0;
  529. }
  530. return pdb_n_peers();
  531. }
  532. pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id)
  533. {
  534. if (!MODULE_INITIALIZED)
  535. {
  536. return PM_PEER_ID_INVALID;
  537. }
  538. return pdb_next_peer_id_get(prev_peer_id);
  539. }
  540. ret_code_t pm_peer_data_load(pm_peer_id_t peer_id,
  541. pm_peer_data_id_t data_id,
  542. void * p_data,
  543. uint16_t * p_length)
  544. {
  545. VERIFY_MODULE_INITIALIZED();
  546. VERIFY_PARAM_NOT_NULL(p_data);
  547. VERIFY_PARAM_NOT_NULL(p_length);
  548. if (ALIGN_NUM(4, *p_length) != *p_length)
  549. {
  550. return NRF_ERROR_INVALID_PARAM;
  551. }
  552. pm_peer_data_t peer_data;
  553. memset(&peer_data, 0, sizeof(peer_data));
  554. peer_data.length_words = BYTES_TO_WORDS(*p_length);
  555. peer_data.data_id = data_id;
  556. peer_data.p_all_data = p_data;
  557. ret_code_t err_code = pdb_raw_read(peer_id, data_id, &peer_data);
  558. *p_length = peer_data.length_words * BYTES_PER_WORD;
  559. return err_code;
  560. }
  561. ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id,
  562. pm_peer_data_bonding_t * p_data)
  563. {
  564. uint16_t length = sizeof(pm_peer_data_bonding_t);
  565. return pm_peer_data_load(peer_id,
  566. PM_PEER_DATA_ID_BONDING,
  567. p_data,
  568. &length);
  569. }
  570. ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id,
  571. ble_gatt_db_srv_t * p_data,
  572. uint16_t * p_length)
  573. {
  574. return pm_peer_data_load(peer_id,
  575. PM_PEER_DATA_ID_GATT_REMOTE,
  576. p_data,
  577. p_length);
  578. }
  579. ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id,
  580. uint8_t * p_data,
  581. uint16_t * p_length)
  582. {
  583. return pm_peer_data_load(peer_id,
  584. PM_PEER_DATA_ID_APPLICATION,
  585. p_data,
  586. p_length);
  587. }
  588. ret_code_t pm_peer_data_store(pm_peer_id_t peer_id,
  589. pm_peer_data_id_t data_id,
  590. void const * p_data,
  591. uint16_t length,
  592. pm_store_token_t * p_token)
  593. {
  594. VERIFY_MODULE_INITIALIZED();
  595. VERIFY_PARAM_NOT_NULL(p_data);
  596. if (ALIGN_NUM(4, length) != length)
  597. {
  598. return NRF_ERROR_INVALID_PARAM;
  599. }
  600. pm_peer_data_const_t peer_data;
  601. memset(&peer_data, 0, sizeof(peer_data));
  602. peer_data.length_words = BYTES_TO_WORDS(length);
  603. peer_data.data_id = data_id;
  604. peer_data.p_all_data = p_data;
  605. return pdb_raw_store(peer_id, &peer_data, p_token);
  606. }
  607. ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id,
  608. pm_peer_data_bonding_t const * p_data,
  609. pm_store_token_t * p_token)
  610. {
  611. return pm_peer_data_store(peer_id,
  612. PM_PEER_DATA_ID_BONDING,
  613. p_data,
  614. ALIGN_NUM(4, sizeof(pm_peer_data_bonding_t)),
  615. p_token);
  616. }
  617. ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id,
  618. ble_gatt_db_srv_t const * p_data,
  619. uint16_t length,
  620. pm_store_token_t * p_token)
  621. {
  622. return pm_peer_data_store(peer_id,
  623. PM_PEER_DATA_ID_GATT_REMOTE,
  624. p_data,
  625. length,
  626. p_token);
  627. }
  628. ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id,
  629. uint8_t const * p_data,
  630. uint16_t length,
  631. pm_store_token_t * p_token)
  632. {
  633. return pm_peer_data_store(peer_id,
  634. PM_PEER_DATA_ID_APPLICATION,
  635. p_data,
  636. length,
  637. p_token);
  638. }
  639. ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
  640. {
  641. VERIFY_MODULE_INITIALIZED();
  642. if (data_id == PM_PEER_DATA_ID_BONDING)
  643. {
  644. return NRF_ERROR_INVALID_PARAM;
  645. }
  646. return pdb_clear(peer_id, data_id);
  647. }
  648. ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id,
  649. pm_peer_data_bonding_t * p_bonding_data,
  650. pm_store_token_t * p_token)
  651. {
  652. VERIFY_MODULE_INITIALIZED();
  653. VERIFY_PARAM_NOT_NULL(p_bonding_data);
  654. VERIFY_PARAM_NOT_NULL(p_new_peer_id);
  655. ret_code_t err_code;
  656. *p_new_peer_id = pdb_peer_allocate();
  657. if (*p_new_peer_id == PM_PEER_ID_INVALID)
  658. {
  659. return NRF_ERROR_NO_MEM;
  660. }
  661. pm_peer_data_const_t peer_data;
  662. memset(&peer_data, 0, sizeof(pm_peer_data_const_t));
  663. peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t));
  664. peer_data.data_id = PM_PEER_DATA_ID_BONDING;
  665. peer_data.p_bonding_data = p_bonding_data;
  666. err_code = pm_peer_data_bonding_store(*p_new_peer_id, p_bonding_data, p_token);
  667. if (err_code != NRF_SUCCESS)
  668. {
  669. ret_code_t err_code_free = im_peer_free(*p_new_peer_id);
  670. if (err_code_free != NRF_SUCCESS)
  671. {
  672. err_code = NRF_ERROR_INTERNAL;
  673. }
  674. }
  675. return err_code;
  676. }
  677. ret_code_t pm_peer_delete(pm_peer_id_t peer_id)
  678. {
  679. VERIFY_MODULE_INITIALIZED();
  680. return im_peer_free(peer_id);
  681. }
  682. ret_code_t pm_peers_delete(void)
  683. {
  684. VERIFY_MODULE_INITIALIZED();
  685. m_pm.deleting_all = true;
  686. pm_peer_id_t current_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
  687. while (current_peer_id != PM_PEER_ID_INVALID)
  688. {
  689. ret_code_t err_code = pm_peer_delete(current_peer_id);
  690. if (err_code != NRF_SUCCESS)
  691. {
  692. return NRF_ERROR_INTERNAL;
  693. }
  694. current_peer_id = pdb_next_peer_id_get(current_peer_id);
  695. }
  696. return NRF_SUCCESS;
  697. }
  698. ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer,
  699. uint32_t * p_highest_rank,
  700. pm_peer_id_t * p_lowest_ranked_peer,
  701. uint32_t * p_lowest_rank)
  702. {
  703. VERIFY_MODULE_INITIALIZED();
  704. pm_peer_id_t peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
  705. uint32_t peer_rank = 0;
  706. //lint -save -e65 -e64
  707. pm_peer_data_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(peer_rank)),
  708. .p_peer_rank = &peer_rank};
  709. //lint -restore
  710. ret_code_t err_code = pdb_raw_read(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data);
  711. uint32_t highest_rank = 0;
  712. uint32_t lowest_rank = 0xFFFFFFFF;
  713. pm_peer_id_t highest_ranked_peer = PM_PEER_ID_INVALID;
  714. pm_peer_id_t lowest_ranked_peer = PM_PEER_ID_INVALID;
  715. if (err_code == NRF_ERROR_INVALID_PARAM)
  716. {
  717. // No peer IDs exist.
  718. return NRF_ERROR_NOT_FOUND;
  719. }
  720. while ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND))
  721. {
  722. if (err_code == NRF_ERROR_NOT_FOUND)
  723. {
  724. peer_rank = 0;
  725. }
  726. if (peer_rank >= highest_rank)
  727. {
  728. highest_rank = peer_rank;
  729. highest_ranked_peer = peer_id;
  730. }
  731. if (peer_rank < lowest_rank)
  732. {
  733. lowest_rank = peer_rank;
  734. lowest_ranked_peer = peer_id;
  735. }
  736. peer_id = pdb_next_peer_id_get(peer_id);
  737. err_code = pdb_raw_read(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data);
  738. }
  739. if (peer_id == PM_PEER_ID_INVALID)
  740. {
  741. err_code = NRF_SUCCESS;
  742. if (p_highest_ranked_peer != NULL)
  743. {
  744. *p_highest_ranked_peer = highest_ranked_peer;
  745. }
  746. if (p_highest_rank != NULL)
  747. {
  748. *p_highest_rank = highest_rank;
  749. }
  750. if (p_lowest_ranked_peer != NULL)
  751. {
  752. *p_lowest_ranked_peer = lowest_ranked_peer;
  753. }
  754. if (p_lowest_rank != NULL)
  755. {
  756. *p_lowest_rank = lowest_rank;
  757. }
  758. }
  759. else
  760. {
  761. err_code = NRF_ERROR_INTERNAL;
  762. }
  763. return err_code;
  764. }
  765. /**@brief Function for initializing peer rank statistics.
  766. */
  767. static void rank_init(void)
  768. {
  769. ret_code_t err_code = pm_peer_ranks_get(&m_pm.highest_ranked_peer,
  770. &m_pm.current_highest_peer_rank,
  771. NULL,
  772. NULL);
  773. if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND))
  774. {
  775. m_pm.peer_rank_initialized = true;
  776. }
  777. }
  778. ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id)
  779. {
  780. VERIFY_MODULE_INITIALIZED();
  781. ret_code_t err_code;
  782. //lint -save -e65 -e64
  783. pm_peer_data_const_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(m_pm.current_highest_peer_rank)),
  784. .data_id = PM_PEER_DATA_ID_PEER_RANK,
  785. .p_peer_rank = &m_pm.current_highest_peer_rank};
  786. //lint -restore
  787. if (!m_pm.peer_rank_initialized)
  788. {
  789. rank_init();
  790. }
  791. if (!m_pm.peer_rank_initialized || (m_pm.peer_rank_token != PM_STORE_TOKEN_INVALID))
  792. {
  793. err_code = NRF_ERROR_BUSY;
  794. }
  795. else
  796. {
  797. if ((peer_id == m_pm.highest_ranked_peer) && (m_pm.current_highest_peer_rank > 0))
  798. {
  799. pm_evt_t pm_evt;
  800. // The reported peer is already regarded as highest (provided it has an index at all)
  801. err_code = NRF_SUCCESS;
  802. memset(&pm_evt, 0, sizeof(pm_evt));
  803. pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
  804. pm_evt.conn_handle = im_conn_handle_get(peer_id);
  805. pm_evt.peer_id = peer_id;
  806. pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_PEER_RANK;
  807. pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
  808. pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
  809. pm_evt.params.peer_data_update_succeeded.flash_changed = false;
  810. evt_send(&pm_evt);
  811. }
  812. else
  813. {
  814. m_pm.current_highest_peer_rank += 1;
  815. err_code = pdb_raw_store(peer_id, &peer_data, &m_pm.peer_rank_token);
  816. if (err_code != NRF_SUCCESS)
  817. {
  818. m_pm.peer_rank_token = PM_STORE_TOKEN_INVALID;
  819. m_pm.current_highest_peer_rank -= 1;
  820. if ((err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_NO_MEM))
  821. {
  822. err_code = NRF_ERROR_INTERNAL;
  823. }
  824. }
  825. }
  826. }
  827. return err_code;
  828. }