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