cvb

Fork of nrf51-sdk by Lancaster University

Committer:
LancasterUniversity
Date:
Wed Apr 06 23:55:25 2016 +0100
Revision:
4:ee5f0a37316e
Parent:
3:ae5e20530aa5
Child:
5:f2faa0f0b8f0
Synchronized with git rev 62ad4f4e
Author: James Devine
nrf51-sdk : rough first draft of working BLE STACK

added correct IRK matching which softdevice doesn't do correctly.

Fixed whitelisting from adding IRK and Address.

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 4:ee5f0a37316e 724 printf("[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 4:ee5f0a37316e 726 printf("[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 4:ee5f0a37316e 749 printf("[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 4:ee5f0a37316e 807 printf("[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 4:ee5f0a37316e 818 printf("[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 4:ee5f0a37316e 820 printf("[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 4:ee5f0a37316e 881 printf("[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 4:ee5f0a37316e 887 printf("[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 4:ee5f0a37316e 892 printf("[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 4:ee5f0a37316e 907 printf("[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 4:ee5f0a37316e 911 printf("[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 4:ee5f0a37316e 962 printf("[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 4:ee5f0a37316e 969 printf("[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 4:ee5f0a37316e 976 printf("[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 4:ee5f0a37316e 1718 printf(
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 4:ee5f0a37316e 1730 printf("[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 4:ee5f0a37316e 1733 printf("[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 4:ee5f0a37316e 1746 printf("[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
LancasterUniversity 4:ee5f0a37316e 1766 uint32_t irkCount = 0;
LancasterUniversity 4:ee5f0a37316e 1767
LancasterUniversity 4:ee5f0a37316e 1768 for (uint32_t index = DEVICE_MANAGER_MAX_BONDS; index > 0; index--)
LancasterUniversity 4:ee5f0a37316e 1769 if((m_peer_table[index].id_bitmap & IRK_ENTRY) == 0 && (m_peer_table[index].id_bitmap & ADDR_ENTRY) == 1)
LancasterUniversity 4:ee5f0a37316e 1770 {
LancasterUniversity 4:ee5f0a37316e 1771 printf("[0x%02X]Index %d is an IRK, placing %d\r\n", m_peer_table[index].id_bitmap,index,irkCount);
LancasterUniversity 4:ee5f0a37316e 1772 m_irk_index_table[irkCount] = index;
LancasterUniversity 4:ee5f0a37316e 1773 irkCount++;
LancasterUniversity 4:ee5f0a37316e 1774 }
LancasterUniversity 4:ee5f0a37316e 1775
Jonathan Austin 0:bc2961fa1ef0 1776 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1777
Jonathan Austin 0:bc2961fa1ef0 1778 DM_TRC("[DM]: << dm_init.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1779
Jonathan Austin 0:bc2961fa1ef0 1780 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1781 }
Jonathan Austin 0:bc2961fa1ef0 1782
Jonathan Austin 0:bc2961fa1ef0 1783
Jonathan Austin 0:bc2961fa1ef0 1784 ret_code_t dm_register(dm_application_instance_t * p_appl_instance,
Jonathan Austin 0:bc2961fa1ef0 1785 dm_application_param_t const * p_appl_param)
Jonathan Austin 0:bc2961fa1ef0 1786 {
Jonathan Austin 0:bc2961fa1ef0 1787 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1788 NULL_PARAM_CHECK(p_appl_instance);
Jonathan Austin 0:bc2961fa1ef0 1789 NULL_PARAM_CHECK(p_appl_param);
Jonathan Austin 0:bc2961fa1ef0 1790 NULL_PARAM_CHECK(p_appl_param->evt_handler);
Jonathan Austin 0:bc2961fa1ef0 1791
Jonathan Austin 0:bc2961fa1ef0 1792 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1793
Jonathan Austin 0:bc2961fa1ef0 1794 DM_LOG("[DM]: >> dm_register.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1795
Jonathan Austin 0:bc2961fa1ef0 1796 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 1797
Jonathan Austin 0:bc2961fa1ef0 1798 //Verify if an application instance is available. Currently only one instance is supported.
Jonathan Austin 0:bc2961fa1ef0 1799 if (m_application_table[0].ntf_cb == NULL)
Jonathan Austin 0:bc2961fa1ef0 1800 {
Jonathan Austin 0:bc2961fa1ef0 1801 DM_LOG("[DM]: Application Instance allocated.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1802
Jonathan Austin 0:bc2961fa1ef0 1803 //Mark instance as allocated.
Jonathan Austin 0:bc2961fa1ef0 1804 m_application_table[0].ntf_cb = p_appl_param->evt_handler;
Jonathan Austin 0:bc2961fa1ef0 1805 m_application_table[0].sec_param = p_appl_param->sec_param;
Jonathan Austin 0:bc2961fa1ef0 1806 m_application_table[0].service = p_appl_param->service_type;
Jonathan Austin 0:bc2961fa1ef0 1807
Jonathan Austin 0:bc2961fa1ef0 1808 m_application_table[0].sec_param.kdist_central.enc = 0;
Jonathan Austin 0:bc2961fa1ef0 1809 m_application_table[0].sec_param.kdist_central.id = 1;
Jonathan Austin 0:bc2961fa1ef0 1810 m_application_table[0].sec_param.kdist_central.sign = 0;
Jonathan Austin 0:bc2961fa1ef0 1811 m_application_table[0].sec_param.kdist_periph.enc = 1;
Jonathan Austin 0:bc2961fa1ef0 1812 m_application_table[0].sec_param.kdist_periph.id = 1;
Jonathan Austin 0:bc2961fa1ef0 1813 m_application_table[0].sec_param.kdist_periph.sign = 0;
Jonathan Austin 0:bc2961fa1ef0 1814 //Populate application's instance variable with the assigned allocation instance.
Jonathan Austin 0:bc2961fa1ef0 1815 *p_appl_instance = 0;
Jonathan Austin 0:bc2961fa1ef0 1816 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1817 }
Jonathan Austin 0:bc2961fa1ef0 1818 else
Jonathan Austin 0:bc2961fa1ef0 1819 {
Jonathan Austin 0:bc2961fa1ef0 1820 err_code = (NRF_ERROR_NO_MEM | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 1821 }
Jonathan Austin 0:bc2961fa1ef0 1822
Jonathan Austin 0:bc2961fa1ef0 1823 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1824
Jonathan Austin 0:bc2961fa1ef0 1825 DM_TRC("[DM]: << dm_register.\r\n");
Jonathan Austin 0:bc2961fa1ef0 1826
Jonathan Austin 0:bc2961fa1ef0 1827 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1828 }
Jonathan Austin 0:bc2961fa1ef0 1829
Jonathan Austin 0:bc2961fa1ef0 1830
Jonathan Austin 0:bc2961fa1ef0 1831 ret_code_t dm_security_setup_req(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1832 {
Jonathan Austin 0:bc2961fa1ef0 1833 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1834 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1835 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 1836 VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 1837
Jonathan Austin 0:bc2961fa1ef0 1838 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1839
Jonathan Austin 0:bc2961fa1ef0 1840 DM_LOG("[DM]: >> dm_security_setup_req\r\n");
Jonathan Austin 0:bc2961fa1ef0 1841
Jonathan Austin 0:bc2961fa1ef0 1842 uint32_t err_code = (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 1843
Jonathan Austin 0:bc2961fa1ef0 1844 if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == STATE_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 1845 {
Jonathan Austin 0:bc2961fa1ef0 1846 err_code = sd_ble_gap_authenticate(m_connection_table[p_handle->connection_id].conn_handle,
Jonathan Austin 0:bc2961fa1ef0 1847 &m_application_table[0].sec_param);
Jonathan Austin 0:bc2961fa1ef0 1848 }
Jonathan Austin 0:bc2961fa1ef0 1849
Jonathan Austin 0:bc2961fa1ef0 1850 DM_TRC("[DM]: << dm_security_setup_req, 0x%08X\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 1851
Jonathan Austin 0:bc2961fa1ef0 1852 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1853
Jonathan Austin 0:bc2961fa1ef0 1854 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1855 }
Jonathan Austin 0:bc2961fa1ef0 1856
Jonathan Austin 0:bc2961fa1ef0 1857
Jonathan Austin 0:bc2961fa1ef0 1858 ret_code_t dm_security_status_req(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 1859 dm_security_status_t * p_status)
Jonathan Austin 0:bc2961fa1ef0 1860 {
Jonathan Austin 0:bc2961fa1ef0 1861 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1862 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1863 NULL_PARAM_CHECK(p_status);
Jonathan Austin 0:bc2961fa1ef0 1864 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 1865 VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 1866
Jonathan Austin 0:bc2961fa1ef0 1867 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1868
Jonathan Austin 0:bc2961fa1ef0 1869 DM_LOG("[DM]: >> dm_security_status_req\r\n");
Jonathan Austin 0:bc2961fa1ef0 1870
Jonathan Austin 0:bc2961fa1ef0 1871 if ((m_connection_table[p_handle->connection_id].state & STATE_PAIRING) ||
Jonathan Austin 0:bc2961fa1ef0 1872 (m_connection_table[p_handle->connection_id].state & STATE_PAIRING_PENDING))
Jonathan Austin 0:bc2961fa1ef0 1873 {
Jonathan Austin 0:bc2961fa1ef0 1874 (*p_status) = ENCRYPTION_IN_PROGRESS;
Jonathan Austin 0:bc2961fa1ef0 1875 }
Jonathan Austin 0:bc2961fa1ef0 1876 else if (m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED)
Jonathan Austin 0:bc2961fa1ef0 1877 {
Jonathan Austin 0:bc2961fa1ef0 1878 (*p_status) = ENCRYPTED;
Jonathan Austin 0:bc2961fa1ef0 1879 }
Jonathan Austin 0:bc2961fa1ef0 1880 else
Jonathan Austin 0:bc2961fa1ef0 1881 {
Jonathan Austin 0:bc2961fa1ef0 1882 (*p_status) = NOT_ENCRYPTED;
Jonathan Austin 0:bc2961fa1ef0 1883 }
Jonathan Austin 0:bc2961fa1ef0 1884
Jonathan Austin 0:bc2961fa1ef0 1885 DM_TRC("[DM]: << dm_security_status_req\r\n");
Jonathan Austin 0:bc2961fa1ef0 1886
Jonathan Austin 0:bc2961fa1ef0 1887 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1888
Jonathan Austin 0:bc2961fa1ef0 1889 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1890 }
Jonathan Austin 0:bc2961fa1ef0 1891
Jonathan Austin 0:bc2961fa1ef0 1892
Jonathan Austin 0:bc2961fa1ef0 1893 ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 1894 ble_gap_whitelist_t * p_whitelist)
Jonathan Austin 0:bc2961fa1ef0 1895 {
Jonathan Austin 0:bc2961fa1ef0 1896 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1897 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1898 NULL_PARAM_CHECK(p_whitelist);
Jonathan Austin 0:bc2961fa1ef0 1899 NULL_PARAM_CHECK(p_whitelist->pp_addrs);
Jonathan Austin 0:bc2961fa1ef0 1900 NULL_PARAM_CHECK(p_whitelist->pp_irks);
Jonathan Austin 0:bc2961fa1ef0 1901 VERIFY_APP_REGISTERED(*p_handle);
Jonathan Austin 0:bc2961fa1ef0 1902
Jonathan Austin 0:bc2961fa1ef0 1903 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1904
Jonathan Austin 0:bc2961fa1ef0 1905 DM_LOG("[DM]: >> dm_whitelist_create\r\n");
Jonathan Austin 0:bc2961fa1ef0 1906
Jonathan Austin 0:bc2961fa1ef0 1907 uint32_t addr_count = 0;
Jonathan Austin 0:bc2961fa1ef0 1908 uint32_t irk_count = 0;
Jonathan Austin 0:bc2961fa1ef0 1909 bool connected = false;
Jonathan Austin 0:bc2961fa1ef0 1910
Jonathan Austin 0:bc2961fa1ef0 1911 for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 1912 {
Jonathan Austin 0:bc2961fa1ef0 1913 connected = false;
Jonathan Austin 0:bc2961fa1ef0 1914
Jonathan Austin 0:bc2961fa1ef0 1915 for (uint32_t c_index = 0; c_index < DEVICE_MANAGER_MAX_CONNECTIONS; c_index++)
Jonathan Austin 0:bc2961fa1ef0 1916 {
Jonathan Austin 0:bc2961fa1ef0 1917 if ((index == m_connection_table[c_index].bonded_dev_id) &&
Jonathan Austin 0:bc2961fa1ef0 1918 ((m_connection_table[c_index].state & STATE_CONNECTED) == STATE_CONNECTED))
Jonathan Austin 0:bc2961fa1ef0 1919 {
Jonathan Austin 0:bc2961fa1ef0 1920 connected = true;
Jonathan Austin 0:bc2961fa1ef0 1921 break;
Jonathan Austin 0:bc2961fa1ef0 1922 }
Jonathan Austin 0:bc2961fa1ef0 1923 }
Jonathan Austin 0:bc2961fa1ef0 1924
Jonathan Austin 0:bc2961fa1ef0 1925 if (connected == false)
Jonathan Austin 0:bc2961fa1ef0 1926 {
LancasterUniversity 4:ee5f0a37316e 1927 printf("irkentry %d addrentry %d", (m_peer_table[index].id_bitmap & IRK_ENTRY), (m_peer_table[index].id_bitmap & ADDR_ENTRY));
Jonathan Austin 0:bc2961fa1ef0 1928 if ((irk_count < p_whitelist->irk_count) &&
LancasterUniversity 4:ee5f0a37316e 1929 ((m_peer_table[index].id_bitmap & IRK_ENTRY) == 0) && (m_peer_table[index].id_bitmap & ADDR_ENTRY) != 0)
Jonathan Austin 0:bc2961fa1ef0 1930 {
Jonathan Austin 0:bc2961fa1ef0 1931 p_whitelist->pp_irks[irk_count] = &m_peer_table[index].peer_id.id_info;
Jonathan Austin 0:bc2961fa1ef0 1932 m_irk_index_table[irk_count] = index;
Jonathan Austin 0:bc2961fa1ef0 1933 irk_count++;
Jonathan Austin 0:bc2961fa1ef0 1934 }
Jonathan Austin 0:bc2961fa1ef0 1935
Jonathan Austin 0:bc2961fa1ef0 1936 if ((addr_count < p_whitelist->addr_count) &&
Jonathan Austin 0:bc2961fa1ef0 1937 (m_peer_table[index].id_bitmap & ADDR_ENTRY) == 0)
Jonathan Austin 0:bc2961fa1ef0 1938 {
Jonathan Austin 0:bc2961fa1ef0 1939 p_whitelist->pp_addrs[addr_count] = &m_peer_table[index].peer_id.id_addr_info;
Jonathan Austin 0:bc2961fa1ef0 1940 addr_count++;
Jonathan Austin 0:bc2961fa1ef0 1941 }
Jonathan Austin 0:bc2961fa1ef0 1942 }
Jonathan Austin 0:bc2961fa1ef0 1943 }
Jonathan Austin 0:bc2961fa1ef0 1944
Jonathan Austin 0:bc2961fa1ef0 1945 p_whitelist->addr_count = addr_count;
Jonathan Austin 0:bc2961fa1ef0 1946 p_whitelist->irk_count = irk_count;
Jonathan Austin 0:bc2961fa1ef0 1947
LancasterUniversity 4:ee5f0a37316e 1948 printf("[DM]: Created whitelist, number of IRK = 0x%02X, number of addr = 0x%02X\r\n",
Jonathan Austin 0:bc2961fa1ef0 1949 irk_count,
Jonathan Austin 0:bc2961fa1ef0 1950 addr_count);
Jonathan Austin 0:bc2961fa1ef0 1951
Jonathan Austin 0:bc2961fa1ef0 1952 DM_TRC("[DM]: << dm_whitelist_create\r\n");
Jonathan Austin 0:bc2961fa1ef0 1953
Jonathan Austin 0:bc2961fa1ef0 1954 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1955
Jonathan Austin 0:bc2961fa1ef0 1956 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 1957 }
Jonathan Austin 0:bc2961fa1ef0 1958
Jonathan Austin 0:bc2961fa1ef0 1959
Jonathan Austin 0:bc2961fa1ef0 1960 ret_code_t dm_device_add(dm_handle_t * p_handle,
Jonathan Austin 0:bc2961fa1ef0 1961 dm_device_context_t const * p_context)
Jonathan Austin 0:bc2961fa1ef0 1962 {
Jonathan Austin 0:bc2961fa1ef0 1963 return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 1964 }
Jonathan Austin 0:bc2961fa1ef0 1965
Jonathan Austin 0:bc2961fa1ef0 1966
Jonathan Austin 0:bc2961fa1ef0 1967 ret_code_t dm_device_delete(dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1968 {
Jonathan Austin 0:bc2961fa1ef0 1969 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1970 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1971 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 1972 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1973
Jonathan Austin 0:bc2961fa1ef0 1974 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1975
Jonathan Austin 0:bc2961fa1ef0 1976 DM_TRC("[DM]: >> dm_device_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 1977
Jonathan Austin 0:bc2961fa1ef0 1978 uint32_t err_code = device_instance_free(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 1979
Jonathan Austin 0:bc2961fa1ef0 1980 DM_TRC("[DM]: << dm_device_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 1981
Jonathan Austin 0:bc2961fa1ef0 1982 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 1983
Jonathan Austin 0:bc2961fa1ef0 1984 return err_code;
Jonathan Austin 0:bc2961fa1ef0 1985 }
Jonathan Austin 0:bc2961fa1ef0 1986
Jonathan Austin 0:bc2961fa1ef0 1987
Jonathan Austin 0:bc2961fa1ef0 1988 ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 1989 {
Jonathan Austin 0:bc2961fa1ef0 1990 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 1991 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 1992 VERIFY_APP_REGISTERED((*p_handle));
Jonathan Austin 0:bc2961fa1ef0 1993
Jonathan Austin 0:bc2961fa1ef0 1994 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 1995
Jonathan Austin 0:bc2961fa1ef0 1996 uint32_t err_code = NRF_SUCCESS;
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 for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
Jonathan Austin 0:bc2961fa1ef0 2001 {
Jonathan Austin 0:bc2961fa1ef0 2002 if (m_peer_table[index].id_bitmap != UNASSIGNED)
Jonathan Austin 0:bc2961fa1ef0 2003 {
Jonathan Austin 0:bc2961fa1ef0 2004 err_code = device_instance_free(index);
Jonathan Austin 0:bc2961fa1ef0 2005 }
Jonathan Austin 0:bc2961fa1ef0 2006 }
Jonathan Austin 0:bc2961fa1ef0 2007
Jonathan Austin 0:bc2961fa1ef0 2008 DM_TRC("[DM]: << dm_device_delete_all\r\n");
Jonathan Austin 0:bc2961fa1ef0 2009
Jonathan Austin 0:bc2961fa1ef0 2010 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2011
Jonathan Austin 0:bc2961fa1ef0 2012 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2013 }
Jonathan Austin 0:bc2961fa1ef0 2014
Jonathan Austin 0:bc2961fa1ef0 2015
Jonathan Austin 0:bc2961fa1ef0 2016 ret_code_t dm_service_context_set(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2017 dm_service_context_t const * p_context)
Jonathan Austin 0:bc2961fa1ef0 2018 {
Jonathan Austin 0:bc2961fa1ef0 2019 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2020 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2021 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2022 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2023 VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 2024 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2025
Jonathan Austin 0:bc2961fa1ef0 2026 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2027
Jonathan Austin 0:bc2961fa1ef0 2028 DM_TRC("[DM]: >> dm_service_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2029
Jonathan Austin 0:bc2961fa1ef0 2030 if ((p_context->context_data.p_data != NULL) &&
Jonathan Austin 0:bc2961fa1ef0 2031 (
Jonathan Austin 0:bc2961fa1ef0 2032 (p_context->context_data.len != 0) &&
Jonathan Austin 0:bc2961fa1ef0 2033 (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE)
Jonathan Austin 0:bc2961fa1ef0 2034 )
Jonathan Austin 0:bc2961fa1ef0 2035 )
Jonathan Austin 0:bc2961fa1ef0 2036 {
Jonathan Austin 0:bc2961fa1ef0 2037 if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
Jonathan Austin 0:bc2961fa1ef0 2038 {
Jonathan Austin 0:bc2961fa1ef0 2039 memcpy(m_gatts_table[p_handle->connection_id].attributes,
Jonathan Austin 0:bc2961fa1ef0 2040 p_context->context_data.p_data,
Jonathan Austin 0:bc2961fa1ef0 2041 p_context->context_data.len);
Jonathan Austin 0:bc2961fa1ef0 2042 }
Jonathan Austin 0:bc2961fa1ef0 2043 }
Jonathan Austin 0:bc2961fa1ef0 2044
Jonathan Austin 0:bc2961fa1ef0 2045 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2046 uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2047 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2048 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2049
Jonathan Austin 0:bc2961fa1ef0 2050 err_code = m_service_context_store[p_context->service_type](&block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 2051
Jonathan Austin 0:bc2961fa1ef0 2052 DM_TRC("[DM]: << dm_service_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2053
Jonathan Austin 0:bc2961fa1ef0 2054 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2055
Jonathan Austin 0:bc2961fa1ef0 2056 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2057 }
Jonathan Austin 0:bc2961fa1ef0 2058
Jonathan Austin 0:bc2961fa1ef0 2059
Jonathan Austin 0:bc2961fa1ef0 2060 ret_code_t dm_service_context_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2061 dm_service_context_t * p_context)
Jonathan Austin 0:bc2961fa1ef0 2062 {
Jonathan Austin 0:bc2961fa1ef0 2063 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2064 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2065 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2066 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2067 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2068
Jonathan Austin 0:bc2961fa1ef0 2069 if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != STATE_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 2070 {
Jonathan Austin 0:bc2961fa1ef0 2071 DM_TRC("[DM]: Device must be connected to get context. \r\n");
Jonathan Austin 0:bc2961fa1ef0 2072
Jonathan Austin 0:bc2961fa1ef0 2073 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2074 }
Jonathan Austin 0:bc2961fa1ef0 2075
Jonathan Austin 0:bc2961fa1ef0 2076 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2077
Jonathan Austin 0:bc2961fa1ef0 2078 DM_TRC("[DM]: >> dm_service_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2079
Jonathan Austin 0:bc2961fa1ef0 2080 if ((p_context->context_data.p_data == NULL) &&
Jonathan Austin 0:bc2961fa1ef0 2081 (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE))
Jonathan Austin 0:bc2961fa1ef0 2082 {
Jonathan Austin 0:bc2961fa1ef0 2083 if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
Jonathan Austin 0:bc2961fa1ef0 2084 {
Jonathan Austin 0:bc2961fa1ef0 2085 p_context->context_data.p_data = m_gatts_table[p_handle->connection_id].attributes;
Jonathan Austin 0:bc2961fa1ef0 2086 p_context->context_data.len = m_gatts_table[p_handle->connection_id].size;
Jonathan Austin 0:bc2961fa1ef0 2087 }
Jonathan Austin 0:bc2961fa1ef0 2088 }
Jonathan Austin 0:bc2961fa1ef0 2089
Jonathan Austin 0:bc2961fa1ef0 2090 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2091 uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2092 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2093 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2094
Jonathan Austin 0:bc2961fa1ef0 2095 err_code = m_service_context_load[p_context->service_type](&block_handle, p_handle);
Jonathan Austin 0:bc2961fa1ef0 2096
Jonathan Austin 0:bc2961fa1ef0 2097 DM_TRC("[DM]: << dm_service_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2098
Jonathan Austin 0:bc2961fa1ef0 2099 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2100
Jonathan Austin 0:bc2961fa1ef0 2101 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2102 }
Jonathan Austin 0:bc2961fa1ef0 2103
Jonathan Austin 0:bc2961fa1ef0 2104
Jonathan Austin 0:bc2961fa1ef0 2105 ret_code_t dm_service_context_delete(dm_handle_t const * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2106 {
Jonathan Austin 0:bc2961fa1ef0 2107 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2108 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2109 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2110 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2111
Jonathan Austin 0:bc2961fa1ef0 2112 DM_LOG("[DM]: Context delete is not supported yet.\r\n");
Jonathan Austin 0:bc2961fa1ef0 2113
Jonathan Austin 0:bc2961fa1ef0 2114 return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2115 }
Jonathan Austin 0:bc2961fa1ef0 2116
Jonathan Austin 0:bc2961fa1ef0 2117
Jonathan Austin 0:bc2961fa1ef0 2118 ret_code_t dm_application_context_set(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2119 dm_application_context_t const * p_context)
Jonathan Austin 0:bc2961fa1ef0 2120 {
Jonathan Austin 0:bc2961fa1ef0 2121 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 2122 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2123 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2124 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2125 NULL_PARAM_CHECK(p_context->p_data);
Jonathan Austin 0:bc2961fa1ef0 2126 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2127 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2128 VERIFY_DEVICE_BOND(p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 2129 SIZE_CHECK_APP_CONTEXT(p_context->len);
Jonathan Austin 0:bc2961fa1ef0 2130
Jonathan Austin 0:bc2961fa1ef0 2131 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2132
Jonathan Austin 0:bc2961fa1ef0 2133 DM_TRC("[DM]: >> dm_application_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2134
Jonathan Austin 0:bc2961fa1ef0 2135 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2136 uint32_t context_len;
Jonathan Austin 0:bc2961fa1ef0 2137 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2138
Jonathan Austin 0:bc2961fa1ef0 2139 storage_operation store_fn = pstorage_store;
Jonathan Austin 0:bc2961fa1ef0 2140
Jonathan Austin 0:bc2961fa1ef0 2141 err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2142 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2143 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2144
Jonathan Austin 0:bc2961fa1ef0 2145 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2146 {
Jonathan Austin 0:bc2961fa1ef0 2147 err_code = pstorage_load((uint8_t *)&context_len,
Jonathan Austin 0:bc2961fa1ef0 2148 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2149 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2150 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2151
Jonathan Austin 0:bc2961fa1ef0 2152 if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
Jonathan Austin 0:bc2961fa1ef0 2153 {
Jonathan Austin 0:bc2961fa1ef0 2154 //Data already exists. Need an update.
Jonathan Austin 0:bc2961fa1ef0 2155 store_fn = pstorage_update;
Jonathan Austin 0:bc2961fa1ef0 2156
Jonathan Austin 0:bc2961fa1ef0 2157 DM_LOG("[DM]:[DI 0x%02X]: Updating existing application context, existing len 0x%08X, "
Jonathan Austin 0:bc2961fa1ef0 2158 "new length 0x%08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2159 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2160 context_len,
Jonathan Austin 0:bc2961fa1ef0 2161 p_context->len);
Jonathan Austin 0:bc2961fa1ef0 2162 }
Jonathan Austin 0:bc2961fa1ef0 2163 else
Jonathan Austin 0:bc2961fa1ef0 2164 {
Jonathan Austin 0:bc2961fa1ef0 2165 DM_LOG("[DM]: Storing application context.\r\n");
Jonathan Austin 0:bc2961fa1ef0 2166 }
Jonathan Austin 0:bc2961fa1ef0 2167
Jonathan Austin 0:bc2961fa1ef0 2168 //Store/update context length.
Jonathan Austin 0:bc2961fa1ef0 2169 err_code = store_fn(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 2170 (uint8_t *)(&p_context->len),
Jonathan Austin 0:bc2961fa1ef0 2171 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2172 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2173
Jonathan Austin 0:bc2961fa1ef0 2174 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2175 {
Jonathan Austin 0:bc2961fa1ef0 2176 //Update context data is used for application context as flash is never
Jonathan Austin 0:bc2961fa1ef0 2177 //cleared if a delete of application context is called.
Jonathan Austin 0:bc2961fa1ef0 2178 err_code = pstorage_update(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 2179 p_context->p_data,
Jonathan Austin 0:bc2961fa1ef0 2180 DEVICE_MANAGER_APP_CONTEXT_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2181 (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
Jonathan Austin 0:bc2961fa1ef0 2182 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2183 {
Jonathan Austin 0:bc2961fa1ef0 2184 m_app_context_table[p_handle->device_id] = p_context->p_data;
Jonathan Austin 0:bc2961fa1ef0 2185 }
Jonathan Austin 0:bc2961fa1ef0 2186 }
Jonathan Austin 0:bc2961fa1ef0 2187 }
Jonathan Austin 0:bc2961fa1ef0 2188
Jonathan Austin 0:bc2961fa1ef0 2189 DM_TRC("[DM]: << dm_application_context_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2190
Jonathan Austin 0:bc2961fa1ef0 2191 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2192
Jonathan Austin 0:bc2961fa1ef0 2193 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2194
Jonathan Austin 0:bc2961fa1ef0 2195 #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2196 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2197 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2198 }
Jonathan Austin 0:bc2961fa1ef0 2199
Jonathan Austin 0:bc2961fa1ef0 2200
Jonathan Austin 0:bc2961fa1ef0 2201 ret_code_t dm_application_context_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2202 dm_application_context_t * p_context)
Jonathan Austin 0:bc2961fa1ef0 2203 {
Jonathan Austin 0:bc2961fa1ef0 2204 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 2205 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2206 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2207 NULL_PARAM_CHECK(p_context);
Jonathan Austin 0:bc2961fa1ef0 2208 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2209 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2210
Jonathan Austin 0:bc2961fa1ef0 2211 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2212
Jonathan Austin 0:bc2961fa1ef0 2213 DM_TRC("[DM]: >> dm_application_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2214
Jonathan Austin 0:bc2961fa1ef0 2215 uint32_t context_len;
Jonathan Austin 0:bc2961fa1ef0 2216 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2217 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2218
Jonathan Austin 0:bc2961fa1ef0 2219 //Check if the context exists.
Jonathan Austin 0:bc2961fa1ef0 2220 if (NULL == p_context->p_data)
Jonathan Austin 0:bc2961fa1ef0 2221 {
Jonathan Austin 0:bc2961fa1ef0 2222 p_context->p_data = m_app_context_table[p_handle->device_id];
Jonathan Austin 0:bc2961fa1ef0 2223 }
Jonathan Austin 0:bc2961fa1ef0 2224 else
Jonathan Austin 0:bc2961fa1ef0 2225 {
Jonathan Austin 0:bc2961fa1ef0 2226 m_app_context_table[p_handle->device_id] = p_context->p_data;
Jonathan Austin 0:bc2961fa1ef0 2227 }
Jonathan Austin 0:bc2961fa1ef0 2228
Jonathan Austin 0:bc2961fa1ef0 2229 err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2230 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2231 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2232
Jonathan Austin 0:bc2961fa1ef0 2233 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2234 {
Jonathan Austin 0:bc2961fa1ef0 2235 err_code = pstorage_load((uint8_t *)&context_len,
Jonathan Austin 0:bc2961fa1ef0 2236 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2237 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2238 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2239
Jonathan Austin 0:bc2961fa1ef0 2240 if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
Jonathan Austin 0:bc2961fa1ef0 2241 {
Jonathan Austin 0:bc2961fa1ef0 2242 err_code = pstorage_load(p_context->p_data,
Jonathan Austin 0:bc2961fa1ef0 2243 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2244 DEVICE_MANAGER_APP_CONTEXT_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2245 (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
Jonathan Austin 0:bc2961fa1ef0 2246 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2247 {
Jonathan Austin 0:bc2961fa1ef0 2248 p_context->len = context_len;
Jonathan Austin 0:bc2961fa1ef0 2249 }
Jonathan Austin 0:bc2961fa1ef0 2250 }
Jonathan Austin 0:bc2961fa1ef0 2251 else
Jonathan Austin 0:bc2961fa1ef0 2252 {
Jonathan Austin 0:bc2961fa1ef0 2253 err_code = DM_NO_APP_CONTEXT;
Jonathan Austin 0:bc2961fa1ef0 2254 }
Jonathan Austin 0:bc2961fa1ef0 2255 }
Jonathan Austin 0:bc2961fa1ef0 2256
Jonathan Austin 0:bc2961fa1ef0 2257 DM_TRC("[DM]: << dm_application_context_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2258
Jonathan Austin 0:bc2961fa1ef0 2259 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2260
Jonathan Austin 0:bc2961fa1ef0 2261 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2262
Jonathan Austin 0:bc2961fa1ef0 2263 #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2264 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2265 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2266 }
Jonathan Austin 0:bc2961fa1ef0 2267
Jonathan Austin 0:bc2961fa1ef0 2268
Jonathan Austin 0:bc2961fa1ef0 2269 ret_code_t dm_application_context_delete(const dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2270 {
Jonathan Austin 0:bc2961fa1ef0 2271 #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
Jonathan Austin 0:bc2961fa1ef0 2272 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2273 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2274 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2275 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2276
Jonathan Austin 0:bc2961fa1ef0 2277 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2278
Jonathan Austin 0:bc2961fa1ef0 2279 DM_TRC("[DM]: >> dm_application_context_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 2280
Jonathan Austin 0:bc2961fa1ef0 2281 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2282 uint32_t context_len;
Jonathan Austin 0:bc2961fa1ef0 2283 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2284
Jonathan Austin 0:bc2961fa1ef0 2285 err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2286 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2287 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2288
Jonathan Austin 0:bc2961fa1ef0 2289 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2290 {
Jonathan Austin 0:bc2961fa1ef0 2291 err_code = pstorage_load((uint8_t *)&context_len,
Jonathan Austin 0:bc2961fa1ef0 2292 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2293 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2294 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2295
Jonathan Austin 0:bc2961fa1ef0 2296 if (context_len != m_context_init_len)
Jonathan Austin 0:bc2961fa1ef0 2297 {
Jonathan Austin 0:bc2961fa1ef0 2298 err_code = pstorage_update(&block_handle,
Jonathan Austin 0:bc2961fa1ef0 2299 (uint8_t *)&m_context_init_len,
Jonathan Austin 0:bc2961fa1ef0 2300 sizeof(uint32_t),
Jonathan Austin 0:bc2961fa1ef0 2301 APP_CONTEXT_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2302
Jonathan Austin 0:bc2961fa1ef0 2303 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2304 {
Jonathan Austin 0:bc2961fa1ef0 2305 DM_ERR("[DM]: Failed to delete application context, reason 0x%08X\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 2306 }
Jonathan Austin 0:bc2961fa1ef0 2307 else
Jonathan Austin 0:bc2961fa1ef0 2308 {
Jonathan Austin 0:bc2961fa1ef0 2309 m_app_context_table[p_handle->device_id] = NULL;
Jonathan Austin 0:bc2961fa1ef0 2310 }
Jonathan Austin 0:bc2961fa1ef0 2311 }
Jonathan Austin 0:bc2961fa1ef0 2312 }
Jonathan Austin 0:bc2961fa1ef0 2313
Jonathan Austin 0:bc2961fa1ef0 2314 DM_TRC("[DM]: << dm_application_context_delete\r\n");
Jonathan Austin 0:bc2961fa1ef0 2315
Jonathan Austin 0:bc2961fa1ef0 2316 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2317
Jonathan Austin 0:bc2961fa1ef0 2318 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2319 #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2320 return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2321 #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
Jonathan Austin 0:bc2961fa1ef0 2322 }
Jonathan Austin 0:bc2961fa1ef0 2323
Jonathan Austin 0:bc2961fa1ef0 2324
Jonathan Austin 0:bc2961fa1ef0 2325 ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance,
Jonathan Austin 0:bc2961fa1ef0 2326 dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2327 {
Jonathan Austin 0:bc2961fa1ef0 2328 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2329 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2330 NULL_PARAM_CHECK(p_appl_instance);
Jonathan Austin 0:bc2961fa1ef0 2331 VERIFY_APP_REGISTERED((*p_appl_instance));
Jonathan Austin 0:bc2961fa1ef0 2332
Jonathan Austin 0:bc2961fa1ef0 2333 p_handle->appl_id = (*p_appl_instance);
Jonathan Austin 0:bc2961fa1ef0 2334
Jonathan Austin 0:bc2961fa1ef0 2335 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2336 }
Jonathan Austin 0:bc2961fa1ef0 2337
Jonathan Austin 0:bc2961fa1ef0 2338
Jonathan Austin 0:bc2961fa1ef0 2339 uint32_t dm_handle_initialize(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2340 {
Jonathan Austin 0:bc2961fa1ef0 2341 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2342
Jonathan Austin 0:bc2961fa1ef0 2343 p_handle->appl_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2344 p_handle->connection_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2345 p_handle->device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2346 p_handle->service_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2347
Jonathan Austin 0:bc2961fa1ef0 2348 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2349 }
Jonathan Austin 0:bc2961fa1ef0 2350
Jonathan Austin 0:bc2961fa1ef0 2351
Jonathan Austin 0:bc2961fa1ef0 2352 ret_code_t dm_peer_addr_set(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2353 ble_gap_addr_t const * p_addr)
Jonathan Austin 0:bc2961fa1ef0 2354 {
Jonathan Austin 0:bc2961fa1ef0 2355 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2356 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2357 NULL_PARAM_CHECK(p_addr);
Jonathan Austin 0:bc2961fa1ef0 2358 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2359 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2360
Jonathan Austin 0:bc2961fa1ef0 2361 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2362
Jonathan Austin 0:bc2961fa1ef0 2363 DM_TRC("[DM]: >> dm_peer_addr_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2364
Jonathan Austin 0:bc2961fa1ef0 2365 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2366
Jonathan Austin 0:bc2961fa1ef0 2367 if ((p_handle->connection_id == DM_INVALID_ID) &&
Jonathan Austin 0:bc2961fa1ef0 2368 (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE))
Jonathan Austin 0:bc2961fa1ef0 2369 {
Jonathan Austin 0:bc2961fa1ef0 2370 m_peer_table[p_handle->device_id].peer_id.id_addr_info = (*p_addr);
Jonathan Austin 0:bc2961fa1ef0 2371 update_status_bit_set(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2372 device_context_store(p_handle, UPDATE_PEER_ADDR);
Jonathan Austin 0:bc2961fa1ef0 2373 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2374 }
Jonathan Austin 0:bc2961fa1ef0 2375 else
Jonathan Austin 0:bc2961fa1ef0 2376 {
Jonathan Austin 0:bc2961fa1ef0 2377 err_code = (NRF_ERROR_INVALID_PARAM | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2378 }
Jonathan Austin 0:bc2961fa1ef0 2379
Jonathan Austin 0:bc2961fa1ef0 2380 DM_TRC("[DM]: << dm_peer_addr_set\r\n");
Jonathan Austin 0:bc2961fa1ef0 2381
Jonathan Austin 0:bc2961fa1ef0 2382 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2383
Jonathan Austin 0:bc2961fa1ef0 2384 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2385 }
Jonathan Austin 0:bc2961fa1ef0 2386
Jonathan Austin 0:bc2961fa1ef0 2387
Jonathan Austin 0:bc2961fa1ef0 2388 ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2389 ble_gap_addr_t * p_addr)
Jonathan Austin 0:bc2961fa1ef0 2390 {
Jonathan Austin 0:bc2961fa1ef0 2391 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2392 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2393 NULL_PARAM_CHECK(p_addr);
Jonathan Austin 0:bc2961fa1ef0 2394 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2395
Jonathan Austin 0:bc2961fa1ef0 2396 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2397
Jonathan Austin 0:bc2961fa1ef0 2398 DM_TRC("[DM]: >> dm_peer_addr_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2399
Jonathan Austin 0:bc2961fa1ef0 2400 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2401
Jonathan Austin 0:bc2961fa1ef0 2402 err_code = (NRF_ERROR_NOT_FOUND | DEVICE_MANAGER_ERR_BASE);
Jonathan Austin 0:bc2961fa1ef0 2403
Jonathan Austin 0:bc2961fa1ef0 2404 if (p_handle->device_id == DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2405 {
Jonathan Austin 0:bc2961fa1ef0 2406 if ((p_handle->connection_id != DM_INVALID_ID) &&
Jonathan Austin 0:bc2961fa1ef0 2407 ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) ==
Jonathan Austin 0:bc2961fa1ef0 2408 STATE_CONNECTED))
Jonathan Austin 0:bc2961fa1ef0 2409 {
Jonathan Austin 0:bc2961fa1ef0 2410 DM_TRC("[DM]:[CI 0x%02X]: Address get for non bonded active connection.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2411 p_handle->connection_id);
Jonathan Austin 0:bc2961fa1ef0 2412
Jonathan Austin 0:bc2961fa1ef0 2413 (*p_addr) = m_connection_table[p_handle->connection_id].peer_addr;
Jonathan Austin 0:bc2961fa1ef0 2414 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2415 }
Jonathan Austin 0:bc2961fa1ef0 2416 }
Jonathan Austin 0:bc2961fa1ef0 2417 else
Jonathan Austin 0:bc2961fa1ef0 2418 {
Jonathan Austin 0:bc2961fa1ef0 2419 if ((m_peer_table[p_handle->device_id].id_bitmap & ADDR_ENTRY) == 0)
Jonathan Austin 0:bc2961fa1ef0 2420 {
Jonathan Austin 0:bc2961fa1ef0 2421 DM_TRC("[DM]:[DI 0x%02X]: Address get for bonded device.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2422 p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2423
Jonathan Austin 0:bc2961fa1ef0 2424 (*p_addr) = m_peer_table[p_handle->device_id].peer_id.id_addr_info;
Jonathan Austin 0:bc2961fa1ef0 2425 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2426 }
Jonathan Austin 0:bc2961fa1ef0 2427 }
Jonathan Austin 0:bc2961fa1ef0 2428
Jonathan Austin 0:bc2961fa1ef0 2429 DM_TRC("[DM]: << dm_peer_addr_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2430
Jonathan Austin 0:bc2961fa1ef0 2431 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2432
Jonathan Austin 0:bc2961fa1ef0 2433 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2434 }
Jonathan Austin 0:bc2961fa1ef0 2435
Jonathan Austin 0:bc2961fa1ef0 2436
Jonathan Austin 0:bc2961fa1ef0 2437 ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle,
Jonathan Austin 0:bc2961fa1ef0 2438 dm_sec_keyset_t * p_key_dist)
Jonathan Austin 0:bc2961fa1ef0 2439 {
Jonathan Austin 0:bc2961fa1ef0 2440 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 2441 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2442 NULL_PARAM_CHECK(p_key_dist);
Jonathan Austin 0:bc2961fa1ef0 2443 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2444 VERIFY_DEVICE_INSTANCE(p_handle->device_id);
Jonathan Austin 0:bc2961fa1ef0 2445
Jonathan Austin 0:bc2961fa1ef0 2446 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2447
Jonathan Austin 0:bc2961fa1ef0 2448 DM_TRC("[DM]: >> dm_distributed_keys_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2449
Jonathan Austin 0:bc2961fa1ef0 2450 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2451 ble_gap_enc_key_t peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2452 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2453
Jonathan Austin 0:bc2961fa1ef0 2454 err_code = NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 2455 p_key_dist->keys_central.enc_key.p_enc_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2456 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 2457 p_key_dist->keys_central.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2458 p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info;
Jonathan Austin 0:bc2961fa1ef0 2459 p_key_dist->keys_periph.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2460 p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2461
Jonathan Austin 0:bc2961fa1ef0 2462 if ((m_peer_table[p_handle->device_id].id_bitmap & IRK_ENTRY) == 0)
Jonathan Austin 0:bc2961fa1ef0 2463 {
Jonathan Austin 0:bc2961fa1ef0 2464 // p_key_dist->keys_periph.p_id_key->id_addr_info.addr_type = INVALID_ADDR_TYPE;
Jonathan Austin 0:bc2961fa1ef0 2465 }
Jonathan Austin 0:bc2961fa1ef0 2466
Jonathan Austin 0:bc2961fa1ef0 2467 err_code = pstorage_block_identifier_get(&m_storage_handle, p_handle->device_id, &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2468 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2469 {
Jonathan Austin 0:bc2961fa1ef0 2470
Jonathan Austin 0:bc2961fa1ef0 2471 err_code = pstorage_load((uint8_t *)&peer_enc_key,
Jonathan Austin 0:bc2961fa1ef0 2472 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2473 BOND_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2474 BOND_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2475
Jonathan Austin 0:bc2961fa1ef0 2476 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2477 {
Jonathan Austin 0:bc2961fa1ef0 2478 p_key_dist->keys_central.enc_key.p_enc_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2479 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 2480 p_key_dist->keys_central.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2481 p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info;
Jonathan Austin 0:bc2961fa1ef0 2482 p_key_dist->keys_periph.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2483 p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2484 }
Jonathan Austin 0:bc2961fa1ef0 2485 }
Jonathan Austin 0:bc2961fa1ef0 2486
Jonathan Austin 0:bc2961fa1ef0 2487 DM_TRC("[DM]: << dm_distributed_keys_get\r\n");
Jonathan Austin 0:bc2961fa1ef0 2488
Jonathan Austin 0:bc2961fa1ef0 2489 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2490
Jonathan Austin 0:bc2961fa1ef0 2491 return err_code;
Jonathan Austin 0:bc2961fa1ef0 2492 }
Jonathan Austin 0:bc2961fa1ef0 2493
Jonathan Austin 0:bc2961fa1ef0 2494
Jonathan Austin 0:bc2961fa1ef0 2495 /**@brief Function for loading bond information for a connection instance.
Jonathan Austin 0:bc2961fa1ef0 2496 */
Jonathan Austin 0:bc2961fa1ef0 2497 void bond_data_load(dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2498 {
Jonathan Austin 0:bc2961fa1ef0 2499 pstorage_handle_t block_handle;
Jonathan Austin 0:bc2961fa1ef0 2500
Jonathan Austin 0:bc2961fa1ef0 2501 uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
Jonathan Austin 0:bc2961fa1ef0 2502 p_handle->device_id,
Jonathan Austin 0:bc2961fa1ef0 2503 &block_handle);
Jonathan Austin 0:bc2961fa1ef0 2504 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2505 {
LancasterUniversity 4:ee5f0a37316e 2506 printf(
Jonathan Austin 0:bc2961fa1ef0 2507 "[DM]:[%02X]:[Block ID 0x%08X]:Loading bond information at %p, size 0x%08X, offset 0x%08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2508 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2509 block_handle.block_id,
Jonathan Austin 0:bc2961fa1ef0 2510 &m_bond_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 2511 BOND_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2512 BOND_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2513
Jonathan Austin 0:bc2961fa1ef0 2514 err_code = pstorage_load((uint8_t *)&m_bond_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 2515 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2516 BOND_SIZE,
Jonathan Austin 0:bc2961fa1ef0 2517 BOND_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2518
Jonathan Austin 0:bc2961fa1ef0 2519 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2520 {
LancasterUniversity 4:ee5f0a37316e 2521 printf("[DM]:[%02X]: Failed to load Bond information, reason %08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2522 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2523 err_code);
Jonathan Austin 0:bc2961fa1ef0 2524 }
Jonathan Austin 0:bc2961fa1ef0 2525
LancasterUniversity 4:ee5f0a37316e 2526 printf(
Jonathan Austin 0:bc2961fa1ef0 2527 "[DM]:[%02X]:Loading service context at %p, size 0x%08X, offset 0x%08X.\r\n",
Jonathan Austin 0:bc2961fa1ef0 2528 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2529 &m_gatts_table[p_handle->connection_id],
Jonathan Austin 0:bc2961fa1ef0 2530 sizeof(dm_gatts_context_t),
Jonathan Austin 0:bc2961fa1ef0 2531 SERVICE_STORAGE_OFFSET);
Jonathan Austin 0:bc2961fa1ef0 2532
Jonathan Austin 0:bc2961fa1ef0 2533 err_code = m_service_context_load[m_application_table[0].service](
Jonathan Austin 0:bc2961fa1ef0 2534 &block_handle,
Jonathan Austin 0:bc2961fa1ef0 2535 p_handle);
Jonathan Austin 0:bc2961fa1ef0 2536
Jonathan Austin 0:bc2961fa1ef0 2537 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2538 {
LancasterUniversity 4:ee5f0a37316e 2539 printf(
Jonathan Austin 0:bc2961fa1ef0 2540 "[DM]:[%02X]: Failed to load service information, reason %08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2541 p_handle->connection_id,
Jonathan Austin 0:bc2961fa1ef0 2542 err_code);
Jonathan Austin 0:bc2961fa1ef0 2543 }
Jonathan Austin 0:bc2961fa1ef0 2544 }
Jonathan Austin 0:bc2961fa1ef0 2545 else
Jonathan Austin 0:bc2961fa1ef0 2546 {
LancasterUniversity 4:ee5f0a37316e 2547 printf("[DM]:[%02X]: Failed to get block identifier for "
Jonathan Austin 0:bc2961fa1ef0 2548 "device %08X, reason %08X.\r\n", p_handle->connection_id, p_handle->device_id, err_code);
Jonathan Austin 0:bc2961fa1ef0 2549 }
Jonathan Austin 0:bc2961fa1ef0 2550 }
Jonathan Austin 0:bc2961fa1ef0 2551
LancasterUniversity 4:ee5f0a37316e 2552 int address_to_device_id(ble_gap_addr_t const * p_addr)
LancasterUniversity 4:ee5f0a37316e 2553 {
LancasterUniversity 4:ee5f0a37316e 2554 for(int peer_iterator = 0; peer_iterator < DEVICE_MANAGER_MAX_BONDS; peer_iterator++)
LancasterUniversity 4:ee5f0a37316e 2555 {
LancasterUniversity 4:ee5f0a37316e 2556 if(im_address_resolve(p_addr, &m_peer_table[peer_iterator].peer_id.id_info))
LancasterUniversity 4:ee5f0a37316e 2557 return peer_iterator;
LancasterUniversity 4:ee5f0a37316e 2558 }
LancasterUniversity 4:ee5f0a37316e 2559
LancasterUniversity 4:ee5f0a37316e 2560 return DM_INVALID_ID;
LancasterUniversity 4:ee5f0a37316e 2561 }
Jonathan Austin 0:bc2961fa1ef0 2562
Jonathan Austin 0:bc2961fa1ef0 2563 void dm_ble_evt_handler(ble_evt_t * p_ble_evt)
Jonathan Austin 0:bc2961fa1ef0 2564 {
Jonathan Austin 0:bc2961fa1ef0 2565 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2566 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 2567 uint32_t device_index = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2568 bool notify_app = false;
Jonathan Austin 0:bc2961fa1ef0 2569 dm_handle_t handle;
Jonathan Austin 0:bc2961fa1ef0 2570 dm_event_t event;
Jonathan Austin 0:bc2961fa1ef0 2571 uint32_t event_result;
Jonathan Austin 0:bc2961fa1ef0 2572 ble_gap_enc_info_t * p_enc_info = NULL;
Jonathan Austin 0:bc2961fa1ef0 2573
Jonathan Austin 0:bc2961fa1ef0 2574 VERIFY_MODULE_INITIALIZED_VOID();
Jonathan Austin 0:bc2961fa1ef0 2575 VERIFY_APP_REGISTERED_VOID(0);
Jonathan Austin 0:bc2961fa1ef0 2576 DM_MUTEX_LOCK();
Jonathan Austin 0:bc2961fa1ef0 2577
Jonathan Austin 0:bc2961fa1ef0 2578 err_code = dm_handle_initialize(&handle);
Jonathan Austin 0:bc2961fa1ef0 2579 APP_ERROR_CHECK(err_code);
Jonathan Austin 0:bc2961fa1ef0 2580
Jonathan Austin 0:bc2961fa1ef0 2581 event_result = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2582 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2583 event.event_param.p_gap_param = &p_ble_evt->evt.gap_evt;
Jonathan Austin 0:bc2961fa1ef0 2584 event.event_paramlen = sizeof(ble_gap_evt_t);
Jonathan Austin 0:bc2961fa1ef0 2585 handle.device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2586 handle.appl_id = 0;
Jonathan Austin 0:bc2961fa1ef0 2587 index = 0x00;
Jonathan Austin 0:bc2961fa1ef0 2588
Jonathan Austin 0:bc2961fa1ef0 2589 if (p_ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED)
Jonathan Austin 0:bc2961fa1ef0 2590 {
Jonathan Austin 0:bc2961fa1ef0 2591 err_code = connection_instance_find(p_ble_evt->evt.gap_evt.conn_handle,
Jonathan Austin 0:bc2961fa1ef0 2592 STATE_CONNECTED,
Jonathan Austin 0:bc2961fa1ef0 2593 &index);
Jonathan Austin 0:bc2961fa1ef0 2594
Jonathan Austin 0:bc2961fa1ef0 2595 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2596 {
Jonathan Austin 0:bc2961fa1ef0 2597 handle.device_id = m_connection_table[index].bonded_dev_id;
Jonathan Austin 0:bc2961fa1ef0 2598 handle.connection_id = index;
Jonathan Austin 0:bc2961fa1ef0 2599 }
Jonathan Austin 0:bc2961fa1ef0 2600 }
Jonathan Austin 0:bc2961fa1ef0 2601
Jonathan Austin 0:bc2961fa1ef0 2602 switch (p_ble_evt->header.evt_id)
Jonathan Austin 0:bc2961fa1ef0 2603 {
Jonathan Austin 0:bc2961fa1ef0 2604 case BLE_GAP_EVT_CONNECTED:
Jonathan Austin 0:bc2961fa1ef0 2605 //Allocate connection instance for a new connection.
Jonathan Austin 0:bc2961fa1ef0 2606 err_code = connection_instance_allocate(&index);
Jonathan Austin 0:bc2961fa1ef0 2607
Jonathan Austin 0:bc2961fa1ef0 2608 //Connection instance is successfully allocated.
Jonathan Austin 0:bc2961fa1ef0 2609 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2610 {
Jonathan Austin 0:bc2961fa1ef0 2611 //Application notification related information.
Jonathan Austin 0:bc2961fa1ef0 2612 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2613 event.event_id = DM_EVT_CONNECTION;
Jonathan Austin 0:bc2961fa1ef0 2614 handle.connection_id = index;
Jonathan Austin 0:bc2961fa1ef0 2615
Jonathan Austin 0:bc2961fa1ef0 2616 m_connection_table[index].conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
Jonathan Austin 0:bc2961fa1ef0 2617 m_connection_table[index].state = STATE_CONNECTED;
Jonathan Austin 0:bc2961fa1ef0 2618 m_connection_table[index].peer_addr =
Jonathan Austin 0:bc2961fa1ef0 2619 p_ble_evt->evt.gap_evt.params.connected.peer_addr;
Jonathan Austin 0:bc2961fa1ef0 2620
LancasterUniversity 4:ee5f0a37316e 2621 if ((device_index = address_to_device_id(&p_ble_evt->evt.gap_evt.params.connected.peer_addr)) != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2622 {
LancasterUniversity 4:ee5f0a37316e 2623 err_code = NRF_SUCCESS;
LancasterUniversity 4:ee5f0a37316e 2624
LancasterUniversity 4:ee5f0a37316e 2625 printf("CONNECT: matched, addr_to_did %d\r\n", device_index);
Jonathan Austin 0:bc2961fa1ef0 2626 }
Jonathan Austin 0:bc2961fa1ef0 2627 else
Jonathan Austin 0:bc2961fa1ef0 2628 {
Jonathan Austin 0:bc2961fa1ef0 2629 //Use the device address to check if the device exists in the bonded device list.
Jonathan Austin 0:bc2961fa1ef0 2630 err_code = device_instance_find(&p_ble_evt->evt.gap_evt.params.connected.peer_addr,
Jonathan Austin 0:bc2961fa1ef0 2631 &device_index, EDIV_INIT_VAL);
LancasterUniversity 4:ee5f0a37316e 2632 printf("CONNECT: not matched, status: %d found manually: %d\r\n", err_code, device_index);
Jonathan Austin 0:bc2961fa1ef0 2633 }
Jonathan Austin 0:bc2961fa1ef0 2634
Jonathan Austin 0:bc2961fa1ef0 2635 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2636 {
LancasterUniversity 4:ee5f0a37316e 2637 printf("CONNECT: SUCCESS!\r\n");
Jonathan Austin 0:bc2961fa1ef0 2638 m_connection_table[index].bonded_dev_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2639 m_connection_table[index].state |= STATE_BONDED;
Jonathan Austin 0:bc2961fa1ef0 2640 handle.device_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2641
Jonathan Austin 0:bc2961fa1ef0 2642 bond_data_load(&handle);
Jonathan Austin 0:bc2961fa1ef0 2643 }
Jonathan Austin 0:bc2961fa1ef0 2644 }
LancasterUniversity 4:ee5f0a37316e 2645
LancasterUniversity 4:ee5f0a37316e 2646 printf("CONNECT: did %d bdid %d\r\n", handle.device_id, m_connection_table[index].bonded_dev_id);
LancasterUniversity 4:ee5f0a37316e 2647
Jonathan Austin 0:bc2961fa1ef0 2648 break;
Jonathan Austin 0:bc2961fa1ef0 2649
Jonathan Austin 0:bc2961fa1ef0 2650 case BLE_GAP_EVT_DISCONNECTED:
Jonathan Austin 0:bc2961fa1ef0 2651 //Disconnection could be peer or self initiated hence disconnecting and connecting
Jonathan Austin 0:bc2961fa1ef0 2652 //both states are permitted, however, connection handle must be known.
LancasterUniversity 4:ee5f0a37316e 2653 printf("[DM]: Disconnect Reason 0x%04X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2654 p_ble_evt->evt.gap_evt.params.disconnected.reason);
Jonathan Austin 0:bc2961fa1ef0 2655
Jonathan Austin 0:bc2961fa1ef0 2656 m_connection_table[index].state &= (~STATE_CONNECTED);
Jonathan Austin 0:bc2961fa1ef0 2657
Jonathan Austin 0:bc2961fa1ef0 2658 if ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED)
Jonathan Austin 0:bc2961fa1ef0 2659 {
Jonathan Austin 0:bc2961fa1ef0 2660 if ((m_connection_table[index].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED)
Jonathan Austin 0:bc2961fa1ef0 2661 {
Jonathan Austin 0:bc2961fa1ef0 2662 //Write bond information persistently.
Jonathan Austin 0:bc2961fa1ef0 2663 device_context_store(&handle, STORE_ALL_CONTEXT);
Jonathan Austin 0:bc2961fa1ef0 2664 }
Jonathan Austin 0:bc2961fa1ef0 2665 }
Jonathan Austin 0:bc2961fa1ef0 2666 else
Jonathan Austin 0:bc2961fa1ef0 2667 {
Jonathan Austin 0:bc2961fa1ef0 2668 //Free any allocated instances for devices that is not bonded.
Jonathan Austin 0:bc2961fa1ef0 2669 if (handle.device_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2670 {
Jonathan Austin 0:bc2961fa1ef0 2671 peer_instance_init(handle.device_id);
Jonathan Austin 0:bc2961fa1ef0 2672 handle.device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2673 }
Jonathan Austin 0:bc2961fa1ef0 2674 }
Jonathan Austin 0:bc2961fa1ef0 2675
Jonathan Austin 0:bc2961fa1ef0 2676 m_connection_table[index].state = STATE_DISCONNECTING;
Jonathan Austin 0:bc2961fa1ef0 2677 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2678 event.event_id = DM_EVT_DISCONNECTION;
Jonathan Austin 0:bc2961fa1ef0 2679
Jonathan Austin 0:bc2961fa1ef0 2680 break;
Jonathan Austin 0:bc2961fa1ef0 2681
Jonathan Austin 0:bc2961fa1ef0 2682 case BLE_GAP_EVT_SEC_INFO_REQUEST:
LancasterUniversity 4:ee5f0a37316e 2683 printf("[DM]: >> BLE_GAP_EVT_SEC_INFO_REQUEST\r\n");
Jonathan Austin 0:bc2961fa1ef0 2684
Jonathan Austin 0:bc2961fa1ef0 2685 //If the device is already bonded, respond with existing info, else NULL.
Jonathan Austin 0:bc2961fa1ef0 2686 if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2687 {
LancasterUniversity 4:ee5f0a37316e 2688 printf("INVALID ID \r\n");
LancasterUniversity 4:ee5f0a37316e 2689
Jonathan Austin 0:bc2961fa1ef0 2690 //Find device based on div.
Jonathan Austin 0:bc2961fa1ef0 2691 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 2692 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2693 {
Jonathan Austin 0:bc2961fa1ef0 2694 //Load needed bonding information.
Jonathan Austin 0:bc2961fa1ef0 2695 m_connection_table[index].bonded_dev_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2696 m_connection_table[index].state |= STATE_BONDED;
Jonathan Austin 0:bc2961fa1ef0 2697 handle.device_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2698 bond_data_load(&handle);
Jonathan Austin 0:bc2961fa1ef0 2699 }
Jonathan Austin 0:bc2961fa1ef0 2700 }
Jonathan Austin 0:bc2961fa1ef0 2701
Jonathan Austin 0:bc2961fa1ef0 2702 if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2703 {
LancasterUniversity 4:ee5f0a37316e 2704 printf("VALID ID index %d bdid %d\r\n",index, m_connection_table[index].bonded_dev_id);
Jonathan Austin 0:bc2961fa1ef0 2705 p_enc_info = &m_bond_table[index].peer_enc_key.enc_info;
Jonathan Austin 0:bc2961fa1ef0 2706 DM_DUMP((uint8_t *)p_enc_info, sizeof(ble_gap_enc_info_t));
Jonathan Austin 0:bc2961fa1ef0 2707 }
Jonathan Austin 0:bc2961fa1ef0 2708
Jonathan Austin 0:bc2961fa1ef0 2709 err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle,
Jonathan Austin 0:bc2961fa1ef0 2710 p_enc_info,
Jonathan Austin 0:bc2961fa1ef0 2711 &m_peer_table[index].peer_id.id_info,
Jonathan Austin 0:bc2961fa1ef0 2712 NULL);
Jonathan Austin 0:bc2961fa1ef0 2713
Jonathan Austin 0:bc2961fa1ef0 2714 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2715 {
LancasterUniversity 4:ee5f0a37316e 2716 printf("[DM]:[CI %02X]:[DI %02X]: Security information response failed, reason "
Jonathan Austin 0:bc2961fa1ef0 2717 "0x%08X\r\n", index, m_connection_table[index].bonded_dev_id, err_code);
Jonathan Austin 0:bc2961fa1ef0 2718 }
Jonathan Austin 0:bc2961fa1ef0 2719 break;
Jonathan Austin 0:bc2961fa1ef0 2720
Jonathan Austin 0:bc2961fa1ef0 2721 case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
Jonathan Austin 0:bc2961fa1ef0 2722 DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n");
Jonathan Austin 0:bc2961fa1ef0 2723
LancasterUniversity 4:ee5f0a37316e 2724 printf("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 2725
Jonathan Austin 0:bc2961fa1ef0 2726 event.event_id = DM_EVT_SECURITY_SETUP;
Jonathan Austin 0:bc2961fa1ef0 2727
Jonathan Austin 0:bc2961fa1ef0 2728 m_connection_table[index].state |= STATE_PAIRING;
Jonathan Austin 0:bc2961fa1ef0 2729 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2730
LancasterUniversity 4:ee5f0a37316e 2731 if ((device_index = address_to_device_id(&p_ble_evt->evt.gap_evt.params.connected.peer_addr)) != DM_INVALID_ID)
LancasterUniversity 4:ee5f0a37316e 2732 {
LancasterUniversity 4:ee5f0a37316e 2733 handle.device_id = device_index;
LancasterUniversity 4:ee5f0a37316e 2734 m_connection_table[index].bonded_dev_id = device_index;
LancasterUniversity 4:ee5f0a37316e 2735 err_code = NRF_SUCCESS;
LancasterUniversity 4:ee5f0a37316e 2736
LancasterUniversity 4:ee5f0a37316e 2737 printf("REBONDING bdid %d, did %d, conn %d\r\n",m_connection_table[index].bonded_dev_id, handle.device_id, index);
LancasterUniversity 4:ee5f0a37316e 2738 }
LancasterUniversity 4:ee5f0a37316e 2739
Jonathan Austin 0:bc2961fa1ef0 2740 if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2741 {
LancasterUniversity 4:ee5f0a37316e 2742 printf("allocating new \r\n");
LancasterUniversity 4:ee5f0a37316e 2743
Jonathan Austin 0:bc2961fa1ef0 2744 //Assign a peer index as a new bond or update existing bonds.
Jonathan Austin 0:bc2961fa1ef0 2745 err_code = device_instance_allocate((uint8_t *)&device_index,
Jonathan Austin 0:bc2961fa1ef0 2746 &m_connection_table[index].peer_addr);
Jonathan Austin 0:bc2961fa1ef0 2747
Jonathan Austin 0:bc2961fa1ef0 2748 //Allocation successful.
Jonathan Austin 0:bc2961fa1ef0 2749 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2750 {
LancasterUniversity 4:ee5f0a37316e 2751
LancasterUniversity 4:ee5f0a37316e 2752 printf("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index);
Jonathan Austin 0:bc2961fa1ef0 2753
Jonathan Austin 0:bc2961fa1ef0 2754 handle.device_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2755 m_connection_table[index].bonded_dev_id = device_index;
Jonathan Austin 0:bc2961fa1ef0 2756 }
Jonathan Austin 0:bc2961fa1ef0 2757 else
Jonathan Austin 0:bc2961fa1ef0 2758 {
LancasterUniversity 4:ee5f0a37316e 2759 printf("[DM]: Security parameter request failed, reason 0x%08X.\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 2760 event_result = err_code;
Jonathan Austin 0:bc2961fa1ef0 2761 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2762 }
Jonathan Austin 0:bc2961fa1ef0 2763 }
Jonathan Austin 0:bc2961fa1ef0 2764 else
Jonathan Austin 0:bc2961fa1ef0 2765 {
LancasterUniversity 4:ee5f0a37316e 2766 printf("refresh\r\n");
Jonathan Austin 0:bc2961fa1ef0 2767 //Bond/key refresh.
Jonathan Austin 0:bc2961fa1ef0 2768 event.event_id = DM_EVT_SECURITY_SETUP_REFRESH;
Jonathan Austin 0:bc2961fa1ef0 2769 memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE);
Jonathan Austin 0:bc2961fa1ef0 2770
Jonathan Austin 0:bc2961fa1ef0 2771 //Set the update flag for bond data.
Jonathan Austin 0:bc2961fa1ef0 2772 m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
Jonathan Austin 0:bc2961fa1ef0 2773 }
Jonathan Austin 0:bc2961fa1ef0 2774
LancasterUniversity 4:ee5f0a37316e 2775 printf("FINAL [DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index);
LancasterUniversity 4:ee5f0a37316e 2776
Jonathan Austin 0:bc2961fa1ef0 2777 ble_gap_sec_keyset_t keys_exchanged;
Jonathan Austin 0:bc2961fa1ef0 2778
Jonathan Austin 0:bc2961fa1ef0 2779 DM_LOG("[DM]: 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2780 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.enc,
Jonathan Austin 0:bc2961fa1ef0 2781 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_central.id,
Jonathan Austin 0:bc2961fa1ef0 2782 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.sign,
Jonathan Austin 0:bc2961fa1ef0 2783 p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.bond);
Jonathan Austin 0:bc2961fa1ef0 2784
Jonathan Austin 0:bc2961fa1ef0 2785 keys_exchanged.keys_central.p_enc_key = NULL;
LancasterUniversity 4:ee5f0a37316e 2786 keys_exchanged.keys_central.p_id_key = &m_peer_table[m_connection_table[index].bonded_dev_id].peer_id;
Jonathan Austin 0:bc2961fa1ef0 2787 keys_exchanged.keys_central.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2788 keys_exchanged.keys_periph.p_enc_key = &m_bond_table[index].peer_enc_key;
Jonathan Austin 0:bc2961fa1ef0 2789 keys_exchanged.keys_periph.p_id_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2790 keys_exchanged.keys_periph.p_sign_key = NULL;
Jonathan Austin 0:bc2961fa1ef0 2791
Jonathan Austin 0:bc2961fa1ef0 2792 err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
Jonathan Austin 0:bc2961fa1ef0 2793 BLE_GAP_SEC_STATUS_SUCCESS,
LancasterUniversity 4:ee5f0a37316e 2794 &m_application_table[0].sec_param,
Jonathan Austin 0:bc2961fa1ef0 2795 &keys_exchanged);
Jonathan Austin 0:bc2961fa1ef0 2796
Jonathan Austin 0:bc2961fa1ef0 2797 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2798 {
Jonathan Austin 0:bc2961fa1ef0 2799 DM_LOG("[DM]: Security parameter reply request failed, reason 0x%08X.\r\n", err_code);
Jonathan Austin 0:bc2961fa1ef0 2800 event_result = err_code;
Jonathan Austin 0:bc2961fa1ef0 2801 notify_app = false;
Jonathan Austin 0:bc2961fa1ef0 2802 }
Jonathan Austin 0:bc2961fa1ef0 2803 break;
Jonathan Austin 0:bc2961fa1ef0 2804
Jonathan Austin 0:bc2961fa1ef0 2805 case BLE_GAP_EVT_AUTH_STATUS:
Jonathan Austin 0:bc2961fa1ef0 2806 {
Jonathan Austin 0:bc2961fa1ef0 2807 DM_LOG("[DM]: >> BLE_GAP_EVT_AUTH_STATUS, status %08X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2808 p_ble_evt->evt.gap_evt.params.auth_status.auth_status);
Jonathan Austin 0:bc2961fa1ef0 2809
Jonathan Austin 0:bc2961fa1ef0 2810 m_application_table[0].state &= (~STATE_CONTROL_PROCEDURE_IN_PROGRESS);
Jonathan Austin 0:bc2961fa1ef0 2811 m_connection_table[index].state &= (~STATE_PAIRING);
Jonathan Austin 0:bc2961fa1ef0 2812 event.event_id = DM_EVT_SECURITY_SETUP_COMPLETE;
Jonathan Austin 0:bc2961fa1ef0 2813 notify_app = true;
Jonathan Austin 0:bc2961fa1ef0 2814
Jonathan Austin 0:bc2961fa1ef0 2815 if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status != BLE_GAP_SEC_STATUS_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2816 {
LancasterUniversity 4:ee5f0a37316e 2817 printf("bond failed\r\n");
Jonathan Austin 0:bc2961fa1ef0 2818 // Free the allocation as bonding failed.
Jonathan Austin 0:bc2961fa1ef0 2819 ret_code_t result = device_instance_free(m_connection_table[index].bonded_dev_id);
Jonathan Austin 0:bc2961fa1ef0 2820 (void) result;
Jonathan Austin 0:bc2961fa1ef0 2821 event_result = p_ble_evt->evt.gap_evt.params.auth_status.auth_status;
Jonathan Austin 0:bc2961fa1ef0 2822 }
Jonathan Austin 0:bc2961fa1ef0 2823 else
Jonathan Austin 0:bc2961fa1ef0 2824 {
LancasterUniversity 4:ee5f0a37316e 2825 printf("bonding\r\n");
Jonathan Austin 0:bc2961fa1ef0 2826 DM_DUMP((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status,
Jonathan Austin 0:bc2961fa1ef0 2827 sizeof(ble_gap_evt_auth_status_t));
Jonathan Austin 0:bc2961fa1ef0 2828 DM_DUMP((uint8_t *)&m_bond_table[index], sizeof(bond_context_t));
Jonathan Austin 0:bc2961fa1ef0 2829
Jonathan Austin 0:bc2961fa1ef0 2830 if (p_ble_evt->evt.gap_evt.params.auth_status.bonded == 1)
Jonathan Austin 0:bc2961fa1ef0 2831 {
Jonathan Austin 0:bc2961fa1ef0 2832 if (handle.device_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2833 {
Jonathan Austin 0:bc2961fa1ef0 2834 m_connection_table[index].state |= STATE_BONDED;
Jonathan Austin 0:bc2961fa1ef0 2835
Jonathan Austin 0:bc2961fa1ef0 2836 //IRK and/or public address is shared, update it.
Jonathan Austin 0:bc2961fa1ef0 2837 if (p_ble_evt->evt.gap_evt.params.auth_status.kdist_central.id == 1)
Jonathan Austin 0:bc2961fa1ef0 2838 {
LancasterUniversity 4:ee5f0a37316e 2839 printf("shared\r\n");
Jonathan Austin 0:bc2961fa1ef0 2840 m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 2841 }
Jonathan Austin 0:bc2961fa1ef0 2842
Jonathan Austin 0:bc2961fa1ef0 2843 if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 2844 {
LancasterUniversity 4:ee5f0a37316e 2845 printf("bonded index %d bdid %d\r\n", index,m_connection_table[index].bonded_dev_id);
Jonathan Austin 0:bc2961fa1ef0 2846 DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",
Jonathan Austin 0:bc2961fa1ef0 2847 index,
Jonathan Austin 0:bc2961fa1ef0 2848 handle.device_id);
Jonathan Austin 0:bc2961fa1ef0 2849
Jonathan Austin 0:bc2961fa1ef0 2850 if (m_connection_table[index].peer_addr.addr_type !=
Jonathan Austin 0:bc2961fa1ef0 2851 BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
Jonathan Austin 0:bc2961fa1ef0 2852 {
LancasterUniversity 4:ee5f0a37316e 2853 printf("not RPR\r\n");
LancasterUniversity 4:ee5f0a37316e 2854
Jonathan Austin 0:bc2961fa1ef0 2855 m_peer_table[handle.device_id].peer_id.id_addr_info =
Jonathan Austin 0:bc2961fa1ef0 2856 m_connection_table[index].peer_addr;
Jonathan Austin 0:bc2961fa1ef0 2857 m_peer_table[handle.device_id].id_bitmap &= (~ADDR_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 2858
Jonathan Austin 0:bc2961fa1ef0 2859 DM_DUMP((uint8_t *)&m_peer_table[handle.device_id].peer_id.id_addr_info,
Jonathan Austin 0:bc2961fa1ef0 2860 sizeof(m_peer_table[handle.device_id].peer_id.id_addr_info));
Jonathan Austin 0:bc2961fa1ef0 2861 }
Jonathan Austin 0:bc2961fa1ef0 2862 else
Jonathan Austin 0:bc2961fa1ef0 2863 {
LancasterUniversity 4:ee5f0a37316e 2864 printf("PR\r\n");
Jonathan Austin 0:bc2961fa1ef0 2865 // Here we must fetch the keys from the keyset distributed.
Jonathan Austin 0:bc2961fa1ef0 2866 m_peer_table[handle.device_id].ediv = m_bond_table[index].peer_enc_key.master_id.ediv;
Jonathan Austin 0:bc2961fa1ef0 2867 m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
Jonathan Austin 0:bc2961fa1ef0 2868 }
Jonathan Austin 0:bc2961fa1ef0 2869
Jonathan Austin 0:bc2961fa1ef0 2870 device_context_store(&handle, FIRST_BOND_STORE);
Jonathan Austin 0:bc2961fa1ef0 2871 }
Jonathan Austin 0:bc2961fa1ef0 2872 }
Jonathan Austin 0:bc2961fa1ef0 2873 }
Jonathan Austin 0:bc2961fa1ef0 2874 else
Jonathan Austin 0:bc2961fa1ef0 2875 {
Jonathan Austin 0:bc2961fa1ef0 2876 //Pairing request, no need to touch the bonding info.
Jonathan Austin 0:bc2961fa1ef0 2877 }
Jonathan Austin 0:bc2961fa1ef0 2878 }
Jonathan Austin 0:bc2961fa1ef0 2879 break;
Jonathan Austin 0:bc2961fa1ef0 2880 }
Jonathan Austin 0:bc2961fa1ef0 2881
Jonathan Austin 0:bc2961fa1ef0 2882 case BLE_GAP_EVT_CONN_SEC_UPDATE:
Jonathan Austin 0:bc2961fa1ef0 2883 DM_LOG("[DM]: >> BLE_GAP_EVT_CONN_SEC_UPDATE, Mode 0x%02X, Level 0x%02X\r\n",
Jonathan Austin 0:bc2961fa1ef0 2884 p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm,
Jonathan Austin 0:bc2961fa1ef0 2885 p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv);
Jonathan Austin 0:bc2961fa1ef0 2886
Jonathan Austin 0:bc2961fa1ef0 2887 if ((p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv == 1) &&
Jonathan Austin 0:bc2961fa1ef0 2888 (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm == 1) &&
Jonathan Austin 0:bc2961fa1ef0 2889 ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED))
Jonathan Austin 0:bc2961fa1ef0 2890 {
Jonathan Austin 0:bc2961fa1ef0 2891 //Lost bond case, generate a security refresh event!
Jonathan Austin 0:bc2961fa1ef0 2892 memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE);
LancasterUniversity 4:ee5f0a37316e 2893
Jonathan Austin 0:bc2961fa1ef0 2894 event.event_id = DM_EVT_SECURITY_SETUP_REFRESH;
Jonathan Austin 0:bc2961fa1ef0 2895 m_connection_table[index].state |= STATE_PAIRING_PENDING;
Jonathan Austin 0:bc2961fa1ef0 2896 m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
Jonathan Austin 0:bc2961fa1ef0 2897 m_application_table[0].state |= STATE_QUEUED_CONTROL_REQUEST;
Jonathan Austin 0:bc2961fa1ef0 2898 }
Jonathan Austin 0:bc2961fa1ef0 2899 else
Jonathan Austin 0:bc2961fa1ef0 2900 {
Jonathan Austin 0:bc2961fa1ef0 2901 m_connection_table[index].state |= STATE_LINK_ENCRYPTED;
Jonathan Austin 0:bc2961fa1ef0 2902 event.event_id = DM_EVT_LINK_SECURED;
Jonathan Austin 0:bc2961fa1ef0 2903
Jonathan Austin 0:bc2961fa1ef0 2904 //Apply service context.
Jonathan Austin 0:bc2961fa1ef0 2905 err_code = m_service_context_apply[m_application_table[0].service](&handle);
Jonathan Austin 0:bc2961fa1ef0 2906
Jonathan Austin 0:bc2961fa1ef0 2907 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 2908 {
Jonathan Austin 0:bc2961fa1ef0 2909 DM_ERR("[DM]:[CI 0x%02X]:[DI 0x%02X]: Failed to apply service context\r\n",
LancasterUniversity 4:ee5f0a37316e 2910 handle.connection_id,
Jonathan Austin 0:bc2961fa1ef0 2911 handle.device_id);
Jonathan Austin 0:bc2961fa1ef0 2912
Jonathan Austin 0:bc2961fa1ef0 2913 event_result = DM_SERVICE_CONTEXT_NOT_APPLIED;
Jonathan Austin 0:bc2961fa1ef0 2914 }
Jonathan Austin 0:bc2961fa1ef0 2915 }
Jonathan Austin 0:bc2961fa1ef0 2916 event_result = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2917 notify_app = true;
LancasterUniversity 4:ee5f0a37316e 2918
Jonathan Austin 0:bc2961fa1ef0 2919 break;
Jonathan Austin 0:bc2961fa1ef0 2920
Jonathan Austin 0:bc2961fa1ef0 2921 case BLE_GATTS_EVT_SYS_ATTR_MISSING:
Jonathan Austin 0:bc2961fa1ef0 2922 DM_LOG("[DM]: >> BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n");
Jonathan Austin 0:bc2961fa1ef0 2923
Jonathan Austin 0:bc2961fa1ef0 2924 //Apply service context.
Jonathan Austin 0:bc2961fa1ef0 2925 event_result = m_service_context_apply[m_application_table[0].service](&handle);
Jonathan Austin 0:bc2961fa1ef0 2926 break;
Jonathan Austin 0:bc2961fa1ef0 2927
Jonathan Austin 0:bc2961fa1ef0 2928 case BLE_GAP_EVT_SEC_REQUEST:
Jonathan Austin 0:bc2961fa1ef0 2929 DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_REQUEST\r\n");
LancasterUniversity 4:ee5f0a37316e 2930
Jonathan Austin 0:bc2961fa1ef0 2931 //Verify if the device is already bonded, and if it is bonded, initiate encryption.
LancasterUniversity 4:ee5f0a37316e 2932 //If the device is not bonded, an instance needs to be allocated in order to initiate
LancasterUniversity 4:ee5f0a37316e 2933 //bonding. The application have to initiate the procedure, the module will not do this
Jonathan Austin 0:bc2961fa1ef0 2934 //automatically.
Jonathan Austin 0:bc2961fa1ef0 2935 event.event_id = DM_EVT_SECURITY_SETUP;
Jonathan Austin 0:bc2961fa1ef0 2936 notify_app = true;
LancasterUniversity 4:ee5f0a37316e 2937
Jonathan Austin 0:bc2961fa1ef0 2938 break;
Jonathan Austin 0:bc2961fa1ef0 2939
Jonathan Austin 0:bc2961fa1ef0 2940 default:
Jonathan Austin 0:bc2961fa1ef0 2941 break;
Jonathan Austin 0:bc2961fa1ef0 2942 }
Jonathan Austin 0:bc2961fa1ef0 2943
Jonathan Austin 0:bc2961fa1ef0 2944 if (notify_app)
Jonathan Austin 0:bc2961fa1ef0 2945 {
Jonathan Austin 0:bc2961fa1ef0 2946 app_evt_notify(&handle, &event, event_result);
Jonathan Austin 0:bc2961fa1ef0 2947
Jonathan Austin 0:bc2961fa1ef0 2948 //Freeing the instance after the event is notified so the application can get the context.
Jonathan Austin 0:bc2961fa1ef0 2949 if (event.event_id == DM_EVT_DISCONNECTION)
Jonathan Austin 0:bc2961fa1ef0 2950 {
Jonathan Austin 0:bc2961fa1ef0 2951 //Free the instance.
Jonathan Austin 0:bc2961fa1ef0 2952 connection_instance_free(&index);
Jonathan Austin 0:bc2961fa1ef0 2953 }
Jonathan Austin 0:bc2961fa1ef0 2954 }
Jonathan Austin 0:bc2961fa1ef0 2955
Jonathan Austin 0:bc2961fa1ef0 2956 UNUSED_VARIABLE(err_code);
Jonathan Austin 0:bc2961fa1ef0 2957
Jonathan Austin 0:bc2961fa1ef0 2958 DM_MUTEX_UNLOCK();
Jonathan Austin 0:bc2961fa1ef0 2959 }
Jonathan Austin 0:bc2961fa1ef0 2960
Jonathan Austin 0:bc2961fa1ef0 2961
Jonathan Austin 0:bc2961fa1ef0 2962 ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle)
Jonathan Austin 0:bc2961fa1ef0 2963 {
Jonathan Austin 0:bc2961fa1ef0 2964 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 2965 uint32_t index;
Jonathan Austin 0:bc2961fa1ef0 2966
Jonathan Austin 0:bc2961fa1ef0 2967 NULL_PARAM_CHECK(p_handle);
Jonathan Austin 0:bc2961fa1ef0 2968 VERIFY_APP_REGISTERED(p_handle->appl_id);
Jonathan Austin 0:bc2961fa1ef0 2969
Jonathan Austin 0:bc2961fa1ef0 2970 p_handle->device_id = DM_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 2971
Jonathan Austin 0:bc2961fa1ef0 2972 err_code = NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 2973
Jonathan Austin 0:bc2961fa1ef0 2974 for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
Jonathan Austin 0:bc2961fa1ef0 2975 {
Jonathan Austin 0:bc2961fa1ef0 2976 //Search for matching connection handle.
Jonathan Austin 0:bc2961fa1ef0 2977 if (conn_handle == m_connection_table[index].conn_handle)
Jonathan Austin 0:bc2961fa1ef0 2978 {
Jonathan Austin 0:bc2961fa1ef0 2979 p_handle->connection_id = index;
Jonathan Austin 0:bc2961fa1ef0 2980 p_handle->device_id = m_connection_table[index].bonded_dev_id;
Jonathan Austin 0:bc2961fa1ef0 2981
Jonathan Austin 0:bc2961fa1ef0 2982 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 2983 break;
Jonathan Austin 0:bc2961fa1ef0 2984 }
Jonathan Austin 0:bc2961fa1ef0 2985 }
Jonathan Austin 0:bc2961fa1ef0 2986 return err_code;
LancasterUniversity 3:ae5e20530aa5 2987 }