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