iOSのBLEコントローラアプリ「RCBController」とmbed HRM1017を接続し、RCサーボモータを操作するテストプログラムです。

Dependencies:   BLE_API_Native_IRC Servo mbed

Fork of BLE_RCBController by Junichi Katsu

  • 古いBLEライブラリを使っているのでプラットフォームは”Nordic nRF51822”を選択してください。
  • ライブラリ類はUpdateしないでください。コンパイルエラーになります。

うまく接続できない時は、iPhone/iPadのBluetoothをOFF->ONしてキャッシュをクリアしてみてください。

/media/uploads/robo8080/img_1560.jpg

Committer:
jksoft
Date:
Thu Jul 10 14:21:52 2014 +0000
Revision:
0:8c643bfe55b7
??

Who changed what in which revision?

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