peer_manager_handler.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. /**
  2. * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "peer_manager_handler.h"
  41. #include <stdint.h>
  42. #include <string.h>
  43. #include "sdk_errors.h"
  44. #include "app_error.h"
  45. #include "peer_manager.h"
  46. #include "ble_gap.h"
  47. #include "ble_gattc.h"
  48. #include "ble_conn_state.h"
  49. #include "fds.h"
  50. #include "nrf_strerror.h"
  51. #include "sdk_config.h"
  52. #if PM_HANDLER_SEC_DELAY_MS > 0
  53. #include "app_timer.h"
  54. #endif
  55. #define NRF_LOG_MODULE_NAME peer_manager_handler
  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. static const char * m_roles_str[] =
  68. {
  69. "Invalid Role",
  70. "Peripheral",
  71. "Central",
  72. };
  73. static const char * m_sec_procedure_str[] =
  74. {
  75. "Encryption",
  76. "Bonding",
  77. "Pairing",
  78. };
  79. #define PM_EVT_STR(_name) [_name] = STRINGIFY(_name)
  80. static const char * m_event_str[] =
  81. {
  82. PM_EVT_STR(PM_EVT_BONDED_PEER_CONNECTED),
  83. PM_EVT_STR(PM_EVT_CONN_SEC_START),
  84. PM_EVT_STR(PM_EVT_CONN_SEC_SUCCEEDED),
  85. PM_EVT_STR(PM_EVT_CONN_SEC_FAILED),
  86. PM_EVT_STR(PM_EVT_CONN_SEC_CONFIG_REQ),
  87. PM_EVT_STR(PM_EVT_CONN_SEC_PARAMS_REQ),
  88. PM_EVT_STR(PM_EVT_STORAGE_FULL),
  89. PM_EVT_STR(PM_EVT_ERROR_UNEXPECTED),
  90. PM_EVT_STR(PM_EVT_PEER_DATA_UPDATE_SUCCEEDED),
  91. PM_EVT_STR(PM_EVT_PEER_DATA_UPDATE_FAILED),
  92. PM_EVT_STR(PM_EVT_PEER_DELETE_SUCCEEDED),
  93. PM_EVT_STR(PM_EVT_PEER_DELETE_FAILED),
  94. PM_EVT_STR(PM_EVT_PEERS_DELETE_SUCCEEDED),
  95. PM_EVT_STR(PM_EVT_PEERS_DELETE_FAILED),
  96. PM_EVT_STR(PM_EVT_LOCAL_DB_CACHE_APPLIED),
  97. PM_EVT_STR(PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED),
  98. PM_EVT_STR(PM_EVT_SERVICE_CHANGED_IND_SENT),
  99. PM_EVT_STR(PM_EVT_SERVICE_CHANGED_IND_CONFIRMED),
  100. PM_EVT_STR(PM_EVT_SLAVE_SECURITY_REQ),
  101. PM_EVT_STR(PM_EVT_FLASH_GARBAGE_COLLECTED),
  102. PM_EVT_STR(PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED),
  103. };
  104. static const char * m_data_id_str[] =
  105. {
  106. "Outdated (0)",
  107. "Service changed pending flag",
  108. "Outdated (2)",
  109. "Outdated (3)",
  110. "Application data",
  111. "Remote database",
  112. "Peer rank",
  113. "Bonding data",
  114. "Local database",
  115. "Central address resolution",
  116. };
  117. static const char * m_data_action_str[] =
  118. {
  119. "Update",
  120. "Delete"
  121. };
  122. #define PM_SEC_ERR_STR(_name) {.error = _name, .error_str = #_name}
  123. typedef struct
  124. {
  125. pm_sec_error_code_t error;
  126. const char * error_str;
  127. } sec_err_str_t;
  128. static const sec_err_str_t m_pm_sec_error_str[] =
  129. {
  130. PM_SEC_ERR_STR(PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING),
  131. PM_SEC_ERR_STR(PM_CONN_SEC_ERROR_MIC_FAILURE),
  132. PM_SEC_ERR_STR(PM_CONN_SEC_ERROR_DISCONNECT),
  133. PM_SEC_ERR_STR(PM_CONN_SEC_ERROR_SMP_TIMEOUT),
  134. };
  135. static const char * sec_err_string_get(pm_sec_error_code_t error)
  136. {
  137. static char errstr[30];
  138. for (uint32_t i = 0; i < (sizeof(m_pm_sec_error_str)/sizeof(sec_err_str_t)); i++)
  139. {
  140. if (m_pm_sec_error_str[i].error == error)
  141. {
  142. return m_pm_sec_error_str[i].error_str;
  143. }
  144. }
  145. int len = snprintf(errstr, sizeof(errstr), "%s 0x%hx", (error < PM_CONN_SEC_ERROR_BASE)
  146. ? "BLE_GAP_SEC_STATUS"
  147. :"PM_CONN_SEC_ERROR", error);
  148. UNUSED_VARIABLE(len);
  149. return errstr;
  150. }
  151. static void _conn_secure(uint16_t conn_handle, bool force)
  152. {
  153. ret_code_t err_code;
  154. if (!force)
  155. {
  156. pm_conn_sec_status_t status;
  157. err_code = pm_conn_sec_status_get(conn_handle, &status);
  158. if (err_code != BLE_ERROR_INVALID_CONN_HANDLE)
  159. {
  160. APP_ERROR_CHECK(err_code);
  161. }
  162. // If the link is already secured, don't initiate security procedure.
  163. if (status.encrypted)
  164. {
  165. NRF_LOG_DEBUG("Already encrypted, skipping security.");
  166. return;
  167. }
  168. }
  169. err_code = pm_conn_secure(conn_handle, false);
  170. if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_BUSY))
  171. {
  172. // Success.
  173. }
  174. else if (err_code == NRF_ERROR_TIMEOUT)
  175. {
  176. NRF_LOG_WARNING("pm_conn_secure() failed because an SMP timeout is preventing security on "\
  177. "the link. Disconnecting conn_handle %d.",
  178. conn_handle);
  179. err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  180. if (err_code != NRF_SUCCESS)
  181. {
  182. NRF_LOG_WARNING("sd_ble_gap_disconnect() returned %s on conn_handle %d.",
  183. nrf_strerror_get(err_code),
  184. conn_handle);
  185. }
  186. }
  187. else if (err_code == NRF_ERROR_INVALID_DATA)
  188. {
  189. NRF_LOG_WARNING("pm_conn_secure() failed because the stored data for conn_handle %d does "\
  190. "not have a valid key.",
  191. conn_handle);
  192. }
  193. else if (err_code == BLE_ERROR_INVALID_CONN_HANDLE)
  194. {
  195. NRF_LOG_WARNING("pm_conn_secure() failed because conn_handle %d is not a valid connection.",
  196. conn_handle);
  197. }
  198. else
  199. {
  200. NRF_LOG_ERROR("Asserting. pm_conn_secure() returned %s on conn_handle %d.",
  201. nrf_strerror_get(err_code),
  202. conn_handle);
  203. APP_ERROR_CHECK(err_code);
  204. }
  205. }
  206. #if PM_HANDLER_SEC_DELAY_MS > 0
  207. APP_TIMER_DEF(secure_delay_timer);
  208. typedef union
  209. {
  210. struct
  211. {
  212. uint16_t conn_handle;
  213. bool force;
  214. } values;
  215. void * p_void;
  216. } conn_secure_context_t;
  217. STATIC_ASSERT(sizeof(conn_secure_context_t) <= sizeof(void *), "conn_secure_context_t is too large.");
  218. static void _conn_secure(uint16_t conn_handle, bool force);
  219. static void delayed_conn_secure(void * context)
  220. {
  221. conn_secure_context_t sec_context = {.p_void = context};
  222. _conn_secure(sec_context.values.conn_handle, sec_context.values.force);
  223. }
  224. static void conn_secure(uint16_t conn_handle, bool force)
  225. {
  226. ret_code_t err_code;
  227. static bool created = false;
  228. if (!created)
  229. {
  230. err_code = app_timer_create(&secure_delay_timer,
  231. APP_TIMER_MODE_SINGLE_SHOT,
  232. delayed_conn_secure);
  233. APP_ERROR_CHECK(err_code);
  234. created = true;
  235. }
  236. conn_secure_context_t sec_context = {0};
  237. sec_context.values.conn_handle = conn_handle;
  238. sec_context.values.force = force;
  239. err_code = app_timer_start(secure_delay_timer,
  240. APP_TIMER_TICKS(PM_HANDLER_SEC_DELAY_MS),
  241. sec_context.p_void);
  242. APP_ERROR_CHECK(err_code);
  243. }
  244. #else
  245. static void conn_secure(uint16_t conn_handle, bool force)
  246. {
  247. _conn_secure(conn_handle, force);
  248. }
  249. #endif
  250. void pm_handler_on_pm_evt(pm_evt_t const * p_pm_evt)
  251. {
  252. pm_handler_pm_evt_log(p_pm_evt);
  253. if (p_pm_evt->evt_id == PM_EVT_BONDED_PEER_CONNECTED)
  254. {
  255. conn_secure(p_pm_evt->conn_handle, false);
  256. }
  257. else if (p_pm_evt->evt_id == PM_EVT_ERROR_UNEXPECTED)
  258. {
  259. NRF_LOG_ERROR("Asserting.");
  260. APP_ERROR_CHECK(p_pm_evt->params.error_unexpected.error);
  261. }
  262. }
  263. void pm_handler_flash_clean_on_return(void)
  264. {
  265. // Trigger the mechanism to make more room in flash.
  266. pm_evt_t storage_full_evt = {.evt_id = PM_EVT_STORAGE_FULL};
  267. pm_handler_flash_clean(&storage_full_evt);
  268. }
  269. static void rank_highest(pm_peer_id_t peer_id)
  270. {
  271. // Trigger a pm_peer_rank_highest() with internal bookkeeping.
  272. pm_evt_t connected_evt = {.evt_id = PM_EVT_BONDED_PEER_CONNECTED, .peer_id = peer_id};
  273. pm_handler_flash_clean(&connected_evt);
  274. }
  275. void pm_handler_flash_clean(pm_evt_t const * p_pm_evt)
  276. {
  277. ret_code_t err_code;
  278. static bool flash_cleaning = false; // Indicates whether garbage collection is currently being run.
  279. static bool flash_write_after_gc = true; // Indicates whether a successful write happened after the last garbage
  280. // collection. If this is false when flash is full, it means just a
  281. // garbage collection won't work, so some data should be deleted.
  282. #define RANK_QUEUE_SIZE 8 // Size of rank_queue.
  283. #define RANK_QUEUE_INIT() PM_PEER_ID_INVALID, // Initial value of rank_queue.
  284. //lint -save -e40 -e26 -esym(628,MACRO_REPEAT_8)
  285. static pm_peer_id_t rank_queue[8] = {MACRO_REPEAT(RANK_QUEUE_SIZE, RANK_QUEUE_INIT)}; // Queue of rank_highest calls that
  286. // failed because of full flash.
  287. //lint -restore
  288. static int rank_queue_wr = 0; // Write pointer for rank_queue.
  289. switch (p_pm_evt->evt_id)
  290. {
  291. case PM_EVT_BONDED_PEER_CONNECTED:
  292. err_code = pm_peer_rank_highest(p_pm_evt->peer_id);
  293. if ((err_code == NRF_ERROR_STORAGE_FULL) ||
  294. (err_code == NRF_ERROR_BUSY))
  295. {
  296. // Queue pm_peer_rank_highest() call and attempt to clean flash.
  297. rank_queue[rank_queue_wr] = p_pm_evt->peer_id;
  298. rank_queue_wr = (rank_queue_wr + 1) % RANK_QUEUE_SIZE;
  299. pm_handler_flash_clean_on_return();
  300. }
  301. else if ((err_code != NRF_ERROR_NOT_SUPPORTED) &&
  302. (err_code != NRF_ERROR_INVALID_PARAM) &&
  303. (err_code != NRF_ERROR_RESOURCES))
  304. {
  305. APP_ERROR_CHECK(err_code);
  306. }
  307. else
  308. {
  309. NRF_LOG_DEBUG("pm_peer_rank_highest() returned %s for peer id %d",
  310. nrf_strerror_get(err_code),
  311. p_pm_evt->peer_id);
  312. }
  313. break;
  314. case PM_EVT_CONN_SEC_START:
  315. break;
  316. case PM_EVT_CONN_SEC_SUCCEEDED:
  317. if ( (p_pm_evt->params.conn_sec_succeeded.procedure == PM_CONN_SEC_PROCEDURE_BONDING)
  318. || (p_pm_evt->params.conn_sec_succeeded.procedure == PM_CONN_SEC_PROCEDURE_ENCRYPTION))
  319. // PM_CONN_SEC_PROCEDURE_ENCRYPTION in case peer was not recognized at connection time.
  320. {
  321. rank_highest(p_pm_evt->peer_id);
  322. }
  323. break;
  324. case PM_EVT_CONN_SEC_FAILED:
  325. case PM_EVT_CONN_SEC_CONFIG_REQ:
  326. case PM_EVT_CONN_SEC_PARAMS_REQ:
  327. break;
  328. case PM_EVT_STORAGE_FULL:
  329. if (!flash_cleaning)
  330. {
  331. err_code = NRF_SUCCESS;
  332. NRF_LOG_INFO("Attempting to clean flash.");
  333. if (!flash_write_after_gc)
  334. {
  335. // Check whether another user of FDS has deleted a record that can be GCed.
  336. fds_stat_t fds_stats;
  337. err_code = fds_stat(&fds_stats);
  338. APP_ERROR_CHECK(err_code);
  339. flash_write_after_gc = (fds_stats.dirty_records > 0);
  340. }
  341. if (!flash_write_after_gc)
  342. {
  343. pm_peer_id_t peer_id_to_delete;
  344. err_code = pm_peer_ranks_get(NULL, NULL, &peer_id_to_delete, NULL);
  345. if (err_code == NRF_SUCCESS)
  346. {
  347. NRF_LOG_INFO("Deleting lowest ranked peer (peer_id: %d)", peer_id_to_delete);
  348. err_code = pm_peer_delete(peer_id_to_delete);
  349. APP_ERROR_CHECK(err_code);
  350. flash_write_after_gc = true;
  351. }
  352. if (err_code == NRF_ERROR_NOT_FOUND)
  353. {
  354. NRF_LOG_ERROR("There are no peers to delete.");
  355. }
  356. else if (err_code == NRF_ERROR_NOT_SUPPORTED)
  357. {
  358. NRF_LOG_WARNING("Peer ranks functionality is disabled, so no peers are deleted.");
  359. }
  360. else
  361. {
  362. APP_ERROR_CHECK(err_code);
  363. }
  364. }
  365. if (err_code == NRF_SUCCESS)
  366. {
  367. err_code = fds_gc();
  368. if (err_code == NRF_SUCCESS)
  369. {
  370. NRF_LOG_DEBUG("Running flash garbage collection.");
  371. flash_cleaning = true;
  372. }
  373. else if (err_code != FDS_ERR_NO_SPACE_IN_QUEUES)
  374. {
  375. APP_ERROR_CHECK(err_code);
  376. }
  377. }
  378. }
  379. break;
  380. case PM_EVT_ERROR_UNEXPECTED:
  381. break;
  382. case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
  383. flash_write_after_gc = true;
  384. break;
  385. case PM_EVT_PEER_DATA_UPDATE_FAILED:
  386. break;
  387. case PM_EVT_PEER_DELETE_SUCCEEDED:
  388. flash_write_after_gc = true;
  389. break;
  390. case PM_EVT_PEER_DELETE_FAILED:
  391. case PM_EVT_PEERS_DELETE_SUCCEEDED:
  392. case PM_EVT_PEERS_DELETE_FAILED:
  393. case PM_EVT_LOCAL_DB_CACHE_APPLIED:
  394. case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
  395. case PM_EVT_SERVICE_CHANGED_IND_SENT:
  396. case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
  397. case PM_EVT_SLAVE_SECURITY_REQ:
  398. break;
  399. case PM_EVT_FLASH_GARBAGE_COLLECTED:
  400. flash_cleaning = false;
  401. flash_write_after_gc = false;
  402. {
  403. // Reattempt queued pm_peer_rank_highest() calls.
  404. int rank_queue_rd = rank_queue_wr;
  405. for (int i = 0; i < RANK_QUEUE_SIZE; i++)
  406. {
  407. pm_peer_id_t peer_id = rank_queue[(i + rank_queue_rd) % RANK_QUEUE_SIZE];
  408. if (peer_id != PM_PEER_ID_INVALID)
  409. {
  410. rank_queue[(i + rank_queue_rd) % RANK_QUEUE_SIZE] = PM_PEER_ID_INVALID;
  411. rank_highest(peer_id);
  412. }
  413. }
  414. }
  415. break;
  416. case PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED:
  417. flash_cleaning = false;
  418. if (p_pm_evt->params.garbage_collection_failed.error == FDS_ERR_BUSY
  419. || p_pm_evt->params.garbage_collection_failed.error == FDS_ERR_OPERATION_TIMEOUT)
  420. {
  421. // Retry immediately if error is transient.
  422. pm_handler_flash_clean_on_return();
  423. }
  424. break;
  425. default:
  426. break;
  427. }
  428. }
  429. void pm_handler_pm_evt_log(pm_evt_t const * p_pm_evt)
  430. {
  431. NRF_LOG_DEBUG("Event %s", m_event_str[p_pm_evt->evt_id]);
  432. switch (p_pm_evt->evt_id)
  433. {
  434. case PM_EVT_BONDED_PEER_CONNECTED:
  435. NRF_LOG_DEBUG("Previously bonded peer connected: role: %s, conn_handle: %d, peer_id: %d",
  436. m_roles_str[ble_conn_state_role(p_pm_evt->conn_handle)],
  437. p_pm_evt->conn_handle,
  438. p_pm_evt->peer_id);
  439. break;
  440. case PM_EVT_CONN_SEC_START:
  441. NRF_LOG_DEBUG("Connection security procedure started: role: %s, conn_handle: %d, procedure: %s",
  442. m_roles_str[ble_conn_state_role(p_pm_evt->conn_handle)],
  443. p_pm_evt->conn_handle,
  444. m_sec_procedure_str[p_pm_evt->params.conn_sec_start.procedure]);
  445. break;
  446. case PM_EVT_CONN_SEC_SUCCEEDED:
  447. NRF_LOG_INFO("Connection secured: role: %s, conn_handle: %d, procedure: %s",
  448. m_roles_str[ble_conn_state_role(p_pm_evt->conn_handle)],
  449. p_pm_evt->conn_handle,
  450. m_sec_procedure_str[p_pm_evt->params.conn_sec_start.procedure]);
  451. break;
  452. case PM_EVT_CONN_SEC_FAILED:
  453. NRF_LOG_INFO("Connection security failed: role: %s, conn_handle: 0x%x, procedure: %s, error: %d",
  454. m_roles_str[ble_conn_state_role(p_pm_evt->conn_handle)],
  455. p_pm_evt->conn_handle,
  456. m_sec_procedure_str[p_pm_evt->params.conn_sec_start.procedure],
  457. p_pm_evt->params.conn_sec_failed.error);
  458. NRF_LOG_DEBUG("Error (decoded): %s",
  459. sec_err_string_get(p_pm_evt->params.conn_sec_failed.error));
  460. break;
  461. case PM_EVT_CONN_SEC_CONFIG_REQ:
  462. NRF_LOG_DEBUG("Security configuration request");
  463. break;
  464. case PM_EVT_CONN_SEC_PARAMS_REQ:
  465. NRF_LOG_DEBUG("Security parameter request");
  466. break;
  467. case PM_EVT_STORAGE_FULL:
  468. NRF_LOG_WARNING("Flash storage is full");
  469. break;
  470. case PM_EVT_ERROR_UNEXPECTED:
  471. NRF_LOG_ERROR("Unexpected fatal error occurred: error: %s",
  472. nrf_strerror_get(p_pm_evt->params.error_unexpected.error));
  473. break;
  474. case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
  475. NRF_LOG_INFO("Peer data updated in flash: peer_id: %d, data_id: %s, action: %s%s",
  476. p_pm_evt->peer_id,
  477. m_data_id_str[p_pm_evt->params.peer_data_update_succeeded.data_id],
  478. m_data_action_str[p_pm_evt->params.peer_data_update_succeeded.action],
  479. p_pm_evt->params.peer_data_update_succeeded.flash_changed ? "" : ", no change");
  480. break;
  481. case PM_EVT_PEER_DATA_UPDATE_FAILED:
  482. // This can happen if the SoftDevice is too busy with BLE operations.
  483. NRF_LOG_WARNING("Peer data updated failed: peer_id: %d, data_id: %s, action: %s, error: %s",
  484. p_pm_evt->peer_id,
  485. m_data_id_str[p_pm_evt->params.peer_data_update_failed.data_id],
  486. m_data_action_str[p_pm_evt->params.peer_data_update_succeeded.action],
  487. nrf_strerror_get(p_pm_evt->params.peer_data_update_failed.error));
  488. break;
  489. case PM_EVT_PEER_DELETE_SUCCEEDED:
  490. NRF_LOG_ERROR("Peer deleted successfully: peer_id: %d", p_pm_evt->peer_id);
  491. break;
  492. case PM_EVT_PEER_DELETE_FAILED:
  493. NRF_LOG_ERROR("Peer deletion failed: peer_id: %d, error: %s",
  494. p_pm_evt->peer_id,
  495. nrf_strerror_get(p_pm_evt->params.peer_delete_failed.error));
  496. break;
  497. case PM_EVT_PEERS_DELETE_SUCCEEDED:
  498. NRF_LOG_INFO("All peers deleted.");
  499. break;
  500. case PM_EVT_PEERS_DELETE_FAILED:
  501. NRF_LOG_ERROR("All peer deletion failed: error: %s",
  502. nrf_strerror_get(p_pm_evt->params.peers_delete_failed_evt.error));
  503. break;
  504. case PM_EVT_LOCAL_DB_CACHE_APPLIED:
  505. NRF_LOG_DEBUG("Previously stored local DB applied: conn_handle: %d, peer_id: %d",
  506. p_pm_evt->conn_handle,
  507. p_pm_evt->peer_id);
  508. break;
  509. case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
  510. // This can happen when the local DB has changed.
  511. NRF_LOG_WARNING("Local DB could not be applied: conn_handle: %d, peer_id: %d",
  512. p_pm_evt->conn_handle,
  513. p_pm_evt->peer_id);
  514. break;
  515. case PM_EVT_SERVICE_CHANGED_IND_SENT:
  516. NRF_LOG_DEBUG("Sending Service Changed indication.");
  517. break;
  518. case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
  519. NRF_LOG_DEBUG("Service Changed indication confirmed.");
  520. break;
  521. case PM_EVT_SLAVE_SECURITY_REQ:
  522. NRF_LOG_DEBUG("Security Request received from peer.");
  523. break;
  524. case PM_EVT_FLASH_GARBAGE_COLLECTED:
  525. NRF_LOG_DEBUG("Flash garbage collection complete.");
  526. break;
  527. case PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED:
  528. NRF_LOG_WARNING("Flash garbage collection failed with error %s.",
  529. nrf_strerror_get(p_pm_evt->params.garbage_collection_failed.error));
  530. break;
  531. default:
  532. NRF_LOG_WARNING("Unexpected PM event ID: 0x%x.", p_pm_evt->evt_id);
  533. break;
  534. }
  535. }
  536. void pm_handler_disconnect_on_sec_failure(pm_evt_t const * p_pm_evt)
  537. {
  538. ret_code_t err_code;
  539. if (p_pm_evt->evt_id == PM_EVT_CONN_SEC_FAILED)
  540. {
  541. NRF_LOG_WARNING("Disconnecting conn_handle %d.", p_pm_evt->conn_handle);
  542. err_code = sd_ble_gap_disconnect(p_pm_evt->conn_handle,
  543. BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  544. if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_INVALID_CONN_HANDLE))
  545. {
  546. APP_ERROR_CHECK(err_code);
  547. }
  548. }
  549. }
  550. void pm_handler_disconnect_on_insufficient_sec(pm_evt_t const * p_pm_evt,
  551. pm_conn_sec_status_t * p_min_conn_sec)
  552. {
  553. if (p_pm_evt->evt_id == PM_EVT_CONN_SEC_SUCCEEDED)
  554. {
  555. if (!pm_sec_is_sufficient(p_pm_evt->conn_handle, p_min_conn_sec))
  556. {
  557. NRF_LOG_WARNING("Connection security is insufficient, disconnecting.");
  558. ret_code_t err_code = sd_ble_gap_disconnect(p_pm_evt->conn_handle,
  559. BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  560. APP_ERROR_CHECK(err_code);
  561. }
  562. }
  563. }
  564. void pm_handler_secure_on_connection(ble_evt_t const * p_ble_evt)
  565. {
  566. switch (p_ble_evt->header.evt_id)
  567. {
  568. case BLE_GAP_EVT_CONNECTED:
  569. NRF_LOG_DEBUG("Connected, securing connection. conn_handle: %d", p_ble_evt->evt.gap_evt.conn_handle);
  570. conn_secure(p_ble_evt->evt.gap_evt.conn_handle, false);
  571. break;
  572. #if PM_HANDLER_SEC_DELAY_MS > 0
  573. case BLE_GAP_EVT_DISCONNECTED:
  574. {
  575. ret_code_t err_code = app_timer_stop(secure_delay_timer);
  576. APP_ERROR_CHECK(err_code);
  577. } break;
  578. #endif
  579. default:
  580. break;
  581. }
  582. }
  583. void pm_handler_secure_on_error(ble_evt_t const * p_ble_evt)
  584. {
  585. if ((p_ble_evt->header.evt_id >= BLE_GATTC_EVT_BASE) && (p_ble_evt->header.evt_id <= BLE_GATTC_EVT_LAST))
  586. {
  587. if ((p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION) ||
  588. (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION))
  589. {
  590. NRF_LOG_INFO("GATTC procedure (evt id 0x%x) failed because it needs encryption. Bonding: conn_handle=%d",
  591. p_ble_evt->header.evt_id,
  592. p_ble_evt->evt.gattc_evt.conn_handle);
  593. conn_secure(p_ble_evt->evt.gattc_evt.conn_handle, true);
  594. }
  595. }
  596. }