Nordic nrf51 sdk sources. Mirrored from https://github.com/ARMmbed/nrf51-sdk.

Dependents:   nRF51822 nRF51822

Committer:
vcoubard
Date:
Thu Apr 07 17:37:29 2016 +0100
Revision:
11:53378d902308
Parent:
10:233fefd8162b
Child:
19:47192cb9def7
Synchronized with git rev 82b18a5c
Author: Liyou Zhou
Porting some of the changes made to nordic files
from ble-nrf51822 module

Who changed what in which revision?

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