cvb

Fork of nrf51-sdk by Lancaster University

Committer:
tb942
Date:
Tue Aug 14 18:27:20 2018 +0000
Revision:
9:d3dd910b0f4b
Parent:
5:f2faa0f0b8f0

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LancasterUniversity 3:ae5e20530aa5 1 /*
LancasterUniversity 3:ae5e20530aa5 2 * Copyright (c) Nordic Semiconductor ASA
LancasterUniversity 3:ae5e20530aa5 3 * All rights reserved.
LancasterUniversity 3:ae5e20530aa5 4 *
LancasterUniversity 3:ae5e20530aa5 5 * Redistribution and use in source and binary forms, with or without modification,
LancasterUniversity 3:ae5e20530aa5 6 * are permitted provided that the following conditions are met:
LancasterUniversity 3:ae5e20530aa5 7 *
LancasterUniversity 3:ae5e20530aa5 8 * 1. Redistributions of source code must retain the above copyright notice, this
LancasterUniversity 3:ae5e20530aa5 9 * list of conditions and the following disclaimer.
LancasterUniversity 3:ae5e20530aa5 10 *
LancasterUniversity 3:ae5e20530aa5 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this
LancasterUniversity 3:ae5e20530aa5 12 * list of conditions and the following disclaimer in the documentation and/or
LancasterUniversity 3:ae5e20530aa5 13 * other materials provided with the distribution.
LancasterUniversity 3:ae5e20530aa5 14 *
LancasterUniversity 3:ae5e20530aa5 15 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other
LancasterUniversity 3:ae5e20530aa5 16 * contributors to this software may be used to endorse or promote products
LancasterUniversity 3:ae5e20530aa5 17 * derived from this software without specific prior written permission.
LancasterUniversity 3:ae5e20530aa5 18 *
LancasterUniversity 3:ae5e20530aa5 19 *
LancasterUniversity 3:ae5e20530aa5 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
LancasterUniversity 3:ae5e20530aa5 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
LancasterUniversity 3:ae5e20530aa5 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
LancasterUniversity 3:ae5e20530aa5 23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
LancasterUniversity 3:ae5e20530aa5 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
LancasterUniversity 3:ae5e20530aa5 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LancasterUniversity 3:ae5e20530aa5 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
LancasterUniversity 3:ae5e20530aa5 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
LancasterUniversity 3:ae5e20530aa5 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
LancasterUniversity 3:ae5e20530aa5 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
LancasterUniversity 3:ae5e20530aa5 30 *
Jonathan Austin 0:bc2961fa1ef0 31 */
Jonathan Austin 0:bc2961fa1ef0 32
Jonathan Austin 0:bc2961fa1ef0 33 #include "device_manager.h"
Jonathan Austin 0:bc2961fa1ef0 34 #include "pstorage.h"
Jonathan Austin 0:bc2961fa1ef0 35 #include "ble_hci.h"
Jonathan Austin 0:bc2961fa1ef0 36 #include "app_error.h"
Jonathan Austin 0:bc2961fa1ef0 37
Jonathan Austin 0:bc2961fa1ef0 38 #if defined ( __CC_ARM )
Jonathan Austin 0:bc2961fa1ef0 39 #ifndef __ALIGN
Jonathan Austin 0:bc2961fa1ef0 40 #define __ALIGN(x) __align(x) /**< Forced aligment keyword for ARM Compiler */
Jonathan Austin 0:bc2961fa1ef0 41 #endif
Jonathan Austin 0:bc2961fa1ef0 42 #elif defined ( __ICCARM__ )
Jonathan Austin 0:bc2961fa1ef0 43 #ifndef __ALIGN
Jonathan Austin 0:bc2961fa1ef0 44 #define __ALIGN(x) /**< Forced aligment keyword for IAR Compiler */
Jonathan Austin 0:bc2961fa1ef0 45 #endif
Jonathan Austin 0:bc2961fa1ef0 46 #elif defined ( __GNUC__ )
Jonathan Austin 0:bc2961fa1ef0 47 #ifndef __ALIGN
Jonathan Austin 0:bc2961fa1ef0 48 #define __ALIGN(x) __attribute__((aligned(x))) /**< Forced aligment keyword for GNU Compiler */
Jonathan Austin 0:bc2961fa1ef0 49 #endif
Jonathan Austin 0:bc2961fa1ef0 50 #endif
Jonathan Austin 0:bc2961fa1ef0 51
Jonathan Austin 0:bc2961fa1ef0 52 #define INVALID_ADDR_TYPE 0xFF /**< Identifier for an invalid address type. */
Jonathan Austin 0:bc2961fa1ef0 53 #define EDIV_INIT_VAL 0xFFFF /**< Initial value for diversifier. */
Jonathan Austin 0:bc2961fa1ef0 54
Jonathan Austin 0:bc2961fa1ef0 55 /**
Jonathan Austin 0:bc2961fa1ef0 56 * @defgroup device_manager_app_states Connection Manager Application States
Jonathan Austin 0:bc2961fa1ef0 57 * @{
Jonathan Austin 0:bc2961fa1ef0 58 */
Jonathan Austin 0:bc2961fa1ef0 59 #define STATE_CONTROL_PROCEDURE_IN_PROGRESS 0x01 /**< State where a security procedure is ongoing. */
Jonathan Austin 0:bc2961fa1ef0 60 #define STATE_QUEUED_CONTROL_REQUEST 0x02 /**< State where it is known if there is any queued security request or not. */
Jonathan Austin 0:bc2961fa1ef0 61 /** @} */
Jonathan Austin 0:bc2961fa1ef0 62
Jonathan Austin 0:bc2961fa1ef0 63 /**
Jonathan Austin 0:bc2961fa1ef0 64 * @defgroup device_manager_conn_inst_states Connection Manager Connection Instances States.
Jonathan Austin 0:bc2961fa1ef0 65 * @{
Jonathan Austin 0:bc2961fa1ef0 66 */
Jonathan Austin 0:bc2961fa1ef0 67 #define STATE_IDLE 0x01 /**< State where connection instance is free. */
Jonathan Austin 0:bc2961fa1ef0 68 #define STATE_CONNECTED 0x02 /**< State where connection is successfully established. */
Jonathan Austin 0:bc2961fa1ef0 69 #define STATE_PAIRING 0x04 /**< State where pairing procedure is in progress. This state is used for pairing and bonding, as pairing is needed for both. */
Jonathan Austin 0:bc2961fa1ef0 70 #define STATE_BONDED 0x08 /**< State where device is bonded. */
Jonathan Austin 0:bc2961fa1ef0 71 #define STATE_DISCONNECTING 0x10 /**< State where disconnection is in progress, application will be notified first, but no further active procedures on the link. */
Jonathan Austin 0:bc2961fa1ef0 72 #define STATE_PAIRING_PENDING 0x20 /**< State where pairing request is pending on the link. */
Jonathan Austin 0:bc2961fa1ef0 73 #define STATE_BOND_INFO_UPDATE 0x40 /**< State where information has been updated, update the flash. */
Jonathan Austin 0:bc2961fa1ef0 74 #define STATE_LINK_ENCRYPTED 0x80 /**< State where link is encrypted. */
Jonathan Austin 0:bc2961fa1ef0 75 /** @} */
Jonathan Austin 0:bc2961fa1ef0 76
Jonathan Austin 0:bc2961fa1ef0 77 /**
Jonathan Austin 0:bc2961fa1ef0 78 * @defgroup device_manager_peer_id_defines Peer Identification Information Defines.
Jonathan Austin 0:bc2961fa1ef0 79 *
Jonathan Austin 0:bc2961fa1ef0 80 * @brief These defines are used to know which of the peer identification is applicable for a peer.
Jonathan Austin 0:bc2961fa1ef0 81 *
Jonathan Austin 0:bc2961fa1ef0 82 * @details These defines are used for peer identification. Here, bit map is used because it is
Jonathan Austin 0:bc2961fa1ef0 83 * possible that the application has both IRK and address for identification.
Jonathan Austin 0:bc2961fa1ef0 84 * @{
Jonathan Austin 0:bc2961fa1ef0 85 */
Jonathan Austin 0:bc2961fa1ef0 86 #define UNASSIGNED 0xFF /**< Peer instance is unassigned/unused. */
Jonathan Austin 0:bc2961fa1ef0 87 #define IRK_ENTRY 0x01 /**< Peer instance has IRK as identification information. */
Jonathan Austin 0:bc2961fa1ef0 88 #define ADDR_ENTRY 0x02 /**< Peer instance has address as identification information. */
Jonathan Austin 0:bc2961fa1ef0 89 #define SERVICE_CONTEXT_ENTRY 0x04 /**< Peer instance has service context set. */
Jonathan Austin 0:bc2961fa1ef0 90 #define APP_CONTEXT_ENTRY 0x08 /**< Peer instance has an application context set. */
Jonathan Austin 0:bc2961fa1ef0 91 /** @} */
Jonathan Austin 0:bc2961fa1ef0 92
Jonathan Austin 0:bc2961fa1ef0 93 /**@brief Device store state identifiers. */
Jonathan Austin 0:bc2961fa1ef0 94 typedef enum
Jonathan Austin 0:bc2961fa1ef0 95 {
Jonathan Austin 0:bc2961fa1ef0 96 STORE_ALL_CONTEXT, /**< Store all context. */
Jonathan Austin 0:bc2961fa1ef0 97 FIRST_BOND_STORE, /**< Store bond. */
Jonathan Austin 0:bc2961fa1ef0 98 UPDATE_PEER_ADDR /**< Update peer address. */
Jonathan Austin 0:bc2961fa1ef0 99 } device_store_state_t;
Jonathan Austin 0:bc2961fa1ef0 100
Jonathan Austin 0:bc2961fa1ef0 101 /**
Jonathan Austin 0:bc2961fa1ef0 102 * @defgroup device_manager_context_offsets Context Offsets
Jonathan Austin 0:bc2961fa1ef0 103 * @{
Jonathan Austin 0:bc2961fa1ef0 104 *
Jonathan Austin 0:bc2961fa1ef0 105 * @brief Context offsets each of the context information in persistent memory.
Jonathan Austin 0:bc2961fa1ef0 106 *
Jonathan Austin 0:bc2961fa1ef0 107 * @details Below is a layout showing how each how the context information is stored in persistent
Jonathan Austin 0:bc2961fa1ef0 108 * memory.
Jonathan Austin 0:bc2961fa1ef0 109 *
Jonathan Austin 0:bc2961fa1ef0 110 * All Device context is stored in the flash as follows:
Jonathan Austin 0:bc2961fa1ef0 111 * +---------+---------+---------+------------------+----------------+--------------------+
Jonathan Austin 0:bc2961fa1ef0 112 * | Block / Device ID + Layout of stored information in storage block |
Jonathan Austin 0:bc2961fa1ef0 113 * +---------+---------+---------+------------------+----------------+--------------------+
Jonathan Austin 0:bc2961fa1ef0 114 * | Block 0 | Device 0| Peer Id | Bond Information | Service Context| Application Context|
Jonathan Austin 0:bc2961fa1ef0 115 * +---------+---------+---------+------------------+----------------+--------------------+
Jonathan Austin 0:bc2961fa1ef0 116 * | Block 1 | Device 1| Peer Id | Bond Information | Service Context| Application Context|
Jonathan Austin 0:bc2961fa1ef0 117 * +---------+---------+---------+------------------+----------------+--------------------+
Jonathan Austin 0:bc2961fa1ef0 118 * | ... | .... |
Jonathan Austin 0:bc2961fa1ef0 119 * +---------+---------+---------+------------------+----------------+--------------------+
Jonathan Austin 0:bc2961fa1ef0 120 * | Block N | Device N| Peer Id | Bond Information | Service Context| Application Context|
Jonathan Austin 0:bc2961fa1ef0 121 * +---------+---------+---------+------------------+----------------+--------------------+
Jonathan Austin 0:bc2961fa1ef0 122 *
Jonathan Austin 0:bc2961fa1ef0 123 * The following defines are used to get offset of each of the components within a block.
Jonathan Austin 0:bc2961fa1ef0 124 */
Jonathan Austin 0:bc2961fa1ef0 125
Jonathan Austin 0:bc2961fa1ef0 126 #define PEER_ID_STORAGE_OFFSET 0 /**< Offset at which peer id is stored in the block. */
Jonathan Austin 0:bc2961fa1ef0 127 #define BOND_STORAGE_OFFSET PEER_ID_SIZE /**< Offset at which bond information is stored in the block. */
Jonathan Austin 0:bc2961fa1ef0 128 #define SERVICE_STORAGE_OFFSET (BOND_STORAGE_OFFSET + BOND_SIZE) /**< Offset at which service context is stored in the block. */
Jonathan Austin 0:bc2961fa1ef0 129 #define APP_CONTEXT_STORAGE_OFFSET (SERVICE_STORAGE_OFFSET + SERVICE_CONTEXT_SIZE) /**< Offset at which application context is stored in the block. */
Jonathan Austin 0:bc2961fa1ef0 130 /** @} */
Jonathan Austin 0:bc2961fa1ef0 131
Jonathan Austin 0:bc2961fa1ef0 132 /**
Jonathan Austin 0:bc2961fa1ef0 133 * @defgroup device_manager_context_size Context size.
Jonathan Austin 0:bc2961fa1ef0 134 * @{
Jonathan Austin 0:bc2961fa1ef0 135 *
Jonathan Austin 0:bc2961fa1ef0 136 * @brief This group defines the size of each of the context information.
Jonathan Austin 0:bc2961fa1ef0 137 */
Jonathan Austin 0:bc2961fa1ef0 138 #define PEER_ID_SIZE (sizeof(peer_id_t)) /**< Size of peer identification information. */
Jonathan Austin 0:bc2961fa1ef0 139 #define BOND_SIZE (sizeof(bond_context_t)) /**< Size of bond information. */
Jonathan Austin 0:bc2961fa1ef0 140 #define DEVICE_CONTEXT_SIZE (PEER_ID_SIZE + BOND_SIZE) /**< Size of Device context, include peer identification and bond information. */
Jonathan Austin 0:bc2961fa1ef0 141 #define GATTS_SERVICE_CONTEXT_SIZE (sizeof(dm_gatts_context_t)) /**< Size of GATTS service context. */
Jonathan Austin 0:bc2961fa1ef0 142 #define GATTC_SERVICE_CONTEXT_SIZE (sizeof(dm_gatt_client_context_t)) /**< Size of GATTC service context. */
Jonathan Austin 0:bc2961fa1ef0 143 #define SERVICE_CONTEXT_SIZE (GATTS_SERVICE_CONTEXT_SIZE + GATTC_SERVICE_CONTEXT_SIZE) /**< Combined size of GATTS and GATTC service contexts. */
Jonathan Austin 0:bc2961fa1ef0 144 #define APP_CONTEXT_MIN_SIZE 4 /**< Minimum size for application context data. */
Jonathan Austin 0:bc2961fa1ef0 145 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 146 #define APP_CONTEXT_SIZE (sizeof(uint32_t) + DEVICE_MANAGER_APP_CONTEXT_SIZE) /**< Size of application context including length field. */
Jonathan Austin 0:bc2961fa1ef0 147 #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 148 #define APP_CONTEXT_SIZE 0 /**< Size of application context. */
Jonathan Austin 0:bc2961fa1ef0 149 #endif // DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 150 #define ALL_CONTEXT_SIZE (DEVICE_CONTEXT_SIZE + SERVICE_CONTEXT_SIZE + APP_CONTEXT_SIZE) /**< Size of all contexts. */
Jonathan Austin 0:bc2961fa1ef0 151 /** @} */
Jonathan Austin 0:bc2961fa1ef0 152
Jonathan Austin 0:bc2961fa1ef0 153
Jonathan Austin 0:bc2961fa1ef0 154 /**
Jonathan Austin 0:bc2961fa1ef0 155 * @defgroup device_manager_log Module's Log Macros
Jonathan Austin 0:bc2961fa1ef0 156 *
Jonathan Austin 0:bc2961fa1ef0 157 * @details Macros used for creating module logs which can be useful in understanding handling
Jonathan Austin 0:bc2961fa1ef0 158 * of events or actions on API requests. These are intended for debugging purposes and
Jonathan Austin 0:bc2961fa1ef0 159 * can be disabled by defining the DM_DISABLE_LOGS.
Jonathan Austin 0:bc2961fa1ef0 160 *
Jonathan Austin 0:bc2961fa1ef0 161 * @note That if ENABLE_DEBUG_LOG_SUPPORT is disabled, having DM_DISABLE_LOGS has no effect.
Jonathan Austin 0:bc2961fa1ef0 162 * @{
Jonathan Austin 0:bc2961fa1ef0 163 */
LancasterUniversity 3:ae5e20530aa5 164 #define DM_DISABLE_LOGS /**< Enable this macro to disable any logs from this module. */
Jonathan Austin 0:bc2961fa1ef0 165
Jonathan Austin 0:bc2961fa1ef0 166 #ifndef DM_DISABLE_LOGS
Jonathan Austin 0:bc2961fa1ef0 167 #define DM_LOG app_trace_log /**< Used for logging details. */
Jonathan Austin 0:bc2961fa1ef0 168 #define DM_ERR app_trace_log /**< Used for logging errors in the module. */
Jonathan Austin 0:bc2961fa1ef0 169 #define DM_TRC app_trace_log /**< Used for getting trace of execution in the module. */
Jonathan Austin 0:bc2961fa1ef0 170 #define DM_DUMP app_trace_dump /**< Used for dumping octet information to get details of bond information etc. */
Jonathan Austin 0:bc2961fa1ef0 171 #else //DM_DISABLE_LOGS
Jonathan Austin 0:bc2961fa1ef0 172 #define DM_DUMP(...) /**< Disables dumping of octet streams. */
Jonathan Austin 0:bc2961fa1ef0 173 #define DM_LOG(...) /**< Disables detailed logs. */
Jonathan Austin 0:bc2961fa1ef0 174 #define DM_ERR(...) /**< Disables error logs. */
Jonathan Austin 0:bc2961fa1ef0 175 #define DM_TRC(...) /**< Disables traces. */
Jonathan Austin 0:bc2961fa1ef0 176 #endif //DM_DISABLE_LOGS
Jonathan Austin 0:bc2961fa1ef0 177 /** @} */
Jonathan Austin 0:bc2961fa1ef0 178
Jonathan Austin 0:bc2961fa1ef0 179 /**
Jonathan Austin 0:bc2961fa1ef0 180 * @defgroup device_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
Jonathan Austin 0:bc2961fa1ef0 181 *
Jonathan Austin 0:bc2961fa1ef0 182 * @details Macros used to lock and unlock modules. Currently the SDK does not use mutexes but
Jonathan Austin 0:bc2961fa1ef0 183 * framework is provided in case need arises to use an alternative architecture.
Jonathan Austin 0:bc2961fa1ef0 184 * @{
Jonathan Austin 0:bc2961fa1ef0 185 */
Jonathan Austin 0:bc2961fa1ef0 186 #define DM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_dm_mutex) /**< Lock module using mutex. */
Jonathan Austin 0:bc2961fa1ef0 187 #define DM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_dm_mutex) /**< Unlock module using mutex. */
Jonathan Austin 0:bc2961fa1ef0 188 /** @} */
Jonathan Austin 0:bc2961fa1ef0 189
Jonathan Austin 0:bc2961fa1ef0 190
Jonathan Austin 0:bc2961fa1ef0 191 /**
Jonathan Austin 0:bc2961fa1ef0 192 * @defgroup device_manager_misc_defines Miscellaneous defines used across the module.
Jonathan Austin 0:bc2961fa1ef0 193 * @{
Jonathan Austin 0:bc2961fa1ef0 194 */
Jonathan Austin 0:bc2961fa1ef0 195 #define DM_GATT_ATTR_SIZE 6 /**< Size of each GATT attribute to be stored persistently. */
Jonathan Austin 0:bc2961fa1ef0 196 #define DM_GATT_SERVER_ATTR_MAX_SIZE ((DM_GATT_ATTR_SIZE * DM_GATT_CCCD_COUNT) + 2) /**< Maximum size of GATT attributes to be stored.*/
Jonathan Austin 0:bc2961fa1ef0 197 #define DM_SERVICE_CONTEXT_COUNT (DM_PROTOCOL_CNTXT_ALL + 1) /**< Maximum number of service contexts. */
Jonathan Austin 0:bc2961fa1ef0 198 #define DM_EVT_DEVICE_CONTEXT_BASE 0x20 /**< Base for device context base. */
Jonathan Austin 0:bc2961fa1ef0 199 #define DM_EVT_SERVICE_CONTEXT_BASE 0x30 /**< Base for service context base. */
Jonathan Austin 0:bc2961fa1ef0 200 #define DM_EVT_APP_CONTEXT_BASE 0x40 /**< Base for application context base. */
Jonathan Austin 0:bc2961fa1ef0 201 #define DM_LOAD_OPERATION_ID 0x01 /**< Load operation identifier. */
Jonathan Austin 0:bc2961fa1ef0 202 #define DM_STORE_OPERATION_ID 0x02 /**< Store operation identifier. */
Jonathan Austin 0:bc2961fa1ef0 203 #define DM_CLEAR_OPERATION_ID 0x03 /**< Clear operation identifier. */
Jonathan Austin 0:bc2961fa1ef0 204 /** @} */
Jonathan Austin 0:bc2961fa1ef0 205
Jonathan Austin 0:bc2961fa1ef0 206 #define DM_GATTS_INVALID_SIZE 0xFFFFFFFF /**< Identifer for GATTS invalid size. */
Jonathan Austin 0:bc2961fa1ef0 207
Jonathan Austin 0:bc2961fa1ef0 208 /**
Jonathan Austin 0:bc2961fa1ef0 209 * @defgroup api_param_check API Parameters check macros.
Jonathan Austin 0:bc2961fa1ef0 210 *
Jonathan Austin 0:bc2961fa1ef0 211 * @details Macros for verifying parameters passed to the module in the APIs. These macros
LancasterUniversity 4:ee5f0a37316e 212 * could be mapped to nothing in the final version of the code in order to save execution
Jonathan Austin 0:bc2961fa1ef0 213 * time and program size.
Jonathan Austin 0:bc2961fa1ef0 214 * @{
Jonathan Austin 0:bc2961fa1ef0 215 */
Jonathan Austin 0:bc2961fa1ef0 216
Jonathan Austin 0:bc2961fa1ef0 217 //#define DM_DISABLE_API_PARAM_CHECK /**< Macro to disable API parameters check. */
Jonathan Austin 0:bc2961fa1ef0 218
Jonathan Austin 0:bc2961fa1ef0 219 #ifndef DM_DISABLE_API_PARAM_CHECK
Jonathan Austin 0:bc2961fa1ef0 220
Jonathan Austin 0:bc2961fa1ef0 221 /**@brief Macro for verifying NULL parameters are not passed to API.
Jonathan Austin 0:bc2961fa1ef0 222 *
Jonathan Austin 0:bc2961fa1ef0 223 * @param[in] PARAM Parameter checked for NULL.
Jonathan Austin 0:bc2961fa1ef0 224 *
Jonathan Austin 0:bc2961fa1ef0 225 * @retval (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE) when @ref PARAM is NULL.
Jonathan Austin 0:bc2961fa1ef0 226 */
Jonathan Austin 0:bc2961fa1ef0 227 #define NULL_PARAM_CHECK(PARAM) \
Jonathan Austin 0:bc2961fa1ef0 228 if ((PARAM) == NULL) \
Jonathan Austin 0:bc2961fa1ef0 229 { \
Jonathan Austin 0:bc2961fa1ef0 230 return (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE); \
Jonathan Austin 0:bc2961fa1ef0 231 }
Jonathan Austin 0:bc2961fa1ef0 232 /**@} */
Jonathan Austin 0:bc2961fa1ef0 233
Jonathan Austin 0:bc2961fa1ef0 234
Jonathan Austin 0:bc2961fa1ef0 235 /**@brief Macro for verifying module's initialization status.
Jonathan Austin 0:bc2961fa1ef0 236 *
Jonathan Austin 0:bc2961fa1ef0 237 * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module is not initialized.
Jonathan Austin 0:bc2961fa1ef0 238 */
Jonathan Austin 0:bc2961fa1ef0 239 #define VERIFY_MODULE_INITIALIZED() \
Jonathan Austin 0:bc2961fa1ef0 240 do \
Jonathan Austin 0:bc2961fa1ef0 241 { \
Jonathan Austin 0:bc2961fa1ef0 242 if (!m_module_initialized) \
Jonathan Austin 0:bc2961fa1ef0 243 { \
Jonathan Austin 0:bc2961fa1ef0 244 return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
Jonathan Austin 0:bc2961fa1ef0 245 } \
Jonathan Austin 0:bc2961fa1ef0 246 } while (0)
Jonathan Austin 0:bc2961fa1ef0 247
Jonathan Austin 0:bc2961fa1ef0 248
Jonathan Austin 0:bc2961fa1ef0 249 /**@brief Macro for verifying module's initialization status. Returns in case it is not initialized.
Jonathan Austin 0:bc2961fa1ef0 250 */
Jonathan Austin 0:bc2961fa1ef0 251 #define VERIFY_MODULE_INITIALIZED_VOID() \
Jonathan Austin 0:bc2961fa1ef0 252 do \
Jonathan Austin 0:bc2961fa1ef0 253 { \
Jonathan Austin 0:bc2961fa1ef0 254 if (!m_module_initialized) \
Jonathan Austin 0:bc2961fa1ef0 255 { \
Jonathan Austin 0:bc2961fa1ef0 256 return; \
Jonathan Austin 0:bc2961fa1ef0 257 } \
Jonathan Austin 0:bc2961fa1ef0 258 } while (0)
Jonathan Austin 0:bc2961fa1ef0 259
Jonathan Austin 0:bc2961fa1ef0 260
Jonathan Austin 0:bc2961fa1ef0 261 /**@brief Macro for verifying that the application is registered.
Jonathan Austin 0:bc2961fa1ef0 262 *
Jonathan Austin 0:bc2961fa1ef0 263 * @param[in] X Application instance identifier.
Jonathan Austin 0:bc2961fa1ef0 264 *
Jonathan Austin 0:bc2961fa1ef0 265 * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module API is called without
Jonathan Austin 0:bc2961fa1ef0 266 * registering an application with the module.
Jonathan Austin 0:bc2961fa1ef0 267 */
Jonathan Austin 0:bc2961fa1ef0 268 #define VERIFY_APP_REGISTERED(X) \
Jonathan Austin 0:bc2961fa1ef0 269 do \
Jonathan Austin 0:bc2961fa1ef0 270 { \
Jonathan Austin 0:bc2961fa1ef0 271 if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \
Jonathan Austin 0:bc2961fa1ef0 272 (m_application_table[(X)].ntf_cb == NULL)) \
Jonathan Austin 0:bc2961fa1ef0 273 { \
Jonathan Austin 0:bc2961fa1ef0 274 return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
Jonathan Austin 0:bc2961fa1ef0 275 } \
Jonathan Austin 0:bc2961fa1ef0 276 } while (0)
Jonathan Austin 0:bc2961fa1ef0 277
Jonathan Austin 0:bc2961fa1ef0 278
Jonathan Austin 0:bc2961fa1ef0 279 /**@brief Macro for verifying that the application is registered. Returns in case it is not
Jonathan Austin 0:bc2961fa1ef0 280 * registered.
Jonathan Austin 0:bc2961fa1ef0 281 *
Jonathan Austin 0:bc2961fa1ef0 282 * @param[in] X Application instance identifier.
Jonathan Austin 0:bc2961fa1ef0 283 */
Jonathan Austin 0:bc2961fa1ef0 284 #define VERIFY_APP_REGISTERED_VOID(X) \
Jonathan Austin 0:bc2961fa1ef0 285 do \
Jonathan Austin 0:bc2961fa1ef0 286 { \
Jonathan Austin 0:bc2961fa1ef0 287 if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \
Jonathan Austin 0:bc2961fa1ef0 288 (m_application_table[(X)].ntf_cb == NULL)) \
Jonathan Austin 0:bc2961fa1ef0 289 { \
Jonathan Austin 0:bc2961fa1ef0 290 return; \
Jonathan Austin 0:bc2961fa1ef0 291 } \
Jonathan Austin 0:bc2961fa1ef0 292 } while (0)
Jonathan Austin 0:bc2961fa1ef0 293
Jonathan Austin 0:bc2961fa1ef0 294
Jonathan Austin 0:bc2961fa1ef0 295 /**@brief Macro for verifying connection instance is allocated.
Jonathan Austin 0:bc2961fa1ef0 296 *
Jonathan Austin 0:bc2961fa1ef0 297 * @param[in] X Connection instance identifier.
Jonathan Austin 0:bc2961fa1ef0 298 *
Jonathan Austin 0:bc2961fa1ef0 299 * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when connection instance is not
Jonathan Austin 0:bc2961fa1ef0 300 * allocated.
Jonathan Austin 0:bc2961fa1ef0 301 */
Jonathan Austin 0:bc2961fa1ef0 302 #define VERIFY_CONNECTION_INSTANCE(X) \
Jonathan Austin 0:bc2961fa1ef0 303 do \
Jonathan Austin 0:bc2961fa1ef0 304 { \
Jonathan Austin 0:bc2961fa1ef0 305 if (((X) >= DEVICE_MANAGER_MAX_CONNECTIONS) || \
Jonathan Austin 0:bc2961fa1ef0 306 (m_connection_table[(X)].state == STATE_IDLE)) \
Jonathan Austin 0:bc2961fa1ef0 307 { \
Jonathan Austin 0:bc2961fa1ef0 308 return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \
Jonathan Austin 0:bc2961fa1ef0 309 } \
Jonathan Austin 0:bc2961fa1ef0 310 } while (0)
Jonathan Austin 0:bc2961fa1ef0 311
Jonathan Austin 0:bc2961fa1ef0 312
Jonathan Austin 0:bc2961fa1ef0 313 /**@brief Macro for verifying if device instance is allocated.
Jonathan Austin 0:bc2961fa1ef0 314 *
Jonathan Austin 0:bc2961fa1ef0 315 * @param[in] X Device instance identifier.
Jonathan Austin 0:bc2961fa1ef0 316 *
Jonathan Austin 0:bc2961fa1ef0 317 * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when device instance is not allocated.
Jonathan Austin 0:bc2961fa1ef0 318 */
Jonathan Austin 0:bc2961fa1ef0 319 #define VERIFY_DEVICE_INSTANCE(X) \
Jonathan Austin 0:bc2961fa1ef0 320 do \
Jonathan Austin 0:bc2961fa1ef0 321 { \
Jonathan Austin 0:bc2961fa1ef0 322 if (((X) >= DEVICE_MANAGER_MAX_BONDS) || \
Jonathan Austin 0:bc2961fa1ef0 323 (m_peer_table[(X)].id_bitmap == UNASSIGNED)) \
Jonathan Austin 0:bc2961fa1ef0 324 { \
Jonathan Austin 0:bc2961fa1ef0 325 return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \
Jonathan Austin 0:bc2961fa1ef0 326 } \
Jonathan Austin 0:bc2961fa1ef0 327 } while (0)
Jonathan Austin 0:bc2961fa1ef0 328
Jonathan Austin 0:bc2961fa1ef0 329 /**@brief Macro for verifying if device is bonded and thus can store data persistantly.
Jonathan Austin 0:bc2961fa1ef0 330 *
Jonathan Austin 0:bc2961fa1ef0 331 * @param[in] X Connection instance identifier.
Jonathan Austin 0:bc2961fa1ef0 332 *
Jonathan Austin 0:bc2961fa1ef0 333 * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when device is not bonded.
Jonathan Austin 0:bc2961fa1ef0 334 */
Jonathan Austin 0:bc2961fa1ef0 335 #define VERIFY_DEVICE_BOND(X) \
Jonathan Austin 0:bc2961fa1ef0 336 do \
Jonathan Austin 0:bc2961fa1ef0 337 { \
Jonathan Austin 0:bc2961fa1ef0 338 if ((m_connection_table[(X)].state & STATE_BONDED) != STATE_BONDED)\
Jonathan Austin 0:bc2961fa1ef0 339 { \
Jonathan Austin 0:bc2961fa1ef0 340 return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
Jonathan Austin 0:bc2961fa1ef0 341 } \
Jonathan Austin 0:bc2961fa1ef0 342 } while (0)
Jonathan Austin 0:bc2961fa1ef0 343 #else
Jonathan Austin 0:bc2961fa1ef0 344 #define NULL_PARAM_CHECK(X)
Jonathan Austin 0:bc2961fa1ef0 345 #define VERIFY_MODULE_INITIALIZED()
Jonathan Austin 0:bc2961fa1ef0 346 #define VERIFY_MODULE_INITIALIZED_VOID()
Jonathan Austin 0:bc2961fa1ef0 347 #define VERIFY_APP_REGISTERED(X)
Jonathan Austin 0:bc2961fa1ef0 348 #define VERIFY_APP_REGISTERED_VOID(X)
Jonathan Austin 0:bc2961fa1ef0 349 #define VERIFY_CONNECTION_INSTANCE(X)
Jonathan Austin 0:bc2961fa1ef0 350 #define VERIFY_DEVICE_INSTANCE(X)
Jonathan Austin 0:bc2961fa1ef0 351 #endif //DM_DISABLE_API_PARAM_CHECK
Jonathan Austin 0:bc2961fa1ef0 352 /** @} */
Jonathan Austin 0:bc2961fa1ef0 353
Jonathan Austin 0:bc2961fa1ef0 354 #define INVALID_CONTEXT_LEN 0xFFFFFFFF /**< Identifier for invalid context length. */
Jonathan Austin 0:bc2961fa1ef0 355 /**@brief Macro for checking that application context size is greater that minimal size.
Jonathan Austin 0:bc2961fa1ef0 356 *
Jonathan Austin 0:bc2961fa1ef0 357 * @param[in] X Size of application context.
Jonathan Austin 0:bc2961fa1ef0 358 *
Jonathan Austin 0:bc2961fa1ef0 359 * @retval (NRF_ERROR_INVALID_PARAM) when size is smaller than minimun required size.
Jonathan Austin 0:bc2961fa1ef0 360 */
Jonathan Austin 0:bc2961fa1ef0 361 #define SIZE_CHECK_APP_CONTEXT(X) \
Jonathan Austin 0:bc2961fa1ef0 362 if ((X) < (APP_CONTEXT_MIN_SIZE)) \
Jonathan Austin 0:bc2961fa1ef0 363 { \
Jonathan Austin 0:bc2961fa1ef0 364 return NRF_ERROR_INVALID_PARAM; \
Jonathan Austin 0:bc2961fa1ef0 365 }
Jonathan Austin 0:bc2961fa1ef0 366
Jonathan Austin 0:bc2961fa1ef0 367
Jonathan Austin 0:bc2961fa1ef0 368 /**
Jonathan Austin 0:bc2961fa1ef0 369 * @defgroup dm_data_types Module's internal data types.
Jonathan Austin 0:bc2961fa1ef0 370 *
Jonathan Austin 0:bc2961fa1ef0 371 * @brief This section describes a module's internal data structures.
Jonathan Austin 0:bc2961fa1ef0 372 * @{
Jonathan Austin 0:bc2961fa1ef0 373 */
Jonathan Austin 0:bc2961fa1ef0 374 /**@brief Peer identification information.
Jonathan Austin 0:bc2961fa1ef0 375 */
Jonathan Austin 0:bc2961fa1ef0 376 typedef struct
LancasterUniversity 4:ee5f0a37316e 377 {
Jonathan Austin 0:bc2961fa1ef0 378 ble_gap_id_key_t peer_id; /**< IRK and/or address of peer. */
Jonathan Austin 0:bc2961fa1ef0 379 uint16_t ediv; /**< Peer's encrypted diversifier. */
Jonathan Austin 0:bc2961fa1ef0 380 uint8_t id_bitmap; /**< Contains information if above field is valid. */
Jonathan Austin 0:bc2961fa1ef0 381 } peer_id_t;
Jonathan Austin 0:bc2961fa1ef0 382
Jonathan Austin 0:bc2961fa1ef0 383 STATIC_ASSERT(sizeof(peer_id_t) % 4 == 0); /**< Check to ensure Peer identification information is a multiple of 4. */
Jonathan Austin 0:bc2961fa1ef0 384
Jonathan Austin 0:bc2961fa1ef0 385 /**@brief Portion of bonding information exchanged by a device during bond creation that needs to
Jonathan Austin 0:bc2961fa1ef0 386 * be stored persistently.
Jonathan Austin 0:bc2961fa1ef0 387 *
Jonathan Austin 0:bc2961fa1ef0 388 * @note An entry is not made in this table unless device is bonded.
Jonathan Austin 0:bc2961fa1ef0 389 */
Jonathan Austin 0:bc2961fa1ef0 390 typedef struct
Jonathan Austin 0:bc2961fa1ef0 391 {
Jonathan Austin 0:bc2961fa1ef0 392 ble_gap_enc_key_t peer_enc_key; /**< Local LTK info, central IRK and address */
Jonathan Austin 0:bc2961fa1ef0 393 } bond_context_t;
Jonathan Austin 0:bc2961fa1ef0 394
Jonathan Austin 0:bc2961fa1ef0 395 STATIC_ASSERT(sizeof(bond_context_t) % 4 == 0); /**< Check to ensure bond information is a multiple of 4. */
Jonathan Austin 0:bc2961fa1ef0 396
Jonathan Austin 0:bc2961fa1ef0 397 /**@brief GATT Server Attributes size and data.
Jonathan Austin 0:bc2961fa1ef0 398 */
Jonathan Austin 0:bc2961fa1ef0 399 typedef struct
Jonathan Austin 0:bc2961fa1ef0 400 {
Jonathan Austin 0:bc2961fa1ef0 401 uint32_t flags; /**< Flags identifying the stored attributes. */
Jonathan Austin 0:bc2961fa1ef0 402 uint32_t size; /**< Size of stored attributes. */
Jonathan Austin 0:bc2961fa1ef0 403 uint8_t attributes[DM_GATT_SERVER_ATTR_MAX_SIZE]; /**< Array to hold the server attributes. */
Jonathan Austin 0:bc2961fa1ef0 404 } dm_gatts_context_t;
Jonathan Austin 0:bc2961fa1ef0 405
Jonathan Austin 0:bc2961fa1ef0 406 STATIC_ASSERT(sizeof(dm_gatts_context_t) % 4 == 0); /**< Check to ensure GATT Server Attributes size and data information is a multiple of 4. */
Jonathan Austin 0:bc2961fa1ef0 407
Jonathan Austin 0:bc2961fa1ef0 408 /**@brief GATT Client context information. Placeholder for now.
Jonathan Austin 0:bc2961fa1ef0 409 */
Jonathan Austin 0:bc2961fa1ef0 410 typedef struct
Jonathan Austin 0:bc2961fa1ef0 411 {
Jonathan Austin 0:bc2961fa1ef0 412 void * p_dummy; /**< Placeholder, currently unused. */
Jonathan Austin 0:bc2961fa1ef0 413 } dm_gatt_client_context_t;
Jonathan Austin 0:bc2961fa1ef0 414
Jonathan Austin 0:bc2961fa1ef0 415 STATIC_ASSERT(sizeof(dm_gatt_client_context_t) % 4 == 0); /**< Check to ensure GATT Client context information is a multiple of 4. */
Jonathan Austin 0:bc2961fa1ef0 416 STATIC_ASSERT((DEVICE_MANAGER_APP_CONTEXT_SIZE % 4) == 0); /**< Check to ensure device manager application context information is a multiple of 4. */
Jonathan Austin 0:bc2961fa1ef0 417
Jonathan Austin 0:bc2961fa1ef0 418 /**@brief Connection instance definition. Maintains information with respect to an active peer.
Jonathan Austin 0:bc2961fa1ef0 419 */
Jonathan Austin 0:bc2961fa1ef0 420 typedef struct
Jonathan Austin 0:bc2961fa1ef0 421 {
Jonathan Austin 0:bc2961fa1ef0 422 ble_gap_addr_t peer_addr; /**< Peer identification information. This information is retained as long as the connection session exists, once disconnected, for non-bonded devices this information is not stored persistently. */
Jonathan Austin 0:bc2961fa1ef0 423 uint16_t conn_handle; /**< Connection handle for the device. */
Jonathan Austin 0:bc2961fa1ef0 424 uint8_t state; /**< Link state. */
Jonathan Austin 0:bc2961fa1ef0 425 uint8_t bonded_dev_id; /**< In case the device is bonded, this points to the corresponding bonded device. This index can be used to index service and bond context as well. */
Jonathan Austin 0:bc2961fa1ef0 426 } connection_instance_t;
Jonathan Austin 0:bc2961fa1ef0 427
Jonathan Austin 0:bc2961fa1ef0 428 /**@brief Application instance definition. Maintains information with respect to a registered
Jonathan Austin 0:bc2961fa1ef0 429 * application.
Jonathan Austin 0:bc2961fa1ef0 430 */
Jonathan Austin 0:bc2961fa1ef0 431 typedef struct
Jonathan Austin 0:bc2961fa1ef0 432 {
Jonathan Austin 0:bc2961fa1ef0 433 dm_event_cb_t ntf_cb; /**< Callback registered with the application. */
Jonathan Austin 0:bc2961fa1ef0 434 ble_gap_sec_params_t sec_param; /**< Local security parameters registered by the application. */
Jonathan Austin 0:bc2961fa1ef0 435 uint8_t state; /**< Application state. Currently this is used only for knowing if any security procedure is in progress and/or a security procedure is pending to be requested. */
Jonathan Austin 0:bc2961fa1ef0 436 uint8_t service; /**< Service registered by the application. */
Jonathan Austin 0:bc2961fa1ef0 437 } application_instance_t;
Jonathan Austin 0:bc2961fa1ef0 438
Jonathan Austin 0:bc2961fa1ef0 439 /**@brief Function for performing necessary action of storing each of the service context as
Jonathan Austin 0:bc2961fa1ef0 440 * registered by the application.
Jonathan Austin 0:bc2961fa1ef0 441 *
Jonathan Austin 0:bc2961fa1ef0 442 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 443 * @param[in] p_handle Device handle identifying device that is stored.
Jonathan Austin 0:bc2961fa1ef0 444 *
Jonathan Austin 0:bc2961fa1ef0 445 * @retval Operation result code.
Jonathan Austin 0:bc2961fa1ef0 446 */
Jonathan Austin 0:bc2961fa1ef0 447 typedef ret_code_t (* service_context_access_t)(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 448 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 449
Jonathan Austin 0:bc2961fa1ef0 450 /**@brief Function for performing necessary action of applying the context information.
Jonathan Austin 0:bc2961fa1ef0 451 *
Jonathan Austin 0:bc2961fa1ef0 452 * @param[in] p_handle Device handle identifying device that is stored.
Jonathan Austin 0:bc2961fa1ef0 453 *
Jonathan Austin 0:bc2961fa1ef0 454 * @retval Operation result code.
Jonathan Austin 0:bc2961fa1ef0 455 */
Jonathan Austin 0:bc2961fa1ef0 456 typedef ret_code_t (* service_context_apply_t)(dm_handle_t * p_handle);
Jonathan Austin 0:bc2961fa1ef0 457
Jonathan Austin 0:bc2961fa1ef0 458 /**@brief Function for performing necessary functions of storing or updating.
Jonathan Austin 0:bc2961fa1ef0 459 *
Jonathan Austin 0:bc2961fa1ef0 460 * @param[in] p_dest Destination address where data is stored persistently.
Jonathan Austin 0:bc2961fa1ef0 461 * @param[in] p_src Source address containing data to be stored.
Jonathan Austin 0:bc2961fa1ef0 462 * @param[in] size Size of data to be stored expressed in bytes. Must be word aligned.
Jonathan Austin 0:bc2961fa1ef0 463 * @param[in] offset Offset in bytes to be applied when writing to the block.
Jonathan Austin 0:bc2961fa1ef0 464 *
Jonathan Austin 0:bc2961fa1ef0 465 * @retval Operation result code.
Jonathan Austin 0:bc2961fa1ef0 466 */
Jonathan Austin 0:bc2961fa1ef0 467 typedef uint32_t (* storage_operation)(pstorage_handle_t * p_dest,
Jonathan Austin 0:bc2961fa1ef0 468 uint8_t * p_src,
Jonathan Austin 0:bc2961fa1ef0 469 pstorage_size_t size,
Jonathan Austin 0:bc2961fa1ef0 470 pstorage_size_t offset);
Jonathan Austin 0:bc2961fa1ef0 471 /** @} */
Jonathan Austin 0:bc2961fa1ef0 472
Jonathan Austin 0:bc2961fa1ef0 473 /**
Jonathan Austin 0:bc2961fa1ef0 474 * @defgroup dm_tables Module's internal tables.
Jonathan Austin 0:bc2961fa1ef0 475 *
Jonathan Austin 0:bc2961fa1ef0 476 * @brief This section describes the module's internal tables and the static global variables
Jonathan Austin 0:bc2961fa1ef0 477 * needed for its functionality.
Jonathan Austin 0:bc2961fa1ef0 478 * @{
Jonathan Austin 0:bc2961fa1ef0 479 */
Jonathan Austin 0:bc2961fa1ef0 480 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 481 static uint8_t * m_app_context_table[DEVICE_MANAGER_MAX_BONDS]; /**< Table to remember application contexts of bonded devices. */
Jonathan Austin 0:bc2961fa1ef0 482 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 483 __ALIGN(sizeof(uint32_t))
Jonathan Austin 0:bc2961fa1ef0 484 static peer_id_t m_peer_table[DEVICE_MANAGER_MAX_BONDS] ; /**< Table to maintain bonded devices' identification information, an instance is allocated in the table when a device is bonded and freed when bond information is deleted. */
Jonathan Austin 0:bc2961fa1ef0 485 __ALIGN(sizeof(uint32_t))
Jonathan Austin 0:bc2961fa1ef0 486 static bond_context_t m_bond_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain bond information for active peers. */
Jonathan Austin 0:bc2961fa1ef0 487 static dm_gatts_context_t m_gatts_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table for service information for active connection instances. */
Jonathan Austin 0:bc2961fa1ef0 488 static connection_instance_t m_connection_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain active peer information. An instance is allocated in the table when a new connection is established and freed on disconnection. */
Jonathan Austin 0:bc2961fa1ef0 489 static application_instance_t m_application_table[DEVICE_MANAGER_MAX_APPLICATIONS]; /**< Table to maintain application instances. */
Jonathan Austin 0:bc2961fa1ef0 490 static pstorage_handle_t m_storage_handle; /**< Persistent storage handle for blocks requested by the module. */
Jonathan Austin 0:bc2961fa1ef0 491 static uint32_t m_peer_addr_update; /**< 32-bit bitmap to remember peer device address update. */
Jonathan Austin 0:bc2961fa1ef0 492 static ble_gap_id_key_t m_local_id_info; /**< ID information of central in case resolvable address is used. */
Jonathan Austin 0:bc2961fa1ef0 493 static bool m_module_initialized = false; /**< State indicating if module is initialized or not. */
Jonathan Austin 0:bc2961fa1ef0 494 static uint8_t m_irk_index_table[DEVICE_MANAGER_MAX_BONDS]; /**< List maintaining IRK index list. */
Jonathan Austin 0:bc2961fa1ef0 495
Jonathan Austin 0:bc2961fa1ef0 496 SDK_MUTEX_DEFINE(m_dm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
Jonathan Austin 0:bc2961fa1ef0 497 /** @} */
Jonathan Austin 0:bc2961fa1ef0 498
Jonathan Austin 0:bc2961fa1ef0 499 static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 500 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 501
Jonathan Austin 0:bc2961fa1ef0 502 static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 503 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 504
Jonathan Austin 0:bc2961fa1ef0 505 static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 506 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 507
Jonathan Austin 0:bc2961fa1ef0 508 static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 509 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 510
Jonathan Austin 0:bc2961fa1ef0 511 static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 512 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 513
Jonathan Austin 0:bc2961fa1ef0 514 static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 515 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 516
Jonathan Austin 0:bc2961fa1ef0 517 static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 518 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 519
Jonathan Austin 0:bc2961fa1ef0 520 static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 521 dm_handle_t const * p_handle);
Jonathan Austin 0:bc2961fa1ef0 522
Jonathan Austin 0:bc2961fa1ef0 523 static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle);
Jonathan Austin 0:bc2961fa1ef0 524
Jonathan Austin 0:bc2961fa1ef0 525 static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle);
Jonathan Austin 0:bc2961fa1ef0 526
Jonathan Austin 0:bc2961fa1ef0 527 static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle);
Jonathan Austin 0:bc2961fa1ef0 528
Jonathan Austin 0:bc2961fa1ef0 529 static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle);
Jonathan Austin 0:bc2961fa1ef0 530
Jonathan Austin 0:bc2961fa1ef0 531
Jonathan Austin 0:bc2961fa1ef0 532 /**< Array of function pointers based on the types of service registered. */
Jonathan Austin 0:bc2961fa1ef0 533 const service_context_access_t m_service_context_store[DM_SERVICE_CONTEXT_COUNT] =
Jonathan Austin 0:bc2961fa1ef0 534 {
Jonathan Austin 0:bc2961fa1ef0 535 no_service_context_store, /**< Dummy function, when there is no service context registered. */
Jonathan Austin 0:bc2961fa1ef0 536 gatts_context_store, /**< GATT Server context store function. */
Jonathan Austin 0:bc2961fa1ef0 537 gattc_context_store, /**< GATT Client context store function. */
Jonathan Austin 0:bc2961fa1ef0 538 gattsc_context_store /**< GATT Server & Client context store function. */
Jonathan Austin 0:bc2961fa1ef0 539 };
Jonathan Austin 0:bc2961fa1ef0 540
Jonathan Austin 0:bc2961fa1ef0 541
Jonathan Austin 0:bc2961fa1ef0 542 /**< Array of function pointers based on the types of service registered. */
Jonathan Austin 0:bc2961fa1ef0 543 const service_context_access_t m_service_context_load[DM_SERVICE_CONTEXT_COUNT] =
Jonathan Austin 0:bc2961fa1ef0 544 {
Jonathan Austin 0:bc2961fa1ef0 545 no_service_context_load, /**< Dummy function, when there is no service context registered. */
Jonathan Austin 0:bc2961fa1ef0 546 gatts_context_load, /**< GATT Server context load function. */
Jonathan Austin 0:bc2961fa1ef0 547 gattc_context_load, /**< GATT Client context load function. */
Jonathan Austin 0:bc2961fa1ef0 548 gattsc_context_load /**< GATT Server & Client context load function. */
Jonathan Austin 0:bc2961fa1ef0 549 };
Jonathan Austin 0:bc2961fa1ef0 550
Jonathan Austin 0:bc2961fa1ef0 551
Jonathan Austin 0:bc2961fa1ef0 552 /**< Array of function pointers based on the types of service registered. */
Jonathan Austin 0:bc2961fa1ef0 553 const service_context_apply_t m_service_context_apply[DM_SERVICE_CONTEXT_COUNT] =
Jonathan Austin 0:bc2961fa1ef0 554 {
Jonathan Austin 0:bc2961fa1ef0 555 no_service_context_apply, /**< Dummy function, when there is no service context registered. */
Jonathan Austin 0:bc2961fa1ef0 556 gatts_context_apply, /**< GATT Server context apply function. */
Jonathan Austin 0:bc2961fa1ef0 557 gattc_context_apply, /**< GATT Client context apply function. */
Jonathan Austin 0:bc2961fa1ef0 558 gattsc_context_apply /**< GATT Server & Client context apply function. */
Jonathan Austin 0:bc2961fa1ef0 559 };
Jonathan Austin 0:bc2961fa1ef0 560
Jonathan Austin 0:bc2961fa1ef0 561
Jonathan Austin 0:bc2961fa1ef0 562 const uint32_t m_context_init_len = 0xFFFFFFFF; /**< Constant used to update the initial value for context in the flash. */
Jonathan Austin 0:bc2961fa1ef0 563
Jonathan Austin 0:bc2961fa1ef0 564 /**@brief Function for setting update status for the device identified by 'index'.
Jonathan Austin 0:bc2961fa1ef0 565 *
Jonathan Austin 0:bc2961fa1ef0 566 * @param[in] index Device identifier.
Jonathan Austin 0:bc2961fa1ef0 567 */
Jonathan Austin 0:bc2961fa1ef0 568 static __INLINE void update_status_bit_set(uint32_t index)
Jonathan Austin 0:bc2961fa1ef0 569 {
Jonathan Austin 0:bc2961fa1ef0 570 m_peer_addr_update |= (BIT_0 << index);
Jonathan Austin 0:bc2961fa1ef0 571 }
Jonathan Austin 0:bc2961fa1ef0 572
Jonathan Austin 0:bc2961fa1ef0 573
Jonathan Austin 0:bc2961fa1ef0 574 /**@brief Function for resetting update status for device identified by 'index'.
Jonathan Austin 0:bc2961fa1ef0 575 *
Jonathan Austin 0:bc2961fa1ef0 576 * @param[in] index Device identifier.
Jonathan Austin 0:bc2961fa1ef0 577 */
Jonathan Austin 0:bc2961fa1ef0 578 static __INLINE void update_status_bit_reset(uint32_t index)
Jonathan Austin 0:bc2961fa1ef0 579 {
Jonathan Austin 0:bc2961fa1ef0 580 m_peer_addr_update &= (~((uint32_t)BIT_0 << index));
Jonathan Austin 0:bc2961fa1ef0 581 }
Jonathan Austin 0:bc2961fa1ef0 582
Jonathan Austin 0:bc2961fa1ef0 583
Jonathan Austin 0:bc2961fa1ef0 584 /**@brief Function for providing update status for the device identified by 'index'.
Jonathan Austin 0:bc2961fa1ef0 585 *
Jonathan Austin 0:bc2961fa1ef0 586 * @param[in] index Device identifier.
Jonathan Austin 0:bc2961fa1ef0 587 *
Jonathan Austin 0:bc2961fa1ef0 588 * @retval true if the bit is set, false otherwise.
Jonathan Austin 0:bc2961fa1ef0 589 */
Jonathan Austin 0:bc2961fa1ef0 590 static __INLINE bool update_status_bit_is_set(uint32_t index)
Jonathan Austin 0:bc2961fa1ef0 591 {
Jonathan Austin 0:bc2961fa1ef0 592 return ((m_peer_addr_update & (BIT_0 << index)) ? true : false);
Jonathan Austin 0:bc2961fa1ef0 593 }
Jonathan Austin 0:bc2961fa1ef0 594
Jonathan Austin 0:bc2961fa1ef0 595
Jonathan Austin 0:bc2961fa1ef0 596 /**@brief Function for initialiasing the application instance identified by 'index'.
Jonathan Austin 0:bc2961fa1ef0 597 *
Jonathan Austin 0:bc2961fa1ef0 598 * @param[in] index Device identifier.
Jonathan Austin 0:bc2961fa1ef0 599 */
Jonathan Austin 0:bc2961fa1ef0 600 static __INLINE void application_instance_init(uint32_t index)
Jonathan Austin 0:bc2961fa1ef0 601 {
Jonathan Austin 0:bc2961fa1ef0 602 DM_TRC("[DM]: Initializing Application Instance 0x%08X.\r\n", index);
Jonathan Austin 0:bc2961fa1ef0 603
Jonathan Austin 0:bc2961fa1ef0 604 m_application_table[index].ntf_cb = NULL;
Jonathan Austin 0:bc2961fa1ef0 605 m_application_table[index].state = 0x00;
Jonathan Austin 0:bc2961fa1ef0 606 m_application_table[index].service = 0x00;
Jonathan Austin 0:bc2961fa1ef0 607 }
Jonathan Austin 0:bc2961fa1ef0 608
Jonathan Austin 0:bc2961fa1ef0 609
Jonathan Austin 0:bc2961fa1ef0 610 /**@brief Function for initialiasing the connection instance identified by 'index'.
Jonathan Austin 0:bc2961fa1ef0 611 *
Jonathan Austin 0:bc2961fa1ef0 612 * @param[in] index Device identifier.
Jonathan Austin 0:bc2961fa1ef0 613 */
Jonathan Austin 0:bc2961fa1ef0 614 static __INLINE void connection_instance_init(uint32_t index)
Jonathan Austin 0:bc2961fa1ef0 615 {
Jonathan Austin 0:bc2961fa1ef0 616 DM_TRC("[DM]: Initializing Connection Instance 0x%08X.\r\n", index);
LancasterUniversity 4:ee5f0a37316e 617
Jonathan Austin 0:bc2961fa1ef0 618 m_connection_table[index].state = STATE_IDLE;
Jonathan Austin 0:bc2961fa1ef0 619 m_connection_table[index].conn_handle = BLE_CONN_HANDLE_INVALID;
Jonathan Austin 0:bc2961fa1ef0 620 m_connection_table[index].bonded_dev_id = DM_INVALID_ID;
LancasterUniversity 4:ee5f0a37316e 621
Jonathan Austin 0:bc2961fa1ef0 622 memset(&m_connection_table[index].peer_addr, 0, sizeof (ble_gap_addr_t));
Jonathan Austin 0:bc2961fa1ef0 623 }
Jonathan Austin 0:bc2961fa1ef0 624
Jonathan Austin 0:bc2961fa1ef0 625
Jonathan Austin 0:bc2961fa1ef0 626 /**@brief Function for initialiasing the peer device instance identified by 'index'.
Jonathan Austin 0:bc2961fa1ef0 627 *
Jonathan Austin 0:bc2961fa1ef0 628 * @param[in] index Device identifier.
Jonathan Austin 0:bc2961fa1ef0 629 */
Jonathan Austin 0:bc2961fa1ef0 630 static __INLINE void peer_instance_init(uint32_t index)
Jonathan Austin 0:bc2961fa1ef0 631 {
Jonathan Austin 0:bc2961fa1ef0 632 DM_TRC("[DM]: Initializing Peer Instance 0x%08X.\r\n", index);
LancasterUniversity 4:ee5f0a37316e 633
Jonathan Austin 0:bc2961fa1ef0 634 memset(m_peer_table[index].peer_id.id_addr_info.addr, 0, BLE_GAP_ADDR_LEN);
Jonathan Austin 0:bc2961fa1ef0 635 memset(m_peer_table[index].peer_id.id_info.irk, 0, BLE_GAP_SEC_KEY_LEN);
Jonathan Austin 0:bc2961fa1ef0 636
Jonathan Austin 0:bc2961fa1ef0 637 //Initialize the address type to invalid.
Jonathan Austin 0:bc2961fa1ef0 638 m_peer_table[index].peer_id.id_addr_info.addr_type = INVALID_ADDR_TYPE;
Jonathan Austin 0:bc2961fa1ef0 639
Jonathan Austin 0:bc2961fa1ef0 640 //Initialize the identification bit map to unassigned.
Jonathan Austin 0:bc2961fa1ef0 641 m_peer_table[index].id_bitmap = UNASSIGNED;
Jonathan Austin 0:bc2961fa1ef0 642
Jonathan Austin 0:bc2961fa1ef0 643 // Initialize diversifier.
Jonathan Austin 0:bc2961fa1ef0 644 m_peer_table[index].ediv = EDIV_INIT_VAL;
Jonathan Austin 0:bc2961fa1ef0 645
Jonathan Austin 0:bc2961fa1ef0 646
Jonathan Austin 0:bc2961fa1ef0 647 //Reset the status bit.
Jonathan Austin 0:bc2961fa1ef0 648 update_status_bit_reset(index);
Jonathan Austin 0:bc2961fa1ef0 649
Jonathan Austin 0:bc2961fa1ef0 650 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 651 //Initialize the application context for bond device.
Jonathan Austin 0:bc2961fa1ef0 652 m_app_context_table[index] = NULL;
Jonathan Austin 0:bc2961fa1ef0 653 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 654 }
Jonathan Austin 0:bc2961fa1ef0 655
Jonathan Austin 0:bc2961fa1ef0 656
Jonathan Austin 0:bc2961fa1ef0 657 /**@brief Function for searching connection instance matching the connection handle and the state
Jonathan Austin 0:bc2961fa1ef0 658 * requested.
Jonathan Austin 0:bc2961fa1ef0 659 *
Jonathan Austin 0:bc2961fa1ef0 660 * @details Connection handle and state information is used to get a connection instance, it
Jonathan Austin 0:bc2961fa1ef0 661 * is possible to ignore the connection handle by using BLE_CONN_HANDLE_INVALID.
Jonathan Austin 0:bc2961fa1ef0 662 *
Jonathan Austin 0:bc2961fa1ef0 663 * @param[in] conn_handle Connection handle.
Jonathan Austin 0:bc2961fa1ef0 664 * @param[in] state Connection instance state.
Jonathan Austin 0:bc2961fa1ef0 665 * @param[out] p_instance Connection instance.
Jonathan Austin 0:bc2961fa1ef0 666 *
Jonathan Austin 0:bc2961fa1ef0 667 * @retval NRF_SUCCESS Operation success.
Jonathan Austin 0:bc2961fa1ef0 668 * @retval NRF_ERROR_INVALID_STATE Operation failure. Invalid state
Jonathan Austin 0:bc2961fa1ef0 669 * @retval NRF_ERROR_NOT_FOUND Operation failure. Not found
Jonathan Austin 0:bc2961fa1ef0 670 */
Jonathan Austin 0:bc2961fa1ef0 671 static ret_code_t connection_instance_find(uint16_t conn_handle,
Jonathan Austin 0:bc2961fa1ef0 672 uint8_t state,
Jonathan Austin 0:bc2961fa1ef0 673 uint32_t * p_instance)
Jonathan Austin 0:bc2961fa1ef0 674 {
Jonathan Austin 0:bc2961fa1ef0 675 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 676 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 677
Jonathan Austin 0:bc2961fa1ef0 678 err_code = NRF_ERROR_INVALID_STATE;
Jonathan Austin 0:bc2961fa1ef0 679
Jonathan Austin 0:bc2961fa1ef0 680 for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
Jonathan Austin 0:bc2961fa1ef0 681 {
Jonathan Austin 0:bc2961fa1ef0 682 //Search only based on the state.
Jonathan Austin 0:bc2961fa1ef0 683 if (state & m_connection_table[index].state)
Jonathan Austin 0:bc2961fa1ef0 684 {
Jonathan Austin 0:bc2961fa1ef0 685 //Ignore the connection handle.
Jonathan Austin 0:bc2961fa1ef0 686 if ((conn_handle == BLE_CONN_HANDLE_INVALID) ||
Jonathan Austin 0:bc2961fa1ef0 687 (conn_handle == m_connection_table[index].conn_handle))
Jonathan Austin 0:bc2961fa1ef0 688 {
Jonathan Austin 0:bc2961fa1ef0 689 //Search for matching connection handle.
Jonathan Austin 0:bc2961fa1ef0 690 (*p_instance) = index;
Jonathan Austin 0:bc2961fa1ef0 691 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 692
Jonathan Austin 0:bc2961fa1ef0 693 break;
Jonathan Austin 0:bc2961fa1ef0 694 }
Jonathan Austin 0:bc2961fa1ef0 695 else
Jonathan Austin 0:bc2961fa1ef0 696 {
Jonathan Austin 0:bc2961fa1ef0 697 err_code = NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 698 }
Jonathan Austin 0:bc2961fa1ef0 699 }
Jonathan Austin 0:bc2961fa1ef0 700 }
Jonathan Austin 0:bc2961fa1ef0 701
Jonathan Austin 0:bc2961fa1ef0 702 return err_code;
Jonathan Austin 0:bc2961fa1ef0 703 }
Jonathan Austin 0:bc2961fa1ef0 704
Jonathan Austin 0:bc2961fa1ef0 705
Jonathan Austin 0:bc2961fa1ef0 706 /**@brief Function for allocating device instance for a bonded device.
Jonathan Austin 0:bc2961fa1ef0 707 *
Jonathan Austin 0:bc2961fa1ef0 708 * @param[out] p_device_index Device index.
Jonathan Austin 0:bc2961fa1ef0 709 * @param[in] p_addr Peer identification information.
Jonathan Austin 0:bc2961fa1ef0 710 *
Jonathan Austin 0:bc2961fa1ef0 711 * @retval NRF_SUCCESS Operation success.
Jonathan Austin 0:bc2961fa1ef0 712 * @retval DM_DEVICE_CONTEXT_FULL Operation failure.
Jonathan Austin 0:bc2961fa1ef0 713 */
Jonathan Austin 0:bc2961fa1ef0 714 static __INLINE ret_code_t device_instance_allocate(uint8_t * p_device_index,
Jonathan Austin 0:bc2961fa1ef0 715 ble_gap_addr_t const * p_addr)
Jonathan Austin 0:bc2961fa1ef0 716 {
Jonathan Austin 0:bc2961fa1ef0 717 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 718 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 719
Jonathan Austin 0:bc2961fa1ef0 720 err_code = DM_DEVICE_CONTEXT_FULL;
Jonathan Austin 0:bc2961fa1ef0 721
Jonathan Austin 0:bc2961fa1ef0 722 for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 723 {
LancasterUniversity 5:f2faa0f0b8f0 724 DM_LOG("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 725 index, m_peer_table[index].peer_id.id_addr_info.addr_type);
LancasterUniversity 5:f2faa0f0b8f0 726 DM_LOG("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 727 m_peer_table[index].peer_id.id_addr_info.addr[0],
Jonathan Austin 0:bc2961fa1ef0 728 m_peer_table[index].peer_id.id_addr_info.addr[1],
Jonathan Austin 0:bc2961fa1ef0 729 m_peer_table[index].peer_id.id_addr_info.addr[2],
Jonathan Austin 0:bc2961fa1ef0 730 m_peer_table[index].peer_id.id_addr_info.addr[3],
Jonathan Austin 0:bc2961fa1ef0 731 m_peer_table[index].peer_id.id_addr_info.addr[4],
Jonathan Austin 0:bc2961fa1ef0 732 m_peer_table[index].peer_id.id_addr_info.addr[5]);
Jonathan Austin 0:bc2961fa1ef0 733
Jonathan Austin 0:bc2961fa1ef0 734 if (m_peer_table[index].id_bitmap == UNASSIGNED)
Jonathan Austin 0:bc2961fa1ef0 735 {
Jonathan Austin 0:bc2961fa1ef0 736 if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
Jonathan Austin 0:bc2961fa1ef0 737 {
Jonathan Austin 0:bc2961fa1ef0 738 m_peer_table[index].id_bitmap &= (~ADDR_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 739 m_peer_table[index].peer_id.id_addr_info = (*p_addr);
Jonathan Austin 0:bc2961fa1ef0 740 }
Jonathan Austin 0:bc2961fa1ef0 741 else
Jonathan Austin 0:bc2961fa1ef0 742 {
Jonathan Austin 0:bc2961fa1ef0 743 m_peer_table[index].id_bitmap &= (~IRK_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 744 }
Jonathan Austin 0:bc2961fa1ef0 745
Jonathan Austin 0:bc2961fa1ef0 746 (*p_device_index) = index;
Jonathan Austin 0:bc2961fa1ef0 747 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 748
LancasterUniversity 5:f2faa0f0b8f0 749 DM_LOG("[DM]: Allocated device instance 0x%02X\r\n", index);
LancasterUniversity 4:ee5f0a37316e 750
Jonathan Austin 0:bc2961fa1ef0 751 break;
Jonathan Austin 0:bc2961fa1ef0 752 }
Jonathan Austin 0:bc2961fa1ef0 753 }
Jonathan Austin 0:bc2961fa1ef0 754
Jonathan Austin 0:bc2961fa1ef0 755 return err_code;
Jonathan Austin 0:bc2961fa1ef0 756 }
Jonathan Austin 0:bc2961fa1ef0 757
Jonathan Austin 0:bc2961fa1ef0 758
Jonathan Austin 0:bc2961fa1ef0 759 /**@brief Function for freeing a device instance allocated for bonded device.
Jonathan Austin 0:bc2961fa1ef0 760 *
Jonathan Austin 0:bc2961fa1ef0 761 * @param[in] device_index Device index.
Jonathan Austin 0:bc2961fa1ef0 762 *
Jonathan Austin 0:bc2961fa1ef0 763 * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
Jonathan Austin 0:bc2961fa1ef0 764 */
Jonathan Austin 0:bc2961fa1ef0 765 static __INLINE ret_code_t device_instance_free(uint32_t device_index)
Jonathan Austin 0:bc2961fa1ef0 766 {
Jonathan Austin 0:bc2961fa1ef0 767 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 768 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 769
Jonathan Austin 0:bc2961fa1ef0 770 //Get the block handle.
Jonathan Austin 0:bc2961fa1ef0 771 err_code = pstorage_block_identifier_get(&m_storage_handle, device_index, &block_handle);
Jonathan Austin 0:bc2961fa1ef0 772
Jonathan Austin 0:bc2961fa1ef0 773 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 774 {
Jonathan Austin 0:bc2961fa1ef0 775 DM_TRC("[DM]:[DI 0x%02X]: Freeing Instance.\r\n", device_index);
Jonathan Austin 0:bc2961fa1ef0 776
Jonathan Austin 0:bc2961fa1ef0 777 //Request clearing of the block.
Jonathan Austin 0:bc2961fa1ef0 778 err_code = pstorage_clear(&block_handle, ALL_CONTEXT_SIZE);
Jonathan Austin 0:bc2961fa1ef0 779
Jonathan Austin 0:bc2961fa1ef0 780 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 781 {
Jonathan Austin 0:bc2961fa1ef0 782 peer_instance_init(device_index);
Jonathan Austin 0:bc2961fa1ef0 783 }
Jonathan Austin 0:bc2961fa1ef0 784 }
Jonathan Austin 0:bc2961fa1ef0 785
Jonathan Austin 0:bc2961fa1ef0 786 return err_code;
Jonathan Austin 0:bc2961fa1ef0 787 }
Jonathan Austin 0:bc2961fa1ef0 788
Jonathan Austin 0:bc2961fa1ef0 789
Jonathan Austin 0:bc2961fa1ef0 790 /**@brief Function for searching for the device in the bonded device list.
Jonathan Austin 0:bc2961fa1ef0 791 *
Jonathan Austin 0:bc2961fa1ef0 792 * @param[in] p_addr Peer identification information.
Jonathan Austin 0:bc2961fa1ef0 793 * @param[out] p_device_index Device index.
Jonathan Austin 0:bc2961fa1ef0 794 *
Jonathan Austin 0:bc2961fa1ef0 795 * @retval NRF_SUCCESS Operation success.
Jonathan Austin 0:bc2961fa1ef0 796 * @retval NRF_ERROR_NOT_FOUND Operation failure.
Jonathan Austin 0:bc2961fa1ef0 797 */
Jonathan Austin 0:bc2961fa1ef0 798 static ret_code_t device_instance_find(ble_gap_addr_t const * p_addr, uint32_t * p_device_index, uint16_t ediv)
Jonathan Austin 0:bc2961fa1ef0 799 {
Jonathan Austin 0:bc2961fa1ef0 800 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 801 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 802
Jonathan Austin 0:bc2961fa1ef0 803 err_code = NRF_ERROR_NOT_FOUND;
LancasterUniversity 4:ee5f0a37316e 804
Jonathan Austin 0:bc2961fa1ef0 805 if (NULL != p_addr)
Jonathan Austin 0:bc2961fa1ef0 806 {
LancasterUniversity 5:f2faa0f0b8f0 807 DM_LOG("[DM]: Searching for device 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 808 p_addr->addr[0],
Jonathan Austin 0:bc2961fa1ef0 809 p_addr->addr[1],
Jonathan Austin 0:bc2961fa1ef0 810 p_addr->addr[2],
Jonathan Austin 0:bc2961fa1ef0 811 p_addr->addr[3],
Jonathan Austin 0:bc2961fa1ef0 812 p_addr->addr[4],
Jonathan Austin 0:bc2961fa1ef0 813 p_addr->addr[5]);
Jonathan Austin 0:bc2961fa1ef0 814 }
Jonathan Austin 0:bc2961fa1ef0 815
Jonathan Austin 0:bc2961fa1ef0 816 for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 817 {
LancasterUniversity 5:f2faa0f0b8f0 818 DM_LOG("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 819 index, m_peer_table[index].peer_id.id_addr_info.addr_type);
LancasterUniversity 5:f2faa0f0b8f0 820 DM_LOG("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 821 m_peer_table[index].peer_id.id_addr_info.addr[0],
Jonathan Austin 0:bc2961fa1ef0 822 m_peer_table[index].peer_id.id_addr_info.addr[1],
Jonathan Austin 0:bc2961fa1ef0 823 m_peer_table[index].peer_id.id_addr_info.addr[2],
Jonathan Austin 0:bc2961fa1ef0 824 m_peer_table[index].peer_id.id_addr_info.addr[3],
Jonathan Austin 0:bc2961fa1ef0 825 m_peer_table[index].peer_id.id_addr_info.addr[4],
Jonathan Austin 0:bc2961fa1ef0 826 m_peer_table[index].peer_id.id_addr_info.addr[5]);
Jonathan Austin 0:bc2961fa1ef0 827
Jonathan Austin 0:bc2961fa1ef0 828 if (((NULL == p_addr) && (ediv == m_peer_table[index].ediv)) ||
Jonathan Austin 0:bc2961fa1ef0 829 ((NULL != p_addr) && (memcmp(&m_peer_table[index].peer_id.id_addr_info, p_addr, sizeof(ble_gap_addr_t)) == 0)))
Jonathan Austin 0:bc2961fa1ef0 830 {
Jonathan Austin 0:bc2961fa1ef0 831 DM_LOG("[DM]: Found device at instance 0x%02X\r\n", index);
Jonathan Austin 0:bc2961fa1ef0 832
Jonathan Austin 0:bc2961fa1ef0 833 (*p_device_index) = index;
Jonathan Austin 0:bc2961fa1ef0 834 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 835
Jonathan Austin 0:bc2961fa1ef0 836 break;
Jonathan Austin 0:bc2961fa1ef0 837 }
Jonathan Austin 0:bc2961fa1ef0 838 }
Jonathan Austin 0:bc2961fa1ef0 839
Jonathan Austin 0:bc2961fa1ef0 840 return err_code;
Jonathan Austin 0:bc2961fa1ef0 841 }
Jonathan Austin 0:bc2961fa1ef0 842
Jonathan Austin 0:bc2961fa1ef0 843
Jonathan Austin 0:bc2961fa1ef0 844 /**@brief Function for notifying connection manager event to the application.
Jonathan Austin 0:bc2961fa1ef0 845 *
Jonathan Austin 0:bc2961fa1ef0 846 * @param[in] p_handle Device handle identifying device.
Jonathan Austin 0:bc2961fa1ef0 847 * @param[in] p_event Connection manager event details.
Jonathan Austin 0:bc2961fa1ef0 848 * @param[in] event_result Event result code.
Jonathan Austin 0:bc2961fa1ef0 849 */
Jonathan Austin 0:bc2961fa1ef0 850 static __INLINE void app_evt_notify(dm_handle_t const * const p_handle,
Jonathan Austin 0:bc2961fa1ef0 851 dm_event_t const * const p_event,
Jonathan Austin 0:bc2961fa1ef0 852 uint32_t event_result)
Jonathan Austin 0:bc2961fa1ef0 853 {
Jonathan Austin 0:bc2961fa1ef0 854 dm_event_cb_t app_cb = m_application_table[0].ntf_cb;
Jonathan Austin 0:bc2961fa1ef0 855
Jonathan Austin 0:bc2961fa1ef0 856 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 857
Jonathan Austin 0:bc2961fa1ef0 858 DM_TRC("[DM]: Notifying application of event 0x%02X\r\n", p_event->event_id);
Jonathan Austin 0:bc2961fa1ef0 859
Jonathan Austin 0:bc2961fa1ef0 860 //No need to do any kind of return value processing thus can be supressed.
Jonathan Austin 0:bc2961fa1ef0 861 UNUSED_VARIABLE(app_cb(p_handle, p_event, event_result));
Jonathan Austin 0:bc2961fa1ef0 862
Jonathan Austin 0:bc2961fa1ef0 863 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 864 }
Jonathan Austin 0:bc2961fa1ef0 865
Jonathan Austin 0:bc2961fa1ef0 866
Jonathan Austin 0:bc2961fa1ef0 867 /**@brief Function for allocating instance.
Jonathan Austin 0:bc2961fa1ef0 868 *
Jonathan Austin 0:bc2961fa1ef0 869 * @details The instance identifier is provided in the 'p_instance' parameter if the routine
Jonathan Austin 0:bc2961fa1ef0 870 * succeeds.
Jonathan Austin 0:bc2961fa1ef0 871 *
Jonathan Austin 0:bc2961fa1ef0 872 * @param[out] p_instance Connection instance.
Jonathan Austin 0:bc2961fa1ef0 873 *
Jonathan Austin 0:bc2961fa1ef0 874 * @retval NRF_SUCCESS Operation success.
Jonathan Austin 0:bc2961fa1ef0 875 * @retval NRF_ERROR_NO_MEM Operation failure. No memory.
Jonathan Austin 0:bc2961fa1ef0 876 */
Jonathan Austin 0:bc2961fa1ef0 877 static __INLINE uint32_t connection_instance_allocate(uint32_t * p_instance)
Jonathan Austin 0:bc2961fa1ef0 878 {
Jonathan Austin 0:bc2961fa1ef0 879 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 880
LancasterUniversity 5:f2faa0f0b8f0 881 DM_LOG("[DM]: Request to allocation connection instance\r\n");
Jonathan Austin 0:bc2961fa1ef0 882
Jonathan Austin 0:bc2961fa1ef0 883 err_code = connection_instance_find(BLE_CONN_HANDLE_INVALID, STATE_IDLE, p_instance);
Jonathan Austin 0:bc2961fa1ef0 884
Jonathan Austin 0:bc2961fa1ef0 885 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 886 {
LancasterUniversity 5:f2faa0f0b8f0 887 DM_LOG("[DM]:[%02X]: Connection Instance Allocated.\r\n", (*p_instance));
Jonathan Austin 0:bc2961fa1ef0 888 m_connection_table[*p_instance].state = STATE_CONNECTED;
Jonathan Austin 0:bc2961fa1ef0 889 }
Jonathan Austin 0:bc2961fa1ef0 890 else
Jonathan Austin 0:bc2961fa1ef0 891 {
LancasterUniversity 5:f2faa0f0b8f0 892 DM_LOG("[DM]: No free connection instances available\r\n");
Jonathan Austin 0:bc2961fa1ef0 893 err_code = NRF_ERROR_NO_MEM;
Jonathan Austin 0:bc2961fa1ef0 894 }
Jonathan Austin 0:bc2961fa1ef0 895
Jonathan Austin 0:bc2961fa1ef0 896 return err_code;
Jonathan Austin 0:bc2961fa1ef0 897 }
Jonathan Austin 0:bc2961fa1ef0 898
Jonathan Austin 0:bc2961fa1ef0 899
Jonathan Austin 0:bc2961fa1ef0 900 /**@brief Function for freeing instance. Instance identifier is provided in the parameter
Jonathan Austin 0:bc2961fa1ef0 901 * 'p_instance' in case the routine succeeds.
Jonathan Austin 0:bc2961fa1ef0 902 *
Jonathan Austin 0:bc2961fa1ef0 903 * @param[in] p_instance Connection instance.
Jonathan Austin 0:bc2961fa1ef0 904 */
Jonathan Austin 0:bc2961fa1ef0 905 static __INLINE void connection_instance_free(uint32_t const * p_instance)
Jonathan Austin 0:bc2961fa1ef0 906 {
LancasterUniversity 5:f2faa0f0b8f0 907 DM_LOG("[DM]:[CI 0x%02X]: Freeing connection instance\r\n", (*p_instance));
Jonathan Austin 0:bc2961fa1ef0 908
Jonathan Austin 0:bc2961fa1ef0 909 if (m_connection_table[*p_instance].state != STATE_IDLE)
Jonathan Austin 0:bc2961fa1ef0 910 {
LancasterUniversity 5:f2faa0f0b8f0 911 DM_LOG("[DM]:[%02X]: Freed connection instance.\r\n", (*p_instance));
Jonathan Austin 0:bc2961fa1ef0 912 connection_instance_init(*p_instance);
Jonathan Austin 0:bc2961fa1ef0 913 }
Jonathan Austin 0:bc2961fa1ef0 914 }
Jonathan Austin 0:bc2961fa1ef0 915
Jonathan Austin 0:bc2961fa1ef0 916
Jonathan Austin 0:bc2961fa1ef0 917 /**@brief Function for storage operation dummy handler.
Jonathan Austin 0:bc2961fa1ef0 918 *
Jonathan Austin 0:bc2961fa1ef0 919 * @param[in] p_dest Destination address where data is to be stored persistently.
Jonathan Austin 0:bc2961fa1ef0 920 * @param[in] p_src Source address containing data to be stored. API assumes this to be resident
Jonathan Austin 0:bc2961fa1ef0 921 * memory and no intermediate copy of data is made by the API.
Jonathan Austin 0:bc2961fa1ef0 922 * @param[in] size Size of data to be stored expressed in bytes. Should be word aligned.
Jonathan Austin 0:bc2961fa1ef0 923 * @param[in] offset Offset in bytes to be applied when writing to the block.
Jonathan Austin 0:bc2961fa1ef0 924 * For example, if within a block of 100 bytes, application wishes to
Jonathan Austin 0:bc2961fa1ef0 925 * write 20 bytes at offset of 12, then this field should be set to 12.
Jonathan Austin 0:bc2961fa1ef0 926 * Should be word aligned.
Jonathan Austin 0:bc2961fa1ef0 927 *
Jonathan Austin 0:bc2961fa1ef0 928 * @retval NRF_SUCCESS Operation success.
Jonathan Austin 0:bc2961fa1ef0 929 */
Jonathan Austin 0:bc2961fa1ef0 930 static uint32_t storage_operation_dummy_handler(pstorage_handle_t * p_dest,
Jonathan Austin 0:bc2961fa1ef0 931 uint8_t * p_src,
Jonathan Austin 0:bc2961fa1ef0 932 pstorage_size_t size,
Jonathan Austin 0:bc2961fa1ef0 933 pstorage_size_t offset)
Jonathan Austin 0:bc2961fa1ef0 934 {
Jonathan Austin 0:bc2961fa1ef0 935 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 936 }
Jonathan Austin 0:bc2961fa1ef0 937
Jonathan Austin 0:bc2961fa1ef0 938
Jonathan Austin 0:bc2961fa1ef0 939 /**@brief Function for saving the device context persistently.
Jonathan Austin 0:bc2961fa1ef0 940 *
Jonathan Austin 0:bc2961fa1ef0 941 * @param[in] p_handle Device handle identifying device.
Jonathan Austin 0:bc2961fa1ef0 942 * @param[in] state Device store state.
Jonathan Austin 0:bc2961fa1ef0 943 */
Jonathan Austin 0:bc2961fa1ef0 944 static __INLINE void device_context_store(dm_handle_t const * p_handle, device_store_state_t state)
Jonathan Austin 0:bc2961fa1ef0 945 {
Jonathan Austin 0:bc2961fa1ef0 946 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 947 storage_operation store_fn;
Jonathan Austin 0:bc2961fa1ef0 948 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 949
Jonathan Austin 0:bc2961fa1ef0 950 DM_LOG("[DM]: --> device_context_store\r\n");
Jonathan Austin 0:bc2961fa1ef0 951
Jonathan Austin 0:bc2961fa1ef0 952 err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 953 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 954 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 955
Jonathan Austin 0:bc2961fa1ef0 956 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 957 {
Jonathan Austin 0:bc2961fa1ef0 958 if ((STATE_BOND_INFO_UPDATE ==
Jonathan Austin 0:bc2961fa1ef0 959 (m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)) ||
Jonathan Austin 0:bc2961fa1ef0 960 (state == UPDATE_PEER_ADDR))
Jonathan Austin 0:bc2961fa1ef0 961 {
LancasterUniversity 5:f2faa0f0b8f0 962 DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Updating bonding information.\r\n",
Jonathan Austin 0:bc2961fa1ef0 963 p_handle->device_id, p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 964
Jonathan Austin 0:bc2961fa1ef0 965 store_fn = pstorage_update;
Jonathan Austin 0:bc2961fa1ef0 966 }
Jonathan Austin 0:bc2961fa1ef0 967 else if (state == FIRST_BOND_STORE)
Jonathan Austin 0:bc2961fa1ef0 968 {
LancasterUniversity 5:f2faa0f0b8f0 969 DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Storing bonding information.\r\n",
Jonathan Austin 0:bc2961fa1ef0 970 p_handle->device_id, p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 971
Jonathan Austin 0:bc2961fa1ef0 972 store_fn = pstorage_store;
Jonathan Austin 0:bc2961fa1ef0 973 }
Jonathan Austin 0:bc2961fa1ef0 974 else
Jonathan Austin 0:bc2961fa1ef0 975 {
LancasterUniversity 5:f2faa0f0b8f0 976 DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> No update in bonding information.\r\n",
Jonathan Austin 0:bc2961fa1ef0 977 p_handle->device_id, p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 978
Jonathan Austin 0:bc2961fa1ef0 979 //No operation needed.
Jonathan Austin 0:bc2961fa1ef0 980 store_fn = storage_operation_dummy_handler;
Jonathan Austin 0:bc2961fa1ef0 981 }
Jonathan Austin 0:bc2961fa1ef0 982
Jonathan Austin 0:bc2961fa1ef0 983 //Store the peer id.
Jonathan Austin 0:bc2961fa1ef0 984 err_code = store_fn(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 985 (uint8_t *)&m_peer_table[p_handle->device_id],
Jonathan Austin 0:bc2961fa1ef0 986 PEER_ID_SIZE,
Jonathan Austin 0:bc2961fa1ef0 987 PEER_ID_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 988
Jonathan Austin 0:bc2961fa1ef0 989 if ((err_code == NRF_SUCCESS) && (state != UPDATE_PEER_ADDR))
Jonathan Austin 0:bc2961fa1ef0 990 {
Jonathan Austin 0:bc2961fa1ef0 991 m_connection_table[p_handle->connection_id].state &= (~STATE_BOND_INFO_UPDATE);
Jonathan Austin 0:bc2961fa1ef0 992
Jonathan Austin 0:bc2961fa1ef0 993 //Store the bond information.
Jonathan Austin 0:bc2961fa1ef0 994 err_code = store_fn(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 995 (uint8_t *)&m_bond_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 996 BOND_SIZE,
Jonathan Austin 0:bc2961fa1ef0 997 BOND_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 998
Jonathan Austin 0:bc2961fa1ef0 999 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1000 {
Jonathan Austin 0:bc2961fa1ef0 1001 DM_ERR("[DM]:[0x%02X]:Failed to store bond information, reason 0x%08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1002 p_handle->device_id, err_code);
Jonathan Austin 0:bc2961fa1ef0 1003 }
Jonathan Austin 0:bc2961fa1ef0 1004 }
Jonathan Austin 0:bc2961fa1ef0 1005
Jonathan Austin 0:bc2961fa1ef0 1006 if (state != UPDATE_PEER_ADDR)
Jonathan Austin 0:bc2961fa1ef0 1007 {
Jonathan Austin 0:bc2961fa1ef0 1008 //Store the service information
Jonathan Austin 0:bc2961fa1ef0 1009 err_code = m_service_context_store[m_application_table[p_handle->appl_id].service]
Jonathan Austin 0:bc2961fa1ef0 1010 (
Jonathan Austin 0:bc2961fa1ef0 1011 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 1012 p_handle
Jonathan Austin 0:bc2961fa1ef0 1013 );
Jonathan Austin 0:bc2961fa1ef0 1014
Jonathan Austin 0:bc2961fa1ef0 1015 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1016 {
Jonathan Austin 0:bc2961fa1ef0 1017 //Notify application of an error event.
Jonathan Austin 0:bc2961fa1ef0 1018 DM_ERR("[DM]: Failed to store service context, reason %08X\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 1019 }
Jonathan Austin 0:bc2961fa1ef0 1020 }
Jonathan Austin 0:bc2961fa1ef0 1021 }
Jonathan Austin 0:bc2961fa1ef0 1022
Jonathan Austin 0:bc2961fa1ef0 1023 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1024 {
Jonathan Austin 0:bc2961fa1ef0 1025 //Notify application of an error event.
Jonathan Austin 0:bc2961fa1ef0 1026 DM_ERR("[DM]: Failed to store device context, reason %08X\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 1027 }
Jonathan Austin 0:bc2961fa1ef0 1028 }
Jonathan Austin 0:bc2961fa1ef0 1029
Jonathan Austin 0:bc2961fa1ef0 1030
Jonathan Austin 0:bc2961fa1ef0 1031 /**@brief Function for storing when there is no service registered.
Jonathan Austin 0:bc2961fa1ef0 1032 *
Jonathan Austin 0:bc2961fa1ef0 1033 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1034 * @param[in] p_handle Device handle identifying device that is loaded.
Jonathan Austin 0:bc2961fa1ef0 1035 *
Jonathan Austin 0:bc2961fa1ef0 1036 * @retval NRF_SUCCESS
Jonathan Austin 0:bc2961fa1ef0 1037 */
Jonathan Austin 0:bc2961fa1ef0 1038 static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1039 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1040 {
Jonathan Austin 0:bc2961fa1ef0 1041 DM_LOG("[DM]: --> no_service_context_store\r\n");
Jonathan Austin 0:bc2961fa1ef0 1042
Jonathan Austin 0:bc2961fa1ef0 1043 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1044 }
Jonathan Austin 0:bc2961fa1ef0 1045
Jonathan Austin 0:bc2961fa1ef0 1046
Jonathan Austin 0:bc2961fa1ef0 1047 /**@brief Function for storing GATT Server context.
Jonathan Austin 0:bc2961fa1ef0 1048 *
Jonathan Austin 0:bc2961fa1ef0 1049 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1050 * @param[in] p_handle Device handle identifying device that is stored.
Jonathan Austin 0:bc2961fa1ef0 1051 *
Jonathan Austin 0:bc2961fa1ef0 1052 * @retval NRF_SUCCESS Operation success.
Jonathan Austin 0:bc2961fa1ef0 1053 */
Jonathan Austin 0:bc2961fa1ef0 1054 static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1055 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1056 {
Jonathan Austin 0:bc2961fa1ef0 1057 storage_operation store_fn;
Jonathan Austin 0:bc2961fa1ef0 1058 uint32_t attr_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS;
Jonathan Austin 0:bc2961fa1ef0 1059 uint16_t attr_len = DM_GATT_SERVER_ATTR_MAX_SIZE;
Jonathan Austin 0:bc2961fa1ef0 1060 uint8_t sys_data[DM_GATT_SERVER_ATTR_MAX_SIZE];
Jonathan Austin 0:bc2961fa1ef0 1061
Jonathan Austin 0:bc2961fa1ef0 1062 DM_LOG("[DM]: --> gatts_context_store\r\n");
Jonathan Austin 0:bc2961fa1ef0 1063
Jonathan Austin 0:bc2961fa1ef0 1064 uint32_t err_code = sd_ble_gatts_sys_attr_get(
Jonathan Austin 0:bc2961fa1ef0 1065 m_connection_table[p_handle->connection_id].conn_handle,
Jonathan Austin 0:bc2961fa1ef0 1066 sys_data,
Jonathan Austin 0:bc2961fa1ef0 1067 &attr_len,
Jonathan Austin 0:bc2961fa1ef0 1068 attr_flags);
Jonathan Austin 0:bc2961fa1ef0 1069
Jonathan Austin 0:bc2961fa1ef0 1070 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1071 {
Jonathan Austin 0:bc2961fa1ef0 1072 if (memcmp(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len) == 0)
Jonathan Austin 0:bc2961fa1ef0 1073 {
Jonathan Austin 0:bc2961fa1ef0 1074 //No store operation is needed.
Jonathan Austin 0:bc2961fa1ef0 1075 DM_LOG("[DM]:[0x%02X]: No change in GATTS Context information.\r\n",
Jonathan Austin 0:bc2961fa1ef0 1076 p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1077
Jonathan Austin 0:bc2961fa1ef0 1078 if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) !=
Jonathan Austin 0:bc2961fa1ef0 1079 STATE_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 1080 {
Jonathan Austin 0:bc2961fa1ef0 1081 DM_LOG("[DM]:[0x%02X]: Resetting GATTS for active instance.\r\n",
Jonathan Austin 0:bc2961fa1ef0 1082 p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 1083
Jonathan Austin 0:bc2961fa1ef0 1084 //Reset GATTS information for the current context.
Jonathan Austin 0:bc2961fa1ef0 1085 memset(&m_gatts_table[p_handle->connection_id], 0, sizeof(dm_gatts_context_t));
Jonathan Austin 0:bc2961fa1ef0 1086 }
Jonathan Austin 0:bc2961fa1ef0 1087 }
Jonathan Austin 0:bc2961fa1ef0 1088 else
Jonathan Austin 0:bc2961fa1ef0 1089 {
Jonathan Austin 0:bc2961fa1ef0 1090 if (m_gatts_table[p_handle->connection_id].size != 0)
Jonathan Austin 0:bc2961fa1ef0 1091 {
Jonathan Austin 0:bc2961fa1ef0 1092 //There is data already stored in persistent memory, therefore an update is needed.
Jonathan Austin 0:bc2961fa1ef0 1093 DM_LOG("[DM]:[0x%02X]: Updating stored service context\r\n", p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1094
Jonathan Austin 0:bc2961fa1ef0 1095 store_fn = pstorage_update;
Jonathan Austin 0:bc2961fa1ef0 1096 }
Jonathan Austin 0:bc2961fa1ef0 1097 else
Jonathan Austin 0:bc2961fa1ef0 1098 {
Jonathan Austin 0:bc2961fa1ef0 1099 //Fresh write, a store is needed.
Jonathan Austin 0:bc2961fa1ef0 1100 DM_LOG("[DM]:[0x%02X]: Storing service context\r\n", p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1101
Jonathan Austin 0:bc2961fa1ef0 1102 store_fn = pstorage_store;
Jonathan Austin 0:bc2961fa1ef0 1103 }
Jonathan Austin 0:bc2961fa1ef0 1104
Jonathan Austin 0:bc2961fa1ef0 1105 m_gatts_table[p_handle->connection_id].flags = attr_flags;
Jonathan Austin 0:bc2961fa1ef0 1106 m_gatts_table[p_handle->connection_id].size = attr_len;
Jonathan Austin 0:bc2961fa1ef0 1107 memcpy(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len);
Jonathan Austin 0:bc2961fa1ef0 1108
Jonathan Austin 0:bc2961fa1ef0 1109 DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t));
Jonathan Austin 0:bc2961fa1ef0 1110
Jonathan Austin 0:bc2961fa1ef0 1111 DM_LOG("[DM]:[0x%02X]: GATTS Data size 0x%08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1112 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 1113 m_gatts_table[p_handle->connection_id].size);
Jonathan Austin 0:bc2961fa1ef0 1114
Jonathan Austin 0:bc2961fa1ef0 1115 //Store GATTS information.
Jonathan Austin 0:bc2961fa1ef0 1116 err_code = store_fn((pstorage_handle_t *)p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1117 (uint8_t *)&m_gatts_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 1118 GATTS_SERVICE_CONTEXT_SIZE,
Jonathan Austin 0:bc2961fa1ef0 1119 SERVICE_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 1120
Jonathan Austin 0:bc2961fa1ef0 1121 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1122 {
Jonathan Austin 0:bc2961fa1ef0 1123 DM_ERR("[DM]:[0x%02X]:Failed to store service context, reason 0x%08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1124 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 1125 err_code);
Jonathan Austin 0:bc2961fa1ef0 1126 }
Jonathan Austin 0:bc2961fa1ef0 1127 else
Jonathan Austin 0:bc2961fa1ef0 1128 {
Jonathan Austin 0:bc2961fa1ef0 1129 DM_LOG("[DM]: Service context successfully stored.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1130 }
Jonathan Austin 0:bc2961fa1ef0 1131 }
Jonathan Austin 0:bc2961fa1ef0 1132 }
Jonathan Austin 0:bc2961fa1ef0 1133
Jonathan Austin 0:bc2961fa1ef0 1134 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1135 }
Jonathan Austin 0:bc2961fa1ef0 1136
Jonathan Austin 0:bc2961fa1ef0 1137
Jonathan Austin 0:bc2961fa1ef0 1138 /**@brief Function for storing GATT Client context.
Jonathan Austin 0:bc2961fa1ef0 1139 *
Jonathan Austin 0:bc2961fa1ef0 1140 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1141 * @param[in] p_handle Device handle identifying device that is stored.
Jonathan Austin 0:bc2961fa1ef0 1142 *
Jonathan Austin 0:bc2961fa1ef0 1143 * @retval NRF_SUCCESS Operation success.
Jonathan Austin 0:bc2961fa1ef0 1144 */
Jonathan Austin 0:bc2961fa1ef0 1145 static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1146 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1147 {
Jonathan Austin 0:bc2961fa1ef0 1148 DM_LOG("[DM]: --> gattc_context_store\r\n");
Jonathan Austin 0:bc2961fa1ef0 1149
Jonathan Austin 0:bc2961fa1ef0 1150 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1151 }
Jonathan Austin 0:bc2961fa1ef0 1152
Jonathan Austin 0:bc2961fa1ef0 1153
Jonathan Austin 0:bc2961fa1ef0 1154 /**@brief Function for storing GATT Server & Client context.
Jonathan Austin 0:bc2961fa1ef0 1155 *
Jonathan Austin 0:bc2961fa1ef0 1156 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1157 * @param[in] p_handle Device handle identifying device that is stored.
Jonathan Austin 0:bc2961fa1ef0 1158 *
Jonathan Austin 0:bc2961fa1ef0 1159 * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
Jonathan Austin 0:bc2961fa1ef0 1160 */
Jonathan Austin 0:bc2961fa1ef0 1161 static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1162 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1163 {
Jonathan Austin 0:bc2961fa1ef0 1164 DM_LOG("[DM]: --> gattsc_context_store\r\n");
Jonathan Austin 0:bc2961fa1ef0 1165
Jonathan Austin 0:bc2961fa1ef0 1166 ret_code_t err_code = gatts_context_store(p_block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 1167
Jonathan Austin 0:bc2961fa1ef0 1168 if (NRF_SUCCESS == err_code)
Jonathan Austin 0:bc2961fa1ef0 1169 {
Jonathan Austin 0:bc2961fa1ef0 1170 err_code = gattc_context_store(p_block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 1171 }
Jonathan Austin 0:bc2961fa1ef0 1172
Jonathan Austin 0:bc2961fa1ef0 1173 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1174 }
Jonathan Austin 0:bc2961fa1ef0 1175
Jonathan Austin 0:bc2961fa1ef0 1176
Jonathan Austin 0:bc2961fa1ef0 1177 /**@brief Function for loading when there is no service registered.
Jonathan Austin 0:bc2961fa1ef0 1178 *
Jonathan Austin 0:bc2961fa1ef0 1179 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1180 * @param[in] p_handle Device handle identifying device that is loaded.
Jonathan Austin 0:bc2961fa1ef0 1181 *
Jonathan Austin 0:bc2961fa1ef0 1182 * @retval NRF_SUCCESS
Jonathan Austin 0:bc2961fa1ef0 1183 */
Jonathan Austin 0:bc2961fa1ef0 1184 static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1185 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1186 {
Jonathan Austin 0:bc2961fa1ef0 1187 DM_LOG("[DM]: --> no_service_context_load\r\n");
Jonathan Austin 0:bc2961fa1ef0 1188
Jonathan Austin 0:bc2961fa1ef0 1189 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1190 }
Jonathan Austin 0:bc2961fa1ef0 1191
Jonathan Austin 0:bc2961fa1ef0 1192
Jonathan Austin 0:bc2961fa1ef0 1193 /**@brief Function for loading GATT Server context.
Jonathan Austin 0:bc2961fa1ef0 1194 *
Jonathan Austin 0:bc2961fa1ef0 1195 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1196 * @param[in] p_handle Device handle identifying device that is loaded.
Jonathan Austin 0:bc2961fa1ef0 1197 *
Jonathan Austin 0:bc2961fa1ef0 1198 * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
Jonathan Austin 0:bc2961fa1ef0 1199 */
Jonathan Austin 0:bc2961fa1ef0 1200 static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1201 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1202 {
Jonathan Austin 0:bc2961fa1ef0 1203 DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: --> gatts_context_load\r\n",
Jonathan Austin 0:bc2961fa1ef0 1204 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 1205 p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1206
Jonathan Austin 0:bc2961fa1ef0 1207 ret_code_t err_code = pstorage_load((uint8_t *)&m_gatts_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 1208 (pstorage_handle_t *)p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1209 GATTS_SERVICE_CONTEXT_SIZE,
Jonathan Austin 0:bc2961fa1ef0 1210 SERVICE_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 1211
Jonathan Austin 0:bc2961fa1ef0 1212 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1213 {
Jonathan Austin 0:bc2961fa1ef0 1214 DM_LOG("[DM]:[%02X]:[Block ID 0x%08X]: Service context loaded, size 0x%08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1215 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 1216 p_block_handle->block_id,
Jonathan Austin 0:bc2961fa1ef0 1217 m_gatts_table[p_handle->connection_id].size);
Jonathan Austin 0:bc2961fa1ef0 1218 DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t));
Jonathan Austin 0:bc2961fa1ef0 1219
Jonathan Austin 0:bc2961fa1ef0 1220 if (m_gatts_table[p_handle->connection_id].size == DM_GATTS_INVALID_SIZE)
Jonathan Austin 0:bc2961fa1ef0 1221 {
Jonathan Austin 0:bc2961fa1ef0 1222 m_gatts_table[p_handle->connection_id].size = 0;
Jonathan Austin 0:bc2961fa1ef0 1223 }
Jonathan Austin 0:bc2961fa1ef0 1224 }
Jonathan Austin 0:bc2961fa1ef0 1225 else
Jonathan Austin 0:bc2961fa1ef0 1226 {
Jonathan Austin 0:bc2961fa1ef0 1227 DM_ERR("[DM]:[%02X]: Failed to load Service context, reason %08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1228 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 1229 err_code);
Jonathan Austin 0:bc2961fa1ef0 1230 }
Jonathan Austin 0:bc2961fa1ef0 1231
Jonathan Austin 0:bc2961fa1ef0 1232 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1233 }
Jonathan Austin 0:bc2961fa1ef0 1234
Jonathan Austin 0:bc2961fa1ef0 1235
Jonathan Austin 0:bc2961fa1ef0 1236 /**@brief Function for loading GATT Client context.
Jonathan Austin 0:bc2961fa1ef0 1237 *
Jonathan Austin 0:bc2961fa1ef0 1238 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1239 * @param[in] p_handle Device handle identifying device that is loaded.
Jonathan Austin 0:bc2961fa1ef0 1240 *
Jonathan Austin 0:bc2961fa1ef0 1241 * @retval NRF_SUCCESS
Jonathan Austin 0:bc2961fa1ef0 1242 */
Jonathan Austin 0:bc2961fa1ef0 1243 static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1244 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1245 {
Jonathan Austin 0:bc2961fa1ef0 1246 DM_LOG("[DM]: --> gattc_context_load\r\n");
Jonathan Austin 0:bc2961fa1ef0 1247
Jonathan Austin 0:bc2961fa1ef0 1248 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1249 }
Jonathan Austin 0:bc2961fa1ef0 1250
Jonathan Austin 0:bc2961fa1ef0 1251
Jonathan Austin 0:bc2961fa1ef0 1252 /**@brief Function for loading GATT Server & Client context.
Jonathan Austin 0:bc2961fa1ef0 1253 *
Jonathan Austin 0:bc2961fa1ef0 1254 * @param[in] p_block_handle Storage block identifier.
Jonathan Austin 0:bc2961fa1ef0 1255 * @param[in] p_handle Device handle identifying device that is loaded.
Jonathan Austin 0:bc2961fa1ef0 1256 *
Jonathan Austin 0:bc2961fa1ef0 1257 * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
Jonathan Austin 0:bc2961fa1ef0 1258 */
Jonathan Austin 0:bc2961fa1ef0 1259 static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle,
Jonathan Austin 0:bc2961fa1ef0 1260 dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1261 {
Jonathan Austin 0:bc2961fa1ef0 1262 DM_LOG("[DM]: --> gattsc_context_load\r\n");
Jonathan Austin 0:bc2961fa1ef0 1263
Jonathan Austin 0:bc2961fa1ef0 1264 ret_code_t err_code = gatts_context_load(p_block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 1265
Jonathan Austin 0:bc2961fa1ef0 1266 if (NRF_SUCCESS == err_code)
Jonathan Austin 0:bc2961fa1ef0 1267 {
Jonathan Austin 0:bc2961fa1ef0 1268 err_code = gattc_context_load(p_block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 1269 }
Jonathan Austin 0:bc2961fa1ef0 1270
Jonathan Austin 0:bc2961fa1ef0 1271 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1272 }
Jonathan Austin 0:bc2961fa1ef0 1273
Jonathan Austin 0:bc2961fa1ef0 1274
Jonathan Austin 0:bc2961fa1ef0 1275 /**@brief Function for applying when there is no service registered.
Jonathan Austin 0:bc2961fa1ef0 1276 *
Jonathan Austin 0:bc2961fa1ef0 1277 * @param[in] p_handle Device handle identifying device that is applied.
Jonathan Austin 0:bc2961fa1ef0 1278 *
Jonathan Austin 0:bc2961fa1ef0 1279 * @retval NRF_SUCCESS
Jonathan Austin 0:bc2961fa1ef0 1280 */
Jonathan Austin 0:bc2961fa1ef0 1281 static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1282 {
Jonathan Austin 0:bc2961fa1ef0 1283 DM_LOG("[DM]: --> no_service_context_apply\r\n");
Jonathan Austin 0:bc2961fa1ef0 1284 DM_LOG("[DM]:[CI 0x%02X]: No Service context\r\n", p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 1285
Jonathan Austin 0:bc2961fa1ef0 1286 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1287 }
Jonathan Austin 0:bc2961fa1ef0 1288
Jonathan Austin 0:bc2961fa1ef0 1289
Jonathan Austin 0:bc2961fa1ef0 1290 /**@brief Function for applying GATT Server context.
Jonathan Austin 0:bc2961fa1ef0 1291 *
Jonathan Austin 0:bc2961fa1ef0 1292 * @param[in] p_handle Device handle identifying device that is applied.
Jonathan Austin 0:bc2961fa1ef0 1293 *
Jonathan Austin 0:bc2961fa1ef0 1294 * @retval NRF_SUCCESS On success.
Jonathan Austin 0:bc2961fa1ef0 1295 * @retval DM_SERVICE_CONTEXT_NOT_APPLIED On failure.
Jonathan Austin 0:bc2961fa1ef0 1296 */
Jonathan Austin 0:bc2961fa1ef0 1297 static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1298 {
Jonathan Austin 0:bc2961fa1ef0 1299 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 1300
Jonathan Austin 0:bc2961fa1ef0 1301 uint8_t * p_gatts_context = NULL;
Jonathan Austin 0:bc2961fa1ef0 1302 uint16_t context_len = 0;
Jonathan Austin 0:bc2961fa1ef0 1303 uint32_t context_flags = 0;
Jonathan Austin 0:bc2961fa1ef0 1304
Jonathan Austin 0:bc2961fa1ef0 1305 DM_LOG("[DM]: --> gatts_context_apply\r\n");
Jonathan Austin 0:bc2961fa1ef0 1306 DM_LOG("[DM]:[CI 0x%02X]: State 0x%02X, Size 0x%08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1307 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 1308 m_connection_table[p_handle->connection_id].state,
Jonathan Austin 0:bc2961fa1ef0 1309 m_gatts_table[p_handle->connection_id].size);
Jonathan Austin 0:bc2961fa1ef0 1310
Jonathan Austin 0:bc2961fa1ef0 1311 if ((m_gatts_table[p_handle->connection_id].size != 0) &&
Jonathan Austin 0:bc2961fa1ef0 1312 (
Jonathan Austin 0:bc2961fa1ef0 1313 ((m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED) &&
Jonathan Austin 0:bc2961fa1ef0 1314 ((m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)
Jonathan Austin 0:bc2961fa1ef0 1315 != STATE_BOND_INFO_UPDATE)
Jonathan Austin 0:bc2961fa1ef0 1316 )
Jonathan Austin 0:bc2961fa1ef0 1317 )
Jonathan Austin 0:bc2961fa1ef0 1318 {
Jonathan Austin 0:bc2961fa1ef0 1319 DM_LOG("[DM]: Setting stored context.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1320
Jonathan Austin 0:bc2961fa1ef0 1321 p_gatts_context = &m_gatts_table[p_handle->connection_id].attributes[0];
Jonathan Austin 0:bc2961fa1ef0 1322 context_len = m_gatts_table[p_handle->connection_id].size;
Jonathan Austin 0:bc2961fa1ef0 1323 context_flags = m_gatts_table[p_handle->connection_id].flags;
Jonathan Austin 0:bc2961fa1ef0 1324 }
Jonathan Austin 0:bc2961fa1ef0 1325
Jonathan Austin 0:bc2961fa1ef0 1326 err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle,
Jonathan Austin 0:bc2961fa1ef0 1327 p_gatts_context,
Jonathan Austin 0:bc2961fa1ef0 1328 context_len,
Jonathan Austin 0:bc2961fa1ef0 1329 context_flags);
Jonathan Austin 0:bc2961fa1ef0 1330
Jonathan Austin 0:bc2961fa1ef0 1331 if (err_code == NRF_ERROR_INVALID_DATA)
Jonathan Austin 0:bc2961fa1ef0 1332 {
Jonathan Austin 0:bc2961fa1ef0 1333 // Indication that the ATT table has changed. Restore the system attributes to system
Jonathan Austin 0:bc2961fa1ef0 1334 // services only and send a service changed indication if possible.
Jonathan Austin 0:bc2961fa1ef0 1335 context_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS;
Jonathan Austin 0:bc2961fa1ef0 1336 err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle,
Jonathan Austin 0:bc2961fa1ef0 1337 p_gatts_context,
Jonathan Austin 0:bc2961fa1ef0 1338 context_len,
Jonathan Austin 0:bc2961fa1ef0 1339 context_flags);
Jonathan Austin 0:bc2961fa1ef0 1340 }
Jonathan Austin 0:bc2961fa1ef0 1341
Jonathan Austin 0:bc2961fa1ef0 1342 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1343 {
Jonathan Austin 0:bc2961fa1ef0 1344 DM_LOG("[DM]: Failed to set system attributes, reason 0x%08X.\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 1345
Jonathan Austin 0:bc2961fa1ef0 1346 err_code = DM_SERVICE_CONTEXT_NOT_APPLIED;
Jonathan Austin 0:bc2961fa1ef0 1347 }
Jonathan Austin 0:bc2961fa1ef0 1348
Jonathan Austin 0:bc2961fa1ef0 1349 if (context_flags == BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS)
Jonathan Austin 0:bc2961fa1ef0 1350 {
Jonathan Austin 0:bc2961fa1ef0 1351 err_code = sd_ble_gatts_service_changed(m_connection_table[p_handle->connection_id].conn_handle,
Jonathan Austin 0:bc2961fa1ef0 1352 0x000C,
Jonathan Austin 0:bc2961fa1ef0 1353 0xFFFF);
Jonathan Austin 0:bc2961fa1ef0 1354 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1355 {
Jonathan Austin 0:bc2961fa1ef0 1356 DM_LOG("[DM]: Failed to send Service Changed indication, reason 0x%08X.\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 1357 if ((err_code != BLE_ERROR_INVALID_CONN_HANDLE) &&
Jonathan Austin 0:bc2961fa1ef0 1358 (err_code != NRF_ERROR_INVALID_STATE) &&
Jonathan Austin 0:bc2961fa1ef0 1359 (err_code != BLE_ERROR_NO_TX_BUFFERS) &&
Jonathan Austin 0:bc2961fa1ef0 1360 (err_code != NRF_ERROR_BUSY))
Jonathan Austin 0:bc2961fa1ef0 1361 {
Jonathan Austin 0:bc2961fa1ef0 1362 // Those errors can be expected when sending trying to send Service Changed
Jonathan Austin 0:bc2961fa1ef0 1363 // Indication if the CCCD is not set to indicate. Thus set the returning error
Jonathan Austin 0:bc2961fa1ef0 1364 // code to success.
Jonathan Austin 0:bc2961fa1ef0 1365 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1366 }
Jonathan Austin 0:bc2961fa1ef0 1367 else
Jonathan Austin 0:bc2961fa1ef0 1368 {
Jonathan Austin 0:bc2961fa1ef0 1369 err_code = DM_SERVICE_CONTEXT_NOT_APPLIED;
Jonathan Austin 0:bc2961fa1ef0 1370 }
Jonathan Austin 0:bc2961fa1ef0 1371 }
Jonathan Austin 0:bc2961fa1ef0 1372 }
Jonathan Austin 0:bc2961fa1ef0 1373
Jonathan Austin 0:bc2961fa1ef0 1374 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1375 }
Jonathan Austin 0:bc2961fa1ef0 1376
Jonathan Austin 0:bc2961fa1ef0 1377
Jonathan Austin 0:bc2961fa1ef0 1378 /**@brief Function for applying GATT Client context.
Jonathan Austin 0:bc2961fa1ef0 1379 *
Jonathan Austin 0:bc2961fa1ef0 1380 * @param[in] p_handle Device handle identifying device that is applied.
Jonathan Austin 0:bc2961fa1ef0 1381 *
Jonathan Austin 0:bc2961fa1ef0 1382 * @retval NRF_SUCCESS On success.
Jonathan Austin 0:bc2961fa1ef0 1383 */
Jonathan Austin 0:bc2961fa1ef0 1384 static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1385 {
Jonathan Austin 0:bc2961fa1ef0 1386 DM_LOG("[DM]: --> gattc_context_apply\r\n");
Jonathan Austin 0:bc2961fa1ef0 1387
Jonathan Austin 0:bc2961fa1ef0 1388 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1389 }
Jonathan Austin 0:bc2961fa1ef0 1390
Jonathan Austin 0:bc2961fa1ef0 1391
Jonathan Austin 0:bc2961fa1ef0 1392 /**@brief Function for applying GATT Server & Client context.
Jonathan Austin 0:bc2961fa1ef0 1393 *
Jonathan Austin 0:bc2961fa1ef0 1394 * @param[in] p_handle Device handle identifying device that is applied.
Jonathan Austin 0:bc2961fa1ef0 1395 *
Jonathan Austin 0:bc2961fa1ef0 1396 * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
Jonathan Austin 0:bc2961fa1ef0 1397 */
Jonathan Austin 0:bc2961fa1ef0 1398 static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1399 {
Jonathan Austin 0:bc2961fa1ef0 1400 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 1401
Jonathan Austin 0:bc2961fa1ef0 1402 DM_LOG("[DM]: --> gattsc_context_apply\r\n");
Jonathan Austin 0:bc2961fa1ef0 1403
Jonathan Austin 0:bc2961fa1ef0 1404 err_code = gatts_context_apply(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1405
Jonathan Austin 0:bc2961fa1ef0 1406 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1407 {
Jonathan Austin 0:bc2961fa1ef0 1408 err_code = gattc_context_apply(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1409 }
Jonathan Austin 0:bc2961fa1ef0 1410
Jonathan Austin 0:bc2961fa1ef0 1411 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1412 }
Jonathan Austin 0:bc2961fa1ef0 1413
Jonathan Austin 0:bc2961fa1ef0 1414
Jonathan Austin 0:bc2961fa1ef0 1415 /**@brief Function for pstorage module callback.
Jonathan Austin 0:bc2961fa1ef0 1416 *
Jonathan Austin 0:bc2961fa1ef0 1417 * @param[in] p_handle Identifies module and block for which callback is received.
Jonathan Austin 0:bc2961fa1ef0 1418 * @param[in] op_code Identifies the operation for which the event is notified.
Jonathan Austin 0:bc2961fa1ef0 1419 * @param[in] result Identifies the result of flash access operation.
Jonathan Austin 0:bc2961fa1ef0 1420 * NRF_SUCCESS implies, operation succeeded.
Jonathan Austin 0:bc2961fa1ef0 1421 * @param[in] p_data Identifies the application data pointer. In case of store operation, this
Jonathan Austin 0:bc2961fa1ef0 1422 * points to the resident source of application memory that application can now
Jonathan Austin 0:bc2961fa1ef0 1423 * free or reuse. In case of clear, this is NULL as no application pointer is
Jonathan Austin 0:bc2961fa1ef0 1424 * needed for this operation.
Jonathan Austin 0:bc2961fa1ef0 1425 * @param[in] data_len Length of data provided by the application for the operation.
Jonathan Austin 0:bc2961fa1ef0 1426 */
Jonathan Austin 0:bc2961fa1ef0 1427 static void dm_pstorage_cb_handler(pstorage_handle_t * p_handle,
Jonathan Austin 0:bc2961fa1ef0 1428 uint8_t op_code,
Jonathan Austin 0:bc2961fa1ef0 1429 uint32_t result,
Jonathan Austin 0:bc2961fa1ef0 1430 uint8_t * p_data,
Jonathan Austin 0:bc2961fa1ef0 1431 uint32_t data_len)
Jonathan Austin 0:bc2961fa1ef0 1432 {
Jonathan Austin 0:bc2961fa1ef0 1433 VERIFY_APP_REGISTERED_VOID(0);
Jonathan Austin 0:bc2961fa1ef0 1434
Jonathan Austin 0:bc2961fa1ef0 1435 if (data_len > ALL_CONTEXT_SIZE)
Jonathan Austin 0:bc2961fa1ef0 1436 {
Jonathan Austin 0:bc2961fa1ef0 1437 //Clearing of all bonds at initialization, no event is generated.
Jonathan Austin 0:bc2961fa1ef0 1438 return;
Jonathan Austin 0:bc2961fa1ef0 1439 }
Jonathan Austin 0:bc2961fa1ef0 1440
Jonathan Austin 0:bc2961fa1ef0 1441 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1442
Jonathan Austin 0:bc2961fa1ef0 1443 dm_event_t dm_event;
Jonathan Austin 0:bc2961fa1ef0 1444 dm_handle_t dm_handle;
Jonathan Austin 0:bc2961fa1ef0 1445 dm_context_t context_data;
Jonathan Austin 0:bc2961fa1ef0 1446 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 1447 uint32_t index_count;
Jonathan Austin 0:bc2961fa1ef0 1448 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 1449
Jonathan Austin 0:bc2961fa1ef0 1450 bool app_notify = true;
Jonathan Austin 0:bc2961fa1ef0 1451
Jonathan Austin 0:bc2961fa1ef0 1452 err_code = dm_handle_initialize(&dm_handle);
Jonathan Austin 0:bc2961fa1ef0 1453 APP_ERROR_CHECK(err_code);
Jonathan Austin 0:bc2961fa1ef0 1454
Jonathan Austin 0:bc2961fa1ef0 1455 dm_handle.appl_id = 0;
Jonathan Austin 0:bc2961fa1ef0 1456 dm_event.event_id = 0x00;
Jonathan Austin 0:bc2961fa1ef0 1457
Jonathan Austin 0:bc2961fa1ef0 1458 //Construct the event which it is related to.
Jonathan Austin 0:bc2961fa1ef0 1459
Jonathan Austin 0:bc2961fa1ef0 1460 //Initialize context data information and length.
Jonathan Austin 0:bc2961fa1ef0 1461 context_data.p_data = p_data;
Jonathan Austin 0:bc2961fa1ef0 1462 context_data.len = data_len;
Jonathan Austin 0:bc2961fa1ef0 1463
Jonathan Austin 0:bc2961fa1ef0 1464 for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 1465 {
Jonathan Austin 0:bc2961fa1ef0 1466 err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle);
Jonathan Austin 0:bc2961fa1ef0 1467 if ((err_code == NRF_SUCCESS) &&
Jonathan Austin 0:bc2961fa1ef0 1468 (
Jonathan Austin 0:bc2961fa1ef0 1469 (memcmp(p_handle, &block_handle, sizeof(pstorage_handle_t)) == 0)
Jonathan Austin 0:bc2961fa1ef0 1470 )
Jonathan Austin 0:bc2961fa1ef0 1471 )
Jonathan Austin 0:bc2961fa1ef0 1472 {
Jonathan Austin 0:bc2961fa1ef0 1473 dm_handle.device_id = index;
Jonathan Austin 0:bc2961fa1ef0 1474 break;
Jonathan Austin 0:bc2961fa1ef0 1475 }
Jonathan Austin 0:bc2961fa1ef0 1476 }
Jonathan Austin 0:bc2961fa1ef0 1477
Jonathan Austin 0:bc2961fa1ef0 1478 if (dm_handle.device_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 1479 {
Jonathan Austin 0:bc2961fa1ef0 1480 if (op_code == PSTORAGE_CLEAR_OP_CODE)
Jonathan Austin 0:bc2961fa1ef0 1481 {
Jonathan Austin 0:bc2961fa1ef0 1482 if (data_len == ALL_CONTEXT_SIZE)
Jonathan Austin 0:bc2961fa1ef0 1483 {
Jonathan Austin 0:bc2961fa1ef0 1484 dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
Jonathan Austin 0:bc2961fa1ef0 1485 }
Jonathan Austin 0:bc2961fa1ef0 1486 else
Jonathan Austin 0:bc2961fa1ef0 1487 {
Jonathan Austin 0:bc2961fa1ef0 1488 dm_event.event_id = DM_EVT_APP_CONTEXT_BASE;
Jonathan Austin 0:bc2961fa1ef0 1489 }
Jonathan Austin 0:bc2961fa1ef0 1490 }
Jonathan Austin 0:bc2961fa1ef0 1491 else
Jonathan Austin 0:bc2961fa1ef0 1492 {
Jonathan Austin 0:bc2961fa1ef0 1493 //Update or store operation.
Jonathan Austin 0:bc2961fa1ef0 1494 //Context is identified based on the pointer value. Device context, application context
Jonathan Austin 0:bc2961fa1ef0 1495 //and service context all have their own value range.
Jonathan Austin 0:bc2961fa1ef0 1496 index_count = ((uint32_t)(p_data - (uint8_t *)m_peer_table)) / PEER_ID_SIZE;
Jonathan Austin 0:bc2961fa1ef0 1497
Jonathan Austin 0:bc2961fa1ef0 1498 if (index_count < DEVICE_MANAGER_MAX_BONDS)
Jonathan Austin 0:bc2961fa1ef0 1499 {
Jonathan Austin 0:bc2961fa1ef0 1500 dm_event.event_param.p_device_context = &context_data;
Jonathan Austin 0:bc2961fa1ef0 1501
Jonathan Austin 0:bc2961fa1ef0 1502 //Only the peer identification is stored, not bond information. Hence do not notify
Jonathan Austin 0:bc2961fa1ef0 1503 //the application yet, unless the store operation resulted in a failure.
Jonathan Austin 0:bc2961fa1ef0 1504 if ((result == NRF_SUCCESS) &&
Jonathan Austin 0:bc2961fa1ef0 1505 (
Jonathan Austin 0:bc2961fa1ef0 1506 (update_status_bit_is_set(dm_handle.device_id) == false)
Jonathan Austin 0:bc2961fa1ef0 1507 )
Jonathan Austin 0:bc2961fa1ef0 1508 )
Jonathan Austin 0:bc2961fa1ef0 1509 {
Jonathan Austin 0:bc2961fa1ef0 1510 app_notify = false;
Jonathan Austin 0:bc2961fa1ef0 1511 }
Jonathan Austin 0:bc2961fa1ef0 1512 else
Jonathan Austin 0:bc2961fa1ef0 1513 {
Jonathan Austin 0:bc2961fa1ef0 1514 //Reset update status since update is complete.
Jonathan Austin 0:bc2961fa1ef0 1515 update_status_bit_reset(dm_handle.device_id);
Jonathan Austin 0:bc2961fa1ef0 1516
Jonathan Austin 0:bc2961fa1ef0 1517 //Notify application of error in storing the context.
Jonathan Austin 0:bc2961fa1ef0 1518 dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
Jonathan Austin 0:bc2961fa1ef0 1519 }
Jonathan Austin 0:bc2961fa1ef0 1520 }
Jonathan Austin 0:bc2961fa1ef0 1521 else
Jonathan Austin 0:bc2961fa1ef0 1522 {
Jonathan Austin 0:bc2961fa1ef0 1523 index_count = ((uint32_t)(p_data - (uint8_t *)m_bond_table)) / BOND_SIZE;
Jonathan Austin 0:bc2961fa1ef0 1524
Jonathan Austin 0:bc2961fa1ef0 1525 if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS)
Jonathan Austin 0:bc2961fa1ef0 1526 {
Jonathan Austin 0:bc2961fa1ef0 1527 DM_LOG("[DM]:[0x%02X]:[0x%02X]: Bond context Event\r\n",
Jonathan Austin 0:bc2961fa1ef0 1528 dm_handle.device_id,
Jonathan Austin 0:bc2961fa1ef0 1529 dm_handle.connection_id);
Jonathan Austin 0:bc2961fa1ef0 1530
Jonathan Austin 0:bc2961fa1ef0 1531 dm_event.event_param.p_device_context = &context_data;
Jonathan Austin 0:bc2961fa1ef0 1532 dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
Jonathan Austin 0:bc2961fa1ef0 1533 dm_handle.connection_id = index_count;
Jonathan Austin 0:bc2961fa1ef0 1534
Jonathan Austin 0:bc2961fa1ef0 1535 ble_gap_sec_keyset_t keys_exchanged;
Jonathan Austin 0:bc2961fa1ef0 1536 keys_exchanged.keys_central.p_enc_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 1537 keys_exchanged.keys_central.p_id_key = &m_local_id_info;
Jonathan Austin 0:bc2961fa1ef0 1538 keys_exchanged.keys_periph.p_enc_key = &m_bond_table[index_count].peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 1539 keys_exchanged.keys_periph.p_id_key =
Jonathan Austin 0:bc2961fa1ef0 1540 &m_peer_table[dm_handle.device_id].peer_id;
Jonathan Austin 0:bc2961fa1ef0 1541
Jonathan Austin 0:bc2961fa1ef0 1542 //Context information updated to provide the keys.
Jonathan Austin 0:bc2961fa1ef0 1543 context_data.p_data = (uint8_t *)&keys_exchanged;
Jonathan Austin 0:bc2961fa1ef0 1544 context_data.len = sizeof(ble_gap_sec_keyset_t);
Jonathan Austin 0:bc2961fa1ef0 1545 }
Jonathan Austin 0:bc2961fa1ef0 1546 else
Jonathan Austin 0:bc2961fa1ef0 1547 {
Jonathan Austin 0:bc2961fa1ef0 1548 index_count = ((uint32_t)(p_data - (uint8_t *)m_gatts_table)) /
Jonathan Austin 0:bc2961fa1ef0 1549 GATTS_SERVICE_CONTEXT_SIZE;
Jonathan Austin 0:bc2961fa1ef0 1550
Jonathan Austin 0:bc2961fa1ef0 1551 if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS)
Jonathan Austin 0:bc2961fa1ef0 1552 {
Jonathan Austin 0:bc2961fa1ef0 1553 DM_LOG("[DM]:[0x%02X]:[0x%02X]: Service context Event\r\n",
Jonathan Austin 0:bc2961fa1ef0 1554 dm_handle.device_id,
Jonathan Austin 0:bc2961fa1ef0 1555 dm_handle.connection_id);
Jonathan Austin 0:bc2961fa1ef0 1556
Jonathan Austin 0:bc2961fa1ef0 1557 //Notify application.
Jonathan Austin 0:bc2961fa1ef0 1558 dm_event.event_id = DM_EVT_SERVICE_CONTEXT_BASE;
Jonathan Austin 0:bc2961fa1ef0 1559 dm_handle.connection_id = index_count;
Jonathan Austin 0:bc2961fa1ef0 1560 dm_handle.service_id = DM_PROTOCOL_CNTXT_GATT_SRVR_ID;
Jonathan Austin 0:bc2961fa1ef0 1561
Jonathan Austin 0:bc2961fa1ef0 1562 //Reset the service context now that it was successfully written to the
Jonathan Austin 0:bc2961fa1ef0 1563 //application and the link is disconnected.
Jonathan Austin 0:bc2961fa1ef0 1564 if ((m_connection_table[index_count].state & STATE_CONNECTED) !=
Jonathan Austin 0:bc2961fa1ef0 1565 STATE_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 1566 {
Jonathan Austin 0:bc2961fa1ef0 1567 DM_LOG("[DM]:[0x%02X]:[0x%02X]: Resetting bond information for "
Jonathan Austin 0:bc2961fa1ef0 1568 "active instance.\r\n",
Jonathan Austin 0:bc2961fa1ef0 1569 dm_handle.device_id,
Jonathan Austin 0:bc2961fa1ef0 1570 dm_handle.connection_id);
Jonathan Austin 0:bc2961fa1ef0 1571
Jonathan Austin 0:bc2961fa1ef0 1572 memset(&m_gatts_table[dm_handle.connection_id],
Jonathan Austin 0:bc2961fa1ef0 1573 0,
Jonathan Austin 0:bc2961fa1ef0 1574 sizeof(dm_gatts_context_t));
Jonathan Austin 0:bc2961fa1ef0 1575 }
Jonathan Austin 0:bc2961fa1ef0 1576 }
Jonathan Austin 0:bc2961fa1ef0 1577 else
Jonathan Austin 0:bc2961fa1ef0 1578 {
Jonathan Austin 0:bc2961fa1ef0 1579 DM_LOG("[DM]:[0x%02X]:[0x%02X]: App context Event\r\n",
Jonathan Austin 0:bc2961fa1ef0 1580 dm_handle.device_id,
Jonathan Austin 0:bc2961fa1ef0 1581 dm_handle.connection_id);
Jonathan Austin 0:bc2961fa1ef0 1582
Jonathan Austin 0:bc2961fa1ef0 1583 app_notify = false;
Jonathan Austin 0:bc2961fa1ef0 1584 dm_event.event_id = DM_EVT_APP_CONTEXT_BASE;
Jonathan Austin 0:bc2961fa1ef0 1585 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 1586
Jonathan Austin 0:bc2961fa1ef0 1587 if (p_data == (uint8_t *)(&m_context_init_len))
Jonathan Austin 0:bc2961fa1ef0 1588 {
Jonathan Austin 0:bc2961fa1ef0 1589 //Context data is deleted.
Jonathan Austin 0:bc2961fa1ef0 1590 //This is a workaround to get the right event as on delete operation
Jonathan Austin 0:bc2961fa1ef0 1591 //update operation is used instead of clear.
Jonathan Austin 0:bc2961fa1ef0 1592 op_code = PSTORAGE_CLEAR_OP_CODE;
Jonathan Austin 0:bc2961fa1ef0 1593 app_notify = true;
Jonathan Austin 0:bc2961fa1ef0 1594 }
Jonathan Austin 0:bc2961fa1ef0 1595 else if (m_app_context_table[dm_handle.device_id] == p_data)
Jonathan Austin 0:bc2961fa1ef0 1596 {
Jonathan Austin 0:bc2961fa1ef0 1597 app_notify = true;
Jonathan Austin 0:bc2961fa1ef0 1598 dm_event.event_param.p_app_context = &context_data;
Jonathan Austin 0:bc2961fa1ef0 1599
Jonathan Austin 0:bc2961fa1ef0 1600 //Verify if the device is connected, if yes set connection instance.
Jonathan Austin 0:bc2961fa1ef0 1601 for (uint32_t index = 0;
Jonathan Austin 0:bc2961fa1ef0 1602 index < DEVICE_MANAGER_MAX_CONNECTIONS;
Jonathan Austin 0:bc2961fa1ef0 1603 index++)
Jonathan Austin 0:bc2961fa1ef0 1604 {
Jonathan Austin 0:bc2961fa1ef0 1605 if (dm_handle.device_id == m_connection_table[index].bonded_dev_id)
Jonathan Austin 0:bc2961fa1ef0 1606 {
Jonathan Austin 0:bc2961fa1ef0 1607 dm_handle.connection_id = index;
Jonathan Austin 0:bc2961fa1ef0 1608 break;
Jonathan Austin 0:bc2961fa1ef0 1609 }
Jonathan Austin 0:bc2961fa1ef0 1610 }
Jonathan Austin 0:bc2961fa1ef0 1611 }
Jonathan Austin 0:bc2961fa1ef0 1612 else
Jonathan Austin 0:bc2961fa1ef0 1613 {
Jonathan Austin 0:bc2961fa1ef0 1614 //No implementation needed.
Jonathan Austin 0:bc2961fa1ef0 1615 }
Jonathan Austin 0:bc2961fa1ef0 1616 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 1617 }
Jonathan Austin 0:bc2961fa1ef0 1618 }
Jonathan Austin 0:bc2961fa1ef0 1619 }
Jonathan Austin 0:bc2961fa1ef0 1620 }
Jonathan Austin 0:bc2961fa1ef0 1621
Jonathan Austin 0:bc2961fa1ef0 1622 if (app_notify == true)
Jonathan Austin 0:bc2961fa1ef0 1623 {
Jonathan Austin 0:bc2961fa1ef0 1624 if (op_code == PSTORAGE_CLEAR_OP_CODE)
Jonathan Austin 0:bc2961fa1ef0 1625 {
Jonathan Austin 0:bc2961fa1ef0 1626 dm_event.event_id |= DM_CLEAR_OPERATION_ID;
Jonathan Austin 0:bc2961fa1ef0 1627 }
Jonathan Austin 0:bc2961fa1ef0 1628 else if (op_code == PSTORAGE_LOAD_OP_CODE)
Jonathan Austin 0:bc2961fa1ef0 1629 {
Jonathan Austin 0:bc2961fa1ef0 1630 dm_event.event_id |= DM_LOAD_OPERATION_ID;
Jonathan Austin 0:bc2961fa1ef0 1631 }
Jonathan Austin 0:bc2961fa1ef0 1632 else
Jonathan Austin 0:bc2961fa1ef0 1633 {
Jonathan Austin 0:bc2961fa1ef0 1634 dm_event.event_id |= DM_STORE_OPERATION_ID;
Jonathan Austin 0:bc2961fa1ef0 1635 }
Jonathan Austin 0:bc2961fa1ef0 1636
Jonathan Austin 0:bc2961fa1ef0 1637 dm_event.event_param.p_app_context = &context_data;
Jonathan Austin 0:bc2961fa1ef0 1638 app_evt_notify(&dm_handle, &dm_event, result);
Jonathan Austin 0:bc2961fa1ef0 1639 }
Jonathan Austin 0:bc2961fa1ef0 1640 }
Jonathan Austin 0:bc2961fa1ef0 1641
Jonathan Austin 0:bc2961fa1ef0 1642 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1643 }
Jonathan Austin 0:bc2961fa1ef0 1644
Jonathan Austin 0:bc2961fa1ef0 1645
Jonathan Austin 0:bc2961fa1ef0 1646 ret_code_t dm_init(dm_init_param_t const * const p_init_param)
Jonathan Austin 0:bc2961fa1ef0 1647 {
Jonathan Austin 0:bc2961fa1ef0 1648 pstorage_module_param_t param;
Jonathan Austin 0:bc2961fa1ef0 1649 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 1650 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 1651 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 1652
Jonathan Austin 0:bc2961fa1ef0 1653 DM_LOG("[DM]: >> dm_init.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1654
Jonathan Austin 0:bc2961fa1ef0 1655 NULL_PARAM_CHECK(p_init_param);
Jonathan Austin 0:bc2961fa1ef0 1656
Jonathan Austin 0:bc2961fa1ef0 1657 SDK_MUTEX_INIT(m_dm_mutex);
Jonathan Austin 0:bc2961fa1ef0 1658
Jonathan Austin 0:bc2961fa1ef0 1659 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1660
Jonathan Austin 0:bc2961fa1ef0 1661 for (index = 0; index < DEVICE_MANAGER_MAX_APPLICATIONS; index++)
Jonathan Austin 0:bc2961fa1ef0 1662 {
Jonathan Austin 0:bc2961fa1ef0 1663 application_instance_init(index);
Jonathan Austin 0:bc2961fa1ef0 1664 }
Jonathan Austin 0:bc2961fa1ef0 1665
Jonathan Austin 0:bc2961fa1ef0 1666 for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
Jonathan Austin 0:bc2961fa1ef0 1667 {
Jonathan Austin 0:bc2961fa1ef0 1668 connection_instance_init(index);
Jonathan Austin 0:bc2961fa1ef0 1669 }
Jonathan Austin 0:bc2961fa1ef0 1670
Jonathan Austin 0:bc2961fa1ef0 1671 memset(m_gatts_table, 0, sizeof(m_gatts_table));
Jonathan Austin 0:bc2961fa1ef0 1672
Jonathan Austin 0:bc2961fa1ef0 1673 //Initialization of all device instances.
Jonathan Austin 0:bc2961fa1ef0 1674 for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 1675 {
Jonathan Austin 0:bc2961fa1ef0 1676 peer_instance_init(index);
Jonathan Austin 0:bc2961fa1ef0 1677 m_irk_index_table[index] = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 1678 }
Jonathan Austin 0:bc2961fa1ef0 1679
Jonathan Austin 0:bc2961fa1ef0 1680 //All context with respect to a particular device is stored contiguously.
Jonathan Austin 0:bc2961fa1ef0 1681 param.block_size = ALL_CONTEXT_SIZE;
Jonathan Austin 0:bc2961fa1ef0 1682 param.block_count = DEVICE_MANAGER_MAX_BONDS;
Jonathan Austin 0:bc2961fa1ef0 1683 param.cb = dm_pstorage_cb_handler;
Jonathan Austin 0:bc2961fa1ef0 1684
Jonathan Austin 0:bc2961fa1ef0 1685 err_code = pstorage_register(&param, &m_storage_handle);
Jonathan Austin 0:bc2961fa1ef0 1686
Jonathan Austin 0:bc2961fa1ef0 1687 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1688 {
Jonathan Austin 0:bc2961fa1ef0 1689 m_module_initialized = true;
Jonathan Austin 0:bc2961fa1ef0 1690
Jonathan Austin 0:bc2961fa1ef0 1691 if (p_init_param->clear_persistent_data == false)
Jonathan Austin 0:bc2961fa1ef0 1692 {
Jonathan Austin 0:bc2961fa1ef0 1693 DM_LOG("[DM]: Storage handle 0x%08X.\r\n", m_storage_handle.block_id);
Jonathan Austin 0:bc2961fa1ef0 1694
Jonathan Austin 0:bc2961fa1ef0 1695 //Copy bonded peer device address and IRK to RAM table.
Jonathan Austin 0:bc2961fa1ef0 1696
Jonathan Austin 0:bc2961fa1ef0 1697 //Bonded devices are stored in range (0,DEVICE_MANAGER_MAX_BONDS-1). The remaining
Jonathan Austin 0:bc2961fa1ef0 1698 //range is for active connections that may or may not be bonded.
Jonathan Austin 0:bc2961fa1ef0 1699 for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 1700 {
Jonathan Austin 0:bc2961fa1ef0 1701 err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle);
Jonathan Austin 0:bc2961fa1ef0 1702
Jonathan Austin 0:bc2961fa1ef0 1703 //Issue read request if you successfully get the block identifier.
Jonathan Austin 0:bc2961fa1ef0 1704 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1705 {
Jonathan Austin 0:bc2961fa1ef0 1706 DM_TRC("[DM]:[0x%02X]: Block handle 0x%08X.\r\n", index, block_handle.block_id);
Jonathan Austin 0:bc2961fa1ef0 1707
Jonathan Austin 0:bc2961fa1ef0 1708 err_code = pstorage_load((uint8_t *)&m_peer_table[index],
Jonathan Austin 0:bc2961fa1ef0 1709 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 1710 sizeof(peer_id_t),
Jonathan Austin 0:bc2961fa1ef0 1711 0);
Jonathan Austin 0:bc2961fa1ef0 1712
Jonathan Austin 0:bc2961fa1ef0 1713 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 1714 {
Jonathan Austin 0:bc2961fa1ef0 1715 // In case a peer device could not be loaded successfully, rest of the
Jonathan Austin 0:bc2961fa1ef0 1716 // initialization procedure are skipped and an error is sent to the
Jonathan Austin 0:bc2961fa1ef0 1717 // application.
LancasterUniversity 5:f2faa0f0b8f0 1718 DM_LOG(
Jonathan Austin 0:bc2961fa1ef0 1719 "[DM]: Failed to load peer device %08X from storage, reason %08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 1720 index,
Jonathan Austin 0:bc2961fa1ef0 1721 err_code);
Jonathan Austin 0:bc2961fa1ef0 1722
LancasterUniversity 4:ee5f0a37316e 1723
LancasterUniversity 4:ee5f0a37316e 1724
Jonathan Austin 0:bc2961fa1ef0 1725 m_module_initialized = false;
Jonathan Austin 0:bc2961fa1ef0 1726 break;
Jonathan Austin 0:bc2961fa1ef0 1727 }
Jonathan Austin 0:bc2961fa1ef0 1728 else
Jonathan Austin 0:bc2961fa1ef0 1729 {
LancasterUniversity 5:f2faa0f0b8f0 1730 DM_LOG("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 1731 index,
Jonathan Austin 0:bc2961fa1ef0 1732 m_peer_table[index].peer_id.id_addr_info.addr_type);
LancasterUniversity 5:f2faa0f0b8f0 1733 DM_LOG("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 1734 m_peer_table[index].peer_id.id_addr_info.addr[0],
Jonathan Austin 0:bc2961fa1ef0 1735 m_peer_table[index].peer_id.id_addr_info.addr[1],
Jonathan Austin 0:bc2961fa1ef0 1736 m_peer_table[index].peer_id.id_addr_info.addr[2],
Jonathan Austin 0:bc2961fa1ef0 1737 m_peer_table[index].peer_id.id_addr_info.addr[3],
Jonathan Austin 0:bc2961fa1ef0 1738 m_peer_table[index].peer_id.id_addr_info.addr[4],
Jonathan Austin 0:bc2961fa1ef0 1739 m_peer_table[index].peer_id.id_addr_info.addr[5]);
Jonathan Austin 0:bc2961fa1ef0 1740 }
Jonathan Austin 0:bc2961fa1ef0 1741 }
Jonathan Austin 0:bc2961fa1ef0 1742 else
Jonathan Austin 0:bc2961fa1ef0 1743 {
Jonathan Austin 0:bc2961fa1ef0 1744 //In case a peer device could not be loaded successfully, rest of the
Jonathan Austin 0:bc2961fa1ef0 1745 //initialization procedure are skipped and an error is sent to the application.
LancasterUniversity 5:f2faa0f0b8f0 1746 DM_LOG("[DM]: Failed to get block handle for instance %08X, reason %08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 1747 index,
Jonathan Austin 0:bc2961fa1ef0 1748 err_code);
Jonathan Austin 0:bc2961fa1ef0 1749
Jonathan Austin 0:bc2961fa1ef0 1750 m_module_initialized = false;
Jonathan Austin 0:bc2961fa1ef0 1751 break;
Jonathan Austin 0:bc2961fa1ef0 1752 }
Jonathan Austin 0:bc2961fa1ef0 1753 }
Jonathan Austin 0:bc2961fa1ef0 1754 }
Jonathan Austin 0:bc2961fa1ef0 1755 else
Jonathan Austin 0:bc2961fa1ef0 1756 {
Jonathan Austin 0:bc2961fa1ef0 1757 err_code = pstorage_clear(&m_storage_handle, (param.block_size * param.block_count));
Jonathan Austin 0:bc2961fa1ef0 1758 DM_ERR("[DM]: Successfully requested clear of persistent data.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1759 }
Jonathan Austin 0:bc2961fa1ef0 1760 }
Jonathan Austin 0:bc2961fa1ef0 1761 else
Jonathan Austin 0:bc2961fa1ef0 1762 {
Jonathan Austin 0:bc2961fa1ef0 1763 DM_ERR("[DM]: Failed to register with storage module, reason 0x%08X.\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 1764 }
Jonathan Austin 0:bc2961fa1ef0 1765
Jonathan Austin 0:bc2961fa1ef0 1766 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1767
Jonathan Austin 0:bc2961fa1ef0 1768 DM_TRC("[DM]: << dm_init.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1769
Jonathan Austin 0:bc2961fa1ef0 1770 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1771 }
Jonathan Austin 0:bc2961fa1ef0 1772
Jonathan Austin 0:bc2961fa1ef0 1773
Jonathan Austin 0:bc2961fa1ef0 1774 ret_code_t dm_register(dm_application_instance_t * p_appl_instance,
Jonathan Austin 0:bc2961fa1ef0 1775 dm_application_param_t const * p_appl_param)
Jonathan Austin 0:bc2961fa1ef0 1776 {
Jonathan Austin 0:bc2961fa1ef0 1777 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1778 NULL_PARAM_CHECK(p_appl_instance);
Jonathan Austin 0:bc2961fa1ef0 1779 NULL_PARAM_CHECK(p_appl_param);
Jonathan Austin 0:bc2961fa1ef0 1780 NULL_PARAM_CHECK(p_appl_param->evt_handler);
Jonathan Austin 0:bc2961fa1ef0 1781
Jonathan Austin 0:bc2961fa1ef0 1782 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1783
Jonathan Austin 0:bc2961fa1ef0 1784 DM_LOG("[DM]: >> dm_register.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1785
Jonathan Austin 0:bc2961fa1ef0 1786 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 1787
Jonathan Austin 0:bc2961fa1ef0 1788 //Verify if an application instance is available. Currently only one instance is supported.
Jonathan Austin 0:bc2961fa1ef0 1789 if (m_application_table[0].ntf_cb == NULL)
Jonathan Austin 0:bc2961fa1ef0 1790 {
Jonathan Austin 0:bc2961fa1ef0 1791 DM_LOG("[DM]: Application Instance allocated.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1792
Jonathan Austin 0:bc2961fa1ef0 1793 //Mark instance as allocated.
Jonathan Austin 0:bc2961fa1ef0 1794 m_application_table[0].ntf_cb = p_appl_param->evt_handler;
Jonathan Austin 0:bc2961fa1ef0 1795 m_application_table[0].sec_param = p_appl_param->sec_param;
Jonathan Austin 0:bc2961fa1ef0 1796 m_application_table[0].service = p_appl_param->service_type;
Jonathan Austin 0:bc2961fa1ef0 1797
Jonathan Austin 0:bc2961fa1ef0 1798 m_application_table[0].sec_param.kdist_central.enc = 0;
Jonathan Austin 0:bc2961fa1ef0 1799 m_application_table[0].sec_param.kdist_central.id = 1;
Jonathan Austin 0:bc2961fa1ef0 1800 m_application_table[0].sec_param.kdist_central.sign = 0;
Jonathan Austin 0:bc2961fa1ef0 1801 m_application_table[0].sec_param.kdist_periph.enc = 1;
Jonathan Austin 0:bc2961fa1ef0 1802 m_application_table[0].sec_param.kdist_periph.id = 1;
Jonathan Austin 0:bc2961fa1ef0 1803 m_application_table[0].sec_param.kdist_periph.sign = 0;
Jonathan Austin 0:bc2961fa1ef0 1804 //Populate application's instance variable with the assigned allocation instance.
Jonathan Austin 0:bc2961fa1ef0 1805 *p_appl_instance = 0;
Jonathan Austin 0:bc2961fa1ef0 1806 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1807 }
Jonathan Austin 0:bc2961fa1ef0 1808 else
Jonathan Austin 0:bc2961fa1ef0 1809 {
Jonathan Austin 0:bc2961fa1ef0 1810 err_code = (NRF_ERROR_NO_MEM | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 1811 }
Jonathan Austin 0:bc2961fa1ef0 1812
Jonathan Austin 0:bc2961fa1ef0 1813 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1814
Jonathan Austin 0:bc2961fa1ef0 1815 DM_TRC("[DM]: << dm_register.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1816
Jonathan Austin 0:bc2961fa1ef0 1817 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1818 }
Jonathan Austin 0:bc2961fa1ef0 1819
Jonathan Austin 0:bc2961fa1ef0 1820
Jonathan Austin 0:bc2961fa1ef0 1821 ret_code_t dm_security_setup_req(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1822 {
Jonathan Austin 0:bc2961fa1ef0 1823 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1824 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1825 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 1826 VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 1827
Jonathan Austin 0:bc2961fa1ef0 1828 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1829
Jonathan Austin 0:bc2961fa1ef0 1830 DM_LOG("[DM]: >> dm_security_setup_req\r\n");
Jonathan Austin 0:bc2961fa1ef0 1831
Jonathan Austin 0:bc2961fa1ef0 1832 uint32_t err_code = (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 1833
Jonathan Austin 0:bc2961fa1ef0 1834 if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == STATE_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 1835 {
Jonathan Austin 0:bc2961fa1ef0 1836 err_code = sd_ble_gap_authenticate(m_connection_table[p_handle->connection_id].conn_handle,
Jonathan Austin 0:bc2961fa1ef0 1837 &m_application_table[0].sec_param);
Jonathan Austin 0:bc2961fa1ef0 1838 }
Jonathan Austin 0:bc2961fa1ef0 1839
Jonathan Austin 0:bc2961fa1ef0 1840 DM_TRC("[DM]: << dm_security_setup_req, 0x%08X\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 1841
Jonathan Austin 0:bc2961fa1ef0 1842 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1843
Jonathan Austin 0:bc2961fa1ef0 1844 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1845 }
Jonathan Austin 0:bc2961fa1ef0 1846
Jonathan Austin 0:bc2961fa1ef0 1847
Jonathan Austin 0:bc2961fa1ef0 1848 ret_code_t dm_security_status_req(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 1849 dm_security_status_t * p_status)
Jonathan Austin 0:bc2961fa1ef0 1850 {
Jonathan Austin 0:bc2961fa1ef0 1851 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1852 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1853 NULL_PARAM_CHECK(p_status);
Jonathan Austin 0:bc2961fa1ef0 1854 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 1855 VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 1856
Jonathan Austin 0:bc2961fa1ef0 1857 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1858
Jonathan Austin 0:bc2961fa1ef0 1859 DM_LOG("[DM]: >> dm_security_status_req\r\n");
Jonathan Austin 0:bc2961fa1ef0 1860
Jonathan Austin 0:bc2961fa1ef0 1861 if ((m_connection_table[p_handle->connection_id].state & STATE_PAIRING) ||
Jonathan Austin 0:bc2961fa1ef0 1862 (m_connection_table[p_handle->connection_id].state & STATE_PAIRING_PENDING))
Jonathan Austin 0:bc2961fa1ef0 1863 {
Jonathan Austin 0:bc2961fa1ef0 1864 (*p_status) = ENCRYPTION_IN_PROGRESS;
Jonathan Austin 0:bc2961fa1ef0 1865 }
Jonathan Austin 0:bc2961fa1ef0 1866 else if (m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED)
Jonathan Austin 0:bc2961fa1ef0 1867 {
Jonathan Austin 0:bc2961fa1ef0 1868 (*p_status) = ENCRYPTED;
Jonathan Austin 0:bc2961fa1ef0 1869 }
Jonathan Austin 0:bc2961fa1ef0 1870 else
Jonathan Austin 0:bc2961fa1ef0 1871 {
Jonathan Austin 0:bc2961fa1ef0 1872 (*p_status) = NOT_ENCRYPTED;
Jonathan Austin 0:bc2961fa1ef0 1873 }
Jonathan Austin 0:bc2961fa1ef0 1874
Jonathan Austin 0:bc2961fa1ef0 1875 DM_TRC("[DM]: << dm_security_status_req\r\n");
Jonathan Austin 0:bc2961fa1ef0 1876
Jonathan Austin 0:bc2961fa1ef0 1877 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1878
Jonathan Austin 0:bc2961fa1ef0 1879 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1880 }
Jonathan Austin 0:bc2961fa1ef0 1881
Jonathan Austin 0:bc2961fa1ef0 1882
Jonathan Austin 0:bc2961fa1ef0 1883 ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 1884 ble_gap_whitelist_t * p_whitelist)
Jonathan Austin 0:bc2961fa1ef0 1885 {
Jonathan Austin 0:bc2961fa1ef0 1886 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1887 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1888 NULL_PARAM_CHECK(p_whitelist);
Jonathan Austin 0:bc2961fa1ef0 1889 NULL_PARAM_CHECK(p_whitelist->pp_addrs);
Jonathan Austin 0:bc2961fa1ef0 1890 NULL_PARAM_CHECK(p_whitelist->pp_irks);
Jonathan Austin 0:bc2961fa1ef0 1891 VERIFY_APP_REGISTERED(*p_handle);
Jonathan Austin 0:bc2961fa1ef0 1892
Jonathan Austin 0:bc2961fa1ef0 1893 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1894
Jonathan Austin 0:bc2961fa1ef0 1895 DM_LOG("[DM]: >> dm_whitelist_create\r\n");
Jonathan Austin 0:bc2961fa1ef0 1896
Jonathan Austin 0:bc2961fa1ef0 1897 uint32_t addr_count = 0;
Jonathan Austin 0:bc2961fa1ef0 1898 uint32_t irk_count = 0;
Jonathan Austin 0:bc2961fa1ef0 1899 bool connected = false;
Jonathan Austin 0:bc2961fa1ef0 1900
Jonathan Austin 0:bc2961fa1ef0 1901 for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 1902 {
Jonathan Austin 0:bc2961fa1ef0 1903 connected = false;
Jonathan Austin 0:bc2961fa1ef0 1904
Jonathan Austin 0:bc2961fa1ef0 1905 for (uint32_t c_index = 0; c_index < DEVICE_MANAGER_MAX_CONNECTIONS; c_index++)
Jonathan Austin 0:bc2961fa1ef0 1906 {
Jonathan Austin 0:bc2961fa1ef0 1907 if ((index == m_connection_table[c_index].bonded_dev_id) &&
Jonathan Austin 0:bc2961fa1ef0 1908 ((m_connection_table[c_index].state & STATE_CONNECTED) == STATE_CONNECTED))
Jonathan Austin 0:bc2961fa1ef0 1909 {
Jonathan Austin 0:bc2961fa1ef0 1910 connected = true;
Jonathan Austin 0:bc2961fa1ef0 1911 break;
Jonathan Austin 0:bc2961fa1ef0 1912 }
Jonathan Austin 0:bc2961fa1ef0 1913 }
Jonathan Austin 0:bc2961fa1ef0 1914
Jonathan Austin 0:bc2961fa1ef0 1915 if (connected == false)
Jonathan Austin 0:bc2961fa1ef0 1916 {
LancasterUniversity 5:f2faa0f0b8f0 1917 DM_LOG("irkentry %d addrentry %d", (m_peer_table[index].id_bitmap & IRK_ENTRY), (m_peer_table[index].id_bitmap & ADDR_ENTRY));
Jonathan Austin 0:bc2961fa1ef0 1918 if ((irk_count < p_whitelist->irk_count) &&
LancasterUniversity 4:ee5f0a37316e 1919 ((m_peer_table[index].id_bitmap & IRK_ENTRY) == 0) && (m_peer_table[index].id_bitmap & ADDR_ENTRY) != 0)
Jonathan Austin 0:bc2961fa1ef0 1920 {
Jonathan Austin 0:bc2961fa1ef0 1921 p_whitelist->pp_irks[irk_count] = &m_peer_table[index].peer_id.id_info;
Jonathan Austin 0:bc2961fa1ef0 1922 m_irk_index_table[irk_count] = index;
Jonathan Austin 0:bc2961fa1ef0 1923 irk_count++;
Jonathan Austin 0:bc2961fa1ef0 1924 }
Jonathan Austin 0:bc2961fa1ef0 1925
Jonathan Austin 0:bc2961fa1ef0 1926 if ((addr_count < p_whitelist->addr_count) &&
Jonathan Austin 0:bc2961fa1ef0 1927 (m_peer_table[index].id_bitmap & ADDR_ENTRY) == 0)
Jonathan Austin 0:bc2961fa1ef0 1928 {
Jonathan Austin 0:bc2961fa1ef0 1929 p_whitelist->pp_addrs[addr_count] = &m_peer_table[index].peer_id.id_addr_info;
Jonathan Austin 0:bc2961fa1ef0 1930 addr_count++;
Jonathan Austin 0:bc2961fa1ef0 1931 }
Jonathan Austin 0:bc2961fa1ef0 1932 }
Jonathan Austin 0:bc2961fa1ef0 1933 }
Jonathan Austin 0:bc2961fa1ef0 1934
Jonathan Austin 0:bc2961fa1ef0 1935 p_whitelist->addr_count = addr_count;
Jonathan Austin 0:bc2961fa1ef0 1936 p_whitelist->irk_count = irk_count;
Jonathan Austin 0:bc2961fa1ef0 1937
LancasterUniversity 5:f2faa0f0b8f0 1938 DM_LOG("[DM]: Created whitelist, number of IRK = 0x%02X, number of addr = 0x%02X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1939 irk_count,
Jonathan Austin 0:bc2961fa1ef0 1940 addr_count);
Jonathan Austin 0:bc2961fa1ef0 1941
Jonathan Austin 0:bc2961fa1ef0 1942 DM_TRC("[DM]: << dm_whitelist_create\r\n");
Jonathan Austin 0:bc2961fa1ef0 1943
Jonathan Austin 0:bc2961fa1ef0 1944 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1945
Jonathan Austin 0:bc2961fa1ef0 1946 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1947 }
Jonathan Austin 0:bc2961fa1ef0 1948
Jonathan Austin 0:bc2961fa1ef0 1949
Jonathan Austin 0:bc2961fa1ef0 1950 ret_code_t dm_device_add(dm_handle_t * p_handle,
Jonathan Austin 0:bc2961fa1ef0 1951 dm_device_context_t const * p_context)
Jonathan Austin 0:bc2961fa1ef0 1952 {
Jonathan Austin 0:bc2961fa1ef0 1953 return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 1954 }
Jonathan Austin 0:bc2961fa1ef0 1955
Jonathan Austin 0:bc2961fa1ef0 1956
Jonathan Austin 0:bc2961fa1ef0 1957 ret_code_t dm_device_delete(dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1958 {
Jonathan Austin 0:bc2961fa1ef0 1959 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1960 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1961 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 1962 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1963
Jonathan Austin 0:bc2961fa1ef0 1964 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1965
Jonathan Austin 0:bc2961fa1ef0 1966 DM_TRC("[DM]: >> dm_device_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 1967
Jonathan Austin 0:bc2961fa1ef0 1968 uint32_t err_code = device_instance_free(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1969
Jonathan Austin 0:bc2961fa1ef0 1970 DM_TRC("[DM]: << dm_device_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 1971
Jonathan Austin 0:bc2961fa1ef0 1972 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1973
Jonathan Austin 0:bc2961fa1ef0 1974 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1975 }
Jonathan Austin 0:bc2961fa1ef0 1976
Jonathan Austin 0:bc2961fa1ef0 1977
Jonathan Austin 0:bc2961fa1ef0 1978 ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1979 {
Jonathan Austin 0:bc2961fa1ef0 1980 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1981 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1982 VERIFY_APP_REGISTERED((*p_handle));
Jonathan Austin 0:bc2961fa1ef0 1983
Jonathan Austin 0:bc2961fa1ef0 1984 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1985
Jonathan Austin 0:bc2961fa1ef0 1986 uint32_t err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1987
Jonathan Austin 0:bc2961fa1ef0 1988 DM_TRC("[DM]: >> dm_device_delete_all\r\n");
Jonathan Austin 0:bc2961fa1ef0 1989
Jonathan Austin 0:bc2961fa1ef0 1990 for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 1991 {
Jonathan Austin 0:bc2961fa1ef0 1992 if (m_peer_table[index].id_bitmap != UNASSIGNED)
Jonathan Austin 0:bc2961fa1ef0 1993 {
Jonathan Austin 0:bc2961fa1ef0 1994 err_code = device_instance_free(index);
Jonathan Austin 0:bc2961fa1ef0 1995 }
Jonathan Austin 0:bc2961fa1ef0 1996 }
Jonathan Austin 0:bc2961fa1ef0 1997
Jonathan Austin 0:bc2961fa1ef0 1998 DM_TRC("[DM]: << dm_device_delete_all\r\n");
Jonathan Austin 0:bc2961fa1ef0 1999
Jonathan Austin 0:bc2961fa1ef0 2000 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2001
Jonathan Austin 0:bc2961fa1ef0 2002 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2003 }
Jonathan Austin 0:bc2961fa1ef0 2004
Jonathan Austin 0:bc2961fa1ef0 2005
Jonathan Austin 0:bc2961fa1ef0 2006 ret_code_t dm_service_context_set(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2007 dm_service_context_t const * p_context)
Jonathan Austin 0:bc2961fa1ef0 2008 {
Jonathan Austin 0:bc2961fa1ef0 2009 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2010 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2011 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2012 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2013 VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 2014 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2015
Jonathan Austin 0:bc2961fa1ef0 2016 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2017
Jonathan Austin 0:bc2961fa1ef0 2018 DM_TRC("[DM]: >> dm_service_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2019
Jonathan Austin 0:bc2961fa1ef0 2020 if ((p_context->context_data.p_data != NULL) &&
Jonathan Austin 0:bc2961fa1ef0 2021 (
Jonathan Austin 0:bc2961fa1ef0 2022 (p_context->context_data.len != 0) &&
Jonathan Austin 0:bc2961fa1ef0 2023 (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE)
Jonathan Austin 0:bc2961fa1ef0 2024 )
Jonathan Austin 0:bc2961fa1ef0 2025 )
Jonathan Austin 0:bc2961fa1ef0 2026 {
Jonathan Austin 0:bc2961fa1ef0 2027 if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
Jonathan Austin 0:bc2961fa1ef0 2028 {
Jonathan Austin 0:bc2961fa1ef0 2029 memcpy(m_gatts_table[p_handle->connection_id].attributes,
Jonathan Austin 0:bc2961fa1ef0 2030 p_context->context_data.p_data,
Jonathan Austin 0:bc2961fa1ef0 2031 p_context->context_data.len);
Jonathan Austin 0:bc2961fa1ef0 2032 }
Jonathan Austin 0:bc2961fa1ef0 2033 }
Jonathan Austin 0:bc2961fa1ef0 2034
Jonathan Austin 0:bc2961fa1ef0 2035 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2036 uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2037 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2038 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2039
Jonathan Austin 0:bc2961fa1ef0 2040 err_code = m_service_context_store[p_context->service_type](&block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 2041
Jonathan Austin 0:bc2961fa1ef0 2042 DM_TRC("[DM]: << dm_service_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2043
Jonathan Austin 0:bc2961fa1ef0 2044 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2045
Jonathan Austin 0:bc2961fa1ef0 2046 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2047 }
Jonathan Austin 0:bc2961fa1ef0 2048
Jonathan Austin 0:bc2961fa1ef0 2049
Jonathan Austin 0:bc2961fa1ef0 2050 ret_code_t dm_service_context_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2051 dm_service_context_t * p_context)
Jonathan Austin 0:bc2961fa1ef0 2052 {
Jonathan Austin 0:bc2961fa1ef0 2053 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2054 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2055 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2056 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2057 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2058
Jonathan Austin 0:bc2961fa1ef0 2059 if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != STATE_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 2060 {
Jonathan Austin 0:bc2961fa1ef0 2061 DM_TRC("[DM]: Device must be connected to get context. \r\n");
Jonathan Austin 0:bc2961fa1ef0 2062
Jonathan Austin 0:bc2961fa1ef0 2063 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2064 }
Jonathan Austin 0:bc2961fa1ef0 2065
Jonathan Austin 0:bc2961fa1ef0 2066 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2067
Jonathan Austin 0:bc2961fa1ef0 2068 DM_TRC("[DM]: >> dm_service_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2069
Jonathan Austin 0:bc2961fa1ef0 2070 if ((p_context->context_data.p_data == NULL) &&
Jonathan Austin 0:bc2961fa1ef0 2071 (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE))
Jonathan Austin 0:bc2961fa1ef0 2072 {
Jonathan Austin 0:bc2961fa1ef0 2073 if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
Jonathan Austin 0:bc2961fa1ef0 2074 {
Jonathan Austin 0:bc2961fa1ef0 2075 p_context->context_data.p_data = m_gatts_table[p_handle->connection_id].attributes;
Jonathan Austin 0:bc2961fa1ef0 2076 p_context->context_data.len = m_gatts_table[p_handle->connection_id].size;
Jonathan Austin 0:bc2961fa1ef0 2077 }
Jonathan Austin 0:bc2961fa1ef0 2078 }
Jonathan Austin 0:bc2961fa1ef0 2079
Jonathan Austin 0:bc2961fa1ef0 2080 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2081 uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2082 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2083 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2084
Jonathan Austin 0:bc2961fa1ef0 2085 err_code = m_service_context_load[p_context->service_type](&block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 2086
Jonathan Austin 0:bc2961fa1ef0 2087 DM_TRC("[DM]: << dm_service_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2088
Jonathan Austin 0:bc2961fa1ef0 2089 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2090
Jonathan Austin 0:bc2961fa1ef0 2091 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2092 }
Jonathan Austin 0:bc2961fa1ef0 2093
Jonathan Austin 0:bc2961fa1ef0 2094
Jonathan Austin 0:bc2961fa1ef0 2095 ret_code_t dm_service_context_delete(dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2096 {
Jonathan Austin 0:bc2961fa1ef0 2097 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2098 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2099 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2100 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2101
Jonathan Austin 0:bc2961fa1ef0 2102 DM_LOG("[DM]: Context delete is not supported yet.\r\n");
Jonathan Austin 0:bc2961fa1ef0 2103
Jonathan Austin 0:bc2961fa1ef0 2104 return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2105 }
Jonathan Austin 0:bc2961fa1ef0 2106
Jonathan Austin 0:bc2961fa1ef0 2107
Jonathan Austin 0:bc2961fa1ef0 2108 ret_code_t dm_application_context_set(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2109 dm_application_context_t const * p_context)
Jonathan Austin 0:bc2961fa1ef0 2110 {
Jonathan Austin 0:bc2961fa1ef0 2111 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 2112 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2113 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2114 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2115 NULL_PARAM_CHECK(p_context->p_data);
Jonathan Austin 0:bc2961fa1ef0 2116 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2117 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2118 VERIFY_DEVICE_BOND(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 2119 SIZE_CHECK_APP_CONTEXT(p_context->len);
Jonathan Austin 0:bc2961fa1ef0 2120
Jonathan Austin 0:bc2961fa1ef0 2121 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2122
Jonathan Austin 0:bc2961fa1ef0 2123 DM_TRC("[DM]: >> dm_application_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2124
Jonathan Austin 0:bc2961fa1ef0 2125 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2126 uint32_t context_len;
Jonathan Austin 0:bc2961fa1ef0 2127 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2128
Jonathan Austin 0:bc2961fa1ef0 2129 storage_operation store_fn = pstorage_store;
Jonathan Austin 0:bc2961fa1ef0 2130
Jonathan Austin 0:bc2961fa1ef0 2131 err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2132 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2133 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2134
Jonathan Austin 0:bc2961fa1ef0 2135 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2136 {
Jonathan Austin 0:bc2961fa1ef0 2137 err_code = pstorage_load((uint8_t *)&context_len,
Jonathan Austin 0:bc2961fa1ef0 2138 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2139 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2140 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2141
Jonathan Austin 0:bc2961fa1ef0 2142 if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
Jonathan Austin 0:bc2961fa1ef0 2143 {
Jonathan Austin 0:bc2961fa1ef0 2144 //Data already exists. Need an update.
Jonathan Austin 0:bc2961fa1ef0 2145 store_fn = pstorage_update;
Jonathan Austin 0:bc2961fa1ef0 2146
Jonathan Austin 0:bc2961fa1ef0 2147 DM_LOG("[DM]:[DI 0x%02X]: Updating existing application context, existing len 0x%08X, "
Jonathan Austin 0:bc2961fa1ef0 2148 "new length 0x%08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2149 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2150 context_len,
Jonathan Austin 0:bc2961fa1ef0 2151 p_context->len);
Jonathan Austin 0:bc2961fa1ef0 2152 }
Jonathan Austin 0:bc2961fa1ef0 2153 else
Jonathan Austin 0:bc2961fa1ef0 2154 {
Jonathan Austin 0:bc2961fa1ef0 2155 DM_LOG("[DM]: Storing application context.\r\n");
Jonathan Austin 0:bc2961fa1ef0 2156 }
Jonathan Austin 0:bc2961fa1ef0 2157
Jonathan Austin 0:bc2961fa1ef0 2158 //Store/update context length.
Jonathan Austin 0:bc2961fa1ef0 2159 err_code = store_fn(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 2160 (uint8_t *)(&p_context->len),
Jonathan Austin 0:bc2961fa1ef0 2161 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2162 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2163
Jonathan Austin 0:bc2961fa1ef0 2164 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2165 {
Jonathan Austin 0:bc2961fa1ef0 2166 //Update context data is used for application context as flash is never
Jonathan Austin 0:bc2961fa1ef0 2167 //cleared if a delete of application context is called.
Jonathan Austin 0:bc2961fa1ef0 2168 err_code = pstorage_update(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 2169 p_context->p_data,
Jonathan Austin 0:bc2961fa1ef0 2170 DEVICE_MANAGER_APP_CONTEXT_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2171 (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
Jonathan Austin 0:bc2961fa1ef0 2172 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2173 {
Jonathan Austin 0:bc2961fa1ef0 2174 m_app_context_table[p_handle->device_id] = p_context->p_data;
Jonathan Austin 0:bc2961fa1ef0 2175 }
Jonathan Austin 0:bc2961fa1ef0 2176 }
Jonathan Austin 0:bc2961fa1ef0 2177 }
Jonathan Austin 0:bc2961fa1ef0 2178
Jonathan Austin 0:bc2961fa1ef0 2179 DM_TRC("[DM]: << dm_application_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2180
Jonathan Austin 0:bc2961fa1ef0 2181 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2182
Jonathan Austin 0:bc2961fa1ef0 2183 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2184
Jonathan Austin 0:bc2961fa1ef0 2185 #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2186 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2187 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2188 }
Jonathan Austin 0:bc2961fa1ef0 2189
Jonathan Austin 0:bc2961fa1ef0 2190
Jonathan Austin 0:bc2961fa1ef0 2191 ret_code_t dm_application_context_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2192 dm_application_context_t * p_context)
Jonathan Austin 0:bc2961fa1ef0 2193 {
Jonathan Austin 0:bc2961fa1ef0 2194 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 2195 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2196 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2197 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2198 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2199 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2200
Jonathan Austin 0:bc2961fa1ef0 2201 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2202
Jonathan Austin 0:bc2961fa1ef0 2203 DM_TRC("[DM]: >> dm_application_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2204
Jonathan Austin 0:bc2961fa1ef0 2205 uint32_t context_len;
Jonathan Austin 0:bc2961fa1ef0 2206 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2207 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2208
Jonathan Austin 0:bc2961fa1ef0 2209 //Check if the context exists.
Jonathan Austin 0:bc2961fa1ef0 2210 if (NULL == p_context->p_data)
Jonathan Austin 0:bc2961fa1ef0 2211 {
Jonathan Austin 0:bc2961fa1ef0 2212 p_context->p_data = m_app_context_table[p_handle->device_id];
Jonathan Austin 0:bc2961fa1ef0 2213 }
Jonathan Austin 0:bc2961fa1ef0 2214 else
Jonathan Austin 0:bc2961fa1ef0 2215 {
Jonathan Austin 0:bc2961fa1ef0 2216 m_app_context_table[p_handle->device_id] = p_context->p_data;
Jonathan Austin 0:bc2961fa1ef0 2217 }
Jonathan Austin 0:bc2961fa1ef0 2218
Jonathan Austin 0:bc2961fa1ef0 2219 err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2220 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2221 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2222
Jonathan Austin 0:bc2961fa1ef0 2223 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2224 {
Jonathan Austin 0:bc2961fa1ef0 2225 err_code = pstorage_load((uint8_t *)&context_len,
Jonathan Austin 0:bc2961fa1ef0 2226 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2227 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2228 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2229
Jonathan Austin 0:bc2961fa1ef0 2230 if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
Jonathan Austin 0:bc2961fa1ef0 2231 {
Jonathan Austin 0:bc2961fa1ef0 2232 err_code = pstorage_load(p_context->p_data,
Jonathan Austin 0:bc2961fa1ef0 2233 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2234 DEVICE_MANAGER_APP_CONTEXT_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2235 (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
Jonathan Austin 0:bc2961fa1ef0 2236 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2237 {
Jonathan Austin 0:bc2961fa1ef0 2238 p_context->len = context_len;
Jonathan Austin 0:bc2961fa1ef0 2239 }
Jonathan Austin 0:bc2961fa1ef0 2240 }
Jonathan Austin 0:bc2961fa1ef0 2241 else
Jonathan Austin 0:bc2961fa1ef0 2242 {
Jonathan Austin 0:bc2961fa1ef0 2243 err_code = DM_NO_APP_CONTEXT;
Jonathan Austin 0:bc2961fa1ef0 2244 }
Jonathan Austin 0:bc2961fa1ef0 2245 }
Jonathan Austin 0:bc2961fa1ef0 2246
Jonathan Austin 0:bc2961fa1ef0 2247 DM_TRC("[DM]: << dm_application_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2248
Jonathan Austin 0:bc2961fa1ef0 2249 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2250
Jonathan Austin 0:bc2961fa1ef0 2251 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2252
Jonathan Austin 0:bc2961fa1ef0 2253 #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2254 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2255 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2256 }
Jonathan Austin 0:bc2961fa1ef0 2257
Jonathan Austin 0:bc2961fa1ef0 2258
Jonathan Austin 0:bc2961fa1ef0 2259 ret_code_t dm_application_context_delete(const dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2260 {
Jonathan Austin 0:bc2961fa1ef0 2261 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 2262 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2263 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2264 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2265 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2266
Jonathan Austin 0:bc2961fa1ef0 2267 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2268
Jonathan Austin 0:bc2961fa1ef0 2269 DM_TRC("[DM]: >> dm_application_context_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 2270
Jonathan Austin 0:bc2961fa1ef0 2271 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2272 uint32_t context_len;
Jonathan Austin 0:bc2961fa1ef0 2273 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2274
Jonathan Austin 0:bc2961fa1ef0 2275 err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2276 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2277 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2278
Jonathan Austin 0:bc2961fa1ef0 2279 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2280 {
Jonathan Austin 0:bc2961fa1ef0 2281 err_code = pstorage_load((uint8_t *)&context_len,
Jonathan Austin 0:bc2961fa1ef0 2282 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2283 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2284 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2285
Jonathan Austin 0:bc2961fa1ef0 2286 if (context_len != m_context_init_len)
Jonathan Austin 0:bc2961fa1ef0 2287 {
Jonathan Austin 0:bc2961fa1ef0 2288 err_code = pstorage_update(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 2289 (uint8_t *)&m_context_init_len,
Jonathan Austin 0:bc2961fa1ef0 2290 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2291 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2292
Jonathan Austin 0:bc2961fa1ef0 2293 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2294 {
Jonathan Austin 0:bc2961fa1ef0 2295 DM_ERR("[DM]: Failed to delete application context, reason 0x%08X\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 2296 }
Jonathan Austin 0:bc2961fa1ef0 2297 else
Jonathan Austin 0:bc2961fa1ef0 2298 {
Jonathan Austin 0:bc2961fa1ef0 2299 m_app_context_table[p_handle->device_id] = NULL;
Jonathan Austin 0:bc2961fa1ef0 2300 }
Jonathan Austin 0:bc2961fa1ef0 2301 }
Jonathan Austin 0:bc2961fa1ef0 2302 }
Jonathan Austin 0:bc2961fa1ef0 2303
Jonathan Austin 0:bc2961fa1ef0 2304 DM_TRC("[DM]: << dm_application_context_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 2305
Jonathan Austin 0:bc2961fa1ef0 2306 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2307
Jonathan Austin 0:bc2961fa1ef0 2308 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2309 #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2310 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2311 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2312 }
Jonathan Austin 0:bc2961fa1ef0 2313
Jonathan Austin 0:bc2961fa1ef0 2314
Jonathan Austin 0:bc2961fa1ef0 2315 ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance,
Jonathan Austin 0:bc2961fa1ef0 2316 dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2317 {
Jonathan Austin 0:bc2961fa1ef0 2318 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2319 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2320 NULL_PARAM_CHECK(p_appl_instance);
Jonathan Austin 0:bc2961fa1ef0 2321 VERIFY_APP_REGISTERED((*p_appl_instance));
Jonathan Austin 0:bc2961fa1ef0 2322
Jonathan Austin 0:bc2961fa1ef0 2323 p_handle->appl_id = (*p_appl_instance);
Jonathan Austin 0:bc2961fa1ef0 2324
Jonathan Austin 0:bc2961fa1ef0 2325 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2326 }
Jonathan Austin 0:bc2961fa1ef0 2327
Jonathan Austin 0:bc2961fa1ef0 2328
Jonathan Austin 0:bc2961fa1ef0 2329 uint32_t dm_handle_initialize(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2330 {
Jonathan Austin 0:bc2961fa1ef0 2331 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2332
Jonathan Austin 0:bc2961fa1ef0 2333 p_handle->appl_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2334 p_handle->connection_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2335 p_handle->device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2336 p_handle->service_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2337
Jonathan Austin 0:bc2961fa1ef0 2338 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2339 }
Jonathan Austin 0:bc2961fa1ef0 2340
Jonathan Austin 0:bc2961fa1ef0 2341
Jonathan Austin 0:bc2961fa1ef0 2342 ret_code_t dm_peer_addr_set(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2343 ble_gap_addr_t const * p_addr)
Jonathan Austin 0:bc2961fa1ef0 2344 {
Jonathan Austin 0:bc2961fa1ef0 2345 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2346 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2347 NULL_PARAM_CHECK(p_addr);
Jonathan Austin 0:bc2961fa1ef0 2348 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2349 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2350
Jonathan Austin 0:bc2961fa1ef0 2351 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2352
Jonathan Austin 0:bc2961fa1ef0 2353 DM_TRC("[DM]: >> dm_peer_addr_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2354
Jonathan Austin 0:bc2961fa1ef0 2355 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2356
Jonathan Austin 0:bc2961fa1ef0 2357 if ((p_handle->connection_id == DM_INVALID_ID) &&
Jonathan Austin 0:bc2961fa1ef0 2358 (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE))
Jonathan Austin 0:bc2961fa1ef0 2359 {
Jonathan Austin 0:bc2961fa1ef0 2360 m_peer_table[p_handle->device_id].peer_id.id_addr_info = (*p_addr);
Jonathan Austin 0:bc2961fa1ef0 2361 update_status_bit_set(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2362 device_context_store(p_handle, UPDATE_PEER_ADDR);
Jonathan Austin 0:bc2961fa1ef0 2363 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2364 }
Jonathan Austin 0:bc2961fa1ef0 2365 else
Jonathan Austin 0:bc2961fa1ef0 2366 {
Jonathan Austin 0:bc2961fa1ef0 2367 err_code = (NRF_ERROR_INVALID_PARAM | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2368 }
Jonathan Austin 0:bc2961fa1ef0 2369
Jonathan Austin 0:bc2961fa1ef0 2370 DM_TRC("[DM]: << dm_peer_addr_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2371
Jonathan Austin 0:bc2961fa1ef0 2372 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2373
Jonathan Austin 0:bc2961fa1ef0 2374 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2375 }
Jonathan Austin 0:bc2961fa1ef0 2376
Jonathan Austin 0:bc2961fa1ef0 2377
Jonathan Austin 0:bc2961fa1ef0 2378 ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2379 ble_gap_addr_t * p_addr)
Jonathan Austin 0:bc2961fa1ef0 2380 {
Jonathan Austin 0:bc2961fa1ef0 2381 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2382 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2383 NULL_PARAM_CHECK(p_addr);
Jonathan Austin 0:bc2961fa1ef0 2384 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2385
Jonathan Austin 0:bc2961fa1ef0 2386 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2387
Jonathan Austin 0:bc2961fa1ef0 2388 DM_TRC("[DM]: >> dm_peer_addr_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2389
Jonathan Austin 0:bc2961fa1ef0 2390 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2391
Jonathan Austin 0:bc2961fa1ef0 2392 err_code = (NRF_ERROR_NOT_FOUND | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2393
Jonathan Austin 0:bc2961fa1ef0 2394 if (p_handle->device_id == DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2395 {
Jonathan Austin 0:bc2961fa1ef0 2396 if ((p_handle->connection_id != DM_INVALID_ID) &&
Jonathan Austin 0:bc2961fa1ef0 2397 ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) ==
Jonathan Austin 0:bc2961fa1ef0 2398 STATE_CONNECTED))
Jonathan Austin 0:bc2961fa1ef0 2399 {
Jonathan Austin 0:bc2961fa1ef0 2400 DM_TRC("[DM]:[CI 0x%02X]: Address get for non bonded active connection.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2401 p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 2402
Jonathan Austin 0:bc2961fa1ef0 2403 (*p_addr) = m_connection_table[p_handle->connection_id].peer_addr;
Jonathan Austin 0:bc2961fa1ef0 2404 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2405 }
Jonathan Austin 0:bc2961fa1ef0 2406 }
Jonathan Austin 0:bc2961fa1ef0 2407 else
Jonathan Austin 0:bc2961fa1ef0 2408 {
Jonathan Austin 0:bc2961fa1ef0 2409 if ((m_peer_table[p_handle->device_id].id_bitmap & ADDR_ENTRY) == 0)
Jonathan Austin 0:bc2961fa1ef0 2410 {
Jonathan Austin 0:bc2961fa1ef0 2411 DM_TRC("[DM]:[DI 0x%02X]: Address get for bonded device.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2412 p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2413
Jonathan Austin 0:bc2961fa1ef0 2414 (*p_addr) = m_peer_table[p_handle->device_id].peer_id.id_addr_info;
Jonathan Austin 0:bc2961fa1ef0 2415 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2416 }
Jonathan Austin 0:bc2961fa1ef0 2417 }
Jonathan Austin 0:bc2961fa1ef0 2418
Jonathan Austin 0:bc2961fa1ef0 2419 DM_TRC("[DM]: << dm_peer_addr_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2420
Jonathan Austin 0:bc2961fa1ef0 2421 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2422
Jonathan Austin 0:bc2961fa1ef0 2423 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2424 }
Jonathan Austin 0:bc2961fa1ef0 2425
Jonathan Austin 0:bc2961fa1ef0 2426
Jonathan Austin 0:bc2961fa1ef0 2427 ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2428 dm_sec_keyset_t * p_key_dist)
Jonathan Austin 0:bc2961fa1ef0 2429 {
Jonathan Austin 0:bc2961fa1ef0 2430 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2431 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2432 NULL_PARAM_CHECK(p_key_dist);
Jonathan Austin 0:bc2961fa1ef0 2433 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2434 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2435
Jonathan Austin 0:bc2961fa1ef0 2436 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2437
Jonathan Austin 0:bc2961fa1ef0 2438 DM_TRC("[DM]: >> dm_distributed_keys_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2439
Jonathan Austin 0:bc2961fa1ef0 2440 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2441 ble_gap_enc_key_t peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2442 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2443
Jonathan Austin 0:bc2961fa1ef0 2444 err_code = NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 2445 p_key_dist->keys_central.enc_key.p_enc_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2446 p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id;
Jonathan Austin 0:bc2961fa1ef0 2447 p_key_dist->keys_central.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2448 p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info;
Jonathan Austin 0:bc2961fa1ef0 2449 p_key_dist->keys_periph.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2450 p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2451
Jonathan Austin 0:bc2961fa1ef0 2452 if ((m_peer_table[p_handle->device_id].id_bitmap & IRK_ENTRY) == 0)
Jonathan Austin 0:bc2961fa1ef0 2453 {
Jonathan Austin 0:bc2961fa1ef0 2454 // p_key_dist->keys_periph.p_id_key->id_addr_info.addr_type = INVALID_ADDR_TYPE;
Jonathan Austin 0:bc2961fa1ef0 2455 }
Jonathan Austin 0:bc2961fa1ef0 2456
Jonathan Austin 0:bc2961fa1ef0 2457 err_code = pstorage_block_identifier_get(&m_storage_handle, p_handle->device_id, &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2458 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2459 {
Jonathan Austin 0:bc2961fa1ef0 2460
Jonathan Austin 0:bc2961fa1ef0 2461 err_code = pstorage_load((uint8_t *)&peer_enc_key,
Jonathan Austin 0:bc2961fa1ef0 2462 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2463 BOND_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2464 BOND_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2465
Jonathan Austin 0:bc2961fa1ef0 2466 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2467 {
Jonathan Austin 0:bc2961fa1ef0 2468 p_key_dist->keys_central.enc_key.p_enc_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2469 p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id;
Jonathan Austin 0:bc2961fa1ef0 2470 p_key_dist->keys_central.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2471 p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info;
Jonathan Austin 0:bc2961fa1ef0 2472 p_key_dist->keys_periph.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2473 p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2474 }
Jonathan Austin 0:bc2961fa1ef0 2475 }
Jonathan Austin 0:bc2961fa1ef0 2476
Jonathan Austin 0:bc2961fa1ef0 2477 DM_TRC("[DM]: << dm_distributed_keys_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2478
Jonathan Austin 0:bc2961fa1ef0 2479 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2480
Jonathan Austin 0:bc2961fa1ef0 2481 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2482 }
Jonathan Austin 0:bc2961fa1ef0 2483
Jonathan Austin 0:bc2961fa1ef0 2484
Jonathan Austin 0:bc2961fa1ef0 2485 /**@brief Function for loading bond information for a connection instance.
Jonathan Austin 0:bc2961fa1ef0 2486 */
Jonathan Austin 0:bc2961fa1ef0 2487 void bond_data_load(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2488 {
Jonathan Austin 0:bc2961fa1ef0 2489 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2490
Jonathan Austin 0:bc2961fa1ef0 2491 uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2492 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2493 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2494 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2495 {
LancasterUniversity 5:f2faa0f0b8f0 2496 DM_LOG(
Jonathan Austin 0:bc2961fa1ef0 2497 "[DM]:[%02X]:[Block ID 0x%08X]:Loading bond information at %p, size 0x%08X, offset 0x%08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2498 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2499 block_handle.block_id,
Jonathan Austin 0:bc2961fa1ef0 2500 &m_bond_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 2501 BOND_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2502 BOND_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2503
Jonathan Austin 0:bc2961fa1ef0 2504 err_code = pstorage_load((uint8_t *)&m_bond_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 2505 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2506 BOND_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2507 BOND_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2508
Jonathan Austin 0:bc2961fa1ef0 2509 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2510 {
LancasterUniversity 5:f2faa0f0b8f0 2511 DM_LOG("[DM]:[%02X]: Failed to load Bond information, reason %08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2512 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2513 err_code);
Jonathan Austin 0:bc2961fa1ef0 2514 }
Jonathan Austin 0:bc2961fa1ef0 2515
LancasterUniversity 5:f2faa0f0b8f0 2516 DM_LOG(
Jonathan Austin 0:bc2961fa1ef0 2517 "[DM]:[%02X]:Loading service context at %p, size 0x%08X, offset 0x%08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2518 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2519 &m_gatts_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 2520 sizeof(dm_gatts_context_t),
Jonathan Austin 0:bc2961fa1ef0 2521 SERVICE_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2522
Jonathan Austin 0:bc2961fa1ef0 2523 err_code = m_service_context_load[m_application_table[0].service](
Jonathan Austin 0:bc2961fa1ef0 2524 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2525 p_handle);
Jonathan Austin 0:bc2961fa1ef0 2526
Jonathan Austin 0:bc2961fa1ef0 2527 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2528 {
LancasterUniversity 5:f2faa0f0b8f0 2529 DM_LOG(
Jonathan Austin 0:bc2961fa1ef0 2530 "[DM]:[%02X]: Failed to load service information, reason %08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2531 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2532 err_code);
Jonathan Austin 0:bc2961fa1ef0 2533 }
Jonathan Austin 0:bc2961fa1ef0 2534 }
Jonathan Austin 0:bc2961fa1ef0 2535 else
Jonathan Austin 0:bc2961fa1ef0 2536 {
LancasterUniversity 5:f2faa0f0b8f0 2537 DM_LOG("[DM]:[%02X]: Failed to get block identifier for "
Jonathan Austin 0:bc2961fa1ef0 2538 "device %08X, reason %08X.\r\n", p_handle->connection_id, p_handle->device_id, err_code);
Jonathan Austin 0:bc2961fa1ef0 2539 }
Jonathan Austin 0:bc2961fa1ef0 2540 }
Jonathan Austin 0:bc2961fa1ef0 2541
LancasterUniversity 4:ee5f0a37316e 2542 int address_to_device_id(ble_gap_addr_t const * p_addr)
LancasterUniversity 4:ee5f0a37316e 2543 {
LancasterUniversity 4:ee5f0a37316e 2544 for(int peer_iterator = 0; peer_iterator < DEVICE_MANAGER_MAX_BONDS; peer_iterator++)
LancasterUniversity 4:ee5f0a37316e 2545 {
LancasterUniversity 4:ee5f0a37316e 2546 if(im_address_resolve(p_addr, &m_peer_table[peer_iterator].peer_id.id_info))
LancasterUniversity 4:ee5f0a37316e 2547 return peer_iterator;
LancasterUniversity 4:ee5f0a37316e 2548 }
LancasterUniversity 4:ee5f0a37316e 2549
LancasterUniversity 4:ee5f0a37316e 2550 return DM_INVALID_ID;
LancasterUniversity 4:ee5f0a37316e 2551 }
Jonathan Austin 0:bc2961fa1ef0 2552
Jonathan Austin 0:bc2961fa1ef0 2553 void dm_ble_evt_handler(ble_evt_t * p_ble_evt)
Jonathan Austin 0:bc2961fa1ef0 2554 {
Jonathan Austin 0:bc2961fa1ef0 2555 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2556 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 2557 uint32_t device_index = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2558 bool notify_app = false;
Jonathan Austin 0:bc2961fa1ef0 2559 dm_handle_t handle;
Jonathan Austin 0:bc2961fa1ef0 2560 dm_event_t event;
Jonathan Austin 0:bc2961fa1ef0 2561 uint32_t event_result;
Jonathan Austin 0:bc2961fa1ef0 2562 ble_gap_enc_info_t * p_enc_info = NULL;
Jonathan Austin 0:bc2961fa1ef0 2563
Jonathan Austin 0:bc2961fa1ef0 2564 VERIFY_MODULE_INITIALIZED_VOID();
Jonathan Austin 0:bc2961fa1ef0 2565 VERIFY_APP_REGISTERED_VOID(0);
Jonathan Austin 0:bc2961fa1ef0 2566 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2567
Jonathan Austin 0:bc2961fa1ef0 2568 err_code = dm_handle_initialize(&handle);
Jonathan Austin 0:bc2961fa1ef0 2569 APP_ERROR_CHECK(err_code);
Jonathan Austin 0:bc2961fa1ef0 2570
Jonathan Austin 0:bc2961fa1ef0 2571 event_result = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2572 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2573 event.event_param.p_gap_param = &p_ble_evt->evt.gap_evt;
Jonathan Austin 0:bc2961fa1ef0 2574 event.event_paramlen = sizeof(ble_gap_evt_t);
Jonathan Austin 0:bc2961fa1ef0 2575 handle.device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2576 handle.appl_id = 0;
Jonathan Austin 0:bc2961fa1ef0 2577 index = 0x00;
Jonathan Austin 0:bc2961fa1ef0 2578
Jonathan Austin 0:bc2961fa1ef0 2579 if (p_ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 2580 {
Jonathan Austin 0:bc2961fa1ef0 2581 err_code = connection_instance_find(p_ble_evt->evt.gap_evt.conn_handle,
Jonathan Austin 0:bc2961fa1ef0 2582 STATE_CONNECTED,
Jonathan Austin 0:bc2961fa1ef0 2583 &index);
Jonathan Austin 0:bc2961fa1ef0 2584
Jonathan Austin 0:bc2961fa1ef0 2585 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2586 {
Jonathan Austin 0:bc2961fa1ef0 2587 handle.device_id = m_connection_table[index].bonded_dev_id;
Jonathan Austin 0:bc2961fa1ef0 2588 handle.connection_id = index;
Jonathan Austin 0:bc2961fa1ef0 2589 }
Jonathan Austin 0:bc2961fa1ef0 2590 }
Jonathan Austin 0:bc2961fa1ef0 2591
Jonathan Austin 0:bc2961fa1ef0 2592 switch (p_ble_evt->header.evt_id)
Jonathan Austin 0:bc2961fa1ef0 2593 {
Jonathan Austin 0:bc2961fa1ef0 2594 case BLE_GAP_EVT_CONNECTED:
Jonathan Austin 0:bc2961fa1ef0 2595 //Allocate connection instance for a new connection.
Jonathan Austin 0:bc2961fa1ef0 2596 err_code = connection_instance_allocate(&index);
Jonathan Austin 0:bc2961fa1ef0 2597
Jonathan Austin 0:bc2961fa1ef0 2598 //Connection instance is successfully allocated.
Jonathan Austin 0:bc2961fa1ef0 2599 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2600 {
Jonathan Austin 0:bc2961fa1ef0 2601 //Application notification related information.
Jonathan Austin 0:bc2961fa1ef0 2602 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2603 event.event_id = DM_EVT_CONNECTION;
Jonathan Austin 0:bc2961fa1ef0 2604 handle.connection_id = index;
Jonathan Austin 0:bc2961fa1ef0 2605
Jonathan Austin 0:bc2961fa1ef0 2606 m_connection_table[index].conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
Jonathan Austin 0:bc2961fa1ef0 2607 m_connection_table[index].state = STATE_CONNECTED;
Jonathan Austin 0:bc2961fa1ef0 2608 m_connection_table[index].peer_addr =
Jonathan Austin 0:bc2961fa1ef0 2609 p_ble_evt->evt.gap_evt.params.connected.peer_addr;
Jonathan Austin 0:bc2961fa1ef0 2610
LancasterUniversity 4:ee5f0a37316e 2611 if ((device_index = address_to_device_id(&p_ble_evt->evt.gap_evt.params.connected.peer_addr)) != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2612 {
LancasterUniversity 4:ee5f0a37316e 2613 err_code = NRF_SUCCESS;
LancasterUniversity 4:ee5f0a37316e 2614
LancasterUniversity 5:f2faa0f0b8f0 2615 DM_LOG("CONNECT: matched, addr_to_did %d\r\n", device_index);
Jonathan Austin 0:bc2961fa1ef0 2616 }
Jonathan Austin 0:bc2961fa1ef0 2617 else
Jonathan Austin 0:bc2961fa1ef0 2618 {
Jonathan Austin 0:bc2961fa1ef0 2619 //Use the device address to check if the device exists in the bonded device list.
Jonathan Austin 0:bc2961fa1ef0 2620 err_code = device_instance_find(&p_ble_evt->evt.gap_evt.params.connected.peer_addr,
Jonathan Austin 0:bc2961fa1ef0 2621 &device_index, EDIV_INIT_VAL);
LancasterUniversity 5:f2faa0f0b8f0 2622 DM_LOG("CONNECT: not matched, status: %d found manually: %d\r\n", err_code, device_index);
Jonathan Austin 0:bc2961fa1ef0 2623 }
Jonathan Austin 0:bc2961fa1ef0 2624
Jonathan Austin 0:bc2961fa1ef0 2625 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2626 {
LancasterUniversity 5:f2faa0f0b8f0 2627 DM_LOG("CONNECT: SUCCESS!\r\n");
Jonathan Austin 0:bc2961fa1ef0 2628 m_connection_table[index].bonded_dev_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2629 m_connection_table[index].state |= STATE_BONDED;
Jonathan Austin 0:bc2961fa1ef0 2630 handle.device_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2631
Jonathan Austin 0:bc2961fa1ef0 2632 bond_data_load(&handle);
Jonathan Austin 0:bc2961fa1ef0 2633 }
Jonathan Austin 0:bc2961fa1ef0 2634 }
LancasterUniversity 4:ee5f0a37316e 2635
LancasterUniversity 5:f2faa0f0b8f0 2636 DM_LOG("CONNECT: did %d bdid %d\r\n", handle.device_id, m_connection_table[index].bonded_dev_id);
LancasterUniversity 4:ee5f0a37316e 2637
Jonathan Austin 0:bc2961fa1ef0 2638 break;
Jonathan Austin 0:bc2961fa1ef0 2639
Jonathan Austin 0:bc2961fa1ef0 2640 case BLE_GAP_EVT_DISCONNECTED:
Jonathan Austin 0:bc2961fa1ef0 2641 //Disconnection could be peer or self initiated hence disconnecting and connecting
Jonathan Austin 0:bc2961fa1ef0 2642 //both states are permitted, however, connection handle must be known.
LancasterUniversity 5:f2faa0f0b8f0 2643 DM_LOG("[DM]: Disconnect Reason 0x%04X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2644 p_ble_evt->evt.gap_evt.params.disconnected.reason);
Jonathan Austin 0:bc2961fa1ef0 2645
Jonathan Austin 0:bc2961fa1ef0 2646 m_connection_table[index].state &= (~STATE_CONNECTED);
Jonathan Austin 0:bc2961fa1ef0 2647
Jonathan Austin 0:bc2961fa1ef0 2648 if ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED)
Jonathan Austin 0:bc2961fa1ef0 2649 {
Jonathan Austin 0:bc2961fa1ef0 2650 if ((m_connection_table[index].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED)
Jonathan Austin 0:bc2961fa1ef0 2651 {
Jonathan Austin 0:bc2961fa1ef0 2652 //Write bond information persistently.
Jonathan Austin 0:bc2961fa1ef0 2653 device_context_store(&handle, STORE_ALL_CONTEXT);
Jonathan Austin 0:bc2961fa1ef0 2654 }
Jonathan Austin 0:bc2961fa1ef0 2655 }
Jonathan Austin 0:bc2961fa1ef0 2656 else
Jonathan Austin 0:bc2961fa1ef0 2657 {
Jonathan Austin 0:bc2961fa1ef0 2658 //Free any allocated instances for devices that is not bonded.
Jonathan Austin 0:bc2961fa1ef0 2659 if (handle.device_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2660 {
Jonathan Austin 0:bc2961fa1ef0 2661 peer_instance_init(handle.device_id);
Jonathan Austin 0:bc2961fa1ef0 2662 handle.device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2663 }
Jonathan Austin 0:bc2961fa1ef0 2664 }
Jonathan Austin 0:bc2961fa1ef0 2665
Jonathan Austin 0:bc2961fa1ef0 2666 m_connection_table[index].state = STATE_DISCONNECTING;
Jonathan Austin 0:bc2961fa1ef0 2667 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2668 event.event_id = DM_EVT_DISCONNECTION;
Jonathan Austin 0:bc2961fa1ef0 2669
Jonathan Austin 0:bc2961fa1ef0 2670 break;
Jonathan Austin 0:bc2961fa1ef0 2671
Jonathan Austin 0:bc2961fa1ef0 2672 case BLE_GAP_EVT_SEC_INFO_REQUEST:
LancasterUniversity 5:f2faa0f0b8f0 2673 DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_INFO_REQUEST\r\n");
Jonathan Austin 0:bc2961fa1ef0 2674
Jonathan Austin 0:bc2961fa1ef0 2675 //If the device is already bonded, respond with existing info, else NULL.
Jonathan Austin 0:bc2961fa1ef0 2676 if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2677 {
LancasterUniversity 5:f2faa0f0b8f0 2678 DM_LOG("INVALID ID \r\n");
LancasterUniversity 4:ee5f0a37316e 2679
Jonathan Austin 0:bc2961fa1ef0 2680 //Find device based on div.
Jonathan Austin 0:bc2961fa1ef0 2681 err_code = device_instance_find(NULL,&device_index, p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv);
Jonathan Austin 0:bc2961fa1ef0 2682 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2683 {
Jonathan Austin 0:bc2961fa1ef0 2684 //Load needed bonding information.
Jonathan Austin 0:bc2961fa1ef0 2685 m_connection_table[index].bonded_dev_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2686 m_connection_table[index].state |= STATE_BONDED;
Jonathan Austin 0:bc2961fa1ef0 2687 handle.device_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2688 bond_data_load(&handle);
Jonathan Austin 0:bc2961fa1ef0 2689 }
Jonathan Austin 0:bc2961fa1ef0 2690 }
Jonathan Austin 0:bc2961fa1ef0 2691
Jonathan Austin 0:bc2961fa1ef0 2692 if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2693 {
LancasterUniversity 5:f2faa0f0b8f0 2694 DM_LOG("VALID ID index %d bdid %d\r\n",index, m_connection_table[index].bonded_dev_id);
Jonathan Austin 0:bc2961fa1ef0 2695 p_enc_info = &m_bond_table[index].peer_enc_key.enc_info;
Jonathan Austin 0:bc2961fa1ef0 2696 DM_DUMP((uint8_t *)p_enc_info, sizeof(ble_gap_enc_info_t));
Jonathan Austin 0:bc2961fa1ef0 2697 }
Jonathan Austin 0:bc2961fa1ef0 2698
Jonathan Austin 0:bc2961fa1ef0 2699 err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle,
Jonathan Austin 0:bc2961fa1ef0 2700 p_enc_info,
Jonathan Austin 0:bc2961fa1ef0 2701 &m_peer_table[index].peer_id.id_info,
Jonathan Austin 0:bc2961fa1ef0 2702 NULL);
Jonathan Austin 0:bc2961fa1ef0 2703
Jonathan Austin 0:bc2961fa1ef0 2704 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2705 {
LancasterUniversity 5:f2faa0f0b8f0 2706 DM_LOG("[DM]:[CI %02X]:[DI %02X]: Security information response failed, reason "
Jonathan Austin 0:bc2961fa1ef0 2707 "0x%08X\r\n", index, m_connection_table[index].bonded_dev_id, err_code);
Jonathan Austin 0:bc2961fa1ef0 2708 }
Jonathan Austin 0:bc2961fa1ef0 2709 break;
Jonathan Austin 0:bc2961fa1ef0 2710
Jonathan Austin 0:bc2961fa1ef0 2711 case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
Jonathan Austin 0:bc2961fa1ef0 2712 DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n");
Jonathan Austin 0:bc2961fa1ef0 2713
LancasterUniversity 5:f2faa0f0b8f0 2714 DM_LOG("SEC_PARAM irkm: %d idx: %d \r\n",p_ble_evt->evt.gap_evt.params.connected.irk_match, p_ble_evt->evt.gap_evt.params.connected.irk_match_idx);
LancasterUniversity 4:ee5f0a37316e 2715
Jonathan Austin 0:bc2961fa1ef0 2716 event.event_id = DM_EVT_SECURITY_SETUP;
Jonathan Austin 0:bc2961fa1ef0 2717
Jonathan Austin 0:bc2961fa1ef0 2718 m_connection_table[index].state |= STATE_PAIRING;
Jonathan Austin 0:bc2961fa1ef0 2719 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2720
LancasterUniversity 4:ee5f0a37316e 2721 if ((device_index = address_to_device_id(&p_ble_evt->evt.gap_evt.params.connected.peer_addr)) != DM_INVALID_ID)
LancasterUniversity 4:ee5f0a37316e 2722 {
LancasterUniversity 4:ee5f0a37316e 2723 handle.device_id = device_index;
LancasterUniversity 4:ee5f0a37316e 2724 m_connection_table[index].bonded_dev_id = device_index;
LancasterUniversity 4:ee5f0a37316e 2725 err_code = NRF_SUCCESS;
LancasterUniversity 4:ee5f0a37316e 2726
LancasterUniversity 5:f2faa0f0b8f0 2727 DM_LOG("REBONDING bdid %d, did %d, conn %d\r\n",m_connection_table[index].bonded_dev_id, handle.device_id, index);
LancasterUniversity 4:ee5f0a37316e 2728 }
LancasterUniversity 4:ee5f0a37316e 2729
Jonathan Austin 0:bc2961fa1ef0 2730 if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2731 {
LancasterUniversity 5:f2faa0f0b8f0 2732 DM_LOG("allocating new \r\n");
LancasterUniversity 4:ee5f0a37316e 2733
Jonathan Austin 0:bc2961fa1ef0 2734 //Assign a peer index as a new bond or update existing bonds.
Jonathan Austin 0:bc2961fa1ef0 2735 err_code = device_instance_allocate((uint8_t *)&device_index,
Jonathan Austin 0:bc2961fa1ef0 2736 &m_connection_table[index].peer_addr);
Jonathan Austin 0:bc2961fa1ef0 2737
Jonathan Austin 0:bc2961fa1ef0 2738 //Allocation successful.
Jonathan Austin 0:bc2961fa1ef0 2739 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2740 {
LancasterUniversity 4:ee5f0a37316e 2741
LancasterUniversity 5:f2faa0f0b8f0 2742 DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index);
Jonathan Austin 0:bc2961fa1ef0 2743
Jonathan Austin 0:bc2961fa1ef0 2744 handle.device_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2745 m_connection_table[index].bonded_dev_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2746 }
Jonathan Austin 0:bc2961fa1ef0 2747 else
Jonathan Austin 0:bc2961fa1ef0 2748 {
LancasterUniversity 5:f2faa0f0b8f0 2749 DM_LOG("[DM]: Security parameter request failed, reason 0x%08X.\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 2750 event_result = err_code;
Jonathan Austin 0:bc2961fa1ef0 2751 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2752 }
Jonathan Austin 0:bc2961fa1ef0 2753 }
Jonathan Austin 0:bc2961fa1ef0 2754 else
Jonathan Austin 0:bc2961fa1ef0 2755 {
LancasterUniversity 5:f2faa0f0b8f0 2756 DM_LOG("refresh\r\n");
Jonathan Austin 0:bc2961fa1ef0 2757 //Bond/key refresh.
Jonathan Austin 0:bc2961fa1ef0 2758 event.event_id = DM_EVT_SECURITY_SETUP_REFRESH;
Jonathan Austin 0:bc2961fa1ef0 2759 memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE);
Jonathan Austin 0:bc2961fa1ef0 2760
Jonathan Austin 0:bc2961fa1ef0 2761 //Set the update flag for bond data.
Jonathan Austin 0:bc2961fa1ef0 2762 m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
Jonathan Austin 0:bc2961fa1ef0 2763 }
Jonathan Austin 0:bc2961fa1ef0 2764
LancasterUniversity 5:f2faa0f0b8f0 2765 DM_LOG("FINAL [DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index);
LancasterUniversity 4:ee5f0a37316e 2766
Jonathan Austin 0:bc2961fa1ef0 2767 ble_gap_sec_keyset_t keys_exchanged;
Jonathan Austin 0:bc2961fa1ef0 2768
Jonathan Austin 0:bc2961fa1ef0 2769 DM_LOG("[DM]: 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2770 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.enc,
Jonathan Austin 0:bc2961fa1ef0 2771 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_central.id,
Jonathan Austin 0:bc2961fa1ef0 2772 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.sign,
Jonathan Austin 0:bc2961fa1ef0 2773 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.bond);
Jonathan Austin 0:bc2961fa1ef0 2774
Jonathan Austin 0:bc2961fa1ef0 2775 keys_exchanged.keys_central.p_enc_key = NULL;
LancasterUniversity 4:ee5f0a37316e 2776 keys_exchanged.keys_central.p_id_key = &m_peer_table[m_connection_table[index].bonded_dev_id].peer_id;
Jonathan Austin 0:bc2961fa1ef0 2777 keys_exchanged.keys_central.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2778 keys_exchanged.keys_periph.p_enc_key = &m_bond_table[index].peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2779 keys_exchanged.keys_periph.p_id_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2780 keys_exchanged.keys_periph.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2781
Jonathan Austin 0:bc2961fa1ef0 2782 err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
Jonathan Austin 0:bc2961fa1ef0 2783 BLE_GAP_SEC_STATUS_SUCCESS,
LancasterUniversity 4:ee5f0a37316e 2784 &m_application_table[0].sec_param,
Jonathan Austin 0:bc2961fa1ef0 2785 &keys_exchanged);
Jonathan Austin 0:bc2961fa1ef0 2786
Jonathan Austin 0:bc2961fa1ef0 2787 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2788 {
Jonathan Austin 0:bc2961fa1ef0 2789 DM_LOG("[DM]: Security parameter reply request failed, reason 0x%08X.\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 2790 event_result = err_code;
Jonathan Austin 0:bc2961fa1ef0 2791 notify_app = false;
Jonathan Austin 0:bc2961fa1ef0 2792 }
Jonathan Austin 0:bc2961fa1ef0 2793 break;
Jonathan Austin 0:bc2961fa1ef0 2794
Jonathan Austin 0:bc2961fa1ef0 2795 case BLE_GAP_EVT_AUTH_STATUS:
Jonathan Austin 0:bc2961fa1ef0 2796 {
Jonathan Austin 0:bc2961fa1ef0 2797 DM_LOG("[DM]: >> BLE_GAP_EVT_AUTH_STATUS, status %08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2798 p_ble_evt->evt.gap_evt.params.auth_status.auth_status);
Jonathan Austin 0:bc2961fa1ef0 2799
Jonathan Austin 0:bc2961fa1ef0 2800 m_application_table[0].state &= (~STATE_CONTROL_PROCEDURE_IN_PROGRESS);
Jonathan Austin 0:bc2961fa1ef0 2801 m_connection_table[index].state &= (~STATE_PAIRING);
Jonathan Austin 0:bc2961fa1ef0 2802 event.event_id = DM_EVT_SECURITY_SETUP_COMPLETE;
Jonathan Austin 0:bc2961fa1ef0 2803 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2804
Jonathan Austin 0:bc2961fa1ef0 2805 if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status != BLE_GAP_SEC_STATUS_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2806 {
LancasterUniversity 5:f2faa0f0b8f0 2807 DM_LOG("bond failed\r\n");
Jonathan Austin 0:bc2961fa1ef0 2808 // Free the allocation as bonding failed.
Jonathan Austin 0:bc2961fa1ef0 2809 ret_code_t result = device_instance_free(m_connection_table[index].bonded_dev_id);
Jonathan Austin 0:bc2961fa1ef0 2810 (void) result;
Jonathan Austin 0:bc2961fa1ef0 2811 event_result = p_ble_evt->evt.gap_evt.params.auth_status.auth_status;
Jonathan Austin 0:bc2961fa1ef0 2812 }
Jonathan Austin 0:bc2961fa1ef0 2813 else
Jonathan Austin 0:bc2961fa1ef0 2814 {
LancasterUniversity 5:f2faa0f0b8f0 2815 DM_LOG("bonding\r\n");
Jonathan Austin 0:bc2961fa1ef0 2816 DM_DUMP((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status,
Jonathan Austin 0:bc2961fa1ef0 2817 sizeof(ble_gap_evt_auth_status_t));
Jonathan Austin 0:bc2961fa1ef0 2818 DM_DUMP((uint8_t *)&m_bond_table[index], sizeof(bond_context_t));
Jonathan Austin 0:bc2961fa1ef0 2819
Jonathan Austin 0:bc2961fa1ef0 2820 if (p_ble_evt->evt.gap_evt.params.auth_status.bonded == 1)
Jonathan Austin 0:bc2961fa1ef0 2821 {
Jonathan Austin 0:bc2961fa1ef0 2822 if (handle.device_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2823 {
Jonathan Austin 0:bc2961fa1ef0 2824 m_connection_table[index].state |= STATE_BONDED;
Jonathan Austin 0:bc2961fa1ef0 2825
Jonathan Austin 0:bc2961fa1ef0 2826 //IRK and/or public address is shared, update it.
Jonathan Austin 0:bc2961fa1ef0 2827 if (p_ble_evt->evt.gap_evt.params.auth_status.kdist_central.id == 1)
Jonathan Austin 0:bc2961fa1ef0 2828 {
LancasterUniversity 5:f2faa0f0b8f0 2829 DM_LOG("shared\r\n");
Jonathan Austin 0:bc2961fa1ef0 2830 m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 2831 }
Jonathan Austin 0:bc2961fa1ef0 2832
Jonathan Austin 0:bc2961fa1ef0 2833 if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2834 {
LancasterUniversity 5:f2faa0f0b8f0 2835 DM_LOG("bonded index %d bdid %d\r\n", index,m_connection_table[index].bonded_dev_id);
Jonathan Austin 0:bc2961fa1ef0 2836 DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",
Jonathan Austin 0:bc2961fa1ef0 2837 index,
Jonathan Austin 0:bc2961fa1ef0 2838 handle.device_id);
Jonathan Austin 0:bc2961fa1ef0 2839
Jonathan Austin 0:bc2961fa1ef0 2840 if (m_connection_table[index].peer_addr.addr_type !=
Jonathan Austin 0:bc2961fa1ef0 2841 BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
Jonathan Austin 0:bc2961fa1ef0 2842 {
LancasterUniversity 5:f2faa0f0b8f0 2843 DM_LOG("not RPR\r\n");
LancasterUniversity 4:ee5f0a37316e 2844
Jonathan Austin 0:bc2961fa1ef0 2845 m_peer_table[handle.device_id].peer_id.id_addr_info =
Jonathan Austin 0:bc2961fa1ef0 2846 m_connection_table[index].peer_addr;
Jonathan Austin 0:bc2961fa1ef0 2847 m_peer_table[handle.device_id].id_bitmap &= (~ADDR_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 2848
Jonathan Austin 0:bc2961fa1ef0 2849 DM_DUMP((uint8_t *)&m_peer_table[handle.device_id].peer_id.id_addr_info,
Jonathan Austin 0:bc2961fa1ef0 2850 sizeof(m_peer_table[handle.device_id].peer_id.id_addr_info));
Jonathan Austin 0:bc2961fa1ef0 2851 }
Jonathan Austin 0:bc2961fa1ef0 2852 else
Jonathan Austin 0:bc2961fa1ef0 2853 {
LancasterUniversity 5:f2faa0f0b8f0 2854 DM_LOG("PR\r\n");
Jonathan Austin 0:bc2961fa1ef0 2855 // Here we must fetch the keys from the keyset distributed.
Jonathan Austin 0:bc2961fa1ef0 2856 m_peer_table[handle.device_id].ediv = m_bond_table[index].peer_enc_key.master_id.ediv;
Jonathan Austin 0:bc2961fa1ef0 2857 m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 2858 }
Jonathan Austin 0:bc2961fa1ef0 2859
Jonathan Austin 0:bc2961fa1ef0 2860 device_context_store(&handle, FIRST_BOND_STORE);
Jonathan Austin 0:bc2961fa1ef0 2861 }
Jonathan Austin 0:bc2961fa1ef0 2862 }
Jonathan Austin 0:bc2961fa1ef0 2863 }
Jonathan Austin 0:bc2961fa1ef0 2864 else
Jonathan Austin 0:bc2961fa1ef0 2865 {
Jonathan Austin 0:bc2961fa1ef0 2866 //Pairing request, no need to touch the bonding info.
Jonathan Austin 0:bc2961fa1ef0 2867 }
Jonathan Austin 0:bc2961fa1ef0 2868 }
Jonathan Austin 0:bc2961fa1ef0 2869 break;
Jonathan Austin 0:bc2961fa1ef0 2870 }
Jonathan Austin 0:bc2961fa1ef0 2871
Jonathan Austin 0:bc2961fa1ef0 2872 case BLE_GAP_EVT_CONN_SEC_UPDATE:
Jonathan Austin 0:bc2961fa1ef0 2873 DM_LOG("[DM]: >> BLE_GAP_EVT_CONN_SEC_UPDATE, Mode 0x%02X, Level 0x%02X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2874 p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm,
Jonathan Austin 0:bc2961fa1ef0 2875 p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv);
Jonathan Austin 0:bc2961fa1ef0 2876
Jonathan Austin 0:bc2961fa1ef0 2877 if ((p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv == 1) &&
Jonathan Austin 0:bc2961fa1ef0 2878 (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm == 1) &&
Jonathan Austin 0:bc2961fa1ef0 2879 ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED))
Jonathan Austin 0:bc2961fa1ef0 2880 {
Jonathan Austin 0:bc2961fa1ef0 2881 //Lost bond case, generate a security refresh event!
Jonathan Austin 0:bc2961fa1ef0 2882 memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE);
LancasterUniversity 4:ee5f0a37316e 2883
Jonathan Austin 0:bc2961fa1ef0 2884 event.event_id = DM_EVT_SECURITY_SETUP_REFRESH;
Jonathan Austin 0:bc2961fa1ef0 2885 m_connection_table[index].state |= STATE_PAIRING_PENDING;
Jonathan Austin 0:bc2961fa1ef0 2886 m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
Jonathan Austin 0:bc2961fa1ef0 2887 m_application_table[0].state |= STATE_QUEUED_CONTROL_REQUEST;
Jonathan Austin 0:bc2961fa1ef0 2888 }
Jonathan Austin 0:bc2961fa1ef0 2889 else
Jonathan Austin 0:bc2961fa1ef0 2890 {
Jonathan Austin 0:bc2961fa1ef0 2891 m_connection_table[index].state |= STATE_LINK_ENCRYPTED;
Jonathan Austin 0:bc2961fa1ef0 2892 event.event_id = DM_EVT_LINK_SECURED;
Jonathan Austin 0:bc2961fa1ef0 2893
Jonathan Austin 0:bc2961fa1ef0 2894 //Apply service context.
Jonathan Austin 0:bc2961fa1ef0 2895 err_code = m_service_context_apply[m_application_table[0].service](&handle);
Jonathan Austin 0:bc2961fa1ef0 2896
Jonathan Austin 0:bc2961fa1ef0 2897 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2898 {
Jonathan Austin 0:bc2961fa1ef0 2899 DM_ERR("[DM]:[CI 0x%02X]:[DI 0x%02X]: Failed to apply service context\r\n",
LancasterUniversity 4:ee5f0a37316e 2900 handle.connection_id,
Jonathan Austin 0:bc2961fa1ef0 2901 handle.device_id);
Jonathan Austin 0:bc2961fa1ef0 2902
Jonathan Austin 0:bc2961fa1ef0 2903 event_result = DM_SERVICE_CONTEXT_NOT_APPLIED;
Jonathan Austin 0:bc2961fa1ef0 2904 }
Jonathan Austin 0:bc2961fa1ef0 2905 }
Jonathan Austin 0:bc2961fa1ef0 2906 event_result = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2907 notify_app = true;
LancasterUniversity 4:ee5f0a37316e 2908
Jonathan Austin 0:bc2961fa1ef0 2909 break;
Jonathan Austin 0:bc2961fa1ef0 2910
Jonathan Austin 0:bc2961fa1ef0 2911 case BLE_GATTS_EVT_SYS_ATTR_MISSING:
Jonathan Austin 0:bc2961fa1ef0 2912 DM_LOG("[DM]: >> BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n");
Jonathan Austin 0:bc2961fa1ef0 2913
Jonathan Austin 0:bc2961fa1ef0 2914 //Apply service context.
Jonathan Austin 0:bc2961fa1ef0 2915 event_result = m_service_context_apply[m_application_table[0].service](&handle);
Jonathan Austin 0:bc2961fa1ef0 2916 break;
Jonathan Austin 0:bc2961fa1ef0 2917
Jonathan Austin 0:bc2961fa1ef0 2918 case BLE_GAP_EVT_SEC_REQUEST:
Jonathan Austin 0:bc2961fa1ef0 2919 DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_REQUEST\r\n");
LancasterUniversity 4:ee5f0a37316e 2920
Jonathan Austin 0:bc2961fa1ef0 2921 //Verify if the device is already bonded, and if it is bonded, initiate encryption.
LancasterUniversity 4:ee5f0a37316e 2922 //If the device is not bonded, an instance needs to be allocated in order to initiate
LancasterUniversity 4:ee5f0a37316e 2923 //bonding. The application have to initiate the procedure, the module will not do this
Jonathan Austin 0:bc2961fa1ef0 2924 //automatically.
Jonathan Austin 0:bc2961fa1ef0 2925 event.event_id = DM_EVT_SECURITY_SETUP;
Jonathan Austin 0:bc2961fa1ef0 2926 notify_app = true;
LancasterUniversity 4:ee5f0a37316e 2927
Jonathan Austin 0:bc2961fa1ef0 2928 break;
Jonathan Austin 0:bc2961fa1ef0 2929
Jonathan Austin 0:bc2961fa1ef0 2930 default:
Jonathan Austin 0:bc2961fa1ef0 2931 break;
Jonathan Austin 0:bc2961fa1ef0 2932 }
Jonathan Austin 0:bc2961fa1ef0 2933
Jonathan Austin 0:bc2961fa1ef0 2934 if (notify_app)
Jonathan Austin 0:bc2961fa1ef0 2935 {
Jonathan Austin 0:bc2961fa1ef0 2936 app_evt_notify(&handle, &event, event_result);
Jonathan Austin 0:bc2961fa1ef0 2937
Jonathan Austin 0:bc2961fa1ef0 2938 //Freeing the instance after the event is notified so the application can get the context.
Jonathan Austin 0:bc2961fa1ef0 2939 if (event.event_id == DM_EVT_DISCONNECTION)
Jonathan Austin 0:bc2961fa1ef0 2940 {
Jonathan Austin 0:bc2961fa1ef0 2941 //Free the instance.
Jonathan Austin 0:bc2961fa1ef0 2942 connection_instance_free(&index);
Jonathan Austin 0:bc2961fa1ef0 2943 }
Jonathan Austin 0:bc2961fa1ef0 2944 }
Jonathan Austin 0:bc2961fa1ef0 2945
Jonathan Austin 0:bc2961fa1ef0 2946 UNUSED_VARIABLE(err_code);
Jonathan Austin 0:bc2961fa1ef0 2947
Jonathan Austin 0:bc2961fa1ef0 2948 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2949 }
Jonathan Austin 0:bc2961fa1ef0 2950
Jonathan Austin 0:bc2961fa1ef0 2951
Jonathan Austin 0:bc2961fa1ef0 2952 ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2953 {
Jonathan Austin 0:bc2961fa1ef0 2954 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2955 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 2956
Jonathan Austin 0:bc2961fa1ef0 2957 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2958 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2959
Jonathan Austin 0:bc2961fa1ef0 2960 p_handle->device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2961
Jonathan Austin 0:bc2961fa1ef0 2962 err_code = NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 2963
Jonathan Austin 0:bc2961fa1ef0 2964 for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
Jonathan Austin 0:bc2961fa1ef0 2965 {
Jonathan Austin 0:bc2961fa1ef0 2966 //Search for matching connection handle.
Jonathan Austin 0:bc2961fa1ef0 2967 if (conn_handle == m_connection_table[index].conn_handle)
Jonathan Austin 0:bc2961fa1ef0 2968 {
Jonathan Austin 0:bc2961fa1ef0 2969 p_handle->connection_id = index;
Jonathan Austin 0:bc2961fa1ef0 2970 p_handle->device_id = m_connection_table[index].bonded_dev_id;
Jonathan Austin 0:bc2961fa1ef0 2971
Jonathan Austin 0:bc2961fa1ef0 2972 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2973 break;
Jonathan Austin 0:bc2961fa1ef0 2974 }
Jonathan Austin 0:bc2961fa1ef0 2975 }
Jonathan Austin 0:bc2961fa1ef0 2976 return err_code;
LancasterUniversity 3:ae5e20530aa5 2977 }