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