Wallbot_CaaS
Dependencies: MPU6050 mbed PID
Fork of BLE_MPU6050_test6_challenge_sb by
ble_bondmngr.cpp
00001 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 #if NEED_BOND_MANAGER /* disabled by default */ 00014 00015 #include "ble_bondmngr.h" 00016 #include <stdlib.h> 00017 #include <stdint.h> 00018 #include <string.h> 00019 #include "nordic_common.h" 00020 #include "nrf_error.h" 00021 #include "ble_gap.h" 00022 #include "ble_srv_common.h " 00023 #include "app_util.h " 00024 #include "nrf_assert.h" 00025 //#include "nrf.h" 00026 #include "nrf51_bitfields.h" 00027 #include "crc16.h " 00028 #include "pstorage.h " 00029 #include "ble_bondmngr_cfg.h" 00030 00031 #define CCCD_SIZE 6 /**< Number of bytes needed for storing the state of one CCCD. */ 00032 #define CRC_SIZE 2 /**< Size of CRC in sys_attribute data. */ 00033 #define SYS_ATTR_BUFFER_MAX_LEN (((BLE_BONDMNGR_CCCD_COUNT + 1) * CCCD_SIZE) + CRC_SIZE) /**< Size of sys_attribute data. */ 00034 #define MAX_NUM_CENTRAL_WHITE_LIST MIN(BLE_BONDMNGR_MAX_BONDED_CENTRALS, 8) /**< Maximum number of whitelisted centrals supported.*/ 00035 #define MAX_BONDS_IN_FLASH 10 /**< Maximum number of bonds that can be stored in flash. */ 00036 #define BOND_MANAGER_DATA_SIGNATURE 0x53240000 00037 00038 /**@defgroup ble_bond_mngr_sec_access Bond Manager Security Status Access Macros 00039 * @brief The following group of macros abstract access to Security Status with a peer. 00040 * @{ 00041 */ 00042 00043 #define SEC_STATUS_INIT_VAL 0x00 /**< Initialization value for security status flags. */ 00044 #define ENC_STATUS_SET_VAL 0x01 /**< Bitmask for encryption status. */ 00045 #define BOND_IN_PROGRESS_SET_VAL 0x02 /**< Bitmask for 'bonding in progress'. */ 00046 00047 00048 /**@brief Macro for setting the Encryption Status for current link. 00049 * 00050 * @details Macro for setting the Encryption Status for current link. 00051 */ 00052 #define ENCRYPTION_STATUS_SET() \ 00053 do \ 00054 { \ 00055 m_sec_con_status |= ENC_STATUS_SET_VAL; \ 00056 } while (0) 00057 00058 /**@brief Macro for getting the Encryption Status for current link. 00059 * 00060 * @details Macro for getting the Encryption Status for current link. 00061 */ 00062 #define ENCRYPTION_STATUS_GET() \ 00063 (((m_sec_con_status & ENC_STATUS_SET_VAL) == 0) ? false : true) 00064 00065 /**@brief Macro for resetting the Encryption Status for current link. 00066 * 00067 * @details Macro for resetting the Encryption Status for current link. 00068 */ 00069 #define ENCRYPTION_STATUS_RESET() \ 00070 do \ 00071 { \ 00072 m_sec_con_status &= (~ENC_STATUS_SET_VAL); \ 00073 } while (0) 00074 00075 00076 /**@brief Macro for resetting the Bonding In Progress status for current link. 00077 * 00078 * @details Macro for resetting the Bonding In Progress status for current link. 00079 */ 00080 #define BONDING_IN_PROGRESS_STATUS_SET() \ 00081 do \ 00082 { \ 00083 m_sec_con_status |= BOND_IN_PROGRESS_SET_VAL; \ 00084 } while (0) 00085 00086 /**@brief Macro for setting the Bonding In Progress status for current link. 00087 * 00088 * @details Macro for setting the Bonding In Progress status for current link. 00089 */ 00090 #define BONDING_IN_PROGRESS_STATUS_GET() \ 00091 (((m_sec_con_status & BOND_IN_PROGRESS_SET_VAL) == 0) ? false: true) 00092 00093 /**@brief Macro for resetting the Bonding In Progress status for current link. 00094 * 00095 * @details Macro for resetting the Bonding In Progress status for current link. 00096 */ 00097 #define BONDING_IN_PROGRESS_STATUS_RESET() \ 00098 do \ 00099 { \ 00100 m_sec_con_status &= (~BOND_IN_PROGRESS_SET_VAL); \ 00101 } while (0) 00102 00103 /**@brief Macro for resetting all security status flags for current link. 00104 * 00105 * @details Macro for resetting all security status flags for current link. 00106 */ 00107 #define SECURITY_STATUS_RESET() \ 00108 do \ 00109 { \ 00110 m_sec_con_status = SEC_STATUS_INIT_VAL; \ 00111 } while (0) 00112 00113 /** @} */ 00114 00115 /**@brief Verify module's initialization status. 00116 * 00117 * @details Verify module's initialization status. Returns NRF_INVALID_STATE in case a module API 00118 * is called without initializing the module. 00119 */ 00120 #define VERIFY_MODULE_INITIALIZED() \ 00121 do \ 00122 { \ 00123 if (!m_is_bondmngr_initialized) \ 00124 { \ 00125 return NRF_ERROR_INVALID_STATE; \ 00126 } \ 00127 } while(0) 00128 00129 00130 /**@brief This structure contains the Bonding Information for one central. 00131 */ 00132 typedef struct 00133 { 00134 int32_t central_handle; /**< Central's handle (NOTE: Size is 32 bits just to make struct size dividable by 4). */ 00135 ble_gap_evt_auth_status_t auth_status; /**< Central authentication data. */ 00136 ble_gap_evt_sec_info_request_t central_id_info; /**< Central identification info. */ 00137 ble_gap_addr_t central_addr; /**< Central's address. */ 00138 } central_bond_t; 00139 00140 STATIC_ASSERT(sizeof(central_bond_t) % 4 == 0); 00141 00142 /**@brief This structure contains the System Attributes information related to one central. 00143 */ 00144 typedef struct 00145 { 00146 int32_t central_handle; /**< Central's handle (NOTE: Size is 32 bits just to make struct size dividable by 4). */ 00147 uint8_t sys_attr[SYS_ATTR_BUFFER_MAX_LEN]; /**< Central sys_attribute data. */ 00148 uint32_t sys_attr_size; /**< Central sys_attribute data's size (NOTE: Size is 32 bits just to make struct size dividable by 4). */ 00149 } central_sys_attr_t; 00150 00151 STATIC_ASSERT(sizeof(central_sys_attr_t) % 4 == 0); 00152 00153 /**@brief This structure contains the Bonding Information and System Attributes related to one 00154 * central. 00155 */ 00156 typedef struct 00157 { 00158 central_bond_t bond; /**< Bonding information. */ 00159 central_sys_attr_t sys_attr; /**< System attribute information. */ 00160 } central_t; 00161 00162 /**@brief This structure contains the whitelisted addresses. 00163 */ 00164 typedef struct 00165 { 00166 int8_t central_handle; /**< Central's handle. */ 00167 ble_gap_addr_t * p_addr; /**< Pointer to the central's address if BLE_GAP_ADDR_TYPE_PUBLIC. */ 00168 } whitelist_addr_t; 00169 00170 /**@brief This structure contains the whitelisted IRKs. 00171 */ 00172 typedef struct 00173 { 00174 int8_t central_handle; /**< Central's handle. */ 00175 ble_gap_irk_t * p_irk; /**< Pointer to the central's irk if available. */ 00176 } whitelist_irk_t; 00177 00178 static bool m_is_bondmngr_initialized = false; /**< Flag for checking if module has been initialized. */ 00179 static ble_bondmngr_init_t m_bondmngr_config; /**< Configuration as specified by the application. */ 00180 static uint16_t m_conn_handle; /**< Current connection handle. */ 00181 static central_t m_central; /**< Current central data. */ 00182 static central_t m_centrals_db[BLE_BONDMNGR_MAX_BONDED_CENTRALS]; /**< Pointer to start of bonded centrals database. */ 00183 static uint8_t m_centrals_in_db_count; /**< Number of bonded centrals. */ 00184 static whitelist_addr_t m_whitelist_addr[MAX_NUM_CENTRAL_WHITE_LIST]; /**< List of central's addresses for the whitelist. */ 00185 static whitelist_irk_t m_whitelist_irk[MAX_NUM_CENTRAL_WHITE_LIST]; /**< List of central's IRKs for the whitelist. */ 00186 static uint8_t m_addr_count; /**< Number of addresses in the whitelist. */ 00187 static uint8_t m_irk_count; /**< Number of IRKs in the whitelist. */ 00188 static uint16_t m_crc_bond_info; /**< Combined CRC for all Bonding Information currently stored in flash. */ 00189 static uint16_t m_crc_sys_attr; /**< Combined CRC for all System Attributes currently stored in flash. */ 00190 static pstorage_handle_t mp_flash_bond_info; /**< Pointer to flash location to write next Bonding Information. */ 00191 static pstorage_handle_t mp_flash_sys_attr; /**< Pointer to flash location to write next System Attribute information. */ 00192 static uint8_t m_bond_info_in_flash_count; /**< Number of Bonding Information currently stored in flash. */ 00193 static uint8_t m_sys_attr_in_flash_count; /**< Number of System Attributes currently stored in flash. */ 00194 static uint8_t m_sec_con_status; /**< Variable to denote security status.*/ 00195 static bool m_bond_loaded; /**< Variable to indicate if the bonding information of the currently connected central is available in the RAM.*/ 00196 static bool m_sys_attr_loaded; /**< Variable to indicate if the system attribute information of the currently connected central is loaded from the database and set in the S110 SoftDevice.*/ 00197 static uint32_t m_bond_crc_array[BLE_BONDMNGR_MAX_BONDED_CENTRALS]; 00198 static uint32_t m_sys_crc_array[BLE_BONDMNGR_MAX_BONDED_CENTRALS]; 00199 00200 /**@brief Function for extracting the CRC from an encoded 32 bit number that typical resides in 00201 * the flash memory 00202 * 00203 * @param[in] header Header containing CRC and magic number. 00204 * @param[out] p_crc Extracted CRC. 00205 * 00206 * @retval NRF_SUCCESS CRC successfully extracted. 00207 * @retval NRF_ERROR_NOT_FOUND Flash seems to be empty. 00208 * @retval NRF_ERROR_INVALID_DATA Header does not contain the magic number. 00209 */ 00210 static uint32_t crc_extract(uint32_t header, uint16_t * p_crc) 00211 { 00212 if ((header & 0xFFFF0000U) == BOND_MANAGER_DATA_SIGNATURE) 00213 { 00214 *p_crc = (uint16_t)(header & 0x0000FFFFU); 00215 00216 return NRF_SUCCESS; 00217 } 00218 else if (header == 0xFFFFFFFFU) 00219 { 00220 return NRF_ERROR_NOT_FOUND; 00221 } 00222 else 00223 { 00224 return NRF_ERROR_INVALID_DATA; 00225 } 00226 } 00227 00228 00229 /**@brief Function for storing the Bonding Information of the specified central to the flash. 00230 * 00231 * @param[in] p_bond Bonding information to be stored. 00232 * 00233 * @return NRF_SUCCESS on success, an error_code otherwise. 00234 */ 00235 static uint32_t bond_info_store(central_bond_t * p_bond) 00236 { 00237 uint32_t err_code; 00238 pstorage_handle_t dest_block; 00239 00240 // Check if flash is full 00241 if (m_bond_info_in_flash_count >= MAX_BONDS_IN_FLASH) 00242 { 00243 return NRF_ERROR_NO_MEM; 00244 } 00245 00246 // Check if this is the first bond to be stored 00247 if (m_bond_info_in_flash_count == 0) 00248 { 00249 // Initialize CRC 00250 m_crc_bond_info = crc16_compute(NULL, 0, NULL); 00251 } 00252 00253 // Get block pointer from base 00254 err_code = pstorage_block_identifier_get(&mp_flash_bond_info,m_bond_info_in_flash_count,&dest_block); 00255 if (err_code != NRF_SUCCESS) 00256 { 00257 return err_code; 00258 } 00259 00260 // Write Bonding Information 00261 err_code = pstorage_store(&dest_block, 00262 (uint8_t *)p_bond, 00263 sizeof(central_bond_t), 00264 sizeof(uint32_t)); 00265 00266 if (err_code != NRF_SUCCESS) 00267 { 00268 return err_code; 00269 } 00270 m_crc_bond_info = crc16_compute((uint8_t *)p_bond, 00271 sizeof(central_bond_t), 00272 &m_crc_bond_info); 00273 00274 // Write header 00275 m_bond_crc_array[m_bond_info_in_flash_count] = (BOND_MANAGER_DATA_SIGNATURE | m_crc_bond_info); 00276 00277 err_code = pstorage_store (&dest_block, (uint8_t *)&m_bond_crc_array[m_bond_info_in_flash_count],sizeof(uint32_t),0); 00278 if (err_code != NRF_SUCCESS) 00279 { 00280 return err_code; 00281 } 00282 00283 m_bond_info_in_flash_count++; 00284 return NRF_SUCCESS; 00285 } 00286 00287 00288 /**@brief Function for storing the System Attributes related to a specified central in flash. 00289 * 00290 * @param[in] p_sys_attr System Attributes to be stored. 00291 * 00292 * @return NRF_SUCCESS on success, an error_code otherwise. 00293 */ 00294 static uint32_t sys_attr_store(central_sys_attr_t * p_sys_attr) 00295 { 00296 uint32_t err_code; 00297 pstorage_handle_t dest_block; 00298 00299 // Check if flash is full. 00300 if (m_sys_attr_in_flash_count >= MAX_BONDS_IN_FLASH) 00301 { 00302 return NRF_ERROR_NO_MEM; 00303 } 00304 00305 // Check if this is the first time any System Attributes is stored. 00306 if (m_sys_attr_in_flash_count == 0) 00307 { 00308 // Initialize CRC 00309 m_crc_sys_attr = crc16_compute(NULL, 0, NULL); 00310 } 00311 00312 00313 // Get block pointer from base 00314 err_code = pstorage_block_identifier_get(&mp_flash_sys_attr,m_sys_attr_in_flash_count,&dest_block); 00315 if (err_code != NRF_SUCCESS) 00316 { 00317 return err_code; 00318 } 00319 00320 // Write System Attributes in flash. 00321 err_code = pstorage_store(&dest_block, 00322 (uint8_t *)p_sys_attr, 00323 sizeof(central_sys_attr_t), 00324 sizeof(uint32_t)); 00325 00326 if (err_code != NRF_SUCCESS) 00327 { 00328 return err_code; 00329 } 00330 m_crc_sys_attr = crc16_compute((uint8_t *)p_sys_attr, 00331 sizeof(central_sys_attr_t), 00332 &m_crc_sys_attr); 00333 00334 // Write header. 00335 m_sys_crc_array[m_sys_attr_in_flash_count] = (BOND_MANAGER_DATA_SIGNATURE | m_crc_sys_attr); 00336 00337 err_code = pstorage_store (&dest_block, 00338 (uint8_t *)&m_sys_crc_array[m_sys_attr_in_flash_count], 00339 sizeof(uint32_t), 00340 0); 00341 if (err_code != NRF_SUCCESS) 00342 { 00343 return err_code; 00344 } 00345 00346 m_sys_attr_in_flash_count++; 00347 00348 00349 return NRF_SUCCESS; 00350 } 00351 00352 00353 /**@brief Function for loading the Bonding Information of one central from flash. 00354 * 00355 * @param[out] p_bond Loaded Bonding Information. 00356 * 00357 * @return NRF_SUCCESS on success, otherwise an error code. 00358 */ 00359 static uint32_t bonding_info_load_from_flash(central_bond_t * p_bond) 00360 { 00361 pstorage_handle_t source_block; 00362 uint32_t err_code; 00363 uint32_t crc; 00364 uint16_t crc_header; 00365 00366 // Check if this is the first bond to be loaded, in which case the 00367 // m_bond_info_in_flash_count variable would have the intial value 0. 00368 if (m_bond_info_in_flash_count == 0) 00369 { 00370 // Initialize CRC. 00371 m_crc_bond_info = crc16_compute(NULL, 0, NULL); 00372 } 00373 00374 // Get block pointer from base 00375 err_code = pstorage_block_identifier_get(&mp_flash_bond_info, 00376 m_bond_info_in_flash_count, 00377 &source_block); 00378 if (err_code != NRF_SUCCESS) 00379 { 00380 return err_code; 00381 } 00382 00383 err_code = pstorage_load((uint8_t *)&crc, &source_block, sizeof(uint32_t), 0); 00384 if (err_code != NRF_SUCCESS) 00385 { 00386 return err_code; 00387 } 00388 00389 // Extract CRC from header. 00390 err_code = crc_extract(crc, &crc_header); 00391 if (err_code != NRF_SUCCESS) 00392 { 00393 return err_code; 00394 } 00395 00396 // Load central. 00397 err_code = pstorage_load((uint8_t *)p_bond, 00398 &source_block, 00399 sizeof(central_bond_t), 00400 sizeof(uint32_t)); 00401 if (err_code != NRF_SUCCESS) 00402 { 00403 return err_code; 00404 } 00405 00406 // Check CRC. 00407 m_crc_bond_info = crc16_compute((uint8_t *)p_bond, 00408 sizeof(central_bond_t), 00409 &m_crc_bond_info); 00410 if (m_crc_bond_info == crc_header) 00411 { 00412 m_bond_info_in_flash_count++; 00413 return NRF_SUCCESS; 00414 } 00415 else 00416 { 00417 return NRF_ERROR_INVALID_DATA; 00418 } 00419 } 00420 00421 00422 00423 /**@brief Function for loading the System Attributes related to one central from flash. 00424 * 00425 * @param[out] p_sys_attr Loaded System Attributes. 00426 * 00427 * @return NRF_SUCCESS on success, otherwise an error code. 00428 */ 00429 static uint32_t sys_attr_load_from_flash(central_sys_attr_t * p_sys_attr) 00430 { 00431 pstorage_handle_t source_block; 00432 uint32_t err_code; 00433 uint32_t crc; 00434 uint16_t crc_header; 00435 00436 // Check if this is the first time System Attributes is loaded from flash, in which case the 00437 // m_sys_attr_in_flash_count variable would have the initial value 0. 00438 if (m_sys_attr_in_flash_count == 0) 00439 { 00440 // Initialize CRC. 00441 m_crc_sys_attr = crc16_compute(NULL, 0, NULL); 00442 } 00443 00444 // Get block pointer from base 00445 err_code = pstorage_block_identifier_get(&mp_flash_sys_attr, 00446 m_sys_attr_in_flash_count, 00447 &source_block); 00448 if (err_code != NRF_SUCCESS) 00449 { 00450 return err_code; 00451 } 00452 00453 err_code = pstorage_load((uint8_t *)&crc, &source_block, sizeof(uint32_t), 0); 00454 if (err_code != NRF_SUCCESS) 00455 { 00456 return err_code; 00457 } 00458 00459 // Extract CRC from header. 00460 err_code = crc_extract(crc, &crc_header); 00461 if (err_code != NRF_SUCCESS) 00462 { 00463 return err_code; 00464 } 00465 00466 err_code = pstorage_load((uint8_t *)p_sys_attr, 00467 &source_block, 00468 sizeof(central_sys_attr_t), 00469 sizeof(uint32_t)); 00470 if (err_code != NRF_SUCCESS) 00471 { 00472 return err_code; 00473 } 00474 00475 // Check CRC. 00476 m_crc_sys_attr = crc16_compute((uint8_t *)p_sys_attr, 00477 sizeof(central_sys_attr_t), 00478 &m_crc_sys_attr); 00479 00480 if (m_crc_sys_attr == crc_header) 00481 { 00482 m_sys_attr_in_flash_count++; 00483 return NRF_SUCCESS; 00484 } 00485 else 00486 { 00487 return NRF_ERROR_INVALID_DATA; 00488 } 00489 } 00490 00491 00492 /**@brief Function for erasing the flash pages that contain Bonding Information and System 00493 * Attributes. 00494 * 00495 * @return NRF_SUCCESS on success, otherwise an error code. 00496 */ 00497 static uint32_t flash_pages_erase(void) 00498 { 00499 uint32_t err_code; 00500 00501 err_code = pstorage_clear(&mp_flash_bond_info, MAX_BONDS_IN_FLASH); 00502 00503 if (err_code == NRF_SUCCESS) 00504 { 00505 err_code = pstorage_clear(&mp_flash_sys_attr, MAX_BONDS_IN_FLASH); 00506 } 00507 00508 return err_code; 00509 } 00510 00511 00512 /**@brief Function for checking if Bonding Information in RAM is different from that in 00513 * flash. 00514 * 00515 * @return TRUE if Bonding Information in flash and RAM are different, FALSE otherwise. 00516 */ 00517 static bool bond_info_changed(void) 00518 { 00519 int i; 00520 uint16_t crc = crc16_compute(NULL, 0, NULL); 00521 00522 // Compute CRC for all bonds in database. 00523 for (i = 0; i < m_centrals_in_db_count; i++) 00524 { 00525 crc = crc16_compute((uint8_t *)&m_centrals_db[i].bond, 00526 sizeof(central_bond_t), 00527 &crc); 00528 } 00529 00530 // Compare the computed CRS to CRC stored in flash. 00531 return (crc != m_crc_bond_info); 00532 } 00533 00534 00535 /**@brief Function for checking if System Attributes in RAM is different from that in flash. 00536 * 00537 * @return TRUE if System Attributes in flash and RAM are different, FALSE otherwise. 00538 */ 00539 static bool sys_attr_changed(void) 00540 { 00541 int i; 00542 uint16_t crc = crc16_compute(NULL, 0, NULL); 00543 00544 // Compute CRC for all System Attributes in database. 00545 for (i = 0; i < m_centrals_in_db_count; i++) 00546 { 00547 crc = crc16_compute((uint8_t *)&m_centrals_db[i].sys_attr, 00548 sizeof(central_sys_attr_t), 00549 &crc); 00550 } 00551 00552 // Compare the CRC of System Attributes in flash with that of the System Attributes in memory. 00553 return (crc != m_crc_sys_attr); 00554 } 00555 00556 00557 /**@brief Function for setting the System Attributes for specified central to the SoftDevice, or 00558 * clearing the System Attributes if central is a previously unknown. 00559 * 00560 * @param[in] p_central Central for which the System Attributes is to be set. 00561 * 00562 * @return NRF_SUCCESS on success, otherwise an error code. 00563 */ 00564 static uint32_t central_sys_attr_set(central_t * p_central) 00565 { 00566 uint8_t * p_sys_attr; 00567 00568 if (m_central.sys_attr.sys_attr_size != 0) 00569 { 00570 if (m_central.sys_attr.sys_attr_size > SYS_ATTR_BUFFER_MAX_LEN) 00571 { 00572 return NRF_ERROR_INTERNAL; 00573 } 00574 00575 p_sys_attr = m_central.sys_attr.sys_attr; 00576 } 00577 else 00578 { 00579 p_sys_attr = NULL; 00580 } 00581 00582 return sd_ble_gatts_sys_attr_set(m_conn_handle, p_sys_attr, m_central.sys_attr.sys_attr_size); 00583 } 00584 00585 00586 /**@brief Function for updating the whitelist data structures. 00587 */ 00588 static void update_whitelist(void) 00589 { 00590 int i; 00591 00592 for (i = 0, m_addr_count = 0, m_irk_count = 0; i < m_centrals_in_db_count; i++) 00593 { 00594 central_bond_t * p_bond = &m_centrals_db[i].bond; 00595 00596 if (p_bond->auth_status.central_kex.irk) 00597 { 00598 m_whitelist_irk[m_irk_count].central_handle = p_bond->central_handle; 00599 m_whitelist_irk[m_irk_count].p_irk = &(p_bond->auth_status.central_keys.irk); 00600 00601 m_irk_count++; 00602 } 00603 00604 if (p_bond->central_addr.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) 00605 { 00606 m_whitelist_addr[m_addr_count].central_handle = p_bond->central_handle; 00607 m_whitelist_addr[m_addr_count].p_addr = &(p_bond->central_addr); 00608 00609 m_addr_count++; 00610 } 00611 } 00612 } 00613 00614 00615 /**@brief Function for handling the authentication status event related to a new central. 00616 * 00617 * @details This function adds the new central to the database and stores the central's Bonding 00618 * Information to flash. It also notifies the application when the new bond is created, 00619 * and sets the System Attributes to prepare the stack for connection with the new 00620 * central. 00621 * 00622 * @param[in] p_auth_status New authentication status. 00623 * 00624 * @return NRF_SUCCESS on success, otherwise an error code. 00625 */ 00626 static uint32_t on_auth_status_from_new_central(ble_gap_evt_auth_status_t * p_auth_status) 00627 { 00628 uint32_t err_code; 00629 00630 if (m_centrals_in_db_count >= BLE_BONDMNGR_MAX_BONDED_CENTRALS) 00631 { 00632 return NRF_ERROR_NO_MEM; 00633 } 00634 00635 // Update central. 00636 m_central.bond.auth_status = *p_auth_status; 00637 m_central.bond.central_id_info.div = p_auth_status->periph_keys.enc_info.div; 00638 m_central.sys_attr.sys_attr_size = 0; 00639 00640 // Add new central to database. 00641 m_central.bond.central_handle = m_centrals_in_db_count; 00642 m_centrals_db[m_centrals_in_db_count++] = m_central; 00643 00644 update_whitelist(); 00645 00646 m_bond_loaded = true; 00647 00648 // Clear System Attributes. 00649 err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); 00650 if (err_code != NRF_SUCCESS) 00651 { 00652 return err_code; 00653 } 00654 00655 // Write new central's Bonding Information to flash. 00656 err_code = bond_info_store(&m_central.bond); 00657 if ((err_code == NRF_ERROR_NO_MEM) && (m_bondmngr_config.evt_handler != NULL)) 00658 { 00659 ble_bondmngr_evt_t evt; 00660 00661 evt.evt_type = BLE_BONDMNGR_EVT_BOND_FLASH_FULL; 00662 evt.central_handle = m_central.bond.central_handle; 00663 evt.central_id = m_central.bond.central_id_info.div; 00664 00665 m_bondmngr_config.evt_handler(&evt); 00666 } 00667 else if (err_code != NRF_SUCCESS) 00668 { 00669 return err_code; 00670 } 00671 00672 // Pass the event to application. 00673 if (m_bondmngr_config.evt_handler != NULL) 00674 { 00675 ble_bondmngr_evt_t evt; 00676 00677 evt.evt_type = BLE_BONDMNGR_EVT_NEW_BOND; 00678 evt.central_handle = m_central.bond.central_handle; 00679 evt.central_id = m_central.bond.central_id_info.div; 00680 00681 m_bondmngr_config.evt_handler(&evt); 00682 } 00683 00684 return NRF_SUCCESS; 00685 } 00686 00687 00688 /**@brief Function for updating the current central's entry in the database. 00689 */ 00690 static uint32_t central_update(void) 00691 { 00692 uint32_t err_code; 00693 int32_t central_handle = m_central.bond.central_handle; 00694 00695 if ((central_handle >= 0) && (central_handle < m_centrals_in_db_count)) 00696 { 00697 // Update the database based on whether the bond and system attributes have 00698 // been loaded or not to avoid overwriting information that was not used in the 00699 // connection session. 00700 if (m_bond_loaded) 00701 { 00702 m_centrals_db[central_handle].bond = m_central.bond; 00703 } 00704 00705 if (m_sys_attr_loaded) 00706 { 00707 m_centrals_db[central_handle].sys_attr = m_central.sys_attr; 00708 } 00709 00710 update_whitelist(); 00711 00712 err_code = NRF_SUCCESS; 00713 } 00714 else 00715 { 00716 err_code = NRF_ERROR_INTERNAL; 00717 } 00718 00719 return err_code; 00720 } 00721 00722 00723 /**@brief Function for searching for the central in the database of known centrals. 00724 * 00725 * @details If the central is found, the variable m_central will be populated with all the 00726 * information (Bonding Information and System Attributes) related to that central. 00727 * 00728 * @param[in] central_id Central Identifier. 00729 * @return NRF_SUCCESS on success, otherwise an error code. 00730 */ 00731 static uint32_t central_find_in_db(uint16_t central_id) 00732 { 00733 int i; 00734 00735 for (i = 0; i < m_centrals_in_db_count; i++) 00736 { 00737 if (central_id == m_centrals_db[i].bond.central_id_info.div) 00738 { 00739 m_central = m_centrals_db[i]; 00740 return NRF_SUCCESS; 00741 } 00742 } 00743 00744 return NRF_ERROR_NOT_FOUND; 00745 } 00746 00747 00748 /**@brief Function for loading all Bonding Information and System Attributes from flash. 00749 * 00750 * @return NRF_SUCCESS on success, otherwise an error code. 00751 */ 00752 static uint32_t load_all_from_flash(void) 00753 { 00754 uint32_t err_code; 00755 int i; 00756 00757 m_centrals_in_db_count = 0; 00758 00759 while (m_centrals_in_db_count < BLE_BONDMNGR_MAX_BONDED_CENTRALS) 00760 { 00761 central_bond_t central_bond_info; 00762 int central_handle; 00763 00764 // Load Bonding Information. 00765 err_code = bonding_info_load_from_flash(¢ral_bond_info); 00766 if (err_code == NRF_ERROR_NOT_FOUND) 00767 { 00768 // No more bonds in flash. 00769 break; 00770 } 00771 else if (err_code != NRF_SUCCESS) 00772 { 00773 return err_code; 00774 } 00775 00776 central_handle = central_bond_info.central_handle; 00777 if (central_handle > m_centrals_in_db_count) 00778 { 00779 // Central handle value(s) missing in flash. This should never happen. 00780 return NRF_ERROR_INVALID_DATA; 00781 } 00782 else 00783 { 00784 // Add/update Bonding Information in central array. 00785 m_centrals_db[central_handle].bond = central_bond_info; 00786 if (central_handle == m_centrals_in_db_count) 00787 { 00788 // New central handle, clear System Attributes. 00789 m_centrals_db[central_handle].sys_attr.sys_attr_size = 0; 00790 m_centrals_db[central_handle].sys_attr.central_handle = INVALID_CENTRAL_HANDLE; 00791 m_centrals_in_db_count++; 00792 } 00793 else 00794 { 00795 // Entry was updated, do nothing. 00796 } 00797 } 00798 } 00799 00800 // Load System Attributes for all previously known centrals. 00801 for (i = 0; i < m_centrals_in_db_count; i++) 00802 { 00803 central_sys_attr_t central_sys_attr; 00804 00805 // Load System Attributes. 00806 err_code = sys_attr_load_from_flash(¢ral_sys_attr); 00807 if (err_code == NRF_ERROR_NOT_FOUND) 00808 { 00809 // No more System Attributes in flash. 00810 break; 00811 } 00812 else if (err_code != NRF_SUCCESS) 00813 { 00814 return err_code; 00815 } 00816 00817 if (central_sys_attr.central_handle > m_centrals_in_db_count) 00818 { 00819 // Central handle value(s) missing in flash. This should never happen. 00820 return NRF_ERROR_INVALID_DATA; 00821 } 00822 else 00823 { 00824 // Add/update Bonding Information in central array. 00825 m_centrals_db[central_sys_attr.central_handle].sys_attr = central_sys_attr; 00826 } 00827 } 00828 00829 // Initialize the remaining empty bond entries in the memory. 00830 for (i = m_centrals_in_db_count; i < BLE_BONDMNGR_MAX_BONDED_CENTRALS; i++) 00831 { 00832 m_centrals_db[i].bond.central_handle = INVALID_CENTRAL_HANDLE; 00833 m_centrals_db[i].sys_attr.sys_attr_size = 0; 00834 m_centrals_db[i].sys_attr.central_handle = INVALID_CENTRAL_HANDLE; 00835 } 00836 00837 // Update whitelist data structures. 00838 update_whitelist(); 00839 00840 return NRF_SUCCESS; 00841 } 00842 00843 00844 /**@brief Function for handling the connected event received from the BLE stack. 00845 * 00846 * @param[in] p_ble_evt Event received from the BLE stack. 00847 */ 00848 static void on_connect(ble_evt_t * p_ble_evt) 00849 { 00850 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; 00851 00852 m_central.bond.central_handle = INVALID_CENTRAL_HANDLE; 00853 m_central.bond.central_addr = p_ble_evt->evt.gap_evt.params.connected.peer_addr; 00854 m_central.sys_attr.sys_attr_size = 0; 00855 00856 if (p_ble_evt->evt.gap_evt.params.connected.irk_match) 00857 { 00858 uint8_t irk_idx = p_ble_evt->evt.gap_evt.params.connected.irk_match_idx; 00859 00860 if ((irk_idx >= MAX_NUM_CENTRAL_WHITE_LIST) || 00861 (m_whitelist_irk[irk_idx].central_handle >= BLE_BONDMNGR_MAX_BONDED_CENTRALS)) 00862 { 00863 m_bondmngr_config.error_handler(NRF_ERROR_INTERNAL); 00864 } 00865 else 00866 { 00867 m_central = m_centrals_db[m_whitelist_irk[irk_idx].central_handle]; 00868 } 00869 } 00870 else 00871 { 00872 int i; 00873 00874 for (i = 0; i < m_addr_count; i++) 00875 { 00876 ble_gap_addr_t * p_cur_addr = m_whitelist_addr[i].p_addr; 00877 00878 if (memcmp(p_cur_addr->addr, m_central.bond.central_addr.addr, BLE_GAP_ADDR_LEN) == 0) 00879 { 00880 m_central = m_centrals_db[m_whitelist_addr[i].central_handle]; 00881 break; 00882 } 00883 } 00884 } 00885 00886 if (m_central.bond.central_handle != INVALID_CENTRAL_HANDLE) 00887 { 00888 // Reset bond and system attributes loaded variables. 00889 m_bond_loaded = false; 00890 m_sys_attr_loaded = false; 00891 00892 // Do not set the system attributes of the central on connection. 00893 if (m_bondmngr_config.evt_handler != NULL) 00894 { 00895 ble_bondmngr_evt_t evt; 00896 00897 evt.evt_type = BLE_BONDMNGR_EVT_CONN_TO_BONDED_CENTRAL; 00898 evt.central_handle = m_central.bond.central_handle; 00899 evt.central_id = m_central.bond.central_id_info.div; 00900 00901 m_bondmngr_config.evt_handler(&evt); 00902 } 00903 } 00904 } 00905 00906 00907 /**@brief Function for handling the 'System Attributes Missing' event received from the 00908 * SoftDevice. 00909 * 00910 * @param[in] p_ble_evt Event received from the BLE stack. 00911 */ 00912 static void on_sys_attr_missing(ble_evt_t * p_ble_evt) 00913 { 00914 uint32_t err_code; 00915 00916 if ( 00917 (m_central.bond.central_handle == INVALID_CENTRAL_HANDLE) || 00918 !ENCRYPTION_STATUS_GET() || 00919 BONDING_IN_PROGRESS_STATUS_GET() 00920 ) 00921 { 00922 err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); 00923 } 00924 else 00925 { 00926 // Current central is valid, use its data. Set the corresponding sys_attr. 00927 err_code = central_sys_attr_set(&m_central); 00928 if (err_code == NRF_SUCCESS) 00929 { 00930 // Set System Attributes loaded status variable. 00931 m_sys_attr_loaded = true; 00932 } 00933 } 00934 00935 if (err_code != NRF_SUCCESS) 00936 { 00937 m_bondmngr_config.error_handler(err_code); 00938 } 00939 } 00940 00941 00942 /**@brief Function for handling the new authentication status event, received from the 00943 * SoftDevice, related to an already bonded central. 00944 * 00945 * @details This function also writes the updated Bonding Information to flash and notifies the 00946 * application. 00947 * 00948 * @param[in] p_auth_status Updated authentication status. 00949 */ 00950 static void auth_status_update(ble_gap_evt_auth_status_t * p_auth_status) 00951 { 00952 uint32_t err_code; 00953 00954 // Authentication status changed, update Bonding Information. 00955 m_central.bond.auth_status = *p_auth_status; 00956 m_central.bond.central_id_info.div = p_auth_status->periph_keys.enc_info.div; 00957 00958 memset(&(m_centrals_db[m_central.bond.central_handle]), 0, sizeof(central_t)); 00959 m_centrals_db[m_central.bond.central_handle] = m_central; 00960 00961 // Write updated Bonding Information to flash. 00962 err_code = bond_info_store(&m_central.bond); 00963 if ((err_code == NRF_ERROR_NO_MEM) && (m_bondmngr_config.evt_handler != NULL)) 00964 { 00965 ble_bondmngr_evt_t evt; 00966 00967 evt.evt_type = BLE_BONDMNGR_EVT_BOND_FLASH_FULL; 00968 evt.central_handle = m_central.bond.central_handle; 00969 evt.central_id = m_central.bond.central_id_info.div; 00970 00971 m_bondmngr_config.evt_handler(&evt); 00972 } 00973 else if (err_code != NRF_SUCCESS) 00974 { 00975 m_bondmngr_config.error_handler(err_code); 00976 } 00977 00978 // Pass the event to the application. 00979 if (m_bondmngr_config.evt_handler != NULL) 00980 { 00981 ble_bondmngr_evt_t evt; 00982 00983 evt.evt_type = BLE_BONDMNGR_EVT_AUTH_STATUS_UPDATED; 00984 evt.central_handle = m_central.bond.central_handle; 00985 evt.central_id = m_central.bond.central_id_info.div; 00986 00987 m_bondmngr_config.evt_handler(&evt); 00988 } 00989 } 00990 00991 00992 /**@brief Function for handling the Authentication Status event received from the BLE stack. 00993 * 00994 * @param[in] p_ble_evt Event received from the BLE stack. 00995 */ 00996 static void on_auth_status(ble_gap_evt_auth_status_t * p_auth_status) 00997 { 00998 if (p_auth_status->auth_status != BLE_GAP_SEC_STATUS_SUCCESS) 00999 { 01000 return; 01001 } 01002 01003 // Verify if its pairing and not bonding 01004 if (!ENCRYPTION_STATUS_GET()) 01005 { 01006 return; 01007 } 01008 01009 if (m_central.bond.central_handle == INVALID_CENTRAL_HANDLE) 01010 { 01011 uint32_t err_code = central_find_in_db(p_auth_status->periph_keys.enc_info.div); 01012 01013 if (err_code == NRF_SUCCESS) 01014 { 01015 // Possible DIV Collision indicate error to application, 01016 // not storing the new LTK 01017 err_code = NRF_ERROR_FORBIDDEN; 01018 } 01019 else 01020 { 01021 // Add the new device to data base 01022 err_code = on_auth_status_from_new_central(p_auth_status); 01023 } 01024 01025 if (err_code != NRF_SUCCESS) 01026 { 01027 m_bondmngr_config.error_handler(err_code); 01028 } 01029 } 01030 else 01031 { 01032 m_bond_loaded = true; 01033 01034 // Receiving a auth status again when already in have existing information! 01035 auth_status_update(p_auth_status); 01036 } 01037 } 01038 01039 01040 /**@brief Function for handling the Security Info Request event received from the BLE stack. 01041 * 01042 * @param[in] p_ble_evt Event received from the BLE stack. 01043 */ 01044 static void on_sec_info_request(ble_evt_t * p_ble_evt) 01045 { 01046 uint32_t err_code; 01047 01048 err_code = central_find_in_db(p_ble_evt->evt.gap_evt.params.sec_info_request.div); 01049 if (err_code == NRF_SUCCESS) 01050 { 01051 // Bond information has been found and loaded for security procedures. Reflect this in the 01052 // status variable 01053 m_bond_loaded = true; 01054 01055 // Central found in the list of bonded central. Use the encryption info for this central. 01056 err_code = sd_ble_gap_sec_info_reply(m_conn_handle, 01057 &m_central.bond.auth_status.periph_keys.enc_info, 01058 NULL); 01059 if (err_code != NRF_SUCCESS) 01060 { 01061 m_bondmngr_config.error_handler(err_code); 01062 } 01063 01064 // Do not set the sys_attr yet, should be set only when sec_update is successful. 01065 } 01066 else if (err_code == NRF_ERROR_NOT_FOUND) 01067 { 01068 m_central.bond.central_id_info = p_ble_evt->evt.gap_evt.params.sec_info_request; 01069 01070 // New central. 01071 err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); 01072 if (err_code != NRF_SUCCESS) 01073 { 01074 m_bondmngr_config.error_handler(err_code); 01075 } 01076 01077 // Initialize the sys_attr. 01078 err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); 01079 } 01080 01081 if (err_code != NRF_SUCCESS) 01082 { 01083 m_bondmngr_config.error_handler(err_code); 01084 } 01085 } 01086 01087 01088 /**@brief Function for handling the Connection Security Update event received from the BLE 01089 * stack. 01090 * 01091 * @param[in] p_ble_evt Event received from the BLE stack. 01092 */ 01093 static void on_sec_update(ble_gap_evt_conn_sec_update_t * p_sec_update) 01094 { 01095 uint8_t security_mode = p_sec_update->conn_sec.sec_mode.sm; 01096 uint8_t security_level = p_sec_update->conn_sec.sec_mode.lv; 01097 01098 if (((security_mode == 1) && (security_level > 1)) || 01099 ((security_mode == 2) && (security_level != 0))) 01100 { 01101 ENCRYPTION_STATUS_SET(); 01102 01103 uint32_t err_code = central_sys_attr_set(&m_central); 01104 01105 if (err_code != NRF_SUCCESS) 01106 { 01107 m_bondmngr_config.error_handler(err_code); 01108 } 01109 else 01110 { 01111 m_sys_attr_loaded = true; 01112 } 01113 01114 if (m_bondmngr_config.evt_handler != NULL) 01115 { 01116 ble_bondmngr_evt_t evt; 01117 01118 evt.evt_type = BLE_BONDMNGR_EVT_ENCRYPTED; 01119 evt.central_handle = m_central.bond.central_handle; 01120 evt.central_id = m_central.bond.central_id_info.div; 01121 01122 m_bondmngr_config.evt_handler(&evt); 01123 } 01124 } 01125 } 01126 01127 01128 /**@brief Function for handling the Connection Security Parameters Request event received from 01129 * the BLE stack. 01130 * 01131 * @param[in] p_ble_evt Event received from the BLE stack. 01132 */ 01133 static void on_sec_param_request(ble_gap_evt_sec_params_request_t * p_sec_update) 01134 { 01135 if (p_sec_update->peer_params.bond) 01136 { 01137 BONDING_IN_PROGRESS_STATUS_SET(); 01138 01139 if (m_central.bond.central_handle != INVALID_CENTRAL_HANDLE) 01140 { 01141 // Bonding request received from a bonded central, make all system attributes null 01142 m_central.sys_attr.sys_attr_size = 0; 01143 memset(m_central.sys_attr.sys_attr, 0, SYS_ATTR_BUFFER_MAX_LEN); 01144 } 01145 } 01146 } 01147 01148 01149 void ble_bondmngr_on_ble_evt(ble_evt_t * p_ble_evt) 01150 { 01151 if (!m_is_bondmngr_initialized) 01152 { 01153 m_bondmngr_config.error_handler(NRF_ERROR_INVALID_STATE); 01154 } 01155 01156 switch (p_ble_evt->header.evt_id) 01157 { 01158 case BLE_GAP_EVT_CONNECTED: 01159 on_connect(p_ble_evt); 01160 break; 01161 01162 // NOTE: All actions to be taken on the Disconnected event are performed in 01163 // ble_bondmngr_bonded_centrals_store(). This function must be called from the 01164 // Disconnected handler of the application before advertising is restarted (to make 01165 // sure the flash blocks are cleared while the radio is inactive). 01166 case BLE_GAP_EVT_DISCONNECTED: 01167 SECURITY_STATUS_RESET(); 01168 break; 01169 01170 case BLE_GATTS_EVT_SYS_ATTR_MISSING: 01171 on_sys_attr_missing(p_ble_evt); 01172 break; 01173 01174 case BLE_GAP_EVT_AUTH_STATUS: 01175 on_auth_status(&p_ble_evt->evt.gap_evt.params.auth_status); 01176 break; 01177 01178 case BLE_GAP_EVT_SEC_INFO_REQUEST: 01179 on_sec_info_request(p_ble_evt); 01180 break; 01181 01182 case BLE_GAP_EVT_SEC_PARAMS_REQUEST: 01183 on_sec_param_request(&p_ble_evt->evt.gap_evt.params.sec_params_request); 01184 break; 01185 01186 case BLE_GAP_EVT_CONN_SEC_UPDATE: 01187 on_sec_update(&p_ble_evt->evt.gap_evt.params.conn_sec_update); 01188 break; 01189 01190 default: 01191 // No implementation needed. 01192 break; 01193 } 01194 } 01195 01196 01197 uint32_t ble_bondmngr_bonded_centrals_store(void) 01198 { 01199 uint32_t err_code; 01200 int i; 01201 01202 VERIFY_MODULE_INITIALIZED(); 01203 01204 if (m_central.bond.central_handle != INVALID_CENTRAL_HANDLE) 01205 { 01206 // Fetch System Attributes from stack. 01207 uint16_t sys_attr_size = SYS_ATTR_BUFFER_MAX_LEN; 01208 01209 err_code = sd_ble_gatts_sys_attr_get(m_conn_handle, 01210 m_central.sys_attr.sys_attr, 01211 &sys_attr_size); 01212 if (err_code != NRF_SUCCESS) 01213 { 01214 return err_code; 01215 } 01216 01217 m_central.sys_attr.central_handle = m_central.bond.central_handle; 01218 m_central.sys_attr.sys_attr_size = (uint16_t)sys_attr_size; 01219 01220 // Update the current central. 01221 err_code = central_update(); 01222 if (err_code != NRF_SUCCESS) 01223 { 01224 return err_code; 01225 } 01226 } 01227 01228 // Save Bonding Information if changed. 01229 if (bond_info_changed()) 01230 { 01231 // Erase flash page. 01232 err_code = pstorage_clear(&mp_flash_bond_info,MAX_BONDS_IN_FLASH); 01233 if (err_code != NRF_SUCCESS) 01234 { 01235 return err_code; 01236 } 01237 01238 // Store bond information for all centrals. 01239 m_bond_info_in_flash_count = 0; 01240 for (i = 0; i < m_centrals_in_db_count; i++) 01241 { 01242 err_code = bond_info_store(&m_centrals_db[i].bond); 01243 if (err_code != NRF_SUCCESS) 01244 { 01245 return err_code; 01246 } 01247 } 01248 } 01249 01250 // Save System Attributes, if changed. 01251 if (sys_attr_changed()) 01252 { 01253 // Erase flash page. 01254 err_code = pstorage_clear(&mp_flash_sys_attr, MAX_BONDS_IN_FLASH); 01255 if (err_code != NRF_SUCCESS) 01256 { 01257 return err_code; 01258 } 01259 01260 // Store System Attributes for all centrals. 01261 m_sys_attr_in_flash_count = 0; 01262 for (i = 0; i < m_centrals_in_db_count; i++) 01263 { 01264 err_code = sys_attr_store(&m_centrals_db[i].sys_attr); 01265 if (err_code != NRF_SUCCESS) 01266 { 01267 return err_code; 01268 } 01269 } 01270 } 01271 01272 m_conn_handle = BLE_CONN_HANDLE_INVALID; 01273 m_central.bond.central_handle = INVALID_CENTRAL_HANDLE; 01274 m_central.sys_attr.central_handle = INVALID_CENTRAL_HANDLE; 01275 m_central.sys_attr.sys_attr_size = 0; 01276 m_bond_loaded = false; 01277 m_sys_attr_loaded = false; 01278 01279 return NRF_SUCCESS; 01280 } 01281 01282 01283 uint32_t ble_bondmngr_sys_attr_store(void) 01284 { 01285 uint32_t err_code; 01286 01287 if (m_central.sys_attr.sys_attr_size == 0) 01288 { 01289 // Connected to new central. So the flash block for System Attributes for this 01290 // central is empty. Hence no erase is needed. 01291 01292 uint16_t sys_attr_size = SYS_ATTR_BUFFER_MAX_LEN; 01293 01294 // Fetch System Attributes from stack. 01295 err_code = sd_ble_gatts_sys_attr_get(m_conn_handle, 01296 m_central.sys_attr.sys_attr, 01297 &sys_attr_size); 01298 01299 if (err_code != NRF_SUCCESS) 01300 { 01301 return err_code; 01302 } 01303 01304 m_central.sys_attr.central_handle = m_central.bond.central_handle; 01305 m_central.sys_attr.sys_attr_size = (uint16_t)sys_attr_size; 01306 01307 // Copy the System Attributes to database. 01308 m_centrals_db[m_central.bond.central_handle].sys_attr = m_central.sys_attr; 01309 01310 // Write new central's System Attributes to flash. 01311 return (sys_attr_store(&m_central.sys_attr)); 01312 } 01313 else 01314 { 01315 // Will not write to flash because System Attributes of an old central would already be 01316 // in flash and so this operation needs a flash erase operation. 01317 return NRF_ERROR_INVALID_STATE; 01318 } 01319 } 01320 01321 01322 uint32_t ble_bondmngr_bonded_centrals_delete(void) 01323 { 01324 VERIFY_MODULE_INITIALIZED(); 01325 01326 m_centrals_in_db_count = 0; 01327 m_bond_info_in_flash_count = 0; 01328 m_sys_attr_in_flash_count = 0; 01329 01330 return flash_pages_erase(); 01331 } 01332 01333 01334 uint32_t ble_bondmngr_central_addr_get(int8_t central_handle, ble_gap_addr_t * p_central_addr) 01335 { 01336 if ( 01337 (central_handle == INVALID_CENTRAL_HANDLE) || 01338 (central_handle >= m_centrals_in_db_count) || 01339 (p_central_addr == NULL) || 01340 ( 01341 m_centrals_db[central_handle].bond.central_addr.addr_type 01342 == 01343 BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 01344 ) 01345 ) 01346 { 01347 return NRF_ERROR_INVALID_PARAM; 01348 } 01349 01350 *p_central_addr = m_centrals_db[central_handle].bond.central_addr; 01351 return NRF_SUCCESS; 01352 } 01353 01354 01355 uint32_t ble_bondmngr_whitelist_get(ble_gap_whitelist_t * p_whitelist) 01356 { 01357 static ble_gap_addr_t * s_addr[MAX_NUM_CENTRAL_WHITE_LIST]; 01358 static ble_gap_irk_t * s_irk[MAX_NUM_CENTRAL_WHITE_LIST]; 01359 01360 int i; 01361 01362 for (i = 0; i < m_irk_count; i++) 01363 { 01364 s_irk[i] = m_whitelist_irk[i].p_irk; 01365 } 01366 for (i = 0; i < m_addr_count; i++) 01367 { 01368 s_addr[i] = m_whitelist_addr[i].p_addr; 01369 } 01370 01371 p_whitelist->addr_count = m_addr_count; 01372 p_whitelist->pp_addrs = (m_addr_count != 0) ? s_addr : NULL; 01373 p_whitelist->irk_count = m_irk_count; 01374 p_whitelist->pp_irks = (m_irk_count != 0) ? s_irk : NULL; 01375 01376 return NRF_SUCCESS; 01377 } 01378 01379 01380 static void bm_pstorage_cb_handler(pstorage_handle_t * handle, 01381 uint8_t op_code, 01382 uint32_t result, 01383 uint8_t * p_data, 01384 uint32_t data_len) 01385 { 01386 if (result != NRF_SUCCESS) 01387 { 01388 m_bondmngr_config.error_handler(result); 01389 } 01390 } 01391 01392 01393 uint32_t ble_bondmngr_init(ble_bondmngr_init_t * p_init) 01394 { 01395 pstorage_module_param_t param; 01396 uint32_t err_code; 01397 01398 if (p_init->error_handler == NULL) 01399 { 01400 return NRF_ERROR_INVALID_PARAM; 01401 } 01402 01403 if (BLE_BONDMNGR_MAX_BONDED_CENTRALS > MAX_BONDS_IN_FLASH) 01404 { 01405 return NRF_ERROR_DATA_SIZE; 01406 } 01407 01408 param.block_size = sizeof (central_bond_t) + sizeof (uint32_t); 01409 param.block_count = MAX_BONDS_IN_FLASH; 01410 param.cb = bm_pstorage_cb_handler; 01411 01412 // Blocks are requested twice, once for bond information and once for system attributes. 01413 // The number of blocks requested has to be the maximum number of bonded devices that 01414 // need to be supported. However, the size of blocks can be different if the sizes of 01415 // system attributes and bonds are not too close. 01416 err_code = pstorage_register(¶m, &mp_flash_bond_info); 01417 if (err_code != NRF_SUCCESS) 01418 { 01419 return err_code; 01420 } 01421 01422 param.block_size = sizeof(central_sys_attr_t) + sizeof(uint32_t); 01423 01424 err_code = pstorage_register(¶m, &mp_flash_sys_attr); 01425 if (err_code != NRF_SUCCESS) 01426 { 01427 return err_code; 01428 } 01429 01430 m_bondmngr_config = *p_init; 01431 01432 memset(&m_central, 0, sizeof(central_t)); 01433 01434 m_central.bond.central_handle = INVALID_CENTRAL_HANDLE; 01435 m_conn_handle = BLE_CONN_HANDLE_INVALID; 01436 m_centrals_in_db_count = 0; 01437 m_bond_info_in_flash_count = 0; 01438 m_sys_attr_in_flash_count = 0; 01439 01440 SECURITY_STATUS_RESET(); 01441 01442 // Erase all stored centrals if specified. 01443 if (m_bondmngr_config.bonds_delete) 01444 { 01445 err_code = flash_pages_erase(); 01446 if (err_code != NRF_SUCCESS) 01447 { 01448 return err_code; 01449 } 01450 01451 m_centrals_in_db_count = 0; 01452 int i; 01453 for (i = m_centrals_in_db_count; i < BLE_BONDMNGR_MAX_BONDED_CENTRALS; i++) 01454 { 01455 m_centrals_db[i].bond.central_handle = INVALID_CENTRAL_HANDLE; 01456 m_centrals_db[i].sys_attr.sys_attr_size = 0; 01457 m_centrals_db[i].sys_attr.central_handle = INVALID_CENTRAL_HANDLE; 01458 } 01459 } 01460 else 01461 { 01462 // Load bond manager data from flash. 01463 err_code = load_all_from_flash(); 01464 if (err_code != NRF_SUCCESS) 01465 { 01466 return err_code; 01467 } 01468 } 01469 01470 m_is_bondmngr_initialized = true; 01471 01472 return NRF_SUCCESS; 01473 } 01474 01475 01476 uint32_t ble_bondmngr_central_ids_get(uint16_t * p_central_ids, uint16_t * p_length) 01477 { 01478 VERIFY_MODULE_INITIALIZED(); 01479 int i; 01480 if (p_length == NULL) 01481 { 01482 return NRF_ERROR_NULL; 01483 } 01484 01485 if (*p_length < m_centrals_in_db_count) 01486 { 01487 // Length of the input array is not enough to fit all known central identifiers. 01488 return NRF_ERROR_DATA_SIZE; 01489 } 01490 01491 *p_length = m_centrals_in_db_count; 01492 if (p_central_ids == NULL) 01493 { 01494 // Only the length field was required to be filled. 01495 return NRF_SUCCESS; 01496 } 01497 01498 for (i = 0; i < m_centrals_in_db_count; i++) 01499 { 01500 p_central_ids[i] = m_centrals_db[i].bond.central_id_info.div; 01501 } 01502 01503 return NRF_SUCCESS; 01504 } 01505 01506 01507 uint32_t ble_bondmngr_bonded_central_delete(uint16_t central_id) 01508 { 01509 VERIFY_MODULE_INITIALIZED(); 01510 01511 int8_t central_handle_to_be_deleted = INVALID_CENTRAL_HANDLE; 01512 uint8_t i; 01513 01514 // Search for the handle of the central. 01515 for (i = 0; i < m_centrals_in_db_count; i++) 01516 { 01517 if (m_centrals_db[i].bond.central_id_info.div == central_id) 01518 { 01519 central_handle_to_be_deleted = i; 01520 break; 01521 } 01522 } 01523 01524 if (central_handle_to_be_deleted == INVALID_CENTRAL_HANDLE) 01525 { 01526 // Central ID not found. 01527 return NRF_ERROR_NOT_FOUND; 01528 } 01529 01530 // Delete the central in RAM. 01531 for (i = central_handle_to_be_deleted; i < (m_centrals_in_db_count - 1); i++) 01532 { 01533 // Overwrite the current central entry with the next one. 01534 m_centrals_db[i] = m_centrals_db[i + 1]; 01535 01536 // Decrement the value of handle. 01537 m_centrals_db[i].bond.central_handle--; 01538 if (INVALID_CENTRAL_HANDLE != m_centrals_db[i].sys_attr.central_handle) 01539 { 01540 m_centrals_db[i].sys_attr.central_handle--; 01541 } 01542 } 01543 01544 // Clear the last database entry. 01545 memset(&(m_centrals_db[m_centrals_in_db_count - 1]), 0, sizeof(central_t)); 01546 01547 m_centrals_in_db_count--; 01548 01549 uint32_t err_code; 01550 01551 // Reinitialize the pointers to the memory where bonding info and System Attributes are stored 01552 // in flash. 01553 // Refresh the data in the flash memory (both Bonding Information and System Attributes). 01554 // Erase and rewrite bonding info and System Attributes. 01555 01556 err_code = flash_pages_erase(); 01557 if (err_code != NRF_SUCCESS) 01558 { 01559 return err_code; 01560 } 01561 01562 m_bond_info_in_flash_count = 0; 01563 m_sys_attr_in_flash_count = 0; 01564 01565 for (i = 0; i < m_centrals_in_db_count; i++) 01566 { 01567 err_code = bond_info_store(&(m_centrals_db[i].bond)); 01568 if (err_code != NRF_SUCCESS) 01569 { 01570 return err_code; 01571 } 01572 } 01573 01574 for (i = 0; i < m_centrals_in_db_count; i++) 01575 { 01576 err_code = sys_attr_store(&(m_centrals_db[i].sys_attr)); 01577 if (err_code != NRF_SUCCESS) 01578 { 01579 return err_code; 01580 } 01581 } 01582 01583 update_whitelist(); 01584 01585 return NRF_SUCCESS; 01586 } 01587 01588 01589 uint32_t ble_bondmngr_is_link_encrypted (bool * status) 01590 { 01591 VERIFY_MODULE_INITIALIZED(); 01592 01593 (*status) = ENCRYPTION_STATUS_GET(); 01594 01595 return NRF_SUCCESS; 01596 } 01597 01598 #endif /* #if NEED_BOND_MANAGER */
Generated on Tue Jul 12 2022 18:33:09 by 1.7.2