テスト用です。

Dependencies:   mbed

Committer:
jksoft
Date:
Tue Oct 11 11:09:42 2016 +0000
Revision:
0:8468a4403fea
SB??ver;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jksoft 0:8468a4403fea 1 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
jksoft 0:8468a4403fea 2 *
jksoft 0:8468a4403fea 3 * The information contained herein is property of Nordic Semiconductor ASA.
jksoft 0:8468a4403fea 4 * Terms and conditions of usage are described in detail in NORDIC
jksoft 0:8468a4403fea 5 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
jksoft 0:8468a4403fea 6 *
jksoft 0:8468a4403fea 7 * Licensees are granted free, non-transferable use of the information. NO
jksoft 0:8468a4403fea 8 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
jksoft 0:8468a4403fea 9 * the file.
jksoft 0:8468a4403fea 10 *
jksoft 0:8468a4403fea 11 */
jksoft 0:8468a4403fea 12
jksoft 0:8468a4403fea 13 #if NEED_BOND_MANAGER /* disabled by default */
jksoft 0:8468a4403fea 14
jksoft 0:8468a4403fea 15 #include "ble_bondmngr.h"
jksoft 0:8468a4403fea 16 #include <stdlib.h>
jksoft 0:8468a4403fea 17 #include <stdint.h>
jksoft 0:8468a4403fea 18 #include <string.h>
jksoft 0:8468a4403fea 19 #include "nordic_common.h"
jksoft 0:8468a4403fea 20 #include "nrf_error.h"
jksoft 0:8468a4403fea 21 #include "ble_gap.h"
jksoft 0:8468a4403fea 22 #include "ble_srv_common.h"
jksoft 0:8468a4403fea 23 #include "app_util.h"
jksoft 0:8468a4403fea 24 #include "nrf_assert.h"
jksoft 0:8468a4403fea 25 //#include "nrf.h"
jksoft 0:8468a4403fea 26 #include "nrf51_bitfields.h"
jksoft 0:8468a4403fea 27 #include "crc16.h"
jksoft 0:8468a4403fea 28 #include "pstorage.h"
jksoft 0:8468a4403fea 29 #include "ble_bondmngr_cfg.h"
jksoft 0:8468a4403fea 30
jksoft 0:8468a4403fea 31 #define CCCD_SIZE 6 /**< Number of bytes needed for storing the state of one CCCD. */
jksoft 0:8468a4403fea 32 #define CRC_SIZE 2 /**< Size of CRC in sys_attribute data. */
jksoft 0:8468a4403fea 33 #define SYS_ATTR_BUFFER_MAX_LEN (((BLE_BONDMNGR_CCCD_COUNT + 1) * CCCD_SIZE) + CRC_SIZE) /**< Size of sys_attribute data. */
jksoft 0:8468a4403fea 34 #define MAX_NUM_CENTRAL_WHITE_LIST MIN(BLE_BONDMNGR_MAX_BONDED_CENTRALS, 8) /**< Maximum number of whitelisted centrals supported.*/
jksoft 0:8468a4403fea 35 #define MAX_BONDS_IN_FLASH 10 /**< Maximum number of bonds that can be stored in flash. */
jksoft 0:8468a4403fea 36 #define BOND_MANAGER_DATA_SIGNATURE 0x53240000
jksoft 0:8468a4403fea 37
jksoft 0:8468a4403fea 38 /**@defgroup ble_bond_mngr_sec_access Bond Manager Security Status Access Macros
jksoft 0:8468a4403fea 39 * @brief The following group of macros abstract access to Security Status with a peer.
jksoft 0:8468a4403fea 40 * @{
jksoft 0:8468a4403fea 41 */
jksoft 0:8468a4403fea 42
jksoft 0:8468a4403fea 43 #define SEC_STATUS_INIT_VAL 0x00 /**< Initialization value for security status flags. */
jksoft 0:8468a4403fea 44 #define ENC_STATUS_SET_VAL 0x01 /**< Bitmask for encryption status. */
jksoft 0:8468a4403fea 45 #define BOND_IN_PROGRESS_SET_VAL 0x02 /**< Bitmask for 'bonding in progress'. */
jksoft 0:8468a4403fea 46
jksoft 0:8468a4403fea 47
jksoft 0:8468a4403fea 48 /**@brief Macro for setting the Encryption Status for current link.
jksoft 0:8468a4403fea 49 *
jksoft 0:8468a4403fea 50 * @details Macro for setting the Encryption Status for current link.
jksoft 0:8468a4403fea 51 */
jksoft 0:8468a4403fea 52 #define ENCRYPTION_STATUS_SET() \
jksoft 0:8468a4403fea 53 do \
jksoft 0:8468a4403fea 54 { \
jksoft 0:8468a4403fea 55 m_sec_con_status |= ENC_STATUS_SET_VAL; \
jksoft 0:8468a4403fea 56 } while (0)
jksoft 0:8468a4403fea 57
jksoft 0:8468a4403fea 58 /**@brief Macro for getting the Encryption Status for current link.
jksoft 0:8468a4403fea 59 *
jksoft 0:8468a4403fea 60 * @details Macro for getting the Encryption Status for current link.
jksoft 0:8468a4403fea 61 */
jksoft 0:8468a4403fea 62 #define ENCRYPTION_STATUS_GET() \
jksoft 0:8468a4403fea 63 (((m_sec_con_status & ENC_STATUS_SET_VAL) == 0) ? false : true)
jksoft 0:8468a4403fea 64
jksoft 0:8468a4403fea 65 /**@brief Macro for resetting the Encryption Status for current link.
jksoft 0:8468a4403fea 66 *
jksoft 0:8468a4403fea 67 * @details Macro for resetting the Encryption Status for current link.
jksoft 0:8468a4403fea 68 */
jksoft 0:8468a4403fea 69 #define ENCRYPTION_STATUS_RESET() \
jksoft 0:8468a4403fea 70 do \
jksoft 0:8468a4403fea 71 { \
jksoft 0:8468a4403fea 72 m_sec_con_status &= (~ENC_STATUS_SET_VAL); \
jksoft 0:8468a4403fea 73 } while (0)
jksoft 0:8468a4403fea 74
jksoft 0:8468a4403fea 75
jksoft 0:8468a4403fea 76 /**@brief Macro for resetting the Bonding In Progress status for current link.
jksoft 0:8468a4403fea 77 *
jksoft 0:8468a4403fea 78 * @details Macro for resetting the Bonding In Progress status for current link.
jksoft 0:8468a4403fea 79 */
jksoft 0:8468a4403fea 80 #define BONDING_IN_PROGRESS_STATUS_SET() \
jksoft 0:8468a4403fea 81 do \
jksoft 0:8468a4403fea 82 { \
jksoft 0:8468a4403fea 83 m_sec_con_status |= BOND_IN_PROGRESS_SET_VAL; \
jksoft 0:8468a4403fea 84 } while (0)
jksoft 0:8468a4403fea 85
jksoft 0:8468a4403fea 86 /**@brief Macro for setting the Bonding In Progress status for current link.
jksoft 0:8468a4403fea 87 *
jksoft 0:8468a4403fea 88 * @details Macro for setting the Bonding In Progress status for current link.
jksoft 0:8468a4403fea 89 */
jksoft 0:8468a4403fea 90 #define BONDING_IN_PROGRESS_STATUS_GET() \
jksoft 0:8468a4403fea 91 (((m_sec_con_status & BOND_IN_PROGRESS_SET_VAL) == 0) ? false: true)
jksoft 0:8468a4403fea 92
jksoft 0:8468a4403fea 93 /**@brief Macro for resetting the Bonding In Progress status for current link.
jksoft 0:8468a4403fea 94 *
jksoft 0:8468a4403fea 95 * @details Macro for resetting the Bonding In Progress status for current link.
jksoft 0:8468a4403fea 96 */
jksoft 0:8468a4403fea 97 #define BONDING_IN_PROGRESS_STATUS_RESET() \
jksoft 0:8468a4403fea 98 do \
jksoft 0:8468a4403fea 99 { \
jksoft 0:8468a4403fea 100 m_sec_con_status &= (~BOND_IN_PROGRESS_SET_VAL); \
jksoft 0:8468a4403fea 101 } while (0)
jksoft 0:8468a4403fea 102
jksoft 0:8468a4403fea 103 /**@brief Macro for resetting all security status flags for current link.
jksoft 0:8468a4403fea 104 *
jksoft 0:8468a4403fea 105 * @details Macro for resetting all security status flags for current link.
jksoft 0:8468a4403fea 106 */
jksoft 0:8468a4403fea 107 #define SECURITY_STATUS_RESET() \
jksoft 0:8468a4403fea 108 do \
jksoft 0:8468a4403fea 109 { \
jksoft 0:8468a4403fea 110 m_sec_con_status = SEC_STATUS_INIT_VAL; \
jksoft 0:8468a4403fea 111 } while (0)
jksoft 0:8468a4403fea 112
jksoft 0:8468a4403fea 113 /** @} */
jksoft 0:8468a4403fea 114
jksoft 0:8468a4403fea 115 /**@brief Verify module's initialization status.
jksoft 0:8468a4403fea 116 *
jksoft 0:8468a4403fea 117 * @details Verify module's initialization status. Returns NRF_INVALID_STATE in case a module API
jksoft 0:8468a4403fea 118 * is called without initializing the module.
jksoft 0:8468a4403fea 119 */
jksoft 0:8468a4403fea 120 #define VERIFY_MODULE_INITIALIZED() \
jksoft 0:8468a4403fea 121 do \
jksoft 0:8468a4403fea 122 { \
jksoft 0:8468a4403fea 123 if (!m_is_bondmngr_initialized) \
jksoft 0:8468a4403fea 124 { \
jksoft 0:8468a4403fea 125 return NRF_ERROR_INVALID_STATE; \
jksoft 0:8468a4403fea 126 } \
jksoft 0:8468a4403fea 127 } while(0)
jksoft 0:8468a4403fea 128
jksoft 0:8468a4403fea 129
jksoft 0:8468a4403fea 130 /**@brief This structure contains the Bonding Information for one central.
jksoft 0:8468a4403fea 131 */
jksoft 0:8468a4403fea 132 typedef struct
jksoft 0:8468a4403fea 133 {
jksoft 0:8468a4403fea 134 int32_t central_handle; /**< Central's handle (NOTE: Size is 32 bits just to make struct size dividable by 4). */
jksoft 0:8468a4403fea 135 ble_gap_evt_auth_status_t auth_status; /**< Central authentication data. */
jksoft 0:8468a4403fea 136 ble_gap_evt_sec_info_request_t central_id_info; /**< Central identification info. */
jksoft 0:8468a4403fea 137 ble_gap_addr_t central_addr; /**< Central's address. */
jksoft 0:8468a4403fea 138 } central_bond_t;
jksoft 0:8468a4403fea 139
jksoft 0:8468a4403fea 140 STATIC_ASSERT(sizeof(central_bond_t) % 4 == 0);
jksoft 0:8468a4403fea 141
jksoft 0:8468a4403fea 142 /**@brief This structure contains the System Attributes information related to one central.
jksoft 0:8468a4403fea 143 */
jksoft 0:8468a4403fea 144 typedef struct
jksoft 0:8468a4403fea 145 {
jksoft 0:8468a4403fea 146 int32_t central_handle; /**< Central's handle (NOTE: Size is 32 bits just to make struct size dividable by 4). */
jksoft 0:8468a4403fea 147 uint8_t sys_attr[SYS_ATTR_BUFFER_MAX_LEN]; /**< Central sys_attribute data. */
jksoft 0:8468a4403fea 148 uint32_t sys_attr_size; /**< Central sys_attribute data's size (NOTE: Size is 32 bits just to make struct size dividable by 4). */
jksoft 0:8468a4403fea 149 } central_sys_attr_t;
jksoft 0:8468a4403fea 150
jksoft 0:8468a4403fea 151 STATIC_ASSERT(sizeof(central_sys_attr_t) % 4 == 0);
jksoft 0:8468a4403fea 152
jksoft 0:8468a4403fea 153 /**@brief This structure contains the Bonding Information and System Attributes related to one
jksoft 0:8468a4403fea 154 * central.
jksoft 0:8468a4403fea 155 */
jksoft 0:8468a4403fea 156 typedef struct
jksoft 0:8468a4403fea 157 {
jksoft 0:8468a4403fea 158 central_bond_t bond; /**< Bonding information. */
jksoft 0:8468a4403fea 159 central_sys_attr_t sys_attr; /**< System attribute information. */
jksoft 0:8468a4403fea 160 } central_t;
jksoft 0:8468a4403fea 161
jksoft 0:8468a4403fea 162 /**@brief This structure contains the whitelisted addresses.
jksoft 0:8468a4403fea 163 */
jksoft 0:8468a4403fea 164 typedef struct
jksoft 0:8468a4403fea 165 {
jksoft 0:8468a4403fea 166 int8_t central_handle; /**< Central's handle. */
jksoft 0:8468a4403fea 167 ble_gap_addr_t * p_addr; /**< Pointer to the central's address if BLE_GAP_ADDR_TYPE_PUBLIC. */
jksoft 0:8468a4403fea 168 } whitelist_addr_t;
jksoft 0:8468a4403fea 169
jksoft 0:8468a4403fea 170 /**@brief This structure contains the whitelisted IRKs.
jksoft 0:8468a4403fea 171 */
jksoft 0:8468a4403fea 172 typedef struct
jksoft 0:8468a4403fea 173 {
jksoft 0:8468a4403fea 174 int8_t central_handle; /**< Central's handle. */
jksoft 0:8468a4403fea 175 ble_gap_irk_t * p_irk; /**< Pointer to the central's irk if available. */
jksoft 0:8468a4403fea 176 } whitelist_irk_t;
jksoft 0:8468a4403fea 177
jksoft 0:8468a4403fea 178 static bool m_is_bondmngr_initialized = false; /**< Flag for checking if module has been initialized. */
jksoft 0:8468a4403fea 179 static ble_bondmngr_init_t m_bondmngr_config; /**< Configuration as specified by the application. */
jksoft 0:8468a4403fea 180 static uint16_t m_conn_handle; /**< Current connection handle. */
jksoft 0:8468a4403fea 181 static central_t m_central; /**< Current central data. */
jksoft 0:8468a4403fea 182 static central_t m_centrals_db[BLE_BONDMNGR_MAX_BONDED_CENTRALS]; /**< Pointer to start of bonded centrals database. */
jksoft 0:8468a4403fea 183 static uint8_t m_centrals_in_db_count; /**< Number of bonded centrals. */
jksoft 0:8468a4403fea 184 static whitelist_addr_t m_whitelist_addr[MAX_NUM_CENTRAL_WHITE_LIST]; /**< List of central's addresses for the whitelist. */
jksoft 0:8468a4403fea 185 static whitelist_irk_t m_whitelist_irk[MAX_NUM_CENTRAL_WHITE_LIST]; /**< List of central's IRKs for the whitelist. */
jksoft 0:8468a4403fea 186 static uint8_t m_addr_count; /**< Number of addresses in the whitelist. */
jksoft 0:8468a4403fea 187 static uint8_t m_irk_count; /**< Number of IRKs in the whitelist. */
jksoft 0:8468a4403fea 188 static uint16_t m_crc_bond_info; /**< Combined CRC for all Bonding Information currently stored in flash. */
jksoft 0:8468a4403fea 189 static uint16_t m_crc_sys_attr; /**< Combined CRC for all System Attributes currently stored in flash. */
jksoft 0:8468a4403fea 190 static pstorage_handle_t mp_flash_bond_info; /**< Pointer to flash location to write next Bonding Information. */
jksoft 0:8468a4403fea 191 static pstorage_handle_t mp_flash_sys_attr; /**< Pointer to flash location to write next System Attribute information. */
jksoft 0:8468a4403fea 192 static uint8_t m_bond_info_in_flash_count; /**< Number of Bonding Information currently stored in flash. */
jksoft 0:8468a4403fea 193 static uint8_t m_sys_attr_in_flash_count; /**< Number of System Attributes currently stored in flash. */
jksoft 0:8468a4403fea 194 static uint8_t m_sec_con_status; /**< Variable to denote security status.*/
jksoft 0:8468a4403fea 195 static bool m_bond_loaded; /**< Variable to indicate if the bonding information of the currently connected central is available in the RAM.*/
jksoft 0:8468a4403fea 196 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.*/
jksoft 0:8468a4403fea 197 static uint32_t m_bond_crc_array[BLE_BONDMNGR_MAX_BONDED_CENTRALS];
jksoft 0:8468a4403fea 198 static uint32_t m_sys_crc_array[BLE_BONDMNGR_MAX_BONDED_CENTRALS];
jksoft 0:8468a4403fea 199
jksoft 0:8468a4403fea 200 /**@brief Function for extracting the CRC from an encoded 32 bit number that typical resides in
jksoft 0:8468a4403fea 201 * the flash memory
jksoft 0:8468a4403fea 202 *
jksoft 0:8468a4403fea 203 * @param[in] header Header containing CRC and magic number.
jksoft 0:8468a4403fea 204 * @param[out] p_crc Extracted CRC.
jksoft 0:8468a4403fea 205 *
jksoft 0:8468a4403fea 206 * @retval NRF_SUCCESS CRC successfully extracted.
jksoft 0:8468a4403fea 207 * @retval NRF_ERROR_NOT_FOUND Flash seems to be empty.
jksoft 0:8468a4403fea 208 * @retval NRF_ERROR_INVALID_DATA Header does not contain the magic number.
jksoft 0:8468a4403fea 209 */
jksoft 0:8468a4403fea 210 static uint32_t crc_extract(uint32_t header, uint16_t * p_crc)
jksoft 0:8468a4403fea 211 {
jksoft 0:8468a4403fea 212 if ((header & 0xFFFF0000U) == BOND_MANAGER_DATA_SIGNATURE)
jksoft 0:8468a4403fea 213 {
jksoft 0:8468a4403fea 214 *p_crc = (uint16_t)(header & 0x0000FFFFU);
jksoft 0:8468a4403fea 215
jksoft 0:8468a4403fea 216 return NRF_SUCCESS;
jksoft 0:8468a4403fea 217 }
jksoft 0:8468a4403fea 218 else if (header == 0xFFFFFFFFU)
jksoft 0:8468a4403fea 219 {
jksoft 0:8468a4403fea 220 return NRF_ERROR_NOT_FOUND;
jksoft 0:8468a4403fea 221 }
jksoft 0:8468a4403fea 222 else
jksoft 0:8468a4403fea 223 {
jksoft 0:8468a4403fea 224 return NRF_ERROR_INVALID_DATA;
jksoft 0:8468a4403fea 225 }
jksoft 0:8468a4403fea 226 }
jksoft 0:8468a4403fea 227
jksoft 0:8468a4403fea 228
jksoft 0:8468a4403fea 229 /**@brief Function for storing the Bonding Information of the specified central to the flash.
jksoft 0:8468a4403fea 230 *
jksoft 0:8468a4403fea 231 * @param[in] p_bond Bonding information to be stored.
jksoft 0:8468a4403fea 232 *
jksoft 0:8468a4403fea 233 * @return NRF_SUCCESS on success, an error_code otherwise.
jksoft 0:8468a4403fea 234 */
jksoft 0:8468a4403fea 235 static uint32_t bond_info_store(central_bond_t * p_bond)
jksoft 0:8468a4403fea 236 {
jksoft 0:8468a4403fea 237 uint32_t err_code;
jksoft 0:8468a4403fea 238 pstorage_handle_t dest_block;
jksoft 0:8468a4403fea 239
jksoft 0:8468a4403fea 240 // Check if flash is full
jksoft 0:8468a4403fea 241 if (m_bond_info_in_flash_count >= MAX_BONDS_IN_FLASH)
jksoft 0:8468a4403fea 242 {
jksoft 0:8468a4403fea 243 return NRF_ERROR_NO_MEM;
jksoft 0:8468a4403fea 244 }
jksoft 0:8468a4403fea 245
jksoft 0:8468a4403fea 246 // Check if this is the first bond to be stored
jksoft 0:8468a4403fea 247 if (m_bond_info_in_flash_count == 0)
jksoft 0:8468a4403fea 248 {
jksoft 0:8468a4403fea 249 // Initialize CRC
jksoft 0:8468a4403fea 250 m_crc_bond_info = crc16_compute(NULL, 0, NULL);
jksoft 0:8468a4403fea 251 }
jksoft 0:8468a4403fea 252
jksoft 0:8468a4403fea 253 // Get block pointer from base
jksoft 0:8468a4403fea 254 err_code = pstorage_block_identifier_get(&mp_flash_bond_info,m_bond_info_in_flash_count,&dest_block);
jksoft 0:8468a4403fea 255 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 256 {
jksoft 0:8468a4403fea 257 return err_code;
jksoft 0:8468a4403fea 258 }
jksoft 0:8468a4403fea 259
jksoft 0:8468a4403fea 260 // Write Bonding Information
jksoft 0:8468a4403fea 261 err_code = pstorage_store(&dest_block,
jksoft 0:8468a4403fea 262 (uint8_t *)p_bond,
jksoft 0:8468a4403fea 263 sizeof(central_bond_t),
jksoft 0:8468a4403fea 264 sizeof(uint32_t));
jksoft 0:8468a4403fea 265
jksoft 0:8468a4403fea 266 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 267 {
jksoft 0:8468a4403fea 268 return err_code;
jksoft 0:8468a4403fea 269 }
jksoft 0:8468a4403fea 270 m_crc_bond_info = crc16_compute((uint8_t *)p_bond,
jksoft 0:8468a4403fea 271 sizeof(central_bond_t),
jksoft 0:8468a4403fea 272 &m_crc_bond_info);
jksoft 0:8468a4403fea 273
jksoft 0:8468a4403fea 274 // Write header
jksoft 0:8468a4403fea 275 m_bond_crc_array[m_bond_info_in_flash_count] = (BOND_MANAGER_DATA_SIGNATURE | m_crc_bond_info);
jksoft 0:8468a4403fea 276
jksoft 0:8468a4403fea 277 err_code = pstorage_store (&dest_block, (uint8_t *)&m_bond_crc_array[m_bond_info_in_flash_count],sizeof(uint32_t),0);
jksoft 0:8468a4403fea 278 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 279 {
jksoft 0:8468a4403fea 280 return err_code;
jksoft 0:8468a4403fea 281 }
jksoft 0:8468a4403fea 282
jksoft 0:8468a4403fea 283 m_bond_info_in_flash_count++;
jksoft 0:8468a4403fea 284 return NRF_SUCCESS;
jksoft 0:8468a4403fea 285 }
jksoft 0:8468a4403fea 286
jksoft 0:8468a4403fea 287
jksoft 0:8468a4403fea 288 /**@brief Function for storing the System Attributes related to a specified central in flash.
jksoft 0:8468a4403fea 289 *
jksoft 0:8468a4403fea 290 * @param[in] p_sys_attr System Attributes to be stored.
jksoft 0:8468a4403fea 291 *
jksoft 0:8468a4403fea 292 * @return NRF_SUCCESS on success, an error_code otherwise.
jksoft 0:8468a4403fea 293 */
jksoft 0:8468a4403fea 294 static uint32_t sys_attr_store(central_sys_attr_t * p_sys_attr)
jksoft 0:8468a4403fea 295 {
jksoft 0:8468a4403fea 296 uint32_t err_code;
jksoft 0:8468a4403fea 297 pstorage_handle_t dest_block;
jksoft 0:8468a4403fea 298
jksoft 0:8468a4403fea 299 // Check if flash is full.
jksoft 0:8468a4403fea 300 if (m_sys_attr_in_flash_count >= MAX_BONDS_IN_FLASH)
jksoft 0:8468a4403fea 301 {
jksoft 0:8468a4403fea 302 return NRF_ERROR_NO_MEM;
jksoft 0:8468a4403fea 303 }
jksoft 0:8468a4403fea 304
jksoft 0:8468a4403fea 305 // Check if this is the first time any System Attributes is stored.
jksoft 0:8468a4403fea 306 if (m_sys_attr_in_flash_count == 0)
jksoft 0:8468a4403fea 307 {
jksoft 0:8468a4403fea 308 // Initialize CRC
jksoft 0:8468a4403fea 309 m_crc_sys_attr = crc16_compute(NULL, 0, NULL);
jksoft 0:8468a4403fea 310 }
jksoft 0:8468a4403fea 311
jksoft 0:8468a4403fea 312
jksoft 0:8468a4403fea 313 // Get block pointer from base
jksoft 0:8468a4403fea 314 err_code = pstorage_block_identifier_get(&mp_flash_sys_attr,m_sys_attr_in_flash_count,&dest_block);
jksoft 0:8468a4403fea 315 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 316 {
jksoft 0:8468a4403fea 317 return err_code;
jksoft 0:8468a4403fea 318 }
jksoft 0:8468a4403fea 319
jksoft 0:8468a4403fea 320 // Write System Attributes in flash.
jksoft 0:8468a4403fea 321 err_code = pstorage_store(&dest_block,
jksoft 0:8468a4403fea 322 (uint8_t *)p_sys_attr,
jksoft 0:8468a4403fea 323 sizeof(central_sys_attr_t),
jksoft 0:8468a4403fea 324 sizeof(uint32_t));
jksoft 0:8468a4403fea 325
jksoft 0:8468a4403fea 326 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 327 {
jksoft 0:8468a4403fea 328 return err_code;
jksoft 0:8468a4403fea 329 }
jksoft 0:8468a4403fea 330 m_crc_sys_attr = crc16_compute((uint8_t *)p_sys_attr,
jksoft 0:8468a4403fea 331 sizeof(central_sys_attr_t),
jksoft 0:8468a4403fea 332 &m_crc_sys_attr);
jksoft 0:8468a4403fea 333
jksoft 0:8468a4403fea 334 // Write header.
jksoft 0:8468a4403fea 335 m_sys_crc_array[m_sys_attr_in_flash_count] = (BOND_MANAGER_DATA_SIGNATURE | m_crc_sys_attr);
jksoft 0:8468a4403fea 336
jksoft 0:8468a4403fea 337 err_code = pstorage_store (&dest_block,
jksoft 0:8468a4403fea 338 (uint8_t *)&m_sys_crc_array[m_sys_attr_in_flash_count],
jksoft 0:8468a4403fea 339 sizeof(uint32_t),
jksoft 0:8468a4403fea 340 0);
jksoft 0:8468a4403fea 341 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 342 {
jksoft 0:8468a4403fea 343 return err_code;
jksoft 0:8468a4403fea 344 }
jksoft 0:8468a4403fea 345
jksoft 0:8468a4403fea 346 m_sys_attr_in_flash_count++;
jksoft 0:8468a4403fea 347
jksoft 0:8468a4403fea 348
jksoft 0:8468a4403fea 349 return NRF_SUCCESS;
jksoft 0:8468a4403fea 350 }
jksoft 0:8468a4403fea 351
jksoft 0:8468a4403fea 352
jksoft 0:8468a4403fea 353 /**@brief Function for loading the Bonding Information of one central from flash.
jksoft 0:8468a4403fea 354 *
jksoft 0:8468a4403fea 355 * @param[out] p_bond Loaded Bonding Information.
jksoft 0:8468a4403fea 356 *
jksoft 0:8468a4403fea 357 * @return NRF_SUCCESS on success, otherwise an error code.
jksoft 0:8468a4403fea 358 */
jksoft 0:8468a4403fea 359 static uint32_t bonding_info_load_from_flash(central_bond_t * p_bond)
jksoft 0:8468a4403fea 360 {
jksoft 0:8468a4403fea 361 pstorage_handle_t source_block;
jksoft 0:8468a4403fea 362 uint32_t err_code;
jksoft 0:8468a4403fea 363 uint32_t crc;
jksoft 0:8468a4403fea 364 uint16_t crc_header;
jksoft 0:8468a4403fea 365
jksoft 0:8468a4403fea 366 // Check if this is the first bond to be loaded, in which case the
jksoft 0:8468a4403fea 367 // m_bond_info_in_flash_count variable would have the intial value 0.
jksoft 0:8468a4403fea 368 if (m_bond_info_in_flash_count == 0)
jksoft 0:8468a4403fea 369 {
jksoft 0:8468a4403fea 370 // Initialize CRC.
jksoft 0:8468a4403fea 371 m_crc_bond_info = crc16_compute(NULL, 0, NULL);
jksoft 0:8468a4403fea 372 }
jksoft 0:8468a4403fea 373
jksoft 0:8468a4403fea 374 // Get block pointer from base
jksoft 0:8468a4403fea 375 err_code = pstorage_block_identifier_get(&mp_flash_bond_info,
jksoft 0:8468a4403fea 376 m_bond_info_in_flash_count,
jksoft 0:8468a4403fea 377 &source_block);
jksoft 0:8468a4403fea 378 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 379 {
jksoft 0:8468a4403fea 380 return err_code;
jksoft 0:8468a4403fea 381 }
jksoft 0:8468a4403fea 382
jksoft 0:8468a4403fea 383 err_code = pstorage_load((uint8_t *)&crc, &source_block, sizeof(uint32_t), 0);
jksoft 0:8468a4403fea 384 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 385 {
jksoft 0:8468a4403fea 386 return err_code;
jksoft 0:8468a4403fea 387 }
jksoft 0:8468a4403fea 388
jksoft 0:8468a4403fea 389 // Extract CRC from header.
jksoft 0:8468a4403fea 390 err_code = crc_extract(crc, &crc_header);
jksoft 0:8468a4403fea 391 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 392 {
jksoft 0:8468a4403fea 393 return err_code;
jksoft 0:8468a4403fea 394 }
jksoft 0:8468a4403fea 395
jksoft 0:8468a4403fea 396 // Load central.
jksoft 0:8468a4403fea 397 err_code = pstorage_load((uint8_t *)p_bond,
jksoft 0:8468a4403fea 398 &source_block,
jksoft 0:8468a4403fea 399 sizeof(central_bond_t),
jksoft 0:8468a4403fea 400 sizeof(uint32_t));
jksoft 0:8468a4403fea 401 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 402 {
jksoft 0:8468a4403fea 403 return err_code;
jksoft 0:8468a4403fea 404 }
jksoft 0:8468a4403fea 405
jksoft 0:8468a4403fea 406 // Check CRC.
jksoft 0:8468a4403fea 407 m_crc_bond_info = crc16_compute((uint8_t *)p_bond,
jksoft 0:8468a4403fea 408 sizeof(central_bond_t),
jksoft 0:8468a4403fea 409 &m_crc_bond_info);
jksoft 0:8468a4403fea 410 if (m_crc_bond_info == crc_header)
jksoft 0:8468a4403fea 411 {
jksoft 0:8468a4403fea 412 m_bond_info_in_flash_count++;
jksoft 0:8468a4403fea 413 return NRF_SUCCESS;
jksoft 0:8468a4403fea 414 }
jksoft 0:8468a4403fea 415 else
jksoft 0:8468a4403fea 416 {
jksoft 0:8468a4403fea 417 return NRF_ERROR_INVALID_DATA;
jksoft 0:8468a4403fea 418 }
jksoft 0:8468a4403fea 419 }
jksoft 0:8468a4403fea 420
jksoft 0:8468a4403fea 421
jksoft 0:8468a4403fea 422
jksoft 0:8468a4403fea 423 /**@brief Function for loading the System Attributes related to one central from flash.
jksoft 0:8468a4403fea 424 *
jksoft 0:8468a4403fea 425 * @param[out] p_sys_attr Loaded System Attributes.
jksoft 0:8468a4403fea 426 *
jksoft 0:8468a4403fea 427 * @return NRF_SUCCESS on success, otherwise an error code.
jksoft 0:8468a4403fea 428 */
jksoft 0:8468a4403fea 429 static uint32_t sys_attr_load_from_flash(central_sys_attr_t * p_sys_attr)
jksoft 0:8468a4403fea 430 {
jksoft 0:8468a4403fea 431 pstorage_handle_t source_block;
jksoft 0:8468a4403fea 432 uint32_t err_code;
jksoft 0:8468a4403fea 433 uint32_t crc;
jksoft 0:8468a4403fea 434 uint16_t crc_header;
jksoft 0:8468a4403fea 435
jksoft 0:8468a4403fea 436 // Check if this is the first time System Attributes is loaded from flash, in which case the
jksoft 0:8468a4403fea 437 // m_sys_attr_in_flash_count variable would have the initial value 0.
jksoft 0:8468a4403fea 438 if (m_sys_attr_in_flash_count == 0)
jksoft 0:8468a4403fea 439 {
jksoft 0:8468a4403fea 440 // Initialize CRC.
jksoft 0:8468a4403fea 441 m_crc_sys_attr = crc16_compute(NULL, 0, NULL);
jksoft 0:8468a4403fea 442 }
jksoft 0:8468a4403fea 443
jksoft 0:8468a4403fea 444 // Get block pointer from base
jksoft 0:8468a4403fea 445 err_code = pstorage_block_identifier_get(&mp_flash_sys_attr,
jksoft 0:8468a4403fea 446 m_sys_attr_in_flash_count,
jksoft 0:8468a4403fea 447 &source_block);
jksoft 0:8468a4403fea 448 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 449 {
jksoft 0:8468a4403fea 450 return err_code;
jksoft 0:8468a4403fea 451 }
jksoft 0:8468a4403fea 452
jksoft 0:8468a4403fea 453 err_code = pstorage_load((uint8_t *)&crc, &source_block, sizeof(uint32_t), 0);
jksoft 0:8468a4403fea 454 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 455 {
jksoft 0:8468a4403fea 456 return err_code;
jksoft 0:8468a4403fea 457 }
jksoft 0:8468a4403fea 458
jksoft 0:8468a4403fea 459 // Extract CRC from header.
jksoft 0:8468a4403fea 460 err_code = crc_extract(crc, &crc_header);
jksoft 0:8468a4403fea 461 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 462 {
jksoft 0:8468a4403fea 463 return err_code;
jksoft 0:8468a4403fea 464 }
jksoft 0:8468a4403fea 465
jksoft 0:8468a4403fea 466 err_code = pstorage_load((uint8_t *)p_sys_attr,
jksoft 0:8468a4403fea 467 &source_block,
jksoft 0:8468a4403fea 468 sizeof(central_sys_attr_t),
jksoft 0:8468a4403fea 469 sizeof(uint32_t));
jksoft 0:8468a4403fea 470 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 471 {
jksoft 0:8468a4403fea 472 return err_code;
jksoft 0:8468a4403fea 473 }
jksoft 0:8468a4403fea 474
jksoft 0:8468a4403fea 475 // Check CRC.
jksoft 0:8468a4403fea 476 m_crc_sys_attr = crc16_compute((uint8_t *)p_sys_attr,
jksoft 0:8468a4403fea 477 sizeof(central_sys_attr_t),
jksoft 0:8468a4403fea 478 &m_crc_sys_attr);
jksoft 0:8468a4403fea 479
jksoft 0:8468a4403fea 480 if (m_crc_sys_attr == crc_header)
jksoft 0:8468a4403fea 481 {
jksoft 0:8468a4403fea 482 m_sys_attr_in_flash_count++;
jksoft 0:8468a4403fea 483 return NRF_SUCCESS;
jksoft 0:8468a4403fea 484 }
jksoft 0:8468a4403fea 485 else
jksoft 0:8468a4403fea 486 {
jksoft 0:8468a4403fea 487 return NRF_ERROR_INVALID_DATA;
jksoft 0:8468a4403fea 488 }
jksoft 0:8468a4403fea 489 }
jksoft 0:8468a4403fea 490
jksoft 0:8468a4403fea 491
jksoft 0:8468a4403fea 492 /**@brief Function for erasing the flash pages that contain Bonding Information and System
jksoft 0:8468a4403fea 493 * Attributes.
jksoft 0:8468a4403fea 494 *
jksoft 0:8468a4403fea 495 * @return NRF_SUCCESS on success, otherwise an error code.
jksoft 0:8468a4403fea 496 */
jksoft 0:8468a4403fea 497 static uint32_t flash_pages_erase(void)
jksoft 0:8468a4403fea 498 {
jksoft 0:8468a4403fea 499 uint32_t err_code;
jksoft 0:8468a4403fea 500
jksoft 0:8468a4403fea 501 err_code = pstorage_clear(&mp_flash_bond_info, MAX_BONDS_IN_FLASH);
jksoft 0:8468a4403fea 502
jksoft 0:8468a4403fea 503 if (err_code == NRF_SUCCESS)
jksoft 0:8468a4403fea 504 {
jksoft 0:8468a4403fea 505 err_code = pstorage_clear(&mp_flash_sys_attr, MAX_BONDS_IN_FLASH);
jksoft 0:8468a4403fea 506 }
jksoft 0:8468a4403fea 507
jksoft 0:8468a4403fea 508 return err_code;
jksoft 0:8468a4403fea 509 }
jksoft 0:8468a4403fea 510
jksoft 0:8468a4403fea 511
jksoft 0:8468a4403fea 512 /**@brief Function for checking if Bonding Information in RAM is different from that in
jksoft 0:8468a4403fea 513 * flash.
jksoft 0:8468a4403fea 514 *
jksoft 0:8468a4403fea 515 * @return TRUE if Bonding Information in flash and RAM are different, FALSE otherwise.
jksoft 0:8468a4403fea 516 */
jksoft 0:8468a4403fea 517 static bool bond_info_changed(void)
jksoft 0:8468a4403fea 518 {
jksoft 0:8468a4403fea 519 int i;
jksoft 0:8468a4403fea 520 uint16_t crc = crc16_compute(NULL, 0, NULL);
jksoft 0:8468a4403fea 521
jksoft 0:8468a4403fea 522 // Compute CRC for all bonds in database.
jksoft 0:8468a4403fea 523 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 524 {
jksoft 0:8468a4403fea 525 crc = crc16_compute((uint8_t *)&m_centrals_db[i].bond,
jksoft 0:8468a4403fea 526 sizeof(central_bond_t),
jksoft 0:8468a4403fea 527 &crc);
jksoft 0:8468a4403fea 528 }
jksoft 0:8468a4403fea 529
jksoft 0:8468a4403fea 530 // Compare the computed CRS to CRC stored in flash.
jksoft 0:8468a4403fea 531 return (crc != m_crc_bond_info);
jksoft 0:8468a4403fea 532 }
jksoft 0:8468a4403fea 533
jksoft 0:8468a4403fea 534
jksoft 0:8468a4403fea 535 /**@brief Function for checking if System Attributes in RAM is different from that in flash.
jksoft 0:8468a4403fea 536 *
jksoft 0:8468a4403fea 537 * @return TRUE if System Attributes in flash and RAM are different, FALSE otherwise.
jksoft 0:8468a4403fea 538 */
jksoft 0:8468a4403fea 539 static bool sys_attr_changed(void)
jksoft 0:8468a4403fea 540 {
jksoft 0:8468a4403fea 541 int i;
jksoft 0:8468a4403fea 542 uint16_t crc = crc16_compute(NULL, 0, NULL);
jksoft 0:8468a4403fea 543
jksoft 0:8468a4403fea 544 // Compute CRC for all System Attributes in database.
jksoft 0:8468a4403fea 545 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 546 {
jksoft 0:8468a4403fea 547 crc = crc16_compute((uint8_t *)&m_centrals_db[i].sys_attr,
jksoft 0:8468a4403fea 548 sizeof(central_sys_attr_t),
jksoft 0:8468a4403fea 549 &crc);
jksoft 0:8468a4403fea 550 }
jksoft 0:8468a4403fea 551
jksoft 0:8468a4403fea 552 // Compare the CRC of System Attributes in flash with that of the System Attributes in memory.
jksoft 0:8468a4403fea 553 return (crc != m_crc_sys_attr);
jksoft 0:8468a4403fea 554 }
jksoft 0:8468a4403fea 555
jksoft 0:8468a4403fea 556
jksoft 0:8468a4403fea 557 /**@brief Function for setting the System Attributes for specified central to the SoftDevice, or
jksoft 0:8468a4403fea 558 * clearing the System Attributes if central is a previously unknown.
jksoft 0:8468a4403fea 559 *
jksoft 0:8468a4403fea 560 * @param[in] p_central Central for which the System Attributes is to be set.
jksoft 0:8468a4403fea 561 *
jksoft 0:8468a4403fea 562 * @return NRF_SUCCESS on success, otherwise an error code.
jksoft 0:8468a4403fea 563 */
jksoft 0:8468a4403fea 564 static uint32_t central_sys_attr_set(central_t * p_central)
jksoft 0:8468a4403fea 565 {
jksoft 0:8468a4403fea 566 uint8_t * p_sys_attr;
jksoft 0:8468a4403fea 567
jksoft 0:8468a4403fea 568 if (m_central.sys_attr.sys_attr_size != 0)
jksoft 0:8468a4403fea 569 {
jksoft 0:8468a4403fea 570 if (m_central.sys_attr.sys_attr_size > SYS_ATTR_BUFFER_MAX_LEN)
jksoft 0:8468a4403fea 571 {
jksoft 0:8468a4403fea 572 return NRF_ERROR_INTERNAL;
jksoft 0:8468a4403fea 573 }
jksoft 0:8468a4403fea 574
jksoft 0:8468a4403fea 575 p_sys_attr = m_central.sys_attr.sys_attr;
jksoft 0:8468a4403fea 576 }
jksoft 0:8468a4403fea 577 else
jksoft 0:8468a4403fea 578 {
jksoft 0:8468a4403fea 579 p_sys_attr = NULL;
jksoft 0:8468a4403fea 580 }
jksoft 0:8468a4403fea 581
jksoft 0:8468a4403fea 582 return sd_ble_gatts_sys_attr_set(m_conn_handle, p_sys_attr, m_central.sys_attr.sys_attr_size);
jksoft 0:8468a4403fea 583 }
jksoft 0:8468a4403fea 584
jksoft 0:8468a4403fea 585
jksoft 0:8468a4403fea 586 /**@brief Function for updating the whitelist data structures.
jksoft 0:8468a4403fea 587 */
jksoft 0:8468a4403fea 588 static void update_whitelist(void)
jksoft 0:8468a4403fea 589 {
jksoft 0:8468a4403fea 590 int i;
jksoft 0:8468a4403fea 591
jksoft 0:8468a4403fea 592 for (i = 0, m_addr_count = 0, m_irk_count = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 593 {
jksoft 0:8468a4403fea 594 central_bond_t * p_bond = &m_centrals_db[i].bond;
jksoft 0:8468a4403fea 595
jksoft 0:8468a4403fea 596 if (p_bond->auth_status.central_kex.irk)
jksoft 0:8468a4403fea 597 {
jksoft 0:8468a4403fea 598 m_whitelist_irk[m_irk_count].central_handle = p_bond->central_handle;
jksoft 0:8468a4403fea 599 m_whitelist_irk[m_irk_count].p_irk = &(p_bond->auth_status.central_keys.irk);
jksoft 0:8468a4403fea 600
jksoft 0:8468a4403fea 601 m_irk_count++;
jksoft 0:8468a4403fea 602 }
jksoft 0:8468a4403fea 603
jksoft 0:8468a4403fea 604 if (p_bond->central_addr.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
jksoft 0:8468a4403fea 605 {
jksoft 0:8468a4403fea 606 m_whitelist_addr[m_addr_count].central_handle = p_bond->central_handle;
jksoft 0:8468a4403fea 607 m_whitelist_addr[m_addr_count].p_addr = &(p_bond->central_addr);
jksoft 0:8468a4403fea 608
jksoft 0:8468a4403fea 609 m_addr_count++;
jksoft 0:8468a4403fea 610 }
jksoft 0:8468a4403fea 611 }
jksoft 0:8468a4403fea 612 }
jksoft 0:8468a4403fea 613
jksoft 0:8468a4403fea 614
jksoft 0:8468a4403fea 615 /**@brief Function for handling the authentication status event related to a new central.
jksoft 0:8468a4403fea 616 *
jksoft 0:8468a4403fea 617 * @details This function adds the new central to the database and stores the central's Bonding
jksoft 0:8468a4403fea 618 * Information to flash. It also notifies the application when the new bond is created,
jksoft 0:8468a4403fea 619 * and sets the System Attributes to prepare the stack for connection with the new
jksoft 0:8468a4403fea 620 * central.
jksoft 0:8468a4403fea 621 *
jksoft 0:8468a4403fea 622 * @param[in] p_auth_status New authentication status.
jksoft 0:8468a4403fea 623 *
jksoft 0:8468a4403fea 624 * @return NRF_SUCCESS on success, otherwise an error code.
jksoft 0:8468a4403fea 625 */
jksoft 0:8468a4403fea 626 static uint32_t on_auth_status_from_new_central(ble_gap_evt_auth_status_t * p_auth_status)
jksoft 0:8468a4403fea 627 {
jksoft 0:8468a4403fea 628 uint32_t err_code;
jksoft 0:8468a4403fea 629
jksoft 0:8468a4403fea 630 if (m_centrals_in_db_count >= BLE_BONDMNGR_MAX_BONDED_CENTRALS)
jksoft 0:8468a4403fea 631 {
jksoft 0:8468a4403fea 632 return NRF_ERROR_NO_MEM;
jksoft 0:8468a4403fea 633 }
jksoft 0:8468a4403fea 634
jksoft 0:8468a4403fea 635 // Update central.
jksoft 0:8468a4403fea 636 m_central.bond.auth_status = *p_auth_status;
jksoft 0:8468a4403fea 637 m_central.bond.central_id_info.div = p_auth_status->periph_keys.enc_info.div;
jksoft 0:8468a4403fea 638 m_central.sys_attr.sys_attr_size = 0;
jksoft 0:8468a4403fea 639
jksoft 0:8468a4403fea 640 // Add new central to database.
jksoft 0:8468a4403fea 641 m_central.bond.central_handle = m_centrals_in_db_count;
jksoft 0:8468a4403fea 642 m_centrals_db[m_centrals_in_db_count++] = m_central;
jksoft 0:8468a4403fea 643
jksoft 0:8468a4403fea 644 update_whitelist();
jksoft 0:8468a4403fea 645
jksoft 0:8468a4403fea 646 m_bond_loaded = true;
jksoft 0:8468a4403fea 647
jksoft 0:8468a4403fea 648 // Clear System Attributes.
jksoft 0:8468a4403fea 649 err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
jksoft 0:8468a4403fea 650 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 651 {
jksoft 0:8468a4403fea 652 return err_code;
jksoft 0:8468a4403fea 653 }
jksoft 0:8468a4403fea 654
jksoft 0:8468a4403fea 655 // Write new central's Bonding Information to flash.
jksoft 0:8468a4403fea 656 err_code = bond_info_store(&m_central.bond);
jksoft 0:8468a4403fea 657 if ((err_code == NRF_ERROR_NO_MEM) && (m_bondmngr_config.evt_handler != NULL))
jksoft 0:8468a4403fea 658 {
jksoft 0:8468a4403fea 659 ble_bondmngr_evt_t evt;
jksoft 0:8468a4403fea 660
jksoft 0:8468a4403fea 661 evt.evt_type = BLE_BONDMNGR_EVT_BOND_FLASH_FULL;
jksoft 0:8468a4403fea 662 evt.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 663 evt.central_id = m_central.bond.central_id_info.div;
jksoft 0:8468a4403fea 664
jksoft 0:8468a4403fea 665 m_bondmngr_config.evt_handler(&evt);
jksoft 0:8468a4403fea 666 }
jksoft 0:8468a4403fea 667 else if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 668 {
jksoft 0:8468a4403fea 669 return err_code;
jksoft 0:8468a4403fea 670 }
jksoft 0:8468a4403fea 671
jksoft 0:8468a4403fea 672 // Pass the event to application.
jksoft 0:8468a4403fea 673 if (m_bondmngr_config.evt_handler != NULL)
jksoft 0:8468a4403fea 674 {
jksoft 0:8468a4403fea 675 ble_bondmngr_evt_t evt;
jksoft 0:8468a4403fea 676
jksoft 0:8468a4403fea 677 evt.evt_type = BLE_BONDMNGR_EVT_NEW_BOND;
jksoft 0:8468a4403fea 678 evt.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 679 evt.central_id = m_central.bond.central_id_info.div;
jksoft 0:8468a4403fea 680
jksoft 0:8468a4403fea 681 m_bondmngr_config.evt_handler(&evt);
jksoft 0:8468a4403fea 682 }
jksoft 0:8468a4403fea 683
jksoft 0:8468a4403fea 684 return NRF_SUCCESS;
jksoft 0:8468a4403fea 685 }
jksoft 0:8468a4403fea 686
jksoft 0:8468a4403fea 687
jksoft 0:8468a4403fea 688 /**@brief Function for updating the current central's entry in the database.
jksoft 0:8468a4403fea 689 */
jksoft 0:8468a4403fea 690 static uint32_t central_update(void)
jksoft 0:8468a4403fea 691 {
jksoft 0:8468a4403fea 692 uint32_t err_code;
jksoft 0:8468a4403fea 693 int32_t central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 694
jksoft 0:8468a4403fea 695 if ((central_handle >= 0) && (central_handle < m_centrals_in_db_count))
jksoft 0:8468a4403fea 696 {
jksoft 0:8468a4403fea 697 // Update the database based on whether the bond and system attributes have
jksoft 0:8468a4403fea 698 // been loaded or not to avoid overwriting information that was not used in the
jksoft 0:8468a4403fea 699 // connection session.
jksoft 0:8468a4403fea 700 if (m_bond_loaded)
jksoft 0:8468a4403fea 701 {
jksoft 0:8468a4403fea 702 m_centrals_db[central_handle].bond = m_central.bond;
jksoft 0:8468a4403fea 703 }
jksoft 0:8468a4403fea 704
jksoft 0:8468a4403fea 705 if (m_sys_attr_loaded)
jksoft 0:8468a4403fea 706 {
jksoft 0:8468a4403fea 707 m_centrals_db[central_handle].sys_attr = m_central.sys_attr;
jksoft 0:8468a4403fea 708 }
jksoft 0:8468a4403fea 709
jksoft 0:8468a4403fea 710 update_whitelist();
jksoft 0:8468a4403fea 711
jksoft 0:8468a4403fea 712 err_code = NRF_SUCCESS;
jksoft 0:8468a4403fea 713 }
jksoft 0:8468a4403fea 714 else
jksoft 0:8468a4403fea 715 {
jksoft 0:8468a4403fea 716 err_code = NRF_ERROR_INTERNAL;
jksoft 0:8468a4403fea 717 }
jksoft 0:8468a4403fea 718
jksoft 0:8468a4403fea 719 return err_code;
jksoft 0:8468a4403fea 720 }
jksoft 0:8468a4403fea 721
jksoft 0:8468a4403fea 722
jksoft 0:8468a4403fea 723 /**@brief Function for searching for the central in the database of known centrals.
jksoft 0:8468a4403fea 724 *
jksoft 0:8468a4403fea 725 * @details If the central is found, the variable m_central will be populated with all the
jksoft 0:8468a4403fea 726 * information (Bonding Information and System Attributes) related to that central.
jksoft 0:8468a4403fea 727 *
jksoft 0:8468a4403fea 728 * @param[in] central_id Central Identifier.
jksoft 0:8468a4403fea 729 * @return NRF_SUCCESS on success, otherwise an error code.
jksoft 0:8468a4403fea 730 */
jksoft 0:8468a4403fea 731 static uint32_t central_find_in_db(uint16_t central_id)
jksoft 0:8468a4403fea 732 {
jksoft 0:8468a4403fea 733 int i;
jksoft 0:8468a4403fea 734
jksoft 0:8468a4403fea 735 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 736 {
jksoft 0:8468a4403fea 737 if (central_id == m_centrals_db[i].bond.central_id_info.div)
jksoft 0:8468a4403fea 738 {
jksoft 0:8468a4403fea 739 m_central = m_centrals_db[i];
jksoft 0:8468a4403fea 740 return NRF_SUCCESS;
jksoft 0:8468a4403fea 741 }
jksoft 0:8468a4403fea 742 }
jksoft 0:8468a4403fea 743
jksoft 0:8468a4403fea 744 return NRF_ERROR_NOT_FOUND;
jksoft 0:8468a4403fea 745 }
jksoft 0:8468a4403fea 746
jksoft 0:8468a4403fea 747
jksoft 0:8468a4403fea 748 /**@brief Function for loading all Bonding Information and System Attributes from flash.
jksoft 0:8468a4403fea 749 *
jksoft 0:8468a4403fea 750 * @return NRF_SUCCESS on success, otherwise an error code.
jksoft 0:8468a4403fea 751 */
jksoft 0:8468a4403fea 752 static uint32_t load_all_from_flash(void)
jksoft 0:8468a4403fea 753 {
jksoft 0:8468a4403fea 754 uint32_t err_code;
jksoft 0:8468a4403fea 755 int i;
jksoft 0:8468a4403fea 756
jksoft 0:8468a4403fea 757 m_centrals_in_db_count = 0;
jksoft 0:8468a4403fea 758
jksoft 0:8468a4403fea 759 while (m_centrals_in_db_count < BLE_BONDMNGR_MAX_BONDED_CENTRALS)
jksoft 0:8468a4403fea 760 {
jksoft 0:8468a4403fea 761 central_bond_t central_bond_info;
jksoft 0:8468a4403fea 762 int central_handle;
jksoft 0:8468a4403fea 763
jksoft 0:8468a4403fea 764 // Load Bonding Information.
jksoft 0:8468a4403fea 765 err_code = bonding_info_load_from_flash(&central_bond_info);
jksoft 0:8468a4403fea 766 if (err_code == NRF_ERROR_NOT_FOUND)
jksoft 0:8468a4403fea 767 {
jksoft 0:8468a4403fea 768 // No more bonds in flash.
jksoft 0:8468a4403fea 769 break;
jksoft 0:8468a4403fea 770 }
jksoft 0:8468a4403fea 771 else if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 772 {
jksoft 0:8468a4403fea 773 return err_code;
jksoft 0:8468a4403fea 774 }
jksoft 0:8468a4403fea 775
jksoft 0:8468a4403fea 776 central_handle = central_bond_info.central_handle;
jksoft 0:8468a4403fea 777 if (central_handle > m_centrals_in_db_count)
jksoft 0:8468a4403fea 778 {
jksoft 0:8468a4403fea 779 // Central handle value(s) missing in flash. This should never happen.
jksoft 0:8468a4403fea 780 return NRF_ERROR_INVALID_DATA;
jksoft 0:8468a4403fea 781 }
jksoft 0:8468a4403fea 782 else
jksoft 0:8468a4403fea 783 {
jksoft 0:8468a4403fea 784 // Add/update Bonding Information in central array.
jksoft 0:8468a4403fea 785 m_centrals_db[central_handle].bond = central_bond_info;
jksoft 0:8468a4403fea 786 if (central_handle == m_centrals_in_db_count)
jksoft 0:8468a4403fea 787 {
jksoft 0:8468a4403fea 788 // New central handle, clear System Attributes.
jksoft 0:8468a4403fea 789 m_centrals_db[central_handle].sys_attr.sys_attr_size = 0;
jksoft 0:8468a4403fea 790 m_centrals_db[central_handle].sys_attr.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 791 m_centrals_in_db_count++;
jksoft 0:8468a4403fea 792 }
jksoft 0:8468a4403fea 793 else
jksoft 0:8468a4403fea 794 {
jksoft 0:8468a4403fea 795 // Entry was updated, do nothing.
jksoft 0:8468a4403fea 796 }
jksoft 0:8468a4403fea 797 }
jksoft 0:8468a4403fea 798 }
jksoft 0:8468a4403fea 799
jksoft 0:8468a4403fea 800 // Load System Attributes for all previously known centrals.
jksoft 0:8468a4403fea 801 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 802 {
jksoft 0:8468a4403fea 803 central_sys_attr_t central_sys_attr;
jksoft 0:8468a4403fea 804
jksoft 0:8468a4403fea 805 // Load System Attributes.
jksoft 0:8468a4403fea 806 err_code = sys_attr_load_from_flash(&central_sys_attr);
jksoft 0:8468a4403fea 807 if (err_code == NRF_ERROR_NOT_FOUND)
jksoft 0:8468a4403fea 808 {
jksoft 0:8468a4403fea 809 // No more System Attributes in flash.
jksoft 0:8468a4403fea 810 break;
jksoft 0:8468a4403fea 811 }
jksoft 0:8468a4403fea 812 else if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 813 {
jksoft 0:8468a4403fea 814 return err_code;
jksoft 0:8468a4403fea 815 }
jksoft 0:8468a4403fea 816
jksoft 0:8468a4403fea 817 if (central_sys_attr.central_handle > m_centrals_in_db_count)
jksoft 0:8468a4403fea 818 {
jksoft 0:8468a4403fea 819 // Central handle value(s) missing in flash. This should never happen.
jksoft 0:8468a4403fea 820 return NRF_ERROR_INVALID_DATA;
jksoft 0:8468a4403fea 821 }
jksoft 0:8468a4403fea 822 else
jksoft 0:8468a4403fea 823 {
jksoft 0:8468a4403fea 824 // Add/update Bonding Information in central array.
jksoft 0:8468a4403fea 825 m_centrals_db[central_sys_attr.central_handle].sys_attr = central_sys_attr;
jksoft 0:8468a4403fea 826 }
jksoft 0:8468a4403fea 827 }
jksoft 0:8468a4403fea 828
jksoft 0:8468a4403fea 829 // Initialize the remaining empty bond entries in the memory.
jksoft 0:8468a4403fea 830 for (i = m_centrals_in_db_count; i < BLE_BONDMNGR_MAX_BONDED_CENTRALS; i++)
jksoft 0:8468a4403fea 831 {
jksoft 0:8468a4403fea 832 m_centrals_db[i].bond.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 833 m_centrals_db[i].sys_attr.sys_attr_size = 0;
jksoft 0:8468a4403fea 834 m_centrals_db[i].sys_attr.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 835 }
jksoft 0:8468a4403fea 836
jksoft 0:8468a4403fea 837 // Update whitelist data structures.
jksoft 0:8468a4403fea 838 update_whitelist();
jksoft 0:8468a4403fea 839
jksoft 0:8468a4403fea 840 return NRF_SUCCESS;
jksoft 0:8468a4403fea 841 }
jksoft 0:8468a4403fea 842
jksoft 0:8468a4403fea 843
jksoft 0:8468a4403fea 844 /**@brief Function for handling the connected event received from the BLE stack.
jksoft 0:8468a4403fea 845 *
jksoft 0:8468a4403fea 846 * @param[in] p_ble_evt Event received from the BLE stack.
jksoft 0:8468a4403fea 847 */
jksoft 0:8468a4403fea 848 static void on_connect(ble_evt_t * p_ble_evt)
jksoft 0:8468a4403fea 849 {
jksoft 0:8468a4403fea 850 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
jksoft 0:8468a4403fea 851
jksoft 0:8468a4403fea 852 m_central.bond.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 853 m_central.bond.central_addr = p_ble_evt->evt.gap_evt.params.connected.peer_addr;
jksoft 0:8468a4403fea 854 m_central.sys_attr.sys_attr_size = 0;
jksoft 0:8468a4403fea 855
jksoft 0:8468a4403fea 856 if (p_ble_evt->evt.gap_evt.params.connected.irk_match)
jksoft 0:8468a4403fea 857 {
jksoft 0:8468a4403fea 858 uint8_t irk_idx = p_ble_evt->evt.gap_evt.params.connected.irk_match_idx;
jksoft 0:8468a4403fea 859
jksoft 0:8468a4403fea 860 if ((irk_idx >= MAX_NUM_CENTRAL_WHITE_LIST) ||
jksoft 0:8468a4403fea 861 (m_whitelist_irk[irk_idx].central_handle >= BLE_BONDMNGR_MAX_BONDED_CENTRALS))
jksoft 0:8468a4403fea 862 {
jksoft 0:8468a4403fea 863 m_bondmngr_config.error_handler(NRF_ERROR_INTERNAL);
jksoft 0:8468a4403fea 864 }
jksoft 0:8468a4403fea 865 else
jksoft 0:8468a4403fea 866 {
jksoft 0:8468a4403fea 867 m_central = m_centrals_db[m_whitelist_irk[irk_idx].central_handle];
jksoft 0:8468a4403fea 868 }
jksoft 0:8468a4403fea 869 }
jksoft 0:8468a4403fea 870 else
jksoft 0:8468a4403fea 871 {
jksoft 0:8468a4403fea 872 int i;
jksoft 0:8468a4403fea 873
jksoft 0:8468a4403fea 874 for (i = 0; i < m_addr_count; i++)
jksoft 0:8468a4403fea 875 {
jksoft 0:8468a4403fea 876 ble_gap_addr_t * p_cur_addr = m_whitelist_addr[i].p_addr;
jksoft 0:8468a4403fea 877
jksoft 0:8468a4403fea 878 if (memcmp(p_cur_addr->addr, m_central.bond.central_addr.addr, BLE_GAP_ADDR_LEN) == 0)
jksoft 0:8468a4403fea 879 {
jksoft 0:8468a4403fea 880 m_central = m_centrals_db[m_whitelist_addr[i].central_handle];
jksoft 0:8468a4403fea 881 break;
jksoft 0:8468a4403fea 882 }
jksoft 0:8468a4403fea 883 }
jksoft 0:8468a4403fea 884 }
jksoft 0:8468a4403fea 885
jksoft 0:8468a4403fea 886 if (m_central.bond.central_handle != INVALID_CENTRAL_HANDLE)
jksoft 0:8468a4403fea 887 {
jksoft 0:8468a4403fea 888 // Reset bond and system attributes loaded variables.
jksoft 0:8468a4403fea 889 m_bond_loaded = false;
jksoft 0:8468a4403fea 890 m_sys_attr_loaded = false;
jksoft 0:8468a4403fea 891
jksoft 0:8468a4403fea 892 // Do not set the system attributes of the central on connection.
jksoft 0:8468a4403fea 893 if (m_bondmngr_config.evt_handler != NULL)
jksoft 0:8468a4403fea 894 {
jksoft 0:8468a4403fea 895 ble_bondmngr_evt_t evt;
jksoft 0:8468a4403fea 896
jksoft 0:8468a4403fea 897 evt.evt_type = BLE_BONDMNGR_EVT_CONN_TO_BONDED_CENTRAL;
jksoft 0:8468a4403fea 898 evt.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 899 evt.central_id = m_central.bond.central_id_info.div;
jksoft 0:8468a4403fea 900
jksoft 0:8468a4403fea 901 m_bondmngr_config.evt_handler(&evt);
jksoft 0:8468a4403fea 902 }
jksoft 0:8468a4403fea 903 }
jksoft 0:8468a4403fea 904 }
jksoft 0:8468a4403fea 905
jksoft 0:8468a4403fea 906
jksoft 0:8468a4403fea 907 /**@brief Function for handling the 'System Attributes Missing' event received from the
jksoft 0:8468a4403fea 908 * SoftDevice.
jksoft 0:8468a4403fea 909 *
jksoft 0:8468a4403fea 910 * @param[in] p_ble_evt Event received from the BLE stack.
jksoft 0:8468a4403fea 911 */
jksoft 0:8468a4403fea 912 static void on_sys_attr_missing(ble_evt_t * p_ble_evt)
jksoft 0:8468a4403fea 913 {
jksoft 0:8468a4403fea 914 uint32_t err_code;
jksoft 0:8468a4403fea 915
jksoft 0:8468a4403fea 916 if (
jksoft 0:8468a4403fea 917 (m_central.bond.central_handle == INVALID_CENTRAL_HANDLE) ||
jksoft 0:8468a4403fea 918 !ENCRYPTION_STATUS_GET() ||
jksoft 0:8468a4403fea 919 BONDING_IN_PROGRESS_STATUS_GET()
jksoft 0:8468a4403fea 920 )
jksoft 0:8468a4403fea 921 {
jksoft 0:8468a4403fea 922 err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
jksoft 0:8468a4403fea 923 }
jksoft 0:8468a4403fea 924 else
jksoft 0:8468a4403fea 925 {
jksoft 0:8468a4403fea 926 // Current central is valid, use its data. Set the corresponding sys_attr.
jksoft 0:8468a4403fea 927 err_code = central_sys_attr_set(&m_central);
jksoft 0:8468a4403fea 928 if (err_code == NRF_SUCCESS)
jksoft 0:8468a4403fea 929 {
jksoft 0:8468a4403fea 930 // Set System Attributes loaded status variable.
jksoft 0:8468a4403fea 931 m_sys_attr_loaded = true;
jksoft 0:8468a4403fea 932 }
jksoft 0:8468a4403fea 933 }
jksoft 0:8468a4403fea 934
jksoft 0:8468a4403fea 935 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 936 {
jksoft 0:8468a4403fea 937 m_bondmngr_config.error_handler(err_code);
jksoft 0:8468a4403fea 938 }
jksoft 0:8468a4403fea 939 }
jksoft 0:8468a4403fea 940
jksoft 0:8468a4403fea 941
jksoft 0:8468a4403fea 942 /**@brief Function for handling the new authentication status event, received from the
jksoft 0:8468a4403fea 943 * SoftDevice, related to an already bonded central.
jksoft 0:8468a4403fea 944 *
jksoft 0:8468a4403fea 945 * @details This function also writes the updated Bonding Information to flash and notifies the
jksoft 0:8468a4403fea 946 * application.
jksoft 0:8468a4403fea 947 *
jksoft 0:8468a4403fea 948 * @param[in] p_auth_status Updated authentication status.
jksoft 0:8468a4403fea 949 */
jksoft 0:8468a4403fea 950 static void auth_status_update(ble_gap_evt_auth_status_t * p_auth_status)
jksoft 0:8468a4403fea 951 {
jksoft 0:8468a4403fea 952 uint32_t err_code;
jksoft 0:8468a4403fea 953
jksoft 0:8468a4403fea 954 // Authentication status changed, update Bonding Information.
jksoft 0:8468a4403fea 955 m_central.bond.auth_status = *p_auth_status;
jksoft 0:8468a4403fea 956 m_central.bond.central_id_info.div = p_auth_status->periph_keys.enc_info.div;
jksoft 0:8468a4403fea 957
jksoft 0:8468a4403fea 958 memset(&(m_centrals_db[m_central.bond.central_handle]), 0, sizeof(central_t));
jksoft 0:8468a4403fea 959 m_centrals_db[m_central.bond.central_handle] = m_central;
jksoft 0:8468a4403fea 960
jksoft 0:8468a4403fea 961 // Write updated Bonding Information to flash.
jksoft 0:8468a4403fea 962 err_code = bond_info_store(&m_central.bond);
jksoft 0:8468a4403fea 963 if ((err_code == NRF_ERROR_NO_MEM) && (m_bondmngr_config.evt_handler != NULL))
jksoft 0:8468a4403fea 964 {
jksoft 0:8468a4403fea 965 ble_bondmngr_evt_t evt;
jksoft 0:8468a4403fea 966
jksoft 0:8468a4403fea 967 evt.evt_type = BLE_BONDMNGR_EVT_BOND_FLASH_FULL;
jksoft 0:8468a4403fea 968 evt.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 969 evt.central_id = m_central.bond.central_id_info.div;
jksoft 0:8468a4403fea 970
jksoft 0:8468a4403fea 971 m_bondmngr_config.evt_handler(&evt);
jksoft 0:8468a4403fea 972 }
jksoft 0:8468a4403fea 973 else if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 974 {
jksoft 0:8468a4403fea 975 m_bondmngr_config.error_handler(err_code);
jksoft 0:8468a4403fea 976 }
jksoft 0:8468a4403fea 977
jksoft 0:8468a4403fea 978 // Pass the event to the application.
jksoft 0:8468a4403fea 979 if (m_bondmngr_config.evt_handler != NULL)
jksoft 0:8468a4403fea 980 {
jksoft 0:8468a4403fea 981 ble_bondmngr_evt_t evt;
jksoft 0:8468a4403fea 982
jksoft 0:8468a4403fea 983 evt.evt_type = BLE_BONDMNGR_EVT_AUTH_STATUS_UPDATED;
jksoft 0:8468a4403fea 984 evt.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 985 evt.central_id = m_central.bond.central_id_info.div;
jksoft 0:8468a4403fea 986
jksoft 0:8468a4403fea 987 m_bondmngr_config.evt_handler(&evt);
jksoft 0:8468a4403fea 988 }
jksoft 0:8468a4403fea 989 }
jksoft 0:8468a4403fea 990
jksoft 0:8468a4403fea 991
jksoft 0:8468a4403fea 992 /**@brief Function for handling the Authentication Status event received from the BLE stack.
jksoft 0:8468a4403fea 993 *
jksoft 0:8468a4403fea 994 * @param[in] p_ble_evt Event received from the BLE stack.
jksoft 0:8468a4403fea 995 */
jksoft 0:8468a4403fea 996 static void on_auth_status(ble_gap_evt_auth_status_t * p_auth_status)
jksoft 0:8468a4403fea 997 {
jksoft 0:8468a4403fea 998 if (p_auth_status->auth_status != BLE_GAP_SEC_STATUS_SUCCESS)
jksoft 0:8468a4403fea 999 {
jksoft 0:8468a4403fea 1000 return;
jksoft 0:8468a4403fea 1001 }
jksoft 0:8468a4403fea 1002
jksoft 0:8468a4403fea 1003 // Verify if its pairing and not bonding
jksoft 0:8468a4403fea 1004 if (!ENCRYPTION_STATUS_GET())
jksoft 0:8468a4403fea 1005 {
jksoft 0:8468a4403fea 1006 return;
jksoft 0:8468a4403fea 1007 }
jksoft 0:8468a4403fea 1008
jksoft 0:8468a4403fea 1009 if (m_central.bond.central_handle == INVALID_CENTRAL_HANDLE)
jksoft 0:8468a4403fea 1010 {
jksoft 0:8468a4403fea 1011 uint32_t err_code = central_find_in_db(p_auth_status->periph_keys.enc_info.div);
jksoft 0:8468a4403fea 1012
jksoft 0:8468a4403fea 1013 if (err_code == NRF_SUCCESS)
jksoft 0:8468a4403fea 1014 {
jksoft 0:8468a4403fea 1015 // Possible DIV Collision indicate error to application,
jksoft 0:8468a4403fea 1016 // not storing the new LTK
jksoft 0:8468a4403fea 1017 err_code = NRF_ERROR_FORBIDDEN;
jksoft 0:8468a4403fea 1018 }
jksoft 0:8468a4403fea 1019 else
jksoft 0:8468a4403fea 1020 {
jksoft 0:8468a4403fea 1021 // Add the new device to data base
jksoft 0:8468a4403fea 1022 err_code = on_auth_status_from_new_central(p_auth_status);
jksoft 0:8468a4403fea 1023 }
jksoft 0:8468a4403fea 1024
jksoft 0:8468a4403fea 1025 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1026 {
jksoft 0:8468a4403fea 1027 m_bondmngr_config.error_handler(err_code);
jksoft 0:8468a4403fea 1028 }
jksoft 0:8468a4403fea 1029 }
jksoft 0:8468a4403fea 1030 else
jksoft 0:8468a4403fea 1031 {
jksoft 0:8468a4403fea 1032 m_bond_loaded = true;
jksoft 0:8468a4403fea 1033
jksoft 0:8468a4403fea 1034 // Receiving a auth status again when already in have existing information!
jksoft 0:8468a4403fea 1035 auth_status_update(p_auth_status);
jksoft 0:8468a4403fea 1036 }
jksoft 0:8468a4403fea 1037 }
jksoft 0:8468a4403fea 1038
jksoft 0:8468a4403fea 1039
jksoft 0:8468a4403fea 1040 /**@brief Function for handling the Security Info Request event received from the BLE stack.
jksoft 0:8468a4403fea 1041 *
jksoft 0:8468a4403fea 1042 * @param[in] p_ble_evt Event received from the BLE stack.
jksoft 0:8468a4403fea 1043 */
jksoft 0:8468a4403fea 1044 static void on_sec_info_request(ble_evt_t * p_ble_evt)
jksoft 0:8468a4403fea 1045 {
jksoft 0:8468a4403fea 1046 uint32_t err_code;
jksoft 0:8468a4403fea 1047
jksoft 0:8468a4403fea 1048 err_code = central_find_in_db(p_ble_evt->evt.gap_evt.params.sec_info_request.div);
jksoft 0:8468a4403fea 1049 if (err_code == NRF_SUCCESS)
jksoft 0:8468a4403fea 1050 {
jksoft 0:8468a4403fea 1051 // Bond information has been found and loaded for security procedures. Reflect this in the
jksoft 0:8468a4403fea 1052 // status variable
jksoft 0:8468a4403fea 1053 m_bond_loaded = true;
jksoft 0:8468a4403fea 1054
jksoft 0:8468a4403fea 1055 // Central found in the list of bonded central. Use the encryption info for this central.
jksoft 0:8468a4403fea 1056 err_code = sd_ble_gap_sec_info_reply(m_conn_handle,
jksoft 0:8468a4403fea 1057 &m_central.bond.auth_status.periph_keys.enc_info,
jksoft 0:8468a4403fea 1058 NULL);
jksoft 0:8468a4403fea 1059 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1060 {
jksoft 0:8468a4403fea 1061 m_bondmngr_config.error_handler(err_code);
jksoft 0:8468a4403fea 1062 }
jksoft 0:8468a4403fea 1063
jksoft 0:8468a4403fea 1064 // Do not set the sys_attr yet, should be set only when sec_update is successful.
jksoft 0:8468a4403fea 1065 }
jksoft 0:8468a4403fea 1066 else if (err_code == NRF_ERROR_NOT_FOUND)
jksoft 0:8468a4403fea 1067 {
jksoft 0:8468a4403fea 1068 m_central.bond.central_id_info = p_ble_evt->evt.gap_evt.params.sec_info_request;
jksoft 0:8468a4403fea 1069
jksoft 0:8468a4403fea 1070 // New central.
jksoft 0:8468a4403fea 1071 err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL);
jksoft 0:8468a4403fea 1072 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1073 {
jksoft 0:8468a4403fea 1074 m_bondmngr_config.error_handler(err_code);
jksoft 0:8468a4403fea 1075 }
jksoft 0:8468a4403fea 1076
jksoft 0:8468a4403fea 1077 // Initialize the sys_attr.
jksoft 0:8468a4403fea 1078 err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
jksoft 0:8468a4403fea 1079 }
jksoft 0:8468a4403fea 1080
jksoft 0:8468a4403fea 1081 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1082 {
jksoft 0:8468a4403fea 1083 m_bondmngr_config.error_handler(err_code);
jksoft 0:8468a4403fea 1084 }
jksoft 0:8468a4403fea 1085 }
jksoft 0:8468a4403fea 1086
jksoft 0:8468a4403fea 1087
jksoft 0:8468a4403fea 1088 /**@brief Function for handling the Connection Security Update event received from the BLE
jksoft 0:8468a4403fea 1089 * stack.
jksoft 0:8468a4403fea 1090 *
jksoft 0:8468a4403fea 1091 * @param[in] p_ble_evt Event received from the BLE stack.
jksoft 0:8468a4403fea 1092 */
jksoft 0:8468a4403fea 1093 static void on_sec_update(ble_gap_evt_conn_sec_update_t * p_sec_update)
jksoft 0:8468a4403fea 1094 {
jksoft 0:8468a4403fea 1095 uint8_t security_mode = p_sec_update->conn_sec.sec_mode.sm;
jksoft 0:8468a4403fea 1096 uint8_t security_level = p_sec_update->conn_sec.sec_mode.lv;
jksoft 0:8468a4403fea 1097
jksoft 0:8468a4403fea 1098 if (((security_mode == 1) && (security_level > 1)) ||
jksoft 0:8468a4403fea 1099 ((security_mode == 2) && (security_level != 0)))
jksoft 0:8468a4403fea 1100 {
jksoft 0:8468a4403fea 1101 ENCRYPTION_STATUS_SET();
jksoft 0:8468a4403fea 1102
jksoft 0:8468a4403fea 1103 uint32_t err_code = central_sys_attr_set(&m_central);
jksoft 0:8468a4403fea 1104
jksoft 0:8468a4403fea 1105 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1106 {
jksoft 0:8468a4403fea 1107 m_bondmngr_config.error_handler(err_code);
jksoft 0:8468a4403fea 1108 }
jksoft 0:8468a4403fea 1109 else
jksoft 0:8468a4403fea 1110 {
jksoft 0:8468a4403fea 1111 m_sys_attr_loaded = true;
jksoft 0:8468a4403fea 1112 }
jksoft 0:8468a4403fea 1113
jksoft 0:8468a4403fea 1114 if (m_bondmngr_config.evt_handler != NULL)
jksoft 0:8468a4403fea 1115 {
jksoft 0:8468a4403fea 1116 ble_bondmngr_evt_t evt;
jksoft 0:8468a4403fea 1117
jksoft 0:8468a4403fea 1118 evt.evt_type = BLE_BONDMNGR_EVT_ENCRYPTED;
jksoft 0:8468a4403fea 1119 evt.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 1120 evt.central_id = m_central.bond.central_id_info.div;
jksoft 0:8468a4403fea 1121
jksoft 0:8468a4403fea 1122 m_bondmngr_config.evt_handler(&evt);
jksoft 0:8468a4403fea 1123 }
jksoft 0:8468a4403fea 1124 }
jksoft 0:8468a4403fea 1125 }
jksoft 0:8468a4403fea 1126
jksoft 0:8468a4403fea 1127
jksoft 0:8468a4403fea 1128 /**@brief Function for handling the Connection Security Parameters Request event received from
jksoft 0:8468a4403fea 1129 * the BLE stack.
jksoft 0:8468a4403fea 1130 *
jksoft 0:8468a4403fea 1131 * @param[in] p_ble_evt Event received from the BLE stack.
jksoft 0:8468a4403fea 1132 */
jksoft 0:8468a4403fea 1133 static void on_sec_param_request(ble_gap_evt_sec_params_request_t * p_sec_update)
jksoft 0:8468a4403fea 1134 {
jksoft 0:8468a4403fea 1135 if (p_sec_update->peer_params.bond)
jksoft 0:8468a4403fea 1136 {
jksoft 0:8468a4403fea 1137 BONDING_IN_PROGRESS_STATUS_SET();
jksoft 0:8468a4403fea 1138
jksoft 0:8468a4403fea 1139 if (m_central.bond.central_handle != INVALID_CENTRAL_HANDLE)
jksoft 0:8468a4403fea 1140 {
jksoft 0:8468a4403fea 1141 // Bonding request received from a bonded central, make all system attributes null
jksoft 0:8468a4403fea 1142 m_central.sys_attr.sys_attr_size = 0;
jksoft 0:8468a4403fea 1143 memset(m_central.sys_attr.sys_attr, 0, SYS_ATTR_BUFFER_MAX_LEN);
jksoft 0:8468a4403fea 1144 }
jksoft 0:8468a4403fea 1145 }
jksoft 0:8468a4403fea 1146 }
jksoft 0:8468a4403fea 1147
jksoft 0:8468a4403fea 1148
jksoft 0:8468a4403fea 1149 void ble_bondmngr_on_ble_evt(ble_evt_t * p_ble_evt)
jksoft 0:8468a4403fea 1150 {
jksoft 0:8468a4403fea 1151 if (!m_is_bondmngr_initialized)
jksoft 0:8468a4403fea 1152 {
jksoft 0:8468a4403fea 1153 m_bondmngr_config.error_handler(NRF_ERROR_INVALID_STATE);
jksoft 0:8468a4403fea 1154 }
jksoft 0:8468a4403fea 1155
jksoft 0:8468a4403fea 1156 switch (p_ble_evt->header.evt_id)
jksoft 0:8468a4403fea 1157 {
jksoft 0:8468a4403fea 1158 case BLE_GAP_EVT_CONNECTED:
jksoft 0:8468a4403fea 1159 on_connect(p_ble_evt);
jksoft 0:8468a4403fea 1160 break;
jksoft 0:8468a4403fea 1161
jksoft 0:8468a4403fea 1162 // NOTE: All actions to be taken on the Disconnected event are performed in
jksoft 0:8468a4403fea 1163 // ble_bondmngr_bonded_centrals_store(). This function must be called from the
jksoft 0:8468a4403fea 1164 // Disconnected handler of the application before advertising is restarted (to make
jksoft 0:8468a4403fea 1165 // sure the flash blocks are cleared while the radio is inactive).
jksoft 0:8468a4403fea 1166 case BLE_GAP_EVT_DISCONNECTED:
jksoft 0:8468a4403fea 1167 SECURITY_STATUS_RESET();
jksoft 0:8468a4403fea 1168 break;
jksoft 0:8468a4403fea 1169
jksoft 0:8468a4403fea 1170 case BLE_GATTS_EVT_SYS_ATTR_MISSING:
jksoft 0:8468a4403fea 1171 on_sys_attr_missing(p_ble_evt);
jksoft 0:8468a4403fea 1172 break;
jksoft 0:8468a4403fea 1173
jksoft 0:8468a4403fea 1174 case BLE_GAP_EVT_AUTH_STATUS:
jksoft 0:8468a4403fea 1175 on_auth_status(&p_ble_evt->evt.gap_evt.params.auth_status);
jksoft 0:8468a4403fea 1176 break;
jksoft 0:8468a4403fea 1177
jksoft 0:8468a4403fea 1178 case BLE_GAP_EVT_SEC_INFO_REQUEST:
jksoft 0:8468a4403fea 1179 on_sec_info_request(p_ble_evt);
jksoft 0:8468a4403fea 1180 break;
jksoft 0:8468a4403fea 1181
jksoft 0:8468a4403fea 1182 case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
jksoft 0:8468a4403fea 1183 on_sec_param_request(&p_ble_evt->evt.gap_evt.params.sec_params_request);
jksoft 0:8468a4403fea 1184 break;
jksoft 0:8468a4403fea 1185
jksoft 0:8468a4403fea 1186 case BLE_GAP_EVT_CONN_SEC_UPDATE:
jksoft 0:8468a4403fea 1187 on_sec_update(&p_ble_evt->evt.gap_evt.params.conn_sec_update);
jksoft 0:8468a4403fea 1188 break;
jksoft 0:8468a4403fea 1189
jksoft 0:8468a4403fea 1190 default:
jksoft 0:8468a4403fea 1191 // No implementation needed.
jksoft 0:8468a4403fea 1192 break;
jksoft 0:8468a4403fea 1193 }
jksoft 0:8468a4403fea 1194 }
jksoft 0:8468a4403fea 1195
jksoft 0:8468a4403fea 1196
jksoft 0:8468a4403fea 1197 uint32_t ble_bondmngr_bonded_centrals_store(void)
jksoft 0:8468a4403fea 1198 {
jksoft 0:8468a4403fea 1199 uint32_t err_code;
jksoft 0:8468a4403fea 1200 int i;
jksoft 0:8468a4403fea 1201
jksoft 0:8468a4403fea 1202 VERIFY_MODULE_INITIALIZED();
jksoft 0:8468a4403fea 1203
jksoft 0:8468a4403fea 1204 if (m_central.bond.central_handle != INVALID_CENTRAL_HANDLE)
jksoft 0:8468a4403fea 1205 {
jksoft 0:8468a4403fea 1206 // Fetch System Attributes from stack.
jksoft 0:8468a4403fea 1207 uint16_t sys_attr_size = SYS_ATTR_BUFFER_MAX_LEN;
jksoft 0:8468a4403fea 1208
jksoft 0:8468a4403fea 1209 err_code = sd_ble_gatts_sys_attr_get(m_conn_handle,
jksoft 0:8468a4403fea 1210 m_central.sys_attr.sys_attr,
jksoft 0:8468a4403fea 1211 &sys_attr_size);
jksoft 0:8468a4403fea 1212 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1213 {
jksoft 0:8468a4403fea 1214 return err_code;
jksoft 0:8468a4403fea 1215 }
jksoft 0:8468a4403fea 1216
jksoft 0:8468a4403fea 1217 m_central.sys_attr.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 1218 m_central.sys_attr.sys_attr_size = (uint16_t)sys_attr_size;
jksoft 0:8468a4403fea 1219
jksoft 0:8468a4403fea 1220 // Update the current central.
jksoft 0:8468a4403fea 1221 err_code = central_update();
jksoft 0:8468a4403fea 1222 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1223 {
jksoft 0:8468a4403fea 1224 return err_code;
jksoft 0:8468a4403fea 1225 }
jksoft 0:8468a4403fea 1226 }
jksoft 0:8468a4403fea 1227
jksoft 0:8468a4403fea 1228 // Save Bonding Information if changed.
jksoft 0:8468a4403fea 1229 if (bond_info_changed())
jksoft 0:8468a4403fea 1230 {
jksoft 0:8468a4403fea 1231 // Erase flash page.
jksoft 0:8468a4403fea 1232 err_code = pstorage_clear(&mp_flash_bond_info,MAX_BONDS_IN_FLASH);
jksoft 0:8468a4403fea 1233 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1234 {
jksoft 0:8468a4403fea 1235 return err_code;
jksoft 0:8468a4403fea 1236 }
jksoft 0:8468a4403fea 1237
jksoft 0:8468a4403fea 1238 // Store bond information for all centrals.
jksoft 0:8468a4403fea 1239 m_bond_info_in_flash_count = 0;
jksoft 0:8468a4403fea 1240 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 1241 {
jksoft 0:8468a4403fea 1242 err_code = bond_info_store(&m_centrals_db[i].bond);
jksoft 0:8468a4403fea 1243 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1244 {
jksoft 0:8468a4403fea 1245 return err_code;
jksoft 0:8468a4403fea 1246 }
jksoft 0:8468a4403fea 1247 }
jksoft 0:8468a4403fea 1248 }
jksoft 0:8468a4403fea 1249
jksoft 0:8468a4403fea 1250 // Save System Attributes, if changed.
jksoft 0:8468a4403fea 1251 if (sys_attr_changed())
jksoft 0:8468a4403fea 1252 {
jksoft 0:8468a4403fea 1253 // Erase flash page.
jksoft 0:8468a4403fea 1254 err_code = pstorage_clear(&mp_flash_sys_attr, MAX_BONDS_IN_FLASH);
jksoft 0:8468a4403fea 1255 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1256 {
jksoft 0:8468a4403fea 1257 return err_code;
jksoft 0:8468a4403fea 1258 }
jksoft 0:8468a4403fea 1259
jksoft 0:8468a4403fea 1260 // Store System Attributes for all centrals.
jksoft 0:8468a4403fea 1261 m_sys_attr_in_flash_count = 0;
jksoft 0:8468a4403fea 1262 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 1263 {
jksoft 0:8468a4403fea 1264 err_code = sys_attr_store(&m_centrals_db[i].sys_attr);
jksoft 0:8468a4403fea 1265 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1266 {
jksoft 0:8468a4403fea 1267 return err_code;
jksoft 0:8468a4403fea 1268 }
jksoft 0:8468a4403fea 1269 }
jksoft 0:8468a4403fea 1270 }
jksoft 0:8468a4403fea 1271
jksoft 0:8468a4403fea 1272 m_conn_handle = BLE_CONN_HANDLE_INVALID;
jksoft 0:8468a4403fea 1273 m_central.bond.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 1274 m_central.sys_attr.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 1275 m_central.sys_attr.sys_attr_size = 0;
jksoft 0:8468a4403fea 1276 m_bond_loaded = false;
jksoft 0:8468a4403fea 1277 m_sys_attr_loaded = false;
jksoft 0:8468a4403fea 1278
jksoft 0:8468a4403fea 1279 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1280 }
jksoft 0:8468a4403fea 1281
jksoft 0:8468a4403fea 1282
jksoft 0:8468a4403fea 1283 uint32_t ble_bondmngr_sys_attr_store(void)
jksoft 0:8468a4403fea 1284 {
jksoft 0:8468a4403fea 1285 uint32_t err_code;
jksoft 0:8468a4403fea 1286
jksoft 0:8468a4403fea 1287 if (m_central.sys_attr.sys_attr_size == 0)
jksoft 0:8468a4403fea 1288 {
jksoft 0:8468a4403fea 1289 // Connected to new central. So the flash block for System Attributes for this
jksoft 0:8468a4403fea 1290 // central is empty. Hence no erase is needed.
jksoft 0:8468a4403fea 1291
jksoft 0:8468a4403fea 1292 uint16_t sys_attr_size = SYS_ATTR_BUFFER_MAX_LEN;
jksoft 0:8468a4403fea 1293
jksoft 0:8468a4403fea 1294 // Fetch System Attributes from stack.
jksoft 0:8468a4403fea 1295 err_code = sd_ble_gatts_sys_attr_get(m_conn_handle,
jksoft 0:8468a4403fea 1296 m_central.sys_attr.sys_attr,
jksoft 0:8468a4403fea 1297 &sys_attr_size);
jksoft 0:8468a4403fea 1298
jksoft 0:8468a4403fea 1299 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1300 {
jksoft 0:8468a4403fea 1301 return err_code;
jksoft 0:8468a4403fea 1302 }
jksoft 0:8468a4403fea 1303
jksoft 0:8468a4403fea 1304 m_central.sys_attr.central_handle = m_central.bond.central_handle;
jksoft 0:8468a4403fea 1305 m_central.sys_attr.sys_attr_size = (uint16_t)sys_attr_size;
jksoft 0:8468a4403fea 1306
jksoft 0:8468a4403fea 1307 // Copy the System Attributes to database.
jksoft 0:8468a4403fea 1308 m_centrals_db[m_central.bond.central_handle].sys_attr = m_central.sys_attr;
jksoft 0:8468a4403fea 1309
jksoft 0:8468a4403fea 1310 // Write new central's System Attributes to flash.
jksoft 0:8468a4403fea 1311 return (sys_attr_store(&m_central.sys_attr));
jksoft 0:8468a4403fea 1312 }
jksoft 0:8468a4403fea 1313 else
jksoft 0:8468a4403fea 1314 {
jksoft 0:8468a4403fea 1315 // Will not write to flash because System Attributes of an old central would already be
jksoft 0:8468a4403fea 1316 // in flash and so this operation needs a flash erase operation.
jksoft 0:8468a4403fea 1317 return NRF_ERROR_INVALID_STATE;
jksoft 0:8468a4403fea 1318 }
jksoft 0:8468a4403fea 1319 }
jksoft 0:8468a4403fea 1320
jksoft 0:8468a4403fea 1321
jksoft 0:8468a4403fea 1322 uint32_t ble_bondmngr_bonded_centrals_delete(void)
jksoft 0:8468a4403fea 1323 {
jksoft 0:8468a4403fea 1324 VERIFY_MODULE_INITIALIZED();
jksoft 0:8468a4403fea 1325
jksoft 0:8468a4403fea 1326 m_centrals_in_db_count = 0;
jksoft 0:8468a4403fea 1327 m_bond_info_in_flash_count = 0;
jksoft 0:8468a4403fea 1328 m_sys_attr_in_flash_count = 0;
jksoft 0:8468a4403fea 1329
jksoft 0:8468a4403fea 1330 return flash_pages_erase();
jksoft 0:8468a4403fea 1331 }
jksoft 0:8468a4403fea 1332
jksoft 0:8468a4403fea 1333
jksoft 0:8468a4403fea 1334 uint32_t ble_bondmngr_central_addr_get(int8_t central_handle, ble_gap_addr_t * p_central_addr)
jksoft 0:8468a4403fea 1335 {
jksoft 0:8468a4403fea 1336 if (
jksoft 0:8468a4403fea 1337 (central_handle == INVALID_CENTRAL_HANDLE) ||
jksoft 0:8468a4403fea 1338 (central_handle >= m_centrals_in_db_count) ||
jksoft 0:8468a4403fea 1339 (p_central_addr == NULL) ||
jksoft 0:8468a4403fea 1340 (
jksoft 0:8468a4403fea 1341 m_centrals_db[central_handle].bond.central_addr.addr_type
jksoft 0:8468a4403fea 1342 ==
jksoft 0:8468a4403fea 1343 BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE
jksoft 0:8468a4403fea 1344 )
jksoft 0:8468a4403fea 1345 )
jksoft 0:8468a4403fea 1346 {
jksoft 0:8468a4403fea 1347 return NRF_ERROR_INVALID_PARAM;
jksoft 0:8468a4403fea 1348 }
jksoft 0:8468a4403fea 1349
jksoft 0:8468a4403fea 1350 *p_central_addr = m_centrals_db[central_handle].bond.central_addr;
jksoft 0:8468a4403fea 1351 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1352 }
jksoft 0:8468a4403fea 1353
jksoft 0:8468a4403fea 1354
jksoft 0:8468a4403fea 1355 uint32_t ble_bondmngr_whitelist_get(ble_gap_whitelist_t * p_whitelist)
jksoft 0:8468a4403fea 1356 {
jksoft 0:8468a4403fea 1357 static ble_gap_addr_t * s_addr[MAX_NUM_CENTRAL_WHITE_LIST];
jksoft 0:8468a4403fea 1358 static ble_gap_irk_t * s_irk[MAX_NUM_CENTRAL_WHITE_LIST];
jksoft 0:8468a4403fea 1359
jksoft 0:8468a4403fea 1360 int i;
jksoft 0:8468a4403fea 1361
jksoft 0:8468a4403fea 1362 for (i = 0; i < m_irk_count; i++)
jksoft 0:8468a4403fea 1363 {
jksoft 0:8468a4403fea 1364 s_irk[i] = m_whitelist_irk[i].p_irk;
jksoft 0:8468a4403fea 1365 }
jksoft 0:8468a4403fea 1366 for (i = 0; i < m_addr_count; i++)
jksoft 0:8468a4403fea 1367 {
jksoft 0:8468a4403fea 1368 s_addr[i] = m_whitelist_addr[i].p_addr;
jksoft 0:8468a4403fea 1369 }
jksoft 0:8468a4403fea 1370
jksoft 0:8468a4403fea 1371 p_whitelist->addr_count = m_addr_count;
jksoft 0:8468a4403fea 1372 p_whitelist->pp_addrs = (m_addr_count != 0) ? s_addr : NULL;
jksoft 0:8468a4403fea 1373 p_whitelist->irk_count = m_irk_count;
jksoft 0:8468a4403fea 1374 p_whitelist->pp_irks = (m_irk_count != 0) ? s_irk : NULL;
jksoft 0:8468a4403fea 1375
jksoft 0:8468a4403fea 1376 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1377 }
jksoft 0:8468a4403fea 1378
jksoft 0:8468a4403fea 1379
jksoft 0:8468a4403fea 1380 static void bm_pstorage_cb_handler(pstorage_handle_t * handle,
jksoft 0:8468a4403fea 1381 uint8_t op_code,
jksoft 0:8468a4403fea 1382 uint32_t result,
jksoft 0:8468a4403fea 1383 uint8_t * p_data,
jksoft 0:8468a4403fea 1384 uint32_t data_len)
jksoft 0:8468a4403fea 1385 {
jksoft 0:8468a4403fea 1386 if (result != NRF_SUCCESS)
jksoft 0:8468a4403fea 1387 {
jksoft 0:8468a4403fea 1388 m_bondmngr_config.error_handler(result);
jksoft 0:8468a4403fea 1389 }
jksoft 0:8468a4403fea 1390 }
jksoft 0:8468a4403fea 1391
jksoft 0:8468a4403fea 1392
jksoft 0:8468a4403fea 1393 uint32_t ble_bondmngr_init(ble_bondmngr_init_t * p_init)
jksoft 0:8468a4403fea 1394 {
jksoft 0:8468a4403fea 1395 pstorage_module_param_t param;
jksoft 0:8468a4403fea 1396 uint32_t err_code;
jksoft 0:8468a4403fea 1397
jksoft 0:8468a4403fea 1398 if (p_init->error_handler == NULL)
jksoft 0:8468a4403fea 1399 {
jksoft 0:8468a4403fea 1400 return NRF_ERROR_INVALID_PARAM;
jksoft 0:8468a4403fea 1401 }
jksoft 0:8468a4403fea 1402
jksoft 0:8468a4403fea 1403 if (BLE_BONDMNGR_MAX_BONDED_CENTRALS > MAX_BONDS_IN_FLASH)
jksoft 0:8468a4403fea 1404 {
jksoft 0:8468a4403fea 1405 return NRF_ERROR_DATA_SIZE;
jksoft 0:8468a4403fea 1406 }
jksoft 0:8468a4403fea 1407
jksoft 0:8468a4403fea 1408 param.block_size = sizeof (central_bond_t) + sizeof (uint32_t);
jksoft 0:8468a4403fea 1409 param.block_count = MAX_BONDS_IN_FLASH;
jksoft 0:8468a4403fea 1410 param.cb = bm_pstorage_cb_handler;
jksoft 0:8468a4403fea 1411
jksoft 0:8468a4403fea 1412 // Blocks are requested twice, once for bond information and once for system attributes.
jksoft 0:8468a4403fea 1413 // The number of blocks requested has to be the maximum number of bonded devices that
jksoft 0:8468a4403fea 1414 // need to be supported. However, the size of blocks can be different if the sizes of
jksoft 0:8468a4403fea 1415 // system attributes and bonds are not too close.
jksoft 0:8468a4403fea 1416 err_code = pstorage_register(&param, &mp_flash_bond_info);
jksoft 0:8468a4403fea 1417 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1418 {
jksoft 0:8468a4403fea 1419 return err_code;
jksoft 0:8468a4403fea 1420 }
jksoft 0:8468a4403fea 1421
jksoft 0:8468a4403fea 1422 param.block_size = sizeof(central_sys_attr_t) + sizeof(uint32_t);
jksoft 0:8468a4403fea 1423
jksoft 0:8468a4403fea 1424 err_code = pstorage_register(&param, &mp_flash_sys_attr);
jksoft 0:8468a4403fea 1425 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1426 {
jksoft 0:8468a4403fea 1427 return err_code;
jksoft 0:8468a4403fea 1428 }
jksoft 0:8468a4403fea 1429
jksoft 0:8468a4403fea 1430 m_bondmngr_config = *p_init;
jksoft 0:8468a4403fea 1431
jksoft 0:8468a4403fea 1432 memset(&m_central, 0, sizeof(central_t));
jksoft 0:8468a4403fea 1433
jksoft 0:8468a4403fea 1434 m_central.bond.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 1435 m_conn_handle = BLE_CONN_HANDLE_INVALID;
jksoft 0:8468a4403fea 1436 m_centrals_in_db_count = 0;
jksoft 0:8468a4403fea 1437 m_bond_info_in_flash_count = 0;
jksoft 0:8468a4403fea 1438 m_sys_attr_in_flash_count = 0;
jksoft 0:8468a4403fea 1439
jksoft 0:8468a4403fea 1440 SECURITY_STATUS_RESET();
jksoft 0:8468a4403fea 1441
jksoft 0:8468a4403fea 1442 // Erase all stored centrals if specified.
jksoft 0:8468a4403fea 1443 if (m_bondmngr_config.bonds_delete)
jksoft 0:8468a4403fea 1444 {
jksoft 0:8468a4403fea 1445 err_code = flash_pages_erase();
jksoft 0:8468a4403fea 1446 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1447 {
jksoft 0:8468a4403fea 1448 return err_code;
jksoft 0:8468a4403fea 1449 }
jksoft 0:8468a4403fea 1450
jksoft 0:8468a4403fea 1451 m_centrals_in_db_count = 0;
jksoft 0:8468a4403fea 1452 int i;
jksoft 0:8468a4403fea 1453 for (i = m_centrals_in_db_count; i < BLE_BONDMNGR_MAX_BONDED_CENTRALS; i++)
jksoft 0:8468a4403fea 1454 {
jksoft 0:8468a4403fea 1455 m_centrals_db[i].bond.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 1456 m_centrals_db[i].sys_attr.sys_attr_size = 0;
jksoft 0:8468a4403fea 1457 m_centrals_db[i].sys_attr.central_handle = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 1458 }
jksoft 0:8468a4403fea 1459 }
jksoft 0:8468a4403fea 1460 else
jksoft 0:8468a4403fea 1461 {
jksoft 0:8468a4403fea 1462 // Load bond manager data from flash.
jksoft 0:8468a4403fea 1463 err_code = load_all_from_flash();
jksoft 0:8468a4403fea 1464 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1465 {
jksoft 0:8468a4403fea 1466 return err_code;
jksoft 0:8468a4403fea 1467 }
jksoft 0:8468a4403fea 1468 }
jksoft 0:8468a4403fea 1469
jksoft 0:8468a4403fea 1470 m_is_bondmngr_initialized = true;
jksoft 0:8468a4403fea 1471
jksoft 0:8468a4403fea 1472 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1473 }
jksoft 0:8468a4403fea 1474
jksoft 0:8468a4403fea 1475
jksoft 0:8468a4403fea 1476 uint32_t ble_bondmngr_central_ids_get(uint16_t * p_central_ids, uint16_t * p_length)
jksoft 0:8468a4403fea 1477 {
jksoft 0:8468a4403fea 1478 VERIFY_MODULE_INITIALIZED();
jksoft 0:8468a4403fea 1479 int i;
jksoft 0:8468a4403fea 1480 if (p_length == NULL)
jksoft 0:8468a4403fea 1481 {
jksoft 0:8468a4403fea 1482 return NRF_ERROR_NULL;
jksoft 0:8468a4403fea 1483 }
jksoft 0:8468a4403fea 1484
jksoft 0:8468a4403fea 1485 if (*p_length < m_centrals_in_db_count)
jksoft 0:8468a4403fea 1486 {
jksoft 0:8468a4403fea 1487 // Length of the input array is not enough to fit all known central identifiers.
jksoft 0:8468a4403fea 1488 return NRF_ERROR_DATA_SIZE;
jksoft 0:8468a4403fea 1489 }
jksoft 0:8468a4403fea 1490
jksoft 0:8468a4403fea 1491 *p_length = m_centrals_in_db_count;
jksoft 0:8468a4403fea 1492 if (p_central_ids == NULL)
jksoft 0:8468a4403fea 1493 {
jksoft 0:8468a4403fea 1494 // Only the length field was required to be filled.
jksoft 0:8468a4403fea 1495 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1496 }
jksoft 0:8468a4403fea 1497
jksoft 0:8468a4403fea 1498 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 1499 {
jksoft 0:8468a4403fea 1500 p_central_ids[i] = m_centrals_db[i].bond.central_id_info.div;
jksoft 0:8468a4403fea 1501 }
jksoft 0:8468a4403fea 1502
jksoft 0:8468a4403fea 1503 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1504 }
jksoft 0:8468a4403fea 1505
jksoft 0:8468a4403fea 1506
jksoft 0:8468a4403fea 1507 uint32_t ble_bondmngr_bonded_central_delete(uint16_t central_id)
jksoft 0:8468a4403fea 1508 {
jksoft 0:8468a4403fea 1509 VERIFY_MODULE_INITIALIZED();
jksoft 0:8468a4403fea 1510
jksoft 0:8468a4403fea 1511 int8_t central_handle_to_be_deleted = INVALID_CENTRAL_HANDLE;
jksoft 0:8468a4403fea 1512 uint8_t i;
jksoft 0:8468a4403fea 1513
jksoft 0:8468a4403fea 1514 // Search for the handle of the central.
jksoft 0:8468a4403fea 1515 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 1516 {
jksoft 0:8468a4403fea 1517 if (m_centrals_db[i].bond.central_id_info.div == central_id)
jksoft 0:8468a4403fea 1518 {
jksoft 0:8468a4403fea 1519 central_handle_to_be_deleted = i;
jksoft 0:8468a4403fea 1520 break;
jksoft 0:8468a4403fea 1521 }
jksoft 0:8468a4403fea 1522 }
jksoft 0:8468a4403fea 1523
jksoft 0:8468a4403fea 1524 if (central_handle_to_be_deleted == INVALID_CENTRAL_HANDLE)
jksoft 0:8468a4403fea 1525 {
jksoft 0:8468a4403fea 1526 // Central ID not found.
jksoft 0:8468a4403fea 1527 return NRF_ERROR_NOT_FOUND;
jksoft 0:8468a4403fea 1528 }
jksoft 0:8468a4403fea 1529
jksoft 0:8468a4403fea 1530 // Delete the central in RAM.
jksoft 0:8468a4403fea 1531 for (i = central_handle_to_be_deleted; i < (m_centrals_in_db_count - 1); i++)
jksoft 0:8468a4403fea 1532 {
jksoft 0:8468a4403fea 1533 // Overwrite the current central entry with the next one.
jksoft 0:8468a4403fea 1534 m_centrals_db[i] = m_centrals_db[i + 1];
jksoft 0:8468a4403fea 1535
jksoft 0:8468a4403fea 1536 // Decrement the value of handle.
jksoft 0:8468a4403fea 1537 m_centrals_db[i].bond.central_handle--;
jksoft 0:8468a4403fea 1538 if (INVALID_CENTRAL_HANDLE != m_centrals_db[i].sys_attr.central_handle)
jksoft 0:8468a4403fea 1539 {
jksoft 0:8468a4403fea 1540 m_centrals_db[i].sys_attr.central_handle--;
jksoft 0:8468a4403fea 1541 }
jksoft 0:8468a4403fea 1542 }
jksoft 0:8468a4403fea 1543
jksoft 0:8468a4403fea 1544 // Clear the last database entry.
jksoft 0:8468a4403fea 1545 memset(&(m_centrals_db[m_centrals_in_db_count - 1]), 0, sizeof(central_t));
jksoft 0:8468a4403fea 1546
jksoft 0:8468a4403fea 1547 m_centrals_in_db_count--;
jksoft 0:8468a4403fea 1548
jksoft 0:8468a4403fea 1549 uint32_t err_code;
jksoft 0:8468a4403fea 1550
jksoft 0:8468a4403fea 1551 // Reinitialize the pointers to the memory where bonding info and System Attributes are stored
jksoft 0:8468a4403fea 1552 // in flash.
jksoft 0:8468a4403fea 1553 // Refresh the data in the flash memory (both Bonding Information and System Attributes).
jksoft 0:8468a4403fea 1554 // Erase and rewrite bonding info and System Attributes.
jksoft 0:8468a4403fea 1555
jksoft 0:8468a4403fea 1556 err_code = flash_pages_erase();
jksoft 0:8468a4403fea 1557 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1558 {
jksoft 0:8468a4403fea 1559 return err_code;
jksoft 0:8468a4403fea 1560 }
jksoft 0:8468a4403fea 1561
jksoft 0:8468a4403fea 1562 m_bond_info_in_flash_count = 0;
jksoft 0:8468a4403fea 1563 m_sys_attr_in_flash_count = 0;
jksoft 0:8468a4403fea 1564
jksoft 0:8468a4403fea 1565 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 1566 {
jksoft 0:8468a4403fea 1567 err_code = bond_info_store(&(m_centrals_db[i].bond));
jksoft 0:8468a4403fea 1568 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1569 {
jksoft 0:8468a4403fea 1570 return err_code;
jksoft 0:8468a4403fea 1571 }
jksoft 0:8468a4403fea 1572 }
jksoft 0:8468a4403fea 1573
jksoft 0:8468a4403fea 1574 for (i = 0; i < m_centrals_in_db_count; i++)
jksoft 0:8468a4403fea 1575 {
jksoft 0:8468a4403fea 1576 err_code = sys_attr_store(&(m_centrals_db[i].sys_attr));
jksoft 0:8468a4403fea 1577 if (err_code != NRF_SUCCESS)
jksoft 0:8468a4403fea 1578 {
jksoft 0:8468a4403fea 1579 return err_code;
jksoft 0:8468a4403fea 1580 }
jksoft 0:8468a4403fea 1581 }
jksoft 0:8468a4403fea 1582
jksoft 0:8468a4403fea 1583 update_whitelist();
jksoft 0:8468a4403fea 1584
jksoft 0:8468a4403fea 1585 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1586 }
jksoft 0:8468a4403fea 1587
jksoft 0:8468a4403fea 1588
jksoft 0:8468a4403fea 1589 uint32_t ble_bondmngr_is_link_encrypted (bool * status)
jksoft 0:8468a4403fea 1590 {
jksoft 0:8468a4403fea 1591 VERIFY_MODULE_INITIALIZED();
jksoft 0:8468a4403fea 1592
jksoft 0:8468a4403fea 1593 (*status) = ENCRYPTION_STATUS_GET();
jksoft 0:8468a4403fea 1594
jksoft 0:8468a4403fea 1595 return NRF_SUCCESS;
jksoft 0:8468a4403fea 1596 }
jksoft 0:8468a4403fea 1597
jksoft 0:8468a4403fea 1598 #endif /* #if NEED_BOND_MANAGER */