Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / cc13x2_26x2 / BLEManagerImpl.cpp
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    Copyright (c) 2019 Nest Labs, Inc.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  * @file
21  * Provides an implementation of the BLEManager object for cc13xx_cc26xx
22  * platform using the Texas Instruments SDK and the OpenThread stack.
23  */
24 #include <string.h>
25
26 /* this file behaves like a config.h, comes first */
27 #include <platform/internal/CHIPDeviceLayerInternal.h>
28
29 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
30
31 #include <ble/CHIPBleServiceData.h>
32 #include <platform/internal/BLEManager.h>
33
34 #include "FreeRTOS.h"
35 #include <queue.h>
36 #include <task.h>
37
38 /* Include DMM module */
39 #include "chipOBleProfile.h"
40 #include "hal_types.h"
41 #include "ti_dmm_application_policy.h"
42 #include <bcomdef.h>
43 #include <devinfoservice.h>
44 #include <dmm/apps/common/freertos/util.h>
45 #include <dmm/dmm_policy.h>
46 #include <dmm/dmm_priority_ble_thread.h>
47 #include <dmm/dmm_scheduler.h>
48 #include <icall.h>
49 #include <icall_ble_api.h>
50 #include <util.h>
51
52 extern "C" {
53 #include "ti_ble_config.h"
54 #include "ti_drivers_config.h"
55 #ifndef ICALL_FEATURE_SEPARATE_IMGINFO
56 #include <icall_addrs.h>
57 #endif /* ICALL_FEATURE_SEPARATE_IMGINFO */
58 }
59
60 // BLE Manager Debug Logs
61 extern "C" {
62 #ifdef BLEMGR_DBG_LOGGING
63 extern void cc13x2_26x2Log(const char * aFormat, ...);
64 #define BLEMGR_LOG(...) cc13x2_26x2Log(__VA_ARGS__);
65 #else
66 #define BLEMGR_LOG(...)
67 #endif
68 }
69
70 #ifndef USE_DEFAULT_USER_CFG
71 #include "ble_user_config.h"
72 // BLE user defined configuration. Required to be globally accesible for BLE initialization
73 icall_userCfg_t user0Cfg = BLE_USER_CFG;
74 #endif // USE_DEFAULT_USER_CFG
75
76 using namespace ::chip;
77 using namespace ::chip::Ble;
78
79 namespace chip {
80 namespace DeviceLayer {
81 namespace Internal {
82
83 /* Static class member initialization */
84 BLEManagerImpl BLEManagerImpl::sInstance;
85 TaskHandle_t BLEManagerImpl::sBleTaskHndl;
86 ICall_EntityID BLEManagerImpl::sSelfEntity;
87 ICall_SyncHandle BLEManagerImpl::sSyncEvent;
88 QueueHandle_t BLEManagerImpl::sEventHandlerMsgQueueID;
89 chipOBleProfileCBs_t BLEManagerImpl::CHIPoBLEProfile_CBs = {
90     // Provisioning GATT Characteristic value change callback
91     CHIPoBLEProfile_charValueChangeCB
92 };
93
94 // GAP Bond Manager Callbacks
95 gapBondCBs_t BLEManagerImpl::BLEMgr_BondMgrCBs = {
96     PasscodeCb, // Passcode callback
97     PairStateCb // Pairing/Bonding state Callback
98 };
99
100 // ===== Members that implement the BLEManager internal interface.
101 CHIP_ERROR BLEManagerImpl::_Init(void)
102 {
103     CHIP_ERROR err = CHIP_NO_ERROR;
104
105     BLEMGR_LOG("BLEMGR: BLE Initialization Start");
106     // Initialize the CHIP BleLayer.
107     err = BleLayer::Init(this, this, &SystemLayer);
108     if (err != CHIP_NO_ERROR)
109     {
110         return err;
111     }
112
113     /* Register BLE Stack assert handler */
114     RegisterAssertCback(AssertHandler);
115
116     mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART);
117     mFlags.Set(Flags::kFastAdvertisingEnabled, true);
118
119     mServiceMode             = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
120     OnChipBleConnectReceived = HandleIncomingBleConnection;
121
122     err = CreateEventHandler();
123     return err;
124 }
125
126 BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void)
127 {
128     return mServiceMode;
129 }
130
131 CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(BLEManager::CHIPoBLEServiceMode val)
132 {
133     mServiceMode = val;
134
135     /* Trigger state update */
136     return DriveBLEState();
137 }
138
139 bool BLEManagerImpl::_IsAdvertisingEnabled(void)
140 {
141     return mFlags.Has(Flags::kAdvertisingEnabled);
142 }
143
144 /* Post event to app processing loop to begin CHIP advertising */
145 CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
146 {
147     mFlags.Set(Flags::kAdvertisingEnabled, val);
148
149     /* Send event to process state change request */
150     return DriveBLEState();
151 }
152
153 CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
154 {
155     CHIP_ERROR ret = CHIP_NO_ERROR;
156
157     switch (mode)
158     {
159     case BLEAdvertisingMode::kFastAdvertising:
160         mFlags.Set(Flags::kFastAdvertisingEnabled, true);
161         break;
162     case BLEAdvertisingMode::kSlowAdvertising:
163         mFlags.Set(Flags::kFastAdvertisingEnabled, false);
164         break;
165     default:
166         return CHIP_ERROR_INVALID_ARGUMENT;
167     }
168     mFlags.Set(Flags::kAdvertisingRefreshNeeded);
169     ret = DriveBLEState();
170     return ret;
171 }
172
173 bool BLEManagerImpl::_IsAdvertising(void)
174 {
175     return mFlags.Has(Flags::kAdvertising);
176 }
177
178 CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
179 {
180     CHIP_ERROR ret = CHIP_NO_ERROR;
181
182     if (bufSize <= GAP_DEVICE_NAME_LEN)
183     {
184         strncpy(buf, mDeviceName, bufSize);
185     }
186     else
187     {
188         ret = CHIP_ERROR_BUFFER_TOO_SMALL;
189     }
190
191     return ret;
192 }
193
194 CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName)
195 {
196     CHIP_ERROR ret = CHIP_NO_ERROR;
197
198     if (strlen(deviceName) <= GAP_DEVICE_NAME_LEN)
199     {
200         strncpy(mDeviceName, deviceName, strlen(deviceName));
201
202         mFlags.Set(Flags::kBLEStackGATTNameUpdate);
203
204         ret = DriveBLEState();
205     }
206     else
207     {
208         ret = CHIP_ERROR_BUFFER_TOO_SMALL;
209     }
210
211     return ret;
212 }
213
214 uint16_t BLEManagerImpl::_NumConnections(void)
215 {
216     uint8_t i, numConns = 0;
217
218     // Try to find an available entry
219     for (i = 0; i < MAX_NUM_BLE_CONNS; i++)
220     {
221         if (connList[i].connHandle != LL_CONNHANDLE_INVALID)
222         {
223             numConns++;
224         }
225     }
226
227     return numConns;
228 }
229
230 void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
231 {
232     switch (event->Type)
233     {
234     case DeviceEventType::kCHIPoBLESubscribe: {
235         ChipDeviceEvent connEstEvent;
236
237         BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLESubscribe");
238         HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
239
240         connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
241
242         PlatformMgr().PostEvent(&connEstEvent);
243     }
244     break;
245
246     case DeviceEventType::kCHIPoBLEUnsubscribe: {
247         BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLEUnsubscribe");
248         HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
249     }
250     break;
251
252     case DeviceEventType::kCHIPoBLEWriteReceived: {
253         BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLEWriteReceived");
254         HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX,
255                             PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
256     }
257     break;
258
259     case DeviceEventType::kCHIPoBLEIndicateConfirm:
260         HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
261         break;
262
263     case DeviceEventType::kCHIPoBLEConnectionError: {
264         BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLEConnectionError");
265         HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
266     }
267     break;
268
269     default:
270         break;
271     }
272 }
273
274 // ===== Members that implement virtual methods on BlePlatformDelegate.
275 bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
276 {
277     void * pMsg = (void *) ICall_malloc(sizeof(void *));
278     pMsg        = (void *) conId;
279
280     EnqueueEvtHdrMsg(BLEManagerIMPL_CHIPOBLE_CLOSE_CONN_EVT, (void *) pMsg);
281
282     return CHIP_NO_ERROR;
283 }
284
285 uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
286 {
287     uint8_t index;
288     uint16_t mtu = 0;
289
290     index = GetBLEConnIndex(*((uint32_t *) conId));
291
292     if (index != MAX_NUM_BLE_CONNS)
293     {
294         mtu = sInstance.connList[index].mtu;
295         /* Prior to MTU update event, MTU is determined by the below formula */
296         if (mtu == 0)
297         {
298             mtu = MAX_PDU_SIZE - 4;
299         }
300     }
301
302     return mtu;
303 }
304
305 // ===== Members that implement virtual methods on BleApplicationDelegate.
306
307 void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId)
308 {
309     // Unused
310 }
311
312 bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
313                                     PacketBufferHandle data)
314 {
315     BLEMGR_LOG("BLEMGR: BLE SendIndication ");
316
317     // Allocate buffers to send to BLE app task
318     uint8_t dataLen = static_cast<uint8_t>(data->DataLength());
319     CHIPoBLEIndEvt_t * pMsg;
320     uint8_t * pBuf;
321
322     pMsg = (CHIPoBLEIndEvt_t *) ICall_malloc(sizeof(CHIPoBLEIndEvt_t));
323     if (NULL == pMsg)
324     {
325         return false;
326     }
327
328     pBuf = (uint8_t *) ICall_malloc(dataLen);
329     if (NULL == pBuf)
330     {
331         ICall_free((void *) pMsg);
332         return false;
333     }
334
335     memset(pBuf, 0x00, dataLen);
336     memcpy(pBuf, data->Start(), dataLen);
337
338     pMsg->pData = pBuf;
339     pMsg->len   = dataLen;
340
341     EnqueueEvtHdrMsg(BLEManagerIMPL_CHIPOBLE_TX_IND_EVT, (void *) pMsg);
342
343     BLEMGR_LOG("BLEMGR: BLE SendIndication RETURN, Length: %d ", dataLen);
344     return true;
345 }
346
347 bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
348                                              const Ble::ChipBleUUID * charId)
349 {
350     /* Unsupported on TI peripheral device implementation */
351     return false;
352 }
353
354 bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
355                                                const Ble::ChipBleUUID * charId)
356 {
357     /* Unsupported on TI peripheral device implementation */
358     return false;
359 }
360
361 bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
362                                       PacketBufferHandle pBuf)
363 {
364     /* Unsupported on TI peripheral device implementation */
365     return false;
366 }
367
368 bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
369                                      PacketBufferHandle pBuf)
370 {
371     /* Unsupported on TI peripheral device implementation */
372     return false;
373 }
374
375 bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
376                                       const ChipBleUUID * svcId, const ChipBleUUID * charId)
377 {
378     /* Unsupported on TI peripheral device implementation */
379     return false;
380 }
381
382 void BLEManagerImpl::HandleIncomingBleConnection(BLEEndPoint * bleEP)
383 {
384     BLEMGR_LOG("BLEMGR: HandleIncomingBleConnection");
385 }
386
387 // ===== Helper Members that implement the Low level BLE Stack behavior.
388
389 /*********************************************************************
390  * @fn      AdvInit
391  *
392  * @brief   Initialize CHIPoBLE Advertisement.
393  *
394  * @param   pMsg - message to process
395  */
396 void BLEManagerImpl::AdvInit(void)
397 {
398     bStatus_t status = FAILURE;
399     uint16_t deviceDiscriminator;
400     uint8_t localDeviceNameLen;
401     uint8_t scanIndex = 0;
402     uint8_t advIndex  = 0;
403     uint8_t scanResLength;
404     uint8_t advLength;
405     uint8_t * advDatachipOBle;
406     uint8_t * scanResDatachipOBle;
407
408     BLEMGR_LOG("BLEMGR: AdvInit");
409
410     ChipBLEDeviceIdentificationInfo mDeviceIdInfo;
411     ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo);
412
413     // Verify device name was not already set
414     if (!sInstance.mFlags.Has(Flags::kBLEStackGATTNameSet))
415     {
416         /* Default device name is CHIP-<DISCRIMINATOR> */
417         deviceDiscriminator = mDeviceIdInfo.GetDeviceDiscriminator();
418
419         localDeviceNameLen = strlen(CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX) + sizeof(deviceDiscriminator);
420
421         memset(sInstance.mDeviceName, 0, GAP_DEVICE_NAME_LEN);
422         snprintf(sInstance.mDeviceName, GAP_DEVICE_NAME_LEN, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX,
423                  deviceDiscriminator);
424
425         // Set the Device Name characteristic in the GAP GATT Service
426         // For more information, see the section in the User's Guide:
427         // http://software-dl.ti.com/lprf/ble5stack-latest/
428         GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, sInstance.mDeviceName);
429
430         BLEMGR_LOG("BLEMGR: AdvInit New device name set: %s", sInstance.mDeviceName);
431     }
432     else
433     {
434         localDeviceNameLen = strlen(sInstance.mDeviceName);
435     }
436
437     scanResLength = localDeviceNameLen + CHIPOBLE_SCANRES_SIZE_NO_NAME;
438
439     scanResDatachipOBle = (uint8_t *) ICall_malloc(scanResLength);
440
441     scanResDatachipOBle[scanIndex++] = localDeviceNameLen + 1;
442     scanResDatachipOBle[scanIndex++] = GAP_ADTYPE_LOCAL_NAME_COMPLETE;
443     memcpy(&scanResDatachipOBle[scanIndex], sInstance.mDeviceName, localDeviceNameLen);
444     scanIndex += localDeviceNameLen;
445     scanResDatachipOBle[scanIndex++] = 0x03;
446     scanResDatachipOBle[scanIndex++] = GAP_ADTYPE_16BIT_COMPLETE;
447     scanResDatachipOBle[scanIndex++] = static_cast<uint8_t>(LO_UINT16(CHIPOBLE_SERV_UUID));
448     scanResDatachipOBle[scanIndex++] = static_cast<uint8_t>(HI_UINT16(CHIPOBLE_SERV_UUID));
449
450     for (uint8_t temp = 0; temp < scanIndex; temp++)
451     {
452         BLEMGR_LOG("BLEMGR: AdvInit Scan Response Data: %x", scanResDatachipOBle[temp]);
453     }
454
455     advLength       = sizeof(static_cast<uint16_t>(CHIPOBLE_SERV_UUID)) + static_cast<uint8_t>(sizeof(mDeviceIdInfo)) + 1;
456     advDatachipOBle = (uint8_t *) ICall_malloc(CHIPOBLE_ADV_SIZE_NO_DEVICE_ID_INFO + advLength);
457
458     BLEMGR_LOG("BLEMGR: AdvInit: MDeviceIDInfo Size: %d", sizeof(mDeviceIdInfo));
459     BLEMGR_LOG("BLEMGR: AdvInit: advlength: %d", advLength);
460     BLEMGR_LOG("BLEMGR: AdvInit:Desc : %d", mDeviceIdInfo.GetDeviceDiscriminator());
461
462     advDatachipOBle[advIndex++] = 0x02;
463     advDatachipOBle[advIndex++] = GAP_ADTYPE_FLAGS;
464     advDatachipOBle[advIndex++] = GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED | GAP_ADTYPE_FLAGS_GENERAL;
465     advDatachipOBle[advIndex++] = advLength;
466     advDatachipOBle[advIndex++] = GAP_ADTYPE_SERVICE_DATA;
467     advDatachipOBle[advIndex++] = static_cast<uint8_t>(LO_UINT16(CHIPOBLE_SERV_UUID));
468     advDatachipOBle[advIndex++] = static_cast<uint8_t>(HI_UINT16(CHIPOBLE_SERV_UUID));
469     memcpy(&advDatachipOBle[advIndex], (void *) &mDeviceIdInfo, static_cast<uint8_t>(sizeof(mDeviceIdInfo)));
470
471     // Setup and start Advertising
472     // For more information, see the GAP section in the User's Guide:
473     // http://software-dl.ti.com/lprf/ble5stack-latest/
474
475     // Create Advertisement set #1 and assign handle
476     status = (bStatus_t) GapAdv_create(&advCallback, &advParams1, &sInstance.advHandleLegacy);
477     assert(status == SUCCESS);
478
479     // Load advertising data for set #1 that is statically allocated by the app
480     status = (bStatus_t) GapAdv_loadByHandle(sInstance.advHandleLegacy, GAP_ADV_DATA_TYPE_ADV,
481                                              CHIPOBLE_ADV_SIZE_NO_DEVICE_ID_INFO + advLength, advDatachipOBle);
482
483     // Load scan response data for set #1 that is statically allocated by the app
484     status =
485         (bStatus_t) GapAdv_loadByHandle(sInstance.advHandleLegacy, GAP_ADV_DATA_TYPE_SCAN_RSP, scanResLength, scanResDatachipOBle);
486     assert(status == SUCCESS);
487
488     // Set event mask for set #1
489     status = (bStatus_t) GapAdv_setEventMask(sInstance.advHandleLegacy,
490                                              GAP_ADV_EVT_MASK_START_AFTER_ENABLE | GAP_ADV_EVT_MASK_END_AFTER_DISABLE |
491                                                  GAP_ADV_EVT_MASK_SET_TERMINATED);
492
493     Util_constructClock(&sInstance.clkAdvTimeout, AdvTimeoutHandler, ADV_TIMEOUT, 0, false, (uintptr_t) NULL);
494 }
495
496 /*********************************************************************
497  * @fn      EventHandler_init
498  *
499  * @brief   Called during initialization and contains application
500  *          specific initialization (ie. hardware initialization/setup,
501  *          table initialization, power up notification, etc), and
502  *          profile initialization/setup.
503  */
504 void BLEManagerImpl::EventHandler_init(void)
505 {
506     BLEMGR_LOG("BLEMGR: EventHandler_init");
507
508     /* Update User Configuration of the stack */
509     user0Cfg.appServiceInfo->timerTickPeriod     = ICall_getTickPeriod();
510     user0Cfg.appServiceInfo->timerMaxMillisecond = ICall_getMaxMSecs();
511
512     /* Initialize ICall module */
513     ICall_init();
514
515     /* Start tasks of external images */
516     ICall_createRemoteTasks();
517     BLEManagerImpl::sBleTaskHndl = (TaskHandle_t)(*((TaskHandle_t *) ICall_getRemoteTaskHandle(0)));
518     DMMSch_registerClient((TaskHandle_t) BLEManagerImpl::sBleTaskHndl, DMMPolicy_StackRole_BlePeripheral);
519     /* set the stacks in default states */
520     DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_IDLE);
521
522     vTaskPrioritySet(xTaskGetCurrentTaskHandle(), 3);
523
524     // ******************************************************************
525     // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
526     // ******************************************************************
527     // Register the current thread as an ICall dispatcher application
528     // so that the application can send and receive messages.
529     ICall_registerApp(&BLEManagerImpl::sSelfEntity, &BLEManagerImpl::sSyncEvent);
530
531 #ifdef USE_RCOSC
532     RCOSC_enableCalibration();
533 #endif // USE_RCOSC
534
535     // Create an RTOS queue for message from profile to be sent to app.
536     Util_constructQueue(&BLEManagerImpl::sEventHandlerMsgQueueID);
537
538     // Configure GAP
539     {
540         uint16_t paramUpdateDecision = DEFAULT_PARAM_UPDATE_REQ_DECISION;
541
542         // Pass all parameter update requests to the app for it to decide
543         GAP_SetParamValue(GAP_PARAM_LINK_UPDATE_DECISION, paramUpdateDecision);
544     }
545
546     // Setup the GAP Bond Manager. For more information see the GAP Bond Manager
547     // section in the User's Guide:
548     // http://software-dl.ti.com/lprf/ble5stack-latest/
549     setBondManagerParameters();
550
551     // Initialize GATT attributes
552     GGS_AddService(GATT_ALL_SERVICES);         // GAP GATT Service
553     GATTServApp_AddService(GATT_ALL_SERVICES); // GATT Service
554     DevInfo_AddService();                      // Device Information Service
555
556     CHIPoBLEProfile_AddService(GATT_ALL_SERVICES);
557
558     // Start Bond Manager and register callback
559     VOID GAPBondMgr_Register(BLEMgr_BondMgrCBs);
560
561     // Register with GAP for HCI/Host messages. This is needed to receive HCI
562     // events. For more information, see the HCI section in the User's Guide:
563     // http://software-dl.ti.com/lprf/ble5stack-latest/
564     GAP_RegisterForMsgs(BLEManagerImpl::sSelfEntity);
565
566     // Register for GATT local events and ATT Responses pending for transmission
567     GATT_RegisterForMsgs(BLEManagerImpl::sSelfEntity);
568
569     CHIPoBLEProfile_RegisterAppCBs(&CHIPoBLEProfile_CBs);
570     // Set default values for Data Length Extension
571     // Extended Data Length Feature is already enabled by default
572     {
573         // This API is documented in hci.h
574         // See the LE Data Length Extension section in the BLE5-Stack User's Guide for information on using this command:
575         // http://software-dl.ti.com/lprf/ble5stack-latest/
576         HCI_LE_WriteSuggestedDefaultDataLenCmd(BLEMANAGER_SUGGESTED_PDU_SIZE, BLEMANAGER_SUGGESTED_TX_TIME);
577     }
578
579     // Initialize GATT Client
580     GATT_InitClient("");
581
582     // Initialize Connection List
583     ClearBLEConnListEntry(LL_CONNHANDLE_ALL);
584
585     // Initialize GAP layer for Peripheral role and register to receive GAP events
586     GAP_DeviceInit(GAP_PROFILE_PERIPHERAL, BLEManagerImpl::sSelfEntity, sInstance.addrMode, &pRandomAddress);
587
588     // Initialize array to store connection handle and RSSI values
589     InitPHYRSSIArray();
590 }
591
592 /*********************************************************************
593  * @fn      InitPHYRSSIArray
594  *
595  * @brief   Initializes the array of structure/s to store data related
596  *          RSSI based auto PHy change
597  *
598  * @param   connHandle - the connection handle
599  *
600  * @param   addr - pointer to device address
601  *
602  * @return  index of connection handle
603  */
604 void BLEManagerImpl::InitPHYRSSIArray(void)
605 {
606     BLEMGR_LOG("BLEMGR: InitPHYRSSIArray");
607
608     // Initialize array to store connection handle and RSSI values
609     memset(sInstance.connList, 0, sizeof(sInstance.connList));
610
611     for (uint8_t index = 0; index < MAX_NUM_BLE_CONNS; index++)
612     {
613         sInstance.connList[index].connHandle = INVALID_HANDLE;
614     }
615 }
616
617 /*********************************************************************
618  * @fn      CreateEventHandler
619  *
620  * @brief   Create FreeRTOS Task for BLE Event handling
621  *
622  */
623 CHIP_ERROR BLEManagerImpl::CreateEventHandler(void)
624 {
625     BLEMGR_LOG("BLEMGR: CreateEventHandler");
626
627     BaseType_t xReturned;
628
629     /* Create the task, storing the handle. */
630     xReturned = xTaskCreate(EventHandler,            /* Function that implements the task. */
631                             "ble_hndlr",             /* Text name for the task. */
632                             4096 / sizeof(uint32_t), /* Stack size in words, not bytes. */
633                             this,                    /* Parameter passed into the task. */
634                             ICALL_TASK_PRIORITIES,   /* Keep priority the same as ICALL until init is complete */
635                             NULL);                   /* Used to pass out the created task's handle. */
636
637     if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY)
638     {
639         return CHIP_ERROR_NO_MEMORY;
640     }
641     else
642     {
643         return CHIP_NO_ERROR;
644     }
645 }
646
647 /*********************************************************************
648  * @fn      RemoteDisplay_processStackMsg
649  *
650  * @brief   Process an incoming stack message.
651  *
652  * @param   pMsg - message to process
653  *
654  * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
655  */
656 uint8_t BLEManagerImpl::ProcessStackEvent(ICall_Hdr * pMsg)
657 {
658     BLEMGR_LOG("BLEMGR: BLE Process Stack Event");
659
660     // Always dealloc pMsg unless set otherwise
661     uint8_t safeToDealloc = TRUE;
662
663     switch (pMsg->event)
664     {
665     case GAP_MSG_EVENT:
666         ProcessGapMessage((gapEventHdr_t *) pMsg);
667         break;
668
669     case GATT_MSG_EVENT:
670         // Process GATT message
671         safeToDealloc = ProcessGATTMsg((gattMsgEvent_t *) pMsg);
672         break;
673     case HCI_GAP_EVENT_EVENT: {
674         // Process HCI message
675         switch (pMsg->status)
676         {
677         case HCI_COMMAND_COMPLETE_EVENT_CODE:
678             // Process HCI Command Complete Events here
679             {
680                 // RemoteDisplay_processCmdCompleteEvt((hciEvt_CmdComplete_t *) pMsg);
681                 break;
682             }
683         case HCI_BLE_HARDWARE_ERROR_EVENT_CODE:
684             assert(false);
685             break;
686         // HCI Commands Events
687         case HCI_COMMAND_STATUS_EVENT_CODE: {
688             hciEvt_CommandStatus_t * pMyMsg = (hciEvt_CommandStatus_t *) pMsg;
689             switch (pMyMsg->cmdOpcode)
690             {
691             case HCI_LE_SET_PHY: {
692                 if (pMyMsg->cmdStatus == HCI_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE)
693                 {
694                     /* PHY Change failure, peer does not support this */
695                 }
696                 break;
697             }
698             default:
699                 break;
700             }
701             break;
702         }
703
704         case HCI_LE_EVENT_CODE: {
705             hciEvt_BLEPhyUpdateComplete_t * pPUC = (hciEvt_BLEPhyUpdateComplete_t *) pMsg;
706
707             // A Phy Update Has Completed or Failed
708             if (pPUC->BLEEventCode == HCI_BLE_PHY_UPDATE_COMPLETE_EVENT)
709             {
710                 if (pPUC->status != SUCCESS)
711                 {
712                     /* PHY Change failure */
713                 }
714                 else
715                 {
716                     /* PHY Update successfull */
717                 }
718             }
719             break;
720         }
721         default:
722             break;
723         }
724
725         break;
726     }
727
728     default:
729         // do nothing
730         break;
731     }
732
733     return safeToDealloc;
734 }
735
736 /*********************************************************************
737  * @fn      ProcessEvtHdrMsg
738  *
739  * @brief   Process an incoming callback from a profile.
740  *
741  * @param   pMsg - message to process
742  *
743  * @return  None.
744  */
745 void BLEManagerImpl::ProcessEvtHdrMsg(QueuedEvt_t * pMsg)
746 {
747     bool dealloc = TRUE;
748
749     BLEMGR_LOG("BLEMGR: ProcessEvtHdrMsg");
750
751     switch (pMsg->event)
752     {
753     /* External CHIPoBLE Event trigger */
754     case BLEManagerIMPL_STATE_UPDATE_EVT: {
755         bStatus_t status;
756
757         /* Verify BLE service mode is enabled */
758         if (sInstance.mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled)
759         {
760             /* Advertising flag set, either advertising or fast adv is enabled: Do nothing  */
761             /* Advertising flag not set, neither advertising nor fast adv is enabled: do nothing */
762             /* Advertising flag not set, either advertising or fast adv is enabled: Turn on */
763             if (!sInstance.mFlags.Has(Flags::kAdvertising))
764             {
765                 BLEMGR_LOG("BLEMGR: BLE Process Application Message: Not advertising");
766
767                 if (sInstance.mFlags.Has(Flags::kAdvertisingEnabled))
768                 {
769
770 // Send notification to thread manager that CHIPoBLE advertising is starting
771 #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
772                     ThreadStackMgr().OnCHIPoBLEAdvertisingStart();
773 #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
774
775                     // Enable legacy advertising for set #1
776                     status = (bStatus_t) GapAdv_enable(sInstance.advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX, 0);
777
778                     assert(status == SUCCESS);
779
780                     sInstance.mFlags.Set(Flags::kAdvertising);
781
782                     if (sInstance.mFlags.Has(Flags::kFastAdvertisingEnabled))
783                     {
784                         BLEMGR_LOG("BLEMGR: BLE Process Application Message: Fast Advertising Enabled");
785                     }
786                     else
787                     {
788                         BLEMGR_LOG("BLEMGR: BLE Process Application Message: Slow Advertising Enabled");
789
790                         // Start advertisement timer
791                         Util_startClock(&sInstance.clkAdvTimeout);
792                     }
793                 }
794             }
795             /* Advertising flag set, neither advertising nor fast adv is enabled: Turn off*/
796             else if (!sInstance.mFlags.Has(Flags::kAdvertisingEnabled) && !sInstance.mFlags.Has(Flags::kFastAdvertisingEnabled))
797             {
798                 BLEMGR_LOG("BLEMGR: BLE Process Application Message: Advertising disables");
799
800                 // Stop advertising
801                 GapAdv_disable(sInstance.advHandleLegacy);
802                 sInstance.mFlags.Clear(Flags::kAdvertising);
803                 mFlags.Set(Flags::kFastAdvertisingEnabled, true);
804
805                 Util_stopClock(&sInstance.clkAdvTimeout);
806             }
807             /* Other case is that advertising is already working, but should be restarted, as its settings changed */
808             else if (sInstance.mFlags.Has(Flags::kAdvertisingRefreshNeeded))
809             {
810                 sInstance.mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
811                 GapAdv_disable(sInstance.advHandleLegacy);
812
813                 // Enable legacy advertising for set #1
814                 status = (bStatus_t) GapAdv_enable(sInstance.advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX, 0);
815                 assert(status == SUCCESS);
816                 sInstance.mFlags.Set(Flags::kAdvertising);
817             }
818         }
819
820         if (sInstance.mFlags.Has(Flags::kBLEStackGATTNameUpdate))
821         {
822             sInstance.mFlags.Clear(Flags::kBLEStackGATTNameUpdate);
823             // Indicate that Device name has been set externally
824             mFlags.Set(Flags::kBLEStackGATTNameSet);
825
826             // Set the Device Name characteristic in the GAP GATT Service
827             GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, sInstance.mDeviceName);
828         }
829     }
830     break;
831
832     case BLEManagerIMPL_CHIPOBLE_CLOSE_CONN_EVT: {
833         uint16_t connHandle = *((uint16_t *) (pMsg->pData));
834
835         // Close active connection
836         GAP_TerminateLinkReq(connHandle, HCI_DISCONNECT_REMOTE_USER_TERM);
837     }
838     break;
839
840     case BLEManagerIMPL_CHIPOBLE_TX_IND_EVT: {
841         uint8_t dataLen = ((CHIPoBLEIndEvt_t *) (pMsg->pData))->len;
842
843         CHIPoBLEProfile_SetParameter(CHIPOBLEPROFILE_TX_CHAR, dataLen, (void *) (((CHIPoBLEIndEvt_t *) (pMsg->pData))->pData),
844                                      BLEManagerImpl::sSelfEntity);
845
846         BLEMGR_LOG("BLEMGR: BLE Process Application Message: BLEManagerIMPL_CHIPOBLE_TX_IND_EVT: Length: %d", dataLen);
847
848         ICall_free((void *) (((CHIPoBLEIndEvt_t *) (pMsg->pData))->pData));
849
850         dealloc = TRUE;
851     }
852     break;
853
854     case CHIPOBLE_CHAR_CHANGE_EVT: {
855         uint16_t writeLen     = ((CHIPoBLEProfChgEvt_t *) (pMsg->pData))->len;
856         uint8_t paramId       = ((CHIPoBLEProfChgEvt_t *) (pMsg->pData))->paramId;
857         uint16_t connHandleId = ((CHIPoBLEProfChgEvt_t *) (pMsg->pData))->connHandle;
858         void * connHandle;
859         ChipDeviceEvent event;
860
861         uint8_t i;
862         ConnRec_t * activeConnObj = NULL;
863
864         // Find active connection
865         for (i = 0; i < MAX_NUM_BLE_CONNS; i++)
866         {
867             if (sInstance.connList[i].connHandle == connHandleId)
868             {
869                 activeConnObj = &sInstance.connList[i];
870             }
871         }
872
873         connHandle = (void *) &activeConnObj->connHandle;
874
875         if (paramId == CHIPOBLEPROFILE_RX_CHAR)
876         {
877             BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, CHIPOBLEPROFILE_RX_CHAR");
878             // Pull written data from CHIPOBLE Profile based on extern server write
879             uint8_t * rxBuf = (uint8_t *) ICall_malloc(writeLen);
880
881             if (rxBuf == NULL)
882             {
883                 // alloc error
884                 return;
885             }
886
887             memset(rxBuf, 0x00, writeLen);
888
889             BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, length: %d", writeLen);
890             CHIPoBLEProfile_GetParameter(CHIPOBLEPROFILE_RX_CHAR, rxBuf, writeLen);
891
892             System::PacketBufferHandle packetBuf = System::PacketBufferHandle::NewWithData(rxBuf, writeLen, 0, 0);
893
894             ICall_free(rxBuf);
895
896             if (packetBuf.IsNull())
897             {
898                 // alloc error
899                 return;
900             }
901
902             // Arrange to post a CHIPoBLERXWriteEvent event to the CHIP queue.
903             event.Type                        = DeviceEventType::kCHIPoBLEWriteReceived;
904             event.CHIPoBLEWriteReceived.ConId = (void *) connHandle;
905             event.CHIPoBLEWriteReceived.Data  = std::move(packetBuf).UnsafeRelease();
906         }
907         else if (paramId == CHIPOBLEPROFILE_CCCWrite)
908         {
909             BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, CHIPOBLEPROFILE_CCCWrite");
910
911             // TODO: Add check to see if subscribing OR unsubscribing from char indications
912             uint8_t cccValue;
913
914             CHIPoBLEProfile_GetParameter(CHIPOBLEPROFILE_CCCWrite, &cccValue, 1);
915
916             // Check whether it is a sub/unsub event. 0x1 = Notofications enabled, 0x2 = Indications enabled
917             if (cccValue & 2)
918             {
919                 // Post event to CHIP
920                 BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, Subscrbe");
921                 event.Type = DeviceEventType::kCHIPoBLESubscribe;
922             }
923             else
924             {
925                 BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, unsubscrbe");
926                 event.Type = DeviceEventType::kCHIPoBLEUnsubscribe;
927             }
928
929             // Post event to CHIP
930             event.CHIPoBLESubscribe.ConId = (void *) connHandle;
931         }
932         PlatformMgr().PostEvent(&event);
933     }
934     break;
935
936     case ADV_EVT:
937         ProcessAdvEvent((GapAdvEventData_t *) (pMsg->pData));
938         break;
939
940     case PAIR_STATE_EVT: {
941         BLEMGR_LOG("BLEMGR: PAIR_STATE_EVT");
942
943         // Send passcode response
944         GAPBondMgr_PasscodeRsp(((PasscodeData_t *) (pMsg->pData))->connHandle, SUCCESS, B_APP_DEFAULT_PASSCODE);
945     }
946     break;
947
948     case PASSCODE_EVT: {
949         BLEMGR_LOG("BLEMGR: PASSCODE_EVT");
950     }
951     break;
952
953     case READ_RPA_EVT:
954         UpdateBLERPA();
955         break;
956
957     case SEND_PARAM_UPDATE_EVT: {
958         // Extract connection handle from data
959         uint16_t connHandle = *(uint16_t *) (((ClockEventData_t *) pMsg->pData)->data);
960
961         if (CHIP_NO_ERROR != ProcessParamUpdate(connHandle))
962         {
963             // error
964             return;
965         }
966
967         // This data is not dynamically allocated
968         dealloc = FALSE;
969
970         /* If we are sending a param update request then the service discovery
971          * should have ended. Changed state to connected */
972         DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_CONNECTED);
973
974         break;
975     }
976
977     case CONN_EVT:
978         break;
979
980     default:
981         // Do nothing.
982         break;
983     }
984
985     // Free message data if it exists and we are to dealloc
986     if ((dealloc == TRUE) && (pMsg->pData != NULL))
987     {
988         ICall_free(pMsg->pData);
989     }
990 }
991
992 /*********************************************************************
993  * @fn      ProcessGapMessage
994  *
995  * @brief   Process an incoming GAP event.
996  *
997  * @param   pMsg - message to process
998  */
999 void BLEManagerImpl::ProcessGapMessage(gapEventHdr_t * pMsg)
1000 {
1001     BLEMGR_LOG("BLEMGR: ProcessGapMessage");
1002
1003     switch (pMsg->opcode)
1004     {
1005     case GAP_DEVICE_INIT_DONE_EVENT: {
1006         BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_DEVICE_INIT_DONE_EVENT");
1007
1008         gapDeviceInitDoneEvent_t * pPkt = (gapDeviceInitDoneEvent_t *) pMsg;
1009
1010         if (pPkt->hdr.status == SUCCESS)
1011         {
1012             // Store the system ID
1013             uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
1014
1015             // use 6 bytes of device address for 8 bytes of system ID value
1016             systemId[0] = pPkt->devAddr[0];
1017             systemId[1] = pPkt->devAddr[1];
1018             systemId[2] = pPkt->devAddr[2];
1019
1020             // set middle bytes to zero
1021             systemId[4] = 0x00;
1022             systemId[3] = 0x00;
1023
1024             // shift three bytes up
1025             systemId[7] = pPkt->devAddr[5];
1026             systemId[6] = pPkt->devAddr[4];
1027             systemId[5] = pPkt->devAddr[3];
1028
1029             // Set Device Info Service Parameter
1030             DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
1031
1032             AdvInit();
1033
1034             sInstance.mFlags.Set(Flags::kBLEStackInitialized);
1035
1036             /* Trigger post-initialization state update */
1037             DriveBLEState();
1038
1039             if (sInstance.addrMode > ADDRMODE_RANDOM)
1040             {
1041                 UpdateBLERPA();
1042                 // Create one-shot clock for RPA check event.
1043                 Util_constructClock(&sInstance.clkRpaRead, ClockHandler, READ_RPA_EVT_PERIOD, 0, true,
1044                                     (uintptr_t) &sInstance.argRpaRead);
1045             }
1046         }
1047         break;
1048     }
1049
1050     case GAP_LINK_ESTABLISHED_EVENT: {
1051         gapEstLinkReqEvent_t * pPkt = (gapEstLinkReqEvent_t *) pMsg;
1052         BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_LINK_ESTABLISHED_EVENT");
1053
1054         // Display the amount of current connections
1055         uint8_t numActive = (uint8_t) linkDB_NumActive("");
1056
1057         if (pPkt->hdr.status == SUCCESS)
1058         {
1059             // Add connection to list and start RSSI
1060             AddBLEConn(pPkt->connectionHandle);
1061         }
1062
1063         DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_HIGH_BANDWIDTH);
1064
1065         if (numActive < MAX_NUM_BLE_CONNS)
1066         {
1067             // Start advertising since there is room for more connections. Advertisements stop automatically following connection.
1068             sInstance.mFlags.Clear(Flags::kAdvertising);
1069         }
1070         else
1071         {
1072             // Stop advertising since there is no room for more connections
1073             BLEMGR_LOG("BLEMGR: BLE event GAP_LINK_ESTABLISHED_EVENT: MAX connections");
1074             sInstance.mFlags.Clear(Flags::kAdvertisingEnabled).Clear(Flags::kAdvertising);
1075             mFlags.Set(Flags::kFastAdvertisingEnabled, true);
1076         }
1077
1078         /* Stop advertisement timeout timer */
1079         Util_stopClock(&sInstance.clkAdvTimeout);
1080
1081         DriveBLEState();
1082
1083         break;
1084     }
1085
1086     case GAP_LINK_TERMINATED_EVENT: {
1087         gapTerminateLinkEvent_t * pPkt = (gapTerminateLinkEvent_t *) pMsg;
1088         BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_LINK_TERMINATED_EVENT, reason: %d", pPkt->reason);
1089
1090         // Remove the connection from the list and disable RSSI if needed
1091         RemoveBLEConn(pPkt->connectionHandle);
1092
1093         ChipDeviceEvent event;
1094         event.Type                           = DeviceEventType::kCHIPoBLEConnectionError;
1095         event.CHIPoBLEConnectionError.ConId  = (void *) &pPkt->connectionHandle;
1096         event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED;
1097         PlatformMgr().PostEvent(&event);
1098
1099         DriveBLEState();
1100
1101         break;
1102     }
1103
1104     case GAP_UPDATE_LINK_PARAM_REQ_EVENT: {
1105         BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_UPDATE_LINK_PARAM_REQ_EVENT");
1106
1107         gapUpdateLinkParamReqReply_t rsp;
1108
1109         gapUpdateLinkParamReqEvent_t * pReq = (gapUpdateLinkParamReqEvent_t *) pMsg;
1110
1111         rsp.connectionHandle = pReq->req.connectionHandle;
1112         rsp.signalIdentifier = pReq->req.signalIdentifier;
1113
1114         // Only accept connection intervals with slave latency of 0
1115         // This is just an example of how the application can send a response
1116         if (pReq->req.connLatency == 0)
1117         {
1118             rsp.intervalMin = pReq->req.intervalMin;
1119             rsp.intervalMax = pReq->req.intervalMax;
1120             rsp.connLatency = pReq->req.connLatency;
1121             rsp.connTimeout = pReq->req.connTimeout;
1122             rsp.accepted    = TRUE;
1123             BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_UPDATE_LINK_PARAM_REQ_EVENT Accecpted");
1124         }
1125         else
1126         {
1127             rsp.accepted = FALSE;
1128             BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_UPDATE_LINK_PARAM_REQ_EVENT Rejected");
1129         }
1130
1131         // Send Reply
1132         VOID GAP_UpdateLinkParamReqReply(&rsp);
1133
1134         break;
1135     }
1136
1137     case GAP_LINK_PARAM_UPDATE_EVENT: {
1138         BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_LINK_PARAM_UPDATE_EVENT");
1139
1140         gapLinkUpdateEvent_t * pPkt = (gapLinkUpdateEvent_t *) pMsg;
1141
1142         // Get the address from the connection handle
1143         linkDBInfo_t linkInfo;
1144         linkDB_GetInfo(pPkt->connectionHandle, &linkInfo);
1145
1146         // Check if there are any queued parameter updates
1147         ConnHandleEntry_t * connHandleEntry = (ConnHandleEntry_t *) List_get(&sInstance.paramUpdateList);
1148         if (connHandleEntry != NULL)
1149         {
1150             // Attempt to send queued update now
1151             ProcessParamUpdate(connHandleEntry->connHandle);
1152
1153             // Free list element
1154             ICall_free(connHandleEntry);
1155         }
1156
1157         break;
1158     }
1159
1160     default:
1161         break;
1162     }
1163 }
1164
1165 /*********************************************************************
1166  * @fn      ProcessGATTMsg
1167  *
1168  * @brief   Process GATT messages and events.
1169  *
1170  * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
1171  */
1172 uint8_t BLEManagerImpl::ProcessGATTMsg(gattMsgEvent_t * pMsg)
1173 {
1174     uint8_t index;
1175     BLEMGR_LOG("BLEMGR: ProcessGATTMsg");
1176
1177     if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
1178     {
1179         // ATT request-response or indication-confirmation flow control is
1180         // violated. All subsequent ATT requests or indications will be dropped.
1181         // The app is informed in case it wants to drop the connection.
1182     }
1183     else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
1184     {
1185         index = GetBLEConnIndex(pMsg->connHandle);
1186
1187         sInstance.connList[index].mtu = pMsg->msg.mtuEvt.MTU;
1188         BLEMGR_LOG("BLEMGR: ProcessGATTMsg, ATT_MTU_UPDATED_EVENT: %d", pMsg->msg.mtuEvt.MTU);
1189     }
1190     else if (pMsg->method == ATT_HANDLE_VALUE_CFM)
1191     {
1192         void * connHandle;
1193         ChipDeviceEvent event;
1194
1195         ConnRec_t * activeConnObj = NULL;
1196
1197         activeConnObj = &sInstance.connList[0];
1198         connHandle    = (void *) &activeConnObj->connHandle;
1199
1200         event.Type                          = DeviceEventType::kCHIPoBLEIndicateConfirm;
1201         event.CHIPoBLEIndicateConfirm.ConId = connHandle;
1202         PlatformMgr().PostEvent(&event);
1203
1204         BLEMGR_LOG("BLEMGR: ProcessGATTMsg, ATT_HANDLE_VALUE_CFM:");
1205     }
1206     // Free message payload. Needed only for ATT Protocol messages
1207     GATT_bm_free(&pMsg->msg, pMsg->method);
1208
1209     // It's safe to free the incoming message
1210     return TRUE;
1211 }
1212
1213 /*********************************************************************
1214  * @fn      ProcessAdvEvent
1215  *
1216  * @brief   Process advertising event in app context
1217  *
1218  * @param   pEventData
1219  */
1220 void BLEManagerImpl::ProcessAdvEvent(GapAdvEventData_t * pEventData)
1221 {
1222     BLEMGR_LOG("BLEMGR: ProcessAdvEvent");
1223
1224     switch (pEventData->event)
1225     {
1226     case GAP_EVT_ADV_START_AFTER_ENABLE: {
1227         BLEMGR_LOG("BLEMGR: ProcessAdvEvent: GAP_EVT_ADV_START_AFTER_ENABLE");
1228
1229         if (linkDB_NumActive("") == 0)
1230         {
1231             DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_ADV);
1232         }
1233     }
1234     break;
1235
1236     case GAP_EVT_ADV_END_AFTER_DISABLE: {
1237         BLEMGR_LOG("BLEMGR: ProcessAdvEvent: GAP_EVT_ADV_END_AFTER_DISABLE");
1238     }
1239     break;
1240
1241     case GAP_EVT_ADV_START:
1242         break;
1243
1244     case GAP_EVT_ADV_END:
1245         break;
1246
1247     // BLE Stack has ended advertising due to connection
1248     case GAP_EVT_ADV_SET_TERMINATED: {
1249         BLEMGR_LOG("BLEMGR: ProcessAdvEvent: GAP_EVT_ADV_SET_TERMINATED");
1250     }
1251     break;
1252
1253     case GAP_EVT_SCAN_REQ_RECEIVED:
1254         break;
1255
1256     case GAP_EVT_INSUFFICIENT_MEMORY:
1257         break;
1258
1259     default:
1260         break;
1261     }
1262
1263     // All events have associated memory to free except the insufficient memory
1264     // event
1265     if (pEventData->event != GAP_EVT_INSUFFICIENT_MEMORY)
1266     {
1267         ICall_free(pEventData->pBuf);
1268     }
1269 }
1270
1271 /*********************************************************************
1272  * @fn      ProcessParamUpdate
1273  *
1274  * @brief   Process a parameters update request
1275  *
1276  * @return  None
1277  */
1278 CHIP_ERROR BLEManagerImpl::ProcessParamUpdate(uint16_t connHandle)
1279 {
1280     gapUpdateLinkParamReq_t req;
1281     uint8_t connIndex;
1282     BLEMGR_LOG("BLEMGR: ProcessParamUpdate");
1283
1284     req.connectionHandle = connHandle;
1285     req.connLatency      = DEFAULT_DESIRED_SLAVE_LATENCY;
1286     req.connTimeout      = DEFAULT_DESIRED_CONN_TIMEOUT;
1287     req.intervalMin      = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
1288     req.intervalMax      = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
1289
1290     connIndex = GetBLEConnIndex(connHandle);
1291     if (!(connIndex < MAX_NUM_BLE_CONNS))
1292     {
1293         return CHIP_ERROR_TOO_MANY_CONNECTIONS;
1294     }
1295
1296     // Deconstruct the clock object
1297     ClockP_destruct(sInstance.connList[connIndex].pUpdateClock);
1298     // Free clock struct
1299     if (sInstance.connList[connIndex].pUpdateClock != NULL)
1300     {
1301         ICall_free(sInstance.connList[connIndex].pUpdateClock);
1302         sInstance.connList[connIndex].pUpdateClock = NULL;
1303     }
1304     // Free ParamUpdateEventData
1305     if (sInstance.connList[connIndex].pParamUpdateEventData != NULL)
1306     {
1307         ICall_free(sInstance.connList[connIndex].pParamUpdateEventData);
1308     }
1309
1310     BLEMGR_LOG("BLEMGR: ProcessParamUpdate Send Link Param Req");
1311     // Send parameter update
1312     bStatus_t status = GAP_UpdateLinkParamReq(&req);
1313
1314     // If there is an ongoing update, queue this for when the udpate completes
1315     if (status == bleAlreadyInRequestedMode)
1316     {
1317
1318         BLEMGR_LOG("BLEMGR: ProcessParamUpdate pending");
1319         ConnHandleEntry_t * connHandleEntry = (ConnHandleEntry_t *) (ICall_malloc(sizeof(ConnHandleEntry_t)));
1320         if (connHandleEntry)
1321         {
1322             connHandleEntry->connHandle = connHandle;
1323             List_put(&sInstance.paramUpdateList, (List_Elem *) connHandleEntry);
1324         }
1325     }
1326
1327     return CHIP_NO_ERROR;
1328 }
1329
1330 /*********************************************************************
1331  * @fn      EnqueueEvtHdrMsg
1332  *
1333  * @brief   Creates a message and puts the message in RTOS queue.
1334  *
1335  * @param   event - message event.
1336  * @param   state - message state.
1337  */
1338 status_t BLEManagerImpl::EnqueueEvtHdrMsg(uint8_t event, void * pData)
1339 {
1340     uint8_t success;
1341     QueuedEvt_t * pMsg = (QueuedEvt_t *) ICall_malloc(sizeof(QueuedEvt_t));
1342     BLEMGR_LOG("BLEMGR: EnqueueEvtHdrMsg");
1343
1344     // Create dynamic pointer to message.
1345     if (pMsg)
1346     {
1347         pMsg->event = event;
1348         pMsg->pData = pData;
1349
1350         // Enqueue the message.
1351         success = Util_enqueueMsg(sEventHandlerMsgQueueID, BLEManagerImpl::sSyncEvent, (uint8_t *) pMsg);
1352
1353         return (success) ? SUCCESS : FAILURE;
1354     }
1355
1356     return bleMemAllocError;
1357 }
1358
1359 /*********************************************************************
1360  * @fn      AddBLEConn
1361  *
1362  * @brief   Add a device to the connected device list
1363  *
1364  * @return  index of the connected device list entry where the new connection
1365  *          info is put in.
1366  *          if there is no room, MAX_NUM_BLE_CONNS will be returned.
1367  */
1368 uint8_t BLEManagerImpl::AddBLEConn(uint16_t connHandle)
1369 {
1370     uint8_t i;
1371     uint8_t status = bleNoResources;
1372     BLEMGR_LOG("BLEMGR: AddBLEConn");
1373
1374     // Try to find an available entry
1375     for (i = 0; i < MAX_NUM_BLE_CONNS; i++)
1376     {
1377         if (sInstance.connList[i].connHandle == LL_CONNHANDLE_INVALID)
1378         {
1379             // Found available entry to put a new connection info in
1380             sInstance.connList[i].connHandle = connHandle;
1381
1382             // Allocate data to send through clock handler
1383             sInstance.connList[i].pParamUpdateEventData =
1384                 (ClockEventData_t *) ICall_malloc(sizeof(ClockEventData_t) + sizeof(uint16_t));
1385             if (sInstance.connList[i].pParamUpdateEventData)
1386             {
1387                 sInstance.connList[i].pParamUpdateEventData->event                = SEND_PARAM_UPDATE_EVT;
1388                 *((uint16_t *) sInstance.connList[i].pParamUpdateEventData->data) = connHandle;
1389
1390                 // Create a clock object and start
1391                 sInstance.connList[i].pUpdateClock = (ClockP_Struct *) ICall_malloc(sizeof(ClockP_Struct));
1392
1393                 if (sInstance.connList[i].pUpdateClock)
1394                 {
1395                     Util_constructClock(sInstance.connList[i].pUpdateClock, ClockHandler, SEND_PARAM_UPDATE_DELAY, 0, true,
1396                                         (uintptr_t) sInstance.connList[i].pParamUpdateEventData);
1397                 }
1398                 else
1399                 {
1400                     ICall_free(sInstance.connList[i].pParamUpdateEventData);
1401                 }
1402             }
1403             else
1404             {
1405                 status = bleMemAllocError;
1406             }
1407
1408             break;
1409         }
1410     }
1411     return status;
1412 }
1413
1414 /*********************************************************************
1415  * @fn      RemoveBLEConn
1416  *
1417  * @brief   Remove a device from the connected device list
1418  *
1419  * @return  index of the connected device list entry where the new connection
1420  *          info is removed from.
1421  *          if connHandle is not found, MAX_NUM_BLE_CONNS will be returned.
1422  */
1423 uint8_t BLEManagerImpl::RemoveBLEConn(uint16_t connHandle)
1424 {
1425     uint8_t connIndex = GetBLEConnIndex(connHandle);
1426     BLEMGR_LOG("BLEMGR: RemoveBLEConn");
1427
1428     if (connIndex != MAX_NUM_BLE_CONNS)
1429     {
1430         ClockP_Struct * pUpdateClock = sInstance.connList[connIndex].pUpdateClock;
1431
1432         if (pUpdateClock != NULL)
1433         {
1434             // Stop and destruct the RTOS clock if it's still alive
1435             if (Util_isActive(pUpdateClock))
1436             {
1437                 Util_stopClock(pUpdateClock);
1438             }
1439
1440             // Destruct the clock object
1441             ClockP_destruct(pUpdateClock);
1442             // Free clock struct
1443             ICall_free(pUpdateClock);
1444             // Free ParamUpdateEventData
1445             ICall_free(sInstance.connList[connIndex].pParamUpdateEventData);
1446         }
1447         // Clear pending update requests from paramUpdateList
1448         ClearPendingBLEParamUpdate(connHandle);
1449
1450         // Clear Connection List Entry
1451         ClearBLEConnListEntry(connHandle);
1452     }
1453     return connIndex;
1454 }
1455
1456 /*********************************************************************
1457  * @fn      GetBLEConnIndex
1458  *
1459  * @brief   Find index in the connected device list by connHandle
1460  *
1461  * @return  the index of the entry that has the given connection handle.
1462  *          if there is no match, MAX_NUM_BLE_CONNS will be returned.
1463  */
1464 uint8_t BLEManagerImpl::GetBLEConnIndex(uint16_t connHandle) const
1465 {
1466     uint8_t i;
1467
1468     BLEMGR_LOG("BLEMGR: GetBLEConnIndex");
1469
1470     for (i = 0; i < MAX_NUM_BLE_CONNS; i++)
1471     {
1472         if (sInstance.connList[i].connHandle == connHandle)
1473         {
1474             return i;
1475         }
1476     }
1477
1478     return MAX_NUM_BLE_CONNS;
1479 }
1480
1481 /*********************************************************************
1482  * @fn      ClearBLEConnListEntry
1483  *
1484  * @brief   Find index in the connected device list by connHandle
1485  *
1486  * @return  the index of the entry that has the given connection handle.
1487  *          if there is no match, MAX_NUM_BLE_CONNS will be returned.
1488  */
1489 uint8_t BLEManagerImpl::ClearBLEConnListEntry(uint16_t connHandle)
1490 {
1491     uint8_t i;
1492     // Set to invalid connection index initially
1493     uint8_t connIndex = MAX_NUM_BLE_CONNS;
1494
1495     BLEMGR_LOG("BLEMGR: ClearBLEConnListEntry");
1496     if (connHandle != LL_CONNHANDLE_ALL)
1497     {
1498         // Get connection index from handle
1499         connIndex = GetBLEConnIndex(connHandle);
1500         if (connIndex >= MAX_NUM_BLE_CONNS)
1501         {
1502             return bleInvalidRange;
1503         }
1504     }
1505
1506     // Clear specific handle or all handles
1507     for (i = 0; i < MAX_NUM_BLE_CONNS; i++)
1508     {
1509         if ((connIndex == i) || (connHandle == LL_CONNHANDLE_ALL))
1510         {
1511             sInstance.connList[i].connHandle   = LL_CONNHANDLE_INVALID;
1512             sInstance.connList[i].currPhy      = 0;
1513             sInstance.connList[i].phyCngRq     = 0;
1514             sInstance.connList[i].phyRqFailCnt = 0;
1515             sInstance.connList[i].rqPhy        = 0;
1516             memset(sInstance.connList[i].rssiArr, 0, MAX_RSSI_STORE_DEPTH);
1517             sInstance.connList[i].rssiAvg         = 0;
1518             sInstance.connList[i].rssiCntr        = 0;
1519             sInstance.connList[i].isAutoPHYEnable = FALSE;
1520             sInstance.connList[i].mtu             = 0;
1521         }
1522     }
1523
1524     return SUCCESS;
1525 }
1526
1527 /*********************************************************************
1528  * @fn      ClearPendingBLEParamUpdate
1529  *
1530  * @brief   clean pending param update request in the paramUpdateList list
1531  *
1532  * @param   connHandle - connection handle to clean
1533  *
1534  * @return  none
1535  */
1536 void BLEManagerImpl::ClearPendingBLEParamUpdate(uint16_t connHandle)
1537 {
1538     List_Elem * curr;
1539
1540     BLEMGR_LOG("BLEMGR: ClearPendingBLEParamUpdate");
1541
1542     for (curr = List_head(&sInstance.paramUpdateList); curr != NULL; curr = List_next(curr))
1543     {
1544         if (((ConnHandleEntry_t *) curr)->connHandle == connHandle)
1545         {
1546             List_remove(&sInstance.paramUpdateList, curr);
1547         }
1548     }
1549 }
1550
1551 /*********************************************************************
1552  * @fn      UpdateBLERPA
1553  *
1554  * @brief   Read the current RPA from the stack and update display
1555  *          if the RPA has changed.
1556  *
1557  * @param   None.
1558  *
1559  * @return  None.
1560  */
1561 void BLEManagerImpl::UpdateBLERPA(void)
1562 {
1563     uint8_t * pRpaNew;
1564     BLEMGR_LOG("BLEMGR: UpdateBLERPA");
1565
1566     // Read the current RPA.
1567     pRpaNew = GAP_GetDevAddress(FALSE);
1568
1569     if (memcmp(pRpaNew, sInstance.rpa, B_ADDR_LEN))
1570     {
1571         memcpy(sInstance.rpa, pRpaNew, B_ADDR_LEN);
1572     }
1573 }
1574
1575 void BLEManagerImpl::EventHandler(void * arg)
1576 {
1577     BLEMGR_LOG("BLEMGR: EventHandler");
1578
1579     sInstance.EventHandler_init();
1580
1581     for (;;)
1582     {
1583         uint32_t events;
1584
1585         // Waits for an event to be posted associated with the calling thread.
1586         // Note that an event associated with a thread is posted when a
1587         // message is queued to the message receive queue of the thread
1588         xQueueReceive((QueueHandle_t) BLEManagerImpl::sSyncEvent, (char *) &events, portMAX_DELAY);
1589
1590         if (events)
1591         {
1592             ICall_EntityID dest;
1593             ICall_ServiceEnum src;
1594             ICall_HciExtEvt * hcipMsg = NULL;
1595
1596             /* Lock CHIP Stack while processing BLE Stack/App events */
1597             PlatformMgr().LockChipStack();
1598
1599             BLEMGR_LOG("BLEMGR: EventHandler: Events received");
1600             // Fetch any available messages that might have been sent from the stack
1601             if (ICall_fetchServiceMsg(&src, &dest, (void **) &hcipMsg) == ICALL_ERRNO_SUCCESS)
1602             {
1603                 BLEMGR_LOG("BLEMGR: EventHandler: Stack Event");
1604
1605                 uint8 safeToDealloc = TRUE;
1606
1607                 if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == BLEManagerImpl::sSelfEntity))
1608                 {
1609                     ICall_Stack_Event * pEvt = (ICall_Stack_Event *) hcipMsg;
1610
1611                     // Check for non-BLE stack events
1612                     if (pEvt->signature != 0xffff)
1613                     {
1614                         // Process inter-task message
1615                         safeToDealloc = sInstance.ProcessStackEvent((ICall_Hdr *) hcipMsg);
1616                     }
1617                 }
1618
1619                 if (hcipMsg && safeToDealloc)
1620                 {
1621                     ICall_freeMsg(hcipMsg);
1622                 }
1623             }
1624
1625             // If RTOS queue is not empty, process CHIP messages.
1626             if (events & QUEUE_EVT)
1627             {
1628                 BLEMGR_LOG("BLEMGR: EventHandler: App Event");
1629
1630                 QueuedEvt_t * pMsg;
1631                 for (;;)
1632                 {
1633                     pMsg = (QueuedEvt_t *) Util_dequeueMsg(BLEManagerImpl::sEventHandlerMsgQueueID);
1634                     if (NULL != pMsg)
1635                     {
1636                         // Process message.
1637                         sInstance.ProcessEvtHdrMsg(pMsg);
1638
1639                         // Free the space from the message.
1640                         ICall_free(pMsg);
1641                     }
1642                     else
1643                     {
1644                         break;
1645                     }
1646                 }
1647             }
1648
1649             PlatformMgr().UnlockChipStack();
1650         }
1651     }
1652 }
1653
1654 /* Post event to app processing loop to begin CHIP advertising */
1655 CHIP_ERROR BLEManagerImpl::DriveBLEState(void)
1656 {
1657     CHIP_ERROR err = CHIP_NO_ERROR;
1658     BLEMGR_LOG("BLEMGR: DriveBLEState");
1659
1660     if (sInstance.EnqueueEvtHdrMsg(BLEManagerIMPL_STATE_UPDATE_EVT, NULL) != SUCCESS)
1661     {
1662         err = CHIP_ERROR_NO_MEMORY;
1663     }
1664     return err;
1665 }
1666
1667 /*********************************************************************
1668  * @fn      advCallback
1669  *
1670  * @brief   GapAdv module callback
1671  *
1672  * @param   pMsg - message to process
1673  */
1674 void BLEManagerImpl::advCallback(uint32_t event, void * pBuf, uintptr_t arg)
1675 {
1676     BLEMGR_LOG("BLEMGR: advCallback");
1677
1678     GapAdvEventData_t * pData = (GapAdvEventData_t *) ICall_malloc(sizeof(GapAdvEventData_t));
1679
1680     if (pData)
1681     {
1682         pData->event = event;
1683         pData->pBuf  = pBuf;
1684         if (sInstance.EnqueueEvtHdrMsg(ADV_EVT, pData) != SUCCESS)
1685         {
1686             ICall_free(pData);
1687         }
1688     }
1689 }
1690
1691 void BLEManagerImpl::AdvTimeoutHandler(uintptr_t arg)
1692 {
1693     BLEMGR_LOG("BLEMGR: AdvTimeoutHandler");
1694
1695     if (sInstance.mFlags.Has(Flags::kAdvertisingEnabled))
1696     {
1697         BLEMGR_LOG("BLEMGR: AdvTimeoutHandler ble adv 15 minute timeout");
1698
1699         sInstance.mFlags.Clear(Flags::kAdvertisingEnabled);
1700         sInstance.mFlags.Set(Flags::kFastAdvertisingEnabled);
1701
1702         /* Send event to process state change request */
1703         DriveBLEState();
1704     }
1705 }
1706
1707 void BLEManagerImpl::ClockHandler(uintptr_t arg)
1708 {
1709     ClockEventData_t * pData = (ClockEventData_t *) arg;
1710     BLEMGR_LOG("BLEMGR: ClockHandler");
1711
1712     if (pData->event == READ_RPA_EVT)
1713     {
1714         BLEMGR_LOG("BLEMGR: ClockHandler RPA EVT");
1715         // Start the next period
1716         Util_startClock(&sInstance.clkRpaRead);
1717
1718         // Post event to read the current RPA
1719         sInstance.EnqueueEvtHdrMsg(READ_RPA_EVT, NULL);
1720     }
1721     else if (pData->event == SEND_PARAM_UPDATE_EVT)
1722     {
1723         BLEMGR_LOG("BLEMGR: ClockHandler PARAM UPDATE EVT");
1724         // Send message to app
1725         if (sInstance.EnqueueEvtHdrMsg(SEND_PARAM_UPDATE_EVT, pData) != SUCCESS)
1726         {
1727             ICall_free(pData);
1728         }
1729     }
1730 }
1731
1732 /*********************************************************************
1733  * @fn      CHIPoBLEProfile_charValueChangeCB
1734  *
1735  * @brief   Callback from CHIPoBLE Profile indicating a characteristic
1736  *          value change.
1737  *          Calling context (BLE Stack Task)
1738  *
1739  * @param   paramId - parameter Id of the value that was changed.
1740  *
1741  * @return  None.
1742  */
1743 void BLEManagerImpl::CHIPoBLEProfile_charValueChangeCB(uint8_t paramId, uint16_t len, uint16_t connHandle)
1744 {
1745     CHIPoBLEProfChgEvt_t * pValue = (CHIPoBLEProfChgEvt_t *) ICall_malloc(sizeof(CHIPoBLEProfChgEvt_t));
1746     BLEMGR_LOG("BLEMGR: CHIPoBLEProfile_charValueChangeCB");
1747
1748     if (pValue)
1749     {
1750         pValue->paramId    = paramId;
1751         pValue->len        = len;
1752         pValue->connHandle = connHandle;
1753
1754         if (sInstance.EnqueueEvtHdrMsg(CHIPOBLE_CHAR_CHANGE_EVT, pValue) != SUCCESS)
1755         {
1756             ICall_free(pValue);
1757         }
1758     }
1759 }
1760
1761 /*********************************************************************
1762  * @fn      RemoteDisplay_passcodeCb
1763  *
1764  * @brief   Passcode callback.
1765  *
1766  * @return  none
1767  */
1768 void BLEManagerImpl::PasscodeCb(uint8_t * pDeviceAddr, uint16_t connHandle, uint8_t uiInputs, uint8_t uiOutputs,
1769                                 uint32_t numComparison)
1770 {
1771     PasscodeData_t * pData = (PasscodeData_t *) ICall_malloc(sizeof(PasscodeData_t));
1772
1773     // Allocate space for the passcode event.
1774     if (pData)
1775     {
1776         pData->connHandle = connHandle;
1777         memcpy(pData->deviceAddr, pDeviceAddr, B_ADDR_LEN);
1778         pData->uiInputs      = uiInputs;
1779         pData->uiOutputs     = uiOutputs;
1780         pData->numComparison = numComparison;
1781
1782         // Enqueue the event.
1783         if (sInstance.EnqueueEvtHdrMsg(PASSCODE_EVT, pData) != SUCCESS)
1784         {
1785             ICall_free(pData);
1786         }
1787     }
1788 }
1789
1790 /*********************************************************************
1791  * @fn      PairStateCb
1792  *
1793  * @brief   Pairing state callback.
1794  *
1795  * @return  none
1796  */
1797 void BLEManagerImpl::PairStateCb(uint16_t connHandle, uint8_t state, uint8_t status)
1798 {
1799     PairStateData_t * pData = (PairStateData_t *) ICall_malloc(sizeof(PairStateData_t));
1800
1801     // Allocate space for the event data.
1802     if (pData)
1803     {
1804         pData->state      = state;
1805         pData->connHandle = connHandle;
1806         pData->status     = status;
1807
1808         // Queue the event.
1809         if (sInstance.EnqueueEvtHdrMsg(PAIR_STATE_EVT, pData) != SUCCESS)
1810         {
1811             ICall_free(pData);
1812         }
1813     }
1814 }
1815
1816 /*******************************************************************************
1817  * @fn          AssertHandler
1818  *
1819  * @brief       This is the Application's callback handler for asserts raised
1820  *              in the stack.  When EXT_HAL_ASSERT is defined in the Stack
1821  *              project this function will be called when an assert is raised,
1822  *              and can be used to observe or trap a violation from expected
1823  *              behavior.
1824  *
1825  *              As an example, for Heap allocation failures the Stack will raise
1826  *              HAL_ASSERT_CAUSE_OUT_OF_MEMORY as the assertCause and
1827  *              HAL_ASSERT_SUBCAUSE_NONE as the assertSubcause.  An application
1828  *              developer could trap any malloc failure on the stack by calling
1829  *              HAL_ASSERT_SPINLOCK under the matching case.
1830  *
1831  *              An application developer is encouraged to extend this function
1832  *              for use by their own application.  To do this, add hal_assert.c
1833  *              to your project workspace, the path to hal_assert.h (this can
1834  *              be found on the stack side). Asserts are raised by including
1835  *              hal_assert.h and using macro HAL_ASSERT(cause) to raise an
1836  *              assert with argument assertCause.  the assertSubcause may be
1837  *              optionally set by macro HAL_ASSERT_SET_SUBCAUSE(subCause) prior
1838  *              to asserting the cause it describes. More information is
1839  *              available in hal_assert.h.
1840  *
1841  * input parameters
1842  *
1843  * @param       assertCause    - Assert cause as defined in hal_assert.h.
1844  * @param       assertSubcause - Optional assert subcause (see hal_assert.h).
1845  *
1846  * output parameters
1847  *
1848  * @param       None.
1849  *
1850  * @return      None.
1851  */
1852 void BLEManagerImpl::AssertHandler(uint8 assertCause, uint8 assertSubcause)
1853 {
1854     // check the assert cause
1855     switch (assertCause)
1856     {
1857     case HAL_ASSERT_CAUSE_OUT_OF_MEMORY:
1858         assert(false);
1859         break;
1860
1861     case HAL_ASSERT_CAUSE_INTERNAL_ERROR:
1862         // check the subcause
1863         if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR)
1864         {
1865             assert(false);
1866         }
1867         else
1868         {
1869             assert(false);
1870         }
1871         break;
1872     case HAL_ASSERT_CAUSE_ICALL_ABORT:
1873         assert(false);
1874
1875     case HAL_ASSERT_CAUSE_ICALL_TIMEOUT:
1876         assert(false);
1877         break;
1878     case HAL_ASSERT_CAUSE_WRONG_API_CALL:
1879         assert(false);
1880         break;
1881     default:
1882         assert(false);
1883         break;
1884     }
1885     return;
1886 }
1887
1888 } // namespace Internal
1889 } // namespace DeviceLayer
1890 } // namespace chip
1891
1892 #endif /* CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE */