3 * Copyright (c) 2021 Project CHIP Authors
4 * Copyright (c) 2020 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * Provides an implementation for BLE Host NVM functions
25 #include "ble_constants.h"
26 #include "fsl_os_abstraction.h"
27 #include "gap_interface.h"
28 #include "gatt_database.h"
30 #include "gatt_db_dynamic.h"
32 #include "ble_function_mux.h"
34 /*******************************************************************************
36 ******************************************************************************/
37 ble_func_mux_app_mode_t currentMode = kBleFuncMux_AppMode_Ota;
40 * Normal BLE variables.
43 /*! Allocate custom 128-bit UUIDs, if any */
44 #include "gatt_uuid_def_x.h"
46 #include "gatt_db_macros.h"
47 #include "gatt_db_x_macros.h"
49 /*! Allocate the arrays for Attribute Values */
50 #include "gatt_alloc_x.h"
52 /*! Declare the Attribute database */
53 static gattDbAttribute_t static_gattDatabase[] = {
54 #ifndef DOXYGEN_SHOULD_SKIP_THIS
55 #include "gatt_decl_x.h"
59 /*! Declare structure to compute the database size */
60 typedef struct sizeCounterStruct_tag
62 #ifndef DOXYGEN_SHOULD_SKIP_THIS
63 #include "gatt_size_x.h"
65 } sizeCounterStruct_t;
67 /*! *********************************************************************************
68 * BLE Stack Configuration
69 ********************************************************************************** */
70 #define gMaxBondedDevices_c 1
72 /* Security Manager */
73 #define smpEdiv 0x1F99
74 #define mcEncryptionKeySize_c 16
80 bleBondIdentityHeaderBlob_t aBondingHeader;
81 bleBondDataDynamicBlob_t aBondingDataDynamic;
82 bleBondDataStaticBlob_t aBondingDataStatic;
83 bleBondDataDeviceInfoBlob_t aBondingDataDeviceInfo;
84 bleBondDataDescriptorBlob_t aBondingDataDescriptor[gcGapMaximumSavedCccds_c];
87 #if (gMaxBondedDevices_c > 0)
88 static bleBondDeviceEntry bondEntries[gMaxBondedDevices_c];
89 static osaMutexId_t bondingMutex;
93 static uint8_t smpLtk[gcSmpMaxLtkSize_c] = { 0xD6, 0x93, 0xE8, 0xA4, 0x23, 0x55, 0x48, 0x99,
94 0x1D, 0x77, 0x61, 0xE6, 0x63, 0x2B, 0x10, 0x8E };
97 static uint8_t smpRand[gcSmpMaxRandSize_c] = { 0x26, 0x1E, 0xF6, 0x09, 0x97, 0x2E, 0xAD, 0x7E };
100 static uint8_t smpIrk[gcSmpIrkSize_c] = { 0x0A, 0x2D, 0xF4, 0x65, 0xE3, 0xBD, 0x7B, 0x49,
101 0x1E, 0xB4, 0xC0, 0x95, 0x95, 0x13, 0x46, 0x73 };
104 static uint8_t smpCsrk[gcSmpCsrkSize_c] = { 0x90, 0xD5, 0x06, 0x95, 0x92, 0xED, 0x91, 0xD7,
105 0xA8, 0x9E, 0x2C, 0xDC, 0x4A, 0x93, 0x5B, 0xF9 };
107 /*! Compute the database size at compile time */
108 #define localGattDbAttributeCount_d ((sizeof(sizeCounterStruct_t)) / 4U)
110 /* Security Manager */
111 gapSmpKeys_t gSmpKeys = { .cLtkSize = mcEncryptionKeySize_c,
112 .aLtk = (void *) smpLtk,
113 .aIrk = (void *) smpIrk,
114 .aCsrk = (void *) smpCsrk,
115 .aRand = (void *) smpRand,
116 .cRandSize = gcSmpMaxRandSize_c,
118 .addressType = gBleAddrTypePublic_c,
122 * Needed by the BLE stack.
124 gattDbAttribute_t * gattDatabase;
125 uint16_t gGattDbAttributeCount_c;
127 uint16_t GattDb_GetIndexOfHandle(uint16_t handle);
128 void App_NvmInit(void);
129 void App_NvmErase(uint8_t mEntryIdx);
130 void App_NvmRead(uint8_t mEntryIdx, void * pBondHeader, void * pBondDataDynamic, void * pBondDataStatic, void * pBondDataDeviceInfo,
131 void * pBondDataDescriptor, uint8_t mDescriptorIndex);
132 void App_NvmWrite(uint8_t mEntryIdx, void * pBondHeader, void * pBondDataDynamic, void * pBondDataStatic,
133 void * pBondDataDeviceInfo, void * pBondDataDescriptor, uint8_t mDescriptorIndex);
134 /*******************************************************************************
135 * Functions needed by the BLE stack
136 ******************************************************************************/
137 extern bleResult_t GattDb_Init(void)
143 case kBleFuncMux_AppMode_Ota: {
144 static bool_t mAlreadyInit = FALSE;
147 return gBleAlreadyInitialized_c;
151 gGattDbAttributeCount_c = localGattDbAttributeCount_d;
152 gattDatabase = static_gattDatabase;
154 /*! Attribute-specific initialization by X-Macro expansion */
155 #ifndef DOXYGEN_SHOULD_SKIP_THIS
156 #include "gatt_init_x.h"
159 return gBleSuccess_c;
163 return gGattDbInvalidHandle_c;
167 uint16_t GattDb_GetIndexOfHandle(uint16_t handle)
169 uint16_t init = (handle >= gGattDbAttributeCount_c) ? (gGattDbAttributeCount_c - 1) : handle;
170 for (uint16_t j = init; j != 0xFFFF && gattDatabase[j].handle >= handle; j--)
172 if (gattDatabase[j].handle == handle)
177 return gGattDbInvalidHandleIndex_d;
180 void App_NvmInit(void)
182 #if (gMaxBondedDevices_c > 0)
184 /* Init the bonded device list */
187 FLib_MemSet(bondEntries, 0, sizeof(bondEntries));
188 bondingMutex = OSA_MutexCreate();
189 assert(bondingMutex != NULL);
190 for (i = 0; i < gMaxBondedDevices_c; i++)
192 bondEntries[i].pdmId = i;
193 bondEntries[i].nbRamWrite = 0;
199 void App_NvmRead(uint8_t mEntryIdx, void * pBondHeader, void * pBondDataDynamic, void * pBondDataStatic, void * pBondDataDeviceInfo,
200 void * pBondDataDescriptor, uint8_t mDescriptorIndex)
202 #if (gMaxBondedDevices_c > 0)
205 OSA_MutexLock(bondingMutex, osaWaitForever_c);
206 if (mEntryIdx < (uint8_t) gMaxBondedDevices_c)
208 if (pBondHeader != NULL)
210 FLib_MemCpy(pBondHeader, (void *) &bondEntries[mEntryIdx].aBondingHeader,
211 sizeof(bondEntries[mEntryIdx].aBondingHeader));
214 if (pBondDataDynamic != NULL)
216 FLib_MemCpy(pBondDataDynamic, (void *) &bondEntries[mEntryIdx].aBondingDataDynamic,
217 sizeof(bondEntries[mEntryIdx].aBondingDataDynamic));
220 if (pBondDataStatic != NULL)
222 FLib_MemCpy(pBondDataStatic, (void *) &bondEntries[mEntryIdx].aBondingDataStatic,
223 sizeof(bondEntries[mEntryIdx].aBondingDataStatic));
226 if (pBondDataDeviceInfo != NULL)
228 FLib_MemCpy(pBondDataDeviceInfo, (void *) &bondEntries[mEntryIdx].aBondingDataDeviceInfo,
229 sizeof(bondEntries[mEntryIdx].aBondingDataDeviceInfo));
232 if (pBondDataDescriptor != NULL && mDescriptorIndex < gcGapMaximumSavedCccds_c)
234 FLib_MemCpy(pBondDataDescriptor, (void *) &bondEntries[mEntryIdx].aBondingDataDescriptor[mDescriptorIndex],
235 gBleBondDataDescriptorSize_c);
238 OSA_MutexUnlock(bondingMutex);
242 NOT_USED(pBondHeader);
243 NOT_USED(pBondDataDynamic);
244 NOT_USED(pBondDataStatic);
245 NOT_USED(pBondDataDeviceInfo);
246 NOT_USED(pBondDataDescriptor);
247 NOT_USED(mDescriptorIndex);
251 void App_NvmWrite(uint8_t mEntryIdx, void * pBondHeader, void * pBondDataDynamic, void * pBondDataStatic,
252 void * pBondDataDeviceInfo, void * pBondDataDescriptor, uint8_t mDescriptorIndex)
254 #if (gMaxBondedDevices_c > 0)
256 OSA_MutexLock(bondingMutex, osaWaitForever_c);
257 if (mEntryIdx < (uint8_t) gMaxBondedDevices_c)
259 if (pBondHeader != NULL)
261 FLib_MemCpy((void *) &bondEntries[mEntryIdx].aBondingHeader, pBondHeader,
262 sizeof(bondEntries[mEntryIdx].aBondingHeader));
263 bondEntries[mEntryIdx].nbRamWrite++;
266 if (pBondDataDynamic != NULL)
268 FLib_MemCpy((void *) &bondEntries[mEntryIdx].aBondingDataDynamic, pBondDataDynamic,
269 sizeof(bondEntries[mEntryIdx].aBondingDataDynamic));
270 bondEntries[mEntryIdx].nbRamWrite++;
273 if (pBondDataStatic != NULL)
275 FLib_MemCpy((void *) &bondEntries[mEntryIdx].aBondingDataStatic, pBondDataStatic,
276 sizeof(bondEntries[mEntryIdx].aBondingDataStatic));
277 bondEntries[mEntryIdx].nbRamWrite++;
280 if (pBondDataDeviceInfo != NULL)
282 FLib_MemCpy((void *) &bondEntries[mEntryIdx].aBondingDataDeviceInfo, pBondDataDeviceInfo,
283 sizeof(bondEntries[mEntryIdx].aBondingDataDeviceInfo));
284 bondEntries[mEntryIdx].nbRamWrite++;
287 if (pBondDataDescriptor != NULL && mDescriptorIndex < gcGapMaximumSavedCccds_c)
289 FLib_MemCpy((void *) &bondEntries[mEntryIdx].aBondingDataDescriptor[mDescriptorIndex], pBondDataDescriptor,
290 gBleBondDataDescriptorSize_c);
291 bondEntries[mEntryIdx].nbRamWrite++;
294 OSA_MutexUnlock(bondingMutex);
298 NOT_USED(pBondHeader);
299 NOT_USED(pBondDataDynamic);
300 NOT_USED(pBondDataStatic);
301 NOT_USED(pBondDataDeviceInfo);
302 NOT_USED(pBondDataDescriptor);
303 NOT_USED(mDescriptorIndex);
307 void App_NvmErase(uint8_t mEntryIdx)
309 #if (gMaxBondedDevices_c > 0)
311 OSA_MutexLock(bondingMutex, osaWaitForever_c);
312 if (mEntryIdx < (uint8_t) gMaxBondedDevices_c)
314 /* Check if a write is required */
315 if (!FLib_MemCmpToVal(&bondEntries[mEntryIdx].aBondingHeader, 0, sizeof(bondEntries[mEntryIdx].aBondingHeader)) ||
316 !FLib_MemCmpToVal(&bondEntries[mEntryIdx].aBondingDataDynamic, 0,
317 sizeof(bondEntries[mEntryIdx].aBondingDataDynamic)) ||
318 !FLib_MemCmpToVal(&bondEntries[mEntryIdx].aBondingDataStatic, 0,
319 sizeof(bondEntries[mEntryIdx].aBondingDataStatic)) ||
320 !FLib_MemCmpToVal(&bondEntries[mEntryIdx].aBondingDataDeviceInfo, 0,
321 sizeof(bondEntries[mEntryIdx].aBondingDataDeviceInfo)) ||
322 !FLib_MemCmpToVal(&bondEntries[mEntryIdx].aBondingDataDescriptor[0], 0,
323 sizeof(bondEntries[mEntryIdx].aBondingDataDescriptor)))
325 FLib_MemSet(&bondEntries[mEntryIdx].aBondingHeader, 0, sizeof(bondEntries[mEntryIdx].aBondingHeader));
326 FLib_MemSet(&bondEntries[mEntryIdx].aBondingDataDynamic, 0, sizeof(bondEntries[mEntryIdx].aBondingDataDynamic));
327 FLib_MemSet(&bondEntries[mEntryIdx].aBondingDataStatic, 0, sizeof(bondEntries[mEntryIdx].aBondingDataStatic));
328 FLib_MemSet(&bondEntries[mEntryIdx].aBondingDataDeviceInfo, 0,
329 sizeof(bondEntries[mEntryIdx].aBondingDataDeviceInfo));
330 FLib_MemSet(&bondEntries[mEntryIdx].aBondingDataDescriptor[0], 0,
331 sizeof(bondEntries[mEntryIdx].aBondingDataDescriptor));
332 bondEntries[mEntryIdx].nbRamWrite++;
335 OSA_MutexUnlock(bondingMutex);