AndroidのBLEラジコンプロポアプリ「BLEPropo」と接続し、RCサーボとDCモータを制御するプログラムです。 mbed HRM1017で動作を確認しています。 BLEPropo → https://github.com/lipoyang/BLEPropo

Dependencies:   BLE_API mbed

Fork of BLE_RCBController2 by Junichi Katsu

BLEを使ったAndroid用ラジコンプロポアプリ「BLEPropo」に対応するmbed HRM1017用ファームウェアです。
BLEPropoは、GitHubにて公開中。
https://github.com/lipoyang/BLEPropo
/media/uploads/lipoyang/blepropo_ui.png
ラジコンは、mbed HRM1017とRCサーボやDCモータを組み合わせて作ります。
/media/uploads/lipoyang/ble_wiring.png

Committer:
lipoyang
Date:
Sat Mar 14 11:51:38 2015 +0000
Revision:
7:505a9a98b776
Parent:
4:ebda47d22091
- adjust servo center position

Who changed what in which revision?

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