Nordic Semiconductor / nrf51-sdk

Dependents:   nRF51822 nRF51822

Committer:
vcoubard
Date:
Thu Apr 07 17:38:01 2016 +0100
Revision:
29:286940b7ee5a
Parent:
28:041dac1366b2
Child:
30:7193e01c2913
Synchronized with git rev 22c7454f
Author: Liyou Zhou
Add copyright license headers.

Who changed what in which revision?

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