Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sat Jun 03 00:22:44 2017 +0000
Revision:
46:b156ef445742
Parent:
18:6a4db94011d3
Final code for internal battlebot competition.

Who changed what in which revision?

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