Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / K32W / BLEManagerImpl.cpp
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    Copyright (c) 2020 Nest Labs, Inc.
5  *    All rights reserved.
6  *
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
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 /**
21  *    @file
22  *          Provides an implementation of the BLEManager singleton object
23  *          for the K32W platforms.
24  */
25
26 /* this file behaves like a config.h, comes first */
27 #include <platform/internal/CHIPDeviceLayerInternal.h>
28
29 #include <crypto/CHIPCryptoPAL.h>
30
31 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
32
33 #include <ble/CHIPBleServiceData.h>
34
35 #include "board.h"
36 #include "fsl_xcvr.h"
37 #include "gatt_db_app_interface.h"
38 #include "gatt_db_handles.h"
39 #include "stdio.h"
40 #include "timers.h"
41
42 #include "RNG_Interface.h"
43
44 /*******************************************************************************
45  * Local data types
46  *******************************************************************************/
47 extern "C" bool_t Ble_ConfigureHostStackConfig(void);
48 extern "C" void (*pfBLE_SignalFromISR)(void);
49 extern "C" bool_t Ble_CheckMemoryStorage(void);
50
51 extern osaEventId_t gHost_TaskEvent;
52 extern msgQueue_t gApp2Host_TaskQueue;
53 extern msgQueue_t gHci2Host_TaskQueue;
54
55 using namespace ::chip;
56 using namespace ::chip::Ble;
57
58 namespace chip {
59 namespace DeviceLayer {
60 namespace Internal {
61
62 namespace {
63
64 /*******************************************************************************
65  * Macros & Constants definitions
66  *******************************************************************************/
67 /* Timeout of BLE commands */
68 #define CHIP_BLE_KW_EVNT_TIMEOUT 1000
69
70 /** BLE advertisment state changed */
71 #define CHIP_BLE_KW_EVNT_ADV_CHANGED 0x0001
72 /** BLE advertisement command failed */
73 #define CHIP_BLE_KW_EVNT_ADV_FAILED 0x0002
74 /** BLE advertisement setup failed */
75 #define CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED 0x0004
76 /** BLE advertisement parameters setup complete */
77 #define CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE 0x0008
78 /** BLE advertisement data setup complete */
79 #define CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE 0x0010
80 /** BLE random address set */
81 #define CHIP_BLE_KW_EVNT_RND_ADDR_SET 0x0020
82 /** BLE Initialization complete */
83 #define CHIP_BLE_KW_EVNT_INIT_COMPLETE 0x0040
84 /** BLE Received a handle value confirmation from the client */
85 #define CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED 0x0080
86 /** BLE send indication failed */
87 #define CHIP_BLE_KW_EVNT_INDICATION_FAILED 0x0100
88 /** Maximal time of connection without activity */
89 #define CHIP_BLE_KW_CONN_TIMEOUT 60000
90
91 #define LOOP_EV_BLE (0x08)
92
93 /* controller task configuration */
94 #define CONTROLLER_TASK_PRIORITY (6U)
95 #define CONTROLLER_TASK_STACK_SIZE (gControllerTaskStackSize_c / sizeof(StackType_t))
96
97 /* host task configuration */
98 #define HOST_TASK_PRIORITY (3U)
99 #define HOST_TASK_STACK_SIZE (gHost_TaskStackSize_c / sizeof(StackType_t))
100
101 /* ble app task configuration */
102 #define CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY (HOST_TASK_PRIORITY - 1)
103 #define CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE (1024)
104
105 /* advertising configuration */
106 #define BLEKW_ADV_MAX_NO (2)
107 #define BLEKW_SCAN_RSP_MAX_NO (2)
108 #define BLEKW_MAX_ADV_DATA_LEN (31)
109 #define CHIP_ADV_SHORT_UUID_LEN (2)
110
111 /* FreeRTOS sw timer */
112 TimerHandle_t sbleAdvTimeoutTimer;
113
114 /* Message list used to synchronize asynchronous messages from the KW BLE tasks */
115 anchor_t blekw_msg_list;
116
117 /* Used to manage asynchronous events from BLE Stack: e.g.: GAP setup finished */
118 osaEventId_t event_msg;
119
120 osaEventId_t mControllerTaskEvent;
121 TimerHandle_t connectionTimeout;
122
123 /* Used by BLE App Task to handle asynchronous GATT events */
124 EventGroupHandle_t bleAppTaskLoopEvent;
125
126 /* keep the device ID of the connected peer */
127 uint8_t device_id;
128
129 const uint8_t ShortUUID_CHIPoBLEService[]  = { 0xAF, 0xFE };
130 const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
131                                                  0x9D, 0x11 } };
132 const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
133                                                  0x9D, 0x12 } };
134 } // namespace
135
136 BLEManagerImpl BLEManagerImpl::sInstance;
137
138 CHIP_ERROR BLEManagerImpl::_Init()
139 {
140     CHIP_ERROR err = CHIP_NO_ERROR;
141     osaEventFlags_t flags;
142     BaseType_t bleAppCreated    = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
143     uint16_t attChipRxHandle[1] = { (uint16_t) value_chipoble_rx };
144
145     mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
146
147     // Check if BLE stack is initialized
148     VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
149
150     // Initialize the Chip BleLayer.
151     err = BleLayer::Init(this, this, &SystemLayer);
152     SuccessOrExit(err);
153
154     (void) RNG_Init();
155     RNG_SetPseudoRandomNoSeed(NULL);
156
157     /* Initialization of message wait events -
158      * used for receiving BLE Stack events */
159     event_msg = OSA_EventCreate(TRUE);
160     VerifyOrExit(event_msg != NULL, err = CHIP_ERROR_INCORRECT_STATE);
161
162     pfBLE_SignalFromISR = BLE_SignalFromISRCallback;
163
164     /* Set the config structure to the host stack */
165     VerifyOrExit(Ble_ConfigureHostStackConfig() == TRUE, err = CHIP_ERROR_INCORRECT_STATE);
166
167     /* Prepare callback input queue.*/
168     MSG_InitQueue(&blekw_msg_list);
169
170     /* Create the connection timeout timer. */
171     connectionTimeout =
172         xTimerCreate("bleTimeoutTmr", pdMS_TO_TICKS(CHIP_BLE_KW_CONN_TIMEOUT), pdFALSE, (void *) 0, blekw_connection_timeout_cb);
173
174     /* Create BLE App Task */
175     bleAppTaskLoopEvent = xEventGroupCreate();
176     VerifyOrExit(bleAppTaskLoopEvent != NULL, err = CHIP_ERROR_INCORRECT_STATE);
177     bleAppCreated = xTaskCreate(bleAppTask, CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME,
178                                 CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE / sizeof(StackType_t), this,
179                                 CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY, NULL);
180     VerifyOrExit(bleAppCreated == pdPASS, err = CHIP_ERROR_INCORRECT_STATE);
181
182     /* BLE Radio Init */
183     XCVR_TemperatureUpdate(BOARD_GetTemperature());
184     VerifyOrExit(XCVR_Init(BLE_MODE, DR_2MBPS) == gXcvrSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);
185
186     /* Create BLE Controller Task */
187     VerifyOrExit(blekw_controller_init() == CHIP_NO_ERROR, err = CHIP_ERROR_INCORRECT_STATE);
188
189     /* Create BLE Host Task */
190     VerifyOrExit(blekw_host_init() == CHIP_NO_ERROR, err = CHIP_ERROR_INCORRECT_STATE);
191
192     /* BLE Host Stack Init */
193     Ble_HostInitialize(blekw_generic_cb, (hciHostToControllerInterface_t) Hci_SendPacketToController);
194
195     /* Register the GATT server callback */
196     VerifyOrExit(GattServer_RegisterCallback(blekw_gatt_server_cb) == gBleSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);
197
198     /* Wait until BLE Stack is ready */
199     VerifyOrExit(OSA_EventWait(event_msg, CHIP_BLE_KW_EVNT_INIT_COMPLETE, TRUE, CHIP_BLE_KW_EVNT_TIMEOUT, &flags) ==
200                      osaStatus_Success,
201                  err = CHIP_ERROR_INCORRECT_STATE);
202
203     GattServer_RegisterHandlesForWriteNotifications(1, attChipRxHandle);
204
205     mFlags.Set(Flags::kK32WBLEStackInitialized);
206     mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false);
207     mFlags.Set(Flags::kFastAdvertisingEnabled);
208
209     // Create FreeRTOS sw timer for BLE timeouts and interval change.
210     sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer",       // Just a text name, not used by the RTOS kernel
211                                        1,                   // == default timer period (mS)
212                                        false,               // no timer reload (==one-shot)
213                                        (void *) this,       // init timer id = ble obj context
214                                        BleAdvTimeoutHandler // timer callback handler
215     );
216     VerifyOrExit(sbleAdvTimeoutTimer != NULL, err = CHIP_ERROR_INCORRECT_STATE);
217 exit:
218     return err;
219 }
220
221 uint16_t BLEManagerImpl::_NumConnections(void)
222 {
223     uint16_t numCons = 0;
224     for (uint16_t i = 0; i < kMaxConnections; i++)
225     {
226         if (mBleConnections[i].allocated)
227         {
228             numCons++;
229         }
230     }
231
232     return numCons;
233 }
234
235 bool BLEManagerImpl::_IsAdvertisingEnabled(void)
236 {
237     return mFlags.Has(Flags::kAdvertisingEnabled);
238 }
239
240 bool BLEManagerImpl::RemoveConnection(uint8_t connectionHandle)
241 {
242     CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true);
243     bool status                     = false;
244
245     if (bleConnState != NULL)
246     {
247         memset(bleConnState, 0, sizeof(CHIPoBLEConState));
248         status = true;
249     }
250
251     return status;
252 }
253
254 void BLEManagerImpl::AddConnection(uint8_t connectionHandle)
255 {
256     CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true);
257
258     if (bleConnState != NULL)
259     {
260         memset(bleConnState, 0, sizeof(CHIPoBLEConState));
261         bleConnState->allocated        = 1;
262         bleConnState->connectionHandle = connectionHandle;
263     }
264 }
265
266 BLEManagerImpl::CHIPoBLEConState * BLEManagerImpl::GetConnectionState(uint8_t connectionHandle, bool allocate)
267 {
268     uint8_t freeIndex = kMaxConnections;
269
270     for (uint8_t i = 0; i < kMaxConnections; i++)
271     {
272         if (mBleConnections[i].allocated == 1)
273         {
274             if (mBleConnections[i].connectionHandle == connectionHandle)
275             {
276                 return &mBleConnections[i];
277             }
278         }
279
280         else if (i < freeIndex)
281         {
282             freeIndex = i;
283         }
284     }
285
286     if (allocate)
287     {
288         if (freeIndex < kMaxConnections)
289         {
290             return &mBleConnections[freeIndex];
291         }
292
293         ChipLogError(DeviceLayer, "Failed to allocate CHIPoBLEConState");
294     }
295
296     return NULL;
297 }
298
299 CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val)
300 {
301     CHIP_ERROR err = CHIP_NO_ERROR;
302
303     VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
304     VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
305
306     if (val != mServiceMode)
307     {
308         mServiceMode = val;
309         PlatformMgr().ScheduleWork(DriveBLEState, 0);
310     }
311
312 exit:
313     return err;
314 }
315
316 CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
317 {
318     CHIP_ERROR err = CHIP_NO_ERROR;
319
320     VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
321
322     if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
323     {
324         mFlags.Set(Flags::kAdvertisingEnabled, val);
325         PlatformMgr().ScheduleWork(DriveBLEState, 0);
326     }
327
328 exit:
329     return err;
330 }
331
332 CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
333 {
334     switch (mode)
335     {
336     case BLEAdvertisingMode::kFastAdvertising:
337         mFlags.Set(Flags::kFastAdvertisingEnabled, true);
338         break;
339     case BLEAdvertisingMode::kSlowAdvertising:
340         mFlags.Set(Flags::kFastAdvertisingEnabled, false);
341         break;
342     default:
343         return CHIP_ERROR_INVALID_ARGUMENT;
344     }
345     mFlags.Set(Flags::kRestartAdvertising);
346     PlatformMgr().ScheduleWork(DriveBLEState, 0);
347     return CHIP_NO_ERROR;
348 }
349
350 CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
351 {
352     if (strlen(mDeviceName) >= bufSize)
353     {
354         return CHIP_ERROR_BUFFER_TOO_SMALL;
355     }
356     strcpy(buf, mDeviceName);
357     return CHIP_NO_ERROR;
358 }
359
360 CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName)
361 {
362     if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported)
363     {
364         return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
365     }
366     if (deviceName != NULL && deviceName[0] != 0)
367     {
368         if (strlen(deviceName) >= kMaxDeviceNameLength)
369         {
370             return CHIP_ERROR_INVALID_ARGUMENT;
371         }
372         memset(mDeviceName, 0, kMaxDeviceNameLength);
373         strcpy(mDeviceName, deviceName);
374         mFlags.Set(Flags::kDeviceNameSet);
375         ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName);
376     }
377     else
378     {
379         mDeviceName[0] = 0;
380         mFlags.Clear(Flags::kDeviceNameSet);
381     }
382
383     return CHIP_NO_ERROR;
384 }
385
386 void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
387 {
388     switch (event->Type)
389     {
390     case DeviceEventType::kCHIPoBLESubscribe:
391         ChipDeviceEvent connEstEvent;
392
393         HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
394         connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
395         PlatformMgr().PostEvent(&connEstEvent);
396         break;
397
398     case DeviceEventType::kCHIPoBLEUnsubscribe:
399         HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
400         break;
401
402     case DeviceEventType::kCHIPoBLEWriteReceived:
403         HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX,
404                             PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
405         break;
406
407     case DeviceEventType::kCHIPoBLEConnectionError:
408         HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
409         break;
410
411     case DeviceEventType::kCHIPoBLEIndicateConfirm:
412         HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
413         break;
414
415 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
416     case DeviceEventType::kServiceProvisioningChange:
417         ChipLogProgress(DeviceLayer, "_OnPlatformEvent kServiceProvisioningChange");
418
419         mFlags.Clear(Flags::kAdvertisingEnabled);
420         PlatformMgr().ScheduleWork(DriveBLEState, 0);
421         break;
422 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
423
424     default:
425         break;
426     }
427 }
428
429 bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
430 {
431     ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported");
432     return false;
433 }
434
435 bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
436 {
437     ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported");
438     return false;
439 }
440
441 bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
442 {
443     ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId);
444
445     if (Gap_Disconnect(conId) != gBleSuccess_c)
446     {
447         ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
448         return false;
449     }
450
451     return true;
452 }
453
454 uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
455 {
456     uint16_t tempMtu = 0;
457     (void) Gatt_GetMtu(conId, &tempMtu);
458
459     return tempMtu;
460 }
461
462 bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
463                                       PacketBufferHandle pBuf)
464 {
465     ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported");
466     return false;
467 }
468
469 bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
470                                      PacketBufferHandle pBuf)
471 {
472     ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported");
473     return false;
474 }
475
476 bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
477                                       const ChipBleUUID * svcId, const ChipBleUUID * charId)
478 {
479     ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported");
480     return false;
481 }
482
483 void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId)
484 {
485     // Nothing to do
486 }
487
488 bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
489                                     PacketBufferHandle data)
490 {
491     CHIP_ERROR err = CHIP_NO_ERROR;
492     uint16_t cId   = (UUIDsMatch(&ChipUUID_CHIPoBLEChar_TX, charId) ? value_chipoble_tx : 0);
493     ChipDeviceEvent event;
494
495     if (cId != 0)
496     {
497         if (blekw_send_event(conId, cId, data->Start(), data->DataLength()) != BLE_OK)
498         {
499             err = CHIP_ERROR_SENDING_BLOCKED;
500         }
501         else
502         {
503             event.Type                          = DeviceEventType::kCHIPoBLEIndicateConfirm;
504             event.CHIPoBLEIndicateConfirm.ConId = conId;
505             PlatformMgr().PostEvent(&event);
506         }
507
508         if (err != CHIP_NO_ERROR)
509         {
510             ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %s", ErrorStr(err));
511             return false;
512         }
513         return true;
514     }
515     return false;
516 }
517
518 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data, uint32_t len)
519 {
520     osaEventFlags_t event_mask;
521
522 #if CHIP_DEVICE_CHIP0BLE_DEBUG
523     ChipLogProgress(DeviceLayer, "Trying to send event.");
524 #endif
525
526     if (connection_handle < 0 || handle <= 0)
527     {
528         ChipLogProgress(DeviceLayer, "BLE Event - Bad Handle");
529         return BLE_E_FAIL;
530     }
531
532     if (len > 0 && data == NULL)
533     {
534         ChipLogProgress(DeviceLayer, "BLE Event - Invalid Data");
535         return BLE_E_FAIL;
536     }
537
538     /************* Send the indication *************/
539     if (OSA_EventClear(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED) != osaStatus_Success)
540     {
541         ChipLogProgress(DeviceLayer, "BLE Event - Can't clear OSA Events");
542         return BLE_E_FAIL;
543     }
544
545     if (GattServer_SendInstantValueIndication(connection_handle, handle, len, data) != gBleSuccess_c)
546     {
547         ChipLogProgress(DeviceLayer, "BLE Event - Can't sent indication");
548         return BLE_E_FAIL;
549     }
550
551     if (OSA_EventWait(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED, FALSE,
552                       CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
553     {
554         ChipLogProgress(DeviceLayer, "BLE Event - OSA Event failed");
555         return BLE_E_FAIL;
556     }
557
558     if (event_mask & CHIP_BLE_KW_EVNT_INDICATION_FAILED)
559     {
560         ChipLogProgress(DeviceLayer, "BLE Event - Sent Failed");
561         return BLE_E_FAIL;
562     }
563
564 #if CHIP_DEVICE_CHIP0BLE_DEBUG
565     ChipLogProgress(DeviceLayer, "BLE Event - Sent :-) ");
566 #endif
567
568     return BLE_OK;
569 }
570 /*******************************************************************************
571  * Private functions
572  *******************************************************************************/
573 CHIP_ERROR BLEManagerImpl::blekw_controller_init(void)
574 {
575     mControllerTaskEvent = OSA_EventCreate(TRUE);
576
577     if (!mControllerTaskEvent)
578     {
579         return CHIP_ERROR_NO_MEMORY;
580     }
581
582     Controller_TaskEventInit(mControllerTaskEvent, gUseRtos_c);
583
584     /* Task creation */
585     if (pdPASS !=
586         xTaskCreate(Controller_TaskHandler, "controllerTask", CONTROLLER_TASK_STACK_SIZE, (void *) 0, CONTROLLER_TASK_PRIORITY,
587                     NULL))
588     {
589         return CHIP_ERROR_NO_MEMORY;
590     }
591
592     /* Setup Interrupt priorities of Interrupt handlers that are used
593      * in application to meet requirements of FreeRTOS */
594
595     // BLE_DP_IRQHandler
596     NVIC_SetPriority(BLE_DP_IRQn, configMAX_PRIORITIES - 1);
597     // BLE_DP0_IRQHandler
598     NVIC_SetPriority(BLE_DP0_IRQn, configMAX_PRIORITIES - 1);
599     // BLE_DP1_IRQHandler
600     NVIC_SetPriority(BLE_DP1_IRQn, configMAX_PRIORITIES - 1);
601     // BLE_DP2_IRQHandler
602     NVIC_SetPriority(BLE_DP2_IRQn, configMAX_PRIORITIES - 1);
603     // BLE_LL_ALL_IRQHandler
604     NVIC_SetPriority(BLE_LL_ALL_IRQn, configMAX_PRIORITIES - 1);
605
606     /* Check for available memory storage */
607     if (!Ble_CheckMemoryStorage())
608     {
609         return CHIP_ERROR_NO_MEMORY;
610     }
611
612     /* BLE Controller Init */
613     if (osaStatus_Success != Controller_Init(Ble_HciRecv))
614     {
615         return CHIP_ERROR_NO_MEMORY;
616     }
617
618     return CHIP_NO_ERROR;
619 }
620
621 void BLEManagerImpl::Host_Task(osaTaskParam_t argument)
622 {
623     Host_TaskHandler((void *) NULL);
624 }
625
626 CHIP_ERROR BLEManagerImpl::blekw_host_init(void)
627 {
628     /* Initialization of task related */
629     gHost_TaskEvent = OSA_EventCreate(TRUE);
630     if (!gHost_TaskEvent)
631     {
632         return CHIP_ERROR_NO_MEMORY;
633     }
634
635     /* Initialization of task message queue */
636     MSG_InitQueue(&gApp2Host_TaskQueue);
637     MSG_InitQueue(&gHci2Host_TaskQueue);
638
639     /* Task creation */
640     if (pdPASS != xTaskCreate(Host_Task, "hostTask", HOST_TASK_STACK_SIZE, (void *) 0, HOST_TASK_PRIORITY, NULL))
641     {
642         return CHIP_ERROR_NO_MEMORY;
643     }
644
645     return CHIP_NO_ERROR;
646 }
647
648 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_start_advertising(gapAdvertisingParameters_t * adv_params,
649                                                                   gapAdvertisingData_t * adv, gapScanResponseData_t * scnrsp)
650 {
651     osaEventFlags_t event_mask;
652
653     /************* Set the advertising parameters *************/
654     OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE));
655
656     /* Set the advertising parameters */
657     if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
658     {
659         vTaskDelay(1);
660
661         /* Retry, just to make sure before giving up and sending an error. */
662         if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
663         {
664             return BLE_E_SET_ADV_PARAMS;
665         }
666     }
667
668     if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE), FALSE,
669                       CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
670     {
671         return BLE_E_ADV_PARAMS_FAILED;
672     }
673
674     if (event_mask & CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED)
675     {
676         return BLE_E_ADV_PARAMS_FAILED;
677     }
678
679     /************* Set the advertising data *************/
680     OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE));
681
682     /* Set the advertising data */
683     if (Gap_SetAdvertisingData(adv, scnrsp) != gBleSuccess_c)
684     {
685         return BLE_E_SET_ADV_DATA;
686     }
687
688     if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE), FALSE,
689                       CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
690     {
691         return BLE_E_ADV_SETUP_FAILED;
692     }
693
694     if (event_mask & CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED)
695     {
696         return BLE_E_ADV_SETUP_FAILED;
697     }
698
699     /************* Start the advertising *************/
700     OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED));
701
702     if (gBleSuccess_c != Gap_CreateRandomDeviceAddress(NULL, NULL))
703     {
704         return BLE_E_SET_ADV_PARAMS;
705     }
706
707     if (OSA_EventWait(event_msg, CHIP_BLE_KW_EVNT_RND_ADDR_SET, FALSE, CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
708     {
709         return BLE_E_ADV_PARAMS_FAILED;
710     }
711
712     /* Start the advertising */
713     if (Gap_StartAdvertising(blekw_gap_advertising_cb, blekw_gap_connection_cb) != gBleSuccess_c)
714     {
715         return BLE_E_START_ADV;
716     }
717
718     if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED), FALSE, CHIP_BLE_KW_EVNT_TIMEOUT,
719                       &event_mask) != osaStatus_Success)
720     {
721         return BLE_E_START_ADV_FAILED;
722     }
723
724     if (event_mask & CHIP_BLE_KW_EVNT_ADV_FAILED)
725     {
726         return BLE_E_START_ADV_FAILED;
727     }
728
729 #if cPWR_UsePowerDownMode
730     PWR_AllowDeviceToSleep();
731 #endif
732
733     return BLE_OK;
734 }
735
736 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_stop_advertising(void)
737 {
738     osaEventFlags_t event_mask;
739     bleResult_t res;
740
741     OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED));
742
743     /* Stop the advertising data */
744     res = Gap_StopAdvertising();
745     if (res != gBleSuccess_c)
746     {
747         ChipLogProgress(DeviceLayer, "Failed to stop advertising %d", res);
748         return BLE_E_STOP;
749     }
750
751     if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED), FALSE, CHIP_BLE_KW_EVNT_TIMEOUT,
752                       &event_mask) != osaStatus_Success)
753     {
754         ChipLogProgress(DeviceLayer, "Stop advertising event timeout.");
755         return BLE_E_ADV_CHANGED;
756     }
757
758     if (event_mask & CHIP_BLE_KW_EVNT_ADV_FAILED)
759     {
760         ChipLogProgress(DeviceLayer, "Stop advertising flat out failed.");
761         return BLE_E_ADV_FAILED;
762     }
763
764     return BLE_OK;
765 }
766
767 CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
768 {
769     ble_err_t err;
770     CHIP_ERROR chipErr;
771     uint16_t discriminator;
772     uint16_t advInterval                                  = 0;
773     gapAdvertisingData_t adv                              = { 0 };
774     gapAdStructure_t adv_data[BLEKW_ADV_MAX_NO]           = { 0 };
775     gapAdStructure_t scan_rsp_data[BLEKW_SCAN_RSP_MAX_NO] = { 0 };
776     uint8_t advPayload[BLEKW_MAX_ADV_DATA_LEN]            = { 0 };
777     gapScanResponseData_t scanRsp                         = { 0 };
778     gapAdvertisingParameters_t adv_params                 = { 0 };
779     uint8_t chipAdvDataFlags                              = (gLeGeneralDiscoverableMode_c | gBrEdrNotSupported_c);
780     uint8_t chipOverBleService[2];
781     ChipBLEDeviceIdentificationInfo mDeviceIdInfo = { 0 };
782     uint8_t mDeviceIdInfoLength                   = 0;
783
784     chipErr = ConfigurationMgr().GetSetupDiscriminator(discriminator);
785     if (chipErr != CHIP_NO_ERROR)
786     {
787         return chipErr;
788     }
789
790     if (!mFlags.Has(Flags::kDeviceNameSet))
791     {
792         memset(mDeviceName, 0, kMaxDeviceNameLength);
793         snprintf(mDeviceName, kMaxDeviceNameLength, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator);
794     }
795
796     /**************** Prepare advertising data *******************************************/
797     adv.cNumAdStructures = BLEKW_ADV_MAX_NO;
798
799     chipErr = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo);
800     SuccessOrExit(chipErr);
801     mDeviceIdInfoLength = sizeof(mDeviceIdInfo);
802
803     if ((mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1) > BLEKW_MAX_ADV_DATA_LEN)
804     {
805         return CHIP_ERROR_INCORRECT_STATE;
806     }
807
808     adv_data[0].length = 0x02;
809     adv_data[0].adType = gAdFlags_c;
810     adv_data[0].aData  = (uint8_t *) (&chipAdvDataFlags);
811
812     adv_data[1].length = static_cast<uint8_t>(mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1);
813     adv_data[1].adType = gAdServiceData16bit_c;
814     memcpy(advPayload, ShortUUID_CHIPoBLEService, CHIP_ADV_SHORT_UUID_LEN);
815     memcpy(&advPayload[CHIP_ADV_SHORT_UUID_LEN], (void *) &mDeviceIdInfo, mDeviceIdInfoLength);
816     adv_data[1].aData = advPayload;
817
818     adv.aAdStructures = adv_data;
819     /**************** Prepare scan response data *******************************************/
820     scanRsp.cNumAdStructures = BLEKW_SCAN_RSP_MAX_NO;
821
822     scan_rsp_data[0].length = static_cast<uint8_t>(strlen(mDeviceName) + 1);
823     scan_rsp_data[0].adType = gAdCompleteLocalName_c;
824     scan_rsp_data[0].aData  = (uint8_t *) mDeviceName;
825
826     scan_rsp_data[1].length = sizeof(chipOverBleService) + 1;
827     scan_rsp_data[1].adType = gAdComplete16bitServiceList_c;
828     chipOverBleService[0]   = ShortUUID_CHIPoBLEService[0];
829     chipOverBleService[1]   = ShortUUID_CHIPoBLEService[1];
830     scan_rsp_data[1].aData  = (uint8_t *) chipOverBleService;
831
832     scanRsp.aAdStructures = scan_rsp_data;
833
834     /**************** Prepare advertising parameters *************************************/
835     if (mFlags.Has(Flags::kFastAdvertisingEnabled))
836     {
837         advInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX;
838     }
839     else
840     {
841         advInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
842     }
843
844     adv_params.minInterval = adv_params.maxInterval = advInterval;
845     adv_params.advertisingType                      = gAdvConnectableUndirected_c;
846     adv_params.ownAddressType                       = gBleAddrTypePublic_c;
847     adv_params.peerAddressType                      = gBleAddrTypePublic_c;
848     memset(adv_params.peerAddress, 0, gcBleDeviceAddressSize_c);
849     adv_params.channelMap   = (gapAdvertisingChannelMapFlags_t)(gAdvChanMapFlag37_c | gAdvChanMapFlag38_c | gAdvChanMapFlag39_c);
850     adv_params.filterPolicy = gProcessAll_c;
851
852     err = blekw_start_advertising(&adv_params, &adv, &scanRsp);
853     if (err == BLE_OK)
854     {
855         ChipLogProgress(DeviceLayer, "Started Advertising.");
856     }
857     else
858     {
859         ChipLogProgress(DeviceLayer, "Advertising error!");
860         return CHIP_ERROR_INCORRECT_STATE;
861     }
862
863 exit:
864     return chipErr;
865 }
866
867 CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
868 {
869     uint32_t bleAdvTimeoutMs = 0;
870
871     mFlags.Set(Flags::kAdvertising);
872     mFlags.Clear(Flags::kRestartAdvertising);
873
874     if (mFlags.Has(Flags::kFastAdvertisingEnabled))
875     {
876         bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT;
877     }
878     else
879     {
880         bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT;
881     }
882     StartBleAdvTimeoutTimer(bleAdvTimeoutMs);
883
884     return ConfigureAdvertisingData();
885 }
886
887 CHIP_ERROR BLEManagerImpl::StopAdvertising(void)
888 {
889     ble_err_t err;
890
891     if (mFlags.Has(Flags::kAdvertising))
892     {
893         mFlags.Clear(Flags::kAdvertising);
894         mFlags.Clear(Flags::kFastAdvertisingEnabled);
895         mFlags.Clear(Flags::kRestartAdvertising);
896
897         err = blekw_stop_advertising();
898         if (err != BLE_OK)
899         {
900             return CHIP_ERROR_INCORRECT_STATE;
901         }
902     }
903     CancelBleAdvTimeoutTimer();
904
905     return CHIP_NO_ERROR;
906 }
907
908 void BLEManagerImpl::DriveBLEState(void)
909 {
910     CHIP_ERROR err = CHIP_NO_ERROR;
911
912     // Check if BLE stack is initialized
913     VerifyOrExit(mFlags.Has(Flags::kK32WBLEStackInitialized), /* */);
914
915 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
916     if (ConfigurationMgr().IsFullyProvisioned())
917     {
918         mFlags.Clear(Flags::kAdvertisingEnabled);
919         ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned");
920     }
921 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
922
923     // Start advertising if needed...
924     if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled))
925     {
926         // Start/re-start advertising if not already started, or if there is a pending change
927         // to the advertising configuration.
928         if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kRestartAdvertising))
929         {
930             err = StartAdvertising();
931             SuccessOrExit(err);
932         }
933     }
934     // Otherwise, stop advertising if it is enabled.
935     else if (mFlags.Has(Flags::kAdvertising))
936     {
937         err = StopAdvertising();
938         SuccessOrExit(err);
939         ChipLogProgress(DeviceLayer, "Stopped Advertising");
940     }
941
942 exit:
943     if (err != CHIP_NO_ERROR)
944     {
945         ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
946         mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
947     }
948 }
949
950 void BLEManagerImpl::DriveBLEState(intptr_t arg)
951 {
952     sInstance.DriveBLEState();
953 }
954
955 /*******************************************************************************
956  * BLE App Task Processing
957  *******************************************************************************/
958 void BLEManagerImpl::bleAppTask(void * p_arg)
959 {
960     while (1)
961     {
962         xEventGroupWaitBits(bleAppTaskLoopEvent, LOOP_EV_BLE, true, false, portMAX_DELAY);
963
964         PlatformMgr().LockChipStack();
965
966         if (MSG_Pending(&blekw_msg_list))
967         {
968             /* There is message from the BLE tasks to solve */
969             blekw_msg_t * msg = (blekw_msg_t *) MSG_DeQueue(&blekw_msg_list);
970
971             assert(msg != NULL);
972
973             if (msg->type == BLE_KW_MSG_ERROR)
974             {
975                 ChipLogProgress(DeviceLayer, "BLE Fatal Error: %d.\n", msg->data.u8);
976             }
977             else if (msg->type == BLE_KW_MSG_CONNECTED)
978             {
979                 sInstance.HandleConnectEvent(msg);
980             }
981             else if (msg->type == BLE_KW_MSG_DISCONNECTED)
982             {
983                 sInstance.HandleConnectionCloseEvent(msg);
984             }
985             else if (msg->type == BLE_KW_MSG_MTU_CHANGED)
986             {
987                 blekw_start_connection_timeout();
988                 ChipLogProgress(DeviceLayer, "BLE MTU size has been changed to %d.", msg->data.u16);
989             }
990             else if (msg->type == BLE_KW_MSG_ATT_WRITTEN || msg->type == BLE_KW_MSG_ATT_LONG_WRITTEN ||
991                      msg->type == BLE_KW_MSG_ATT_CCCD_WRITTEN)
992             {
993                 sInstance.HandleWriteEvent(msg);
994             }
995             else if (msg->type == BLE_KW_MSG_FORCE_DISCONNECT)
996             {
997                 ChipLogProgress(DeviceLayer, "BLE connection timeout: Forcing disconnection.");
998
999                 /* Set the advertising parameters */
1000                 if (Gap_Disconnect(device_id) != gBleSuccess_c)
1001                 {
1002                     ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
1003                 }
1004             }
1005
1006             /* Freed the message from the queue */
1007             MSG_Free(msg);
1008         }
1009         PlatformMgr().UnlockChipStack();
1010     }
1011 }
1012
1013 void BLEManagerImpl::HandleConnectEvent(blekw_msg_t * msg)
1014 {
1015     uint8_t device_id_loc = msg->data.u8;
1016     ChipLogProgress(DeviceLayer, "BLE is connected with device: %d.\n", device_id_loc);
1017
1018     device_id = device_id_loc;
1019     blekw_start_connection_timeout();
1020     sInstance.AddConnection(device_id_loc);
1021     mFlags.Set(Flags::kRestartAdvertising);
1022     PlatformMgr().ScheduleWork(DriveBLEState, 0);
1023 }
1024
1025 void BLEManagerImpl::HandleConnectionCloseEvent(blekw_msg_t * msg)
1026 {
1027     uint8_t device_id_loc = msg->data.u8;
1028     ChipLogProgress(DeviceLayer, "BLE is disconnected with device: %d.\n", device_id_loc);
1029
1030     if (sInstance.RemoveConnection(device_id_loc))
1031     {
1032         ChipDeviceEvent event;
1033         event.Type                           = DeviceEventType::kCHIPoBLEConnectionError;
1034         event.CHIPoBLEConnectionError.ConId  = device_id_loc;
1035         event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED;
1036
1037         PlatformMgr().PostEvent(&event);
1038         mFlags.Set(Flags::kRestartAdvertising);
1039         mFlags.Set(Flags::kFastAdvertisingEnabled);
1040         PlatformMgr().ScheduleWork(DriveBLEState, 0);
1041     }
1042 }
1043
1044 void BLEManagerImpl::HandleWriteEvent(blekw_msg_t * msg)
1045 {
1046     blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1047     attErrorCode_t status                  = gAttErrCodeNoError_c;
1048
1049 #if CHIP_DEVICE_CHIP0BLE_DEBUG
1050     ChipLogProgress(DeviceLayer, "Attribute write request(device: %d,handle: %d).", att_wr_data->device_id, att_wr_data->handle);
1051 #endif
1052
1053     blekw_start_connection_timeout();
1054
1055     if (value_chipoble_rx == att_wr_data->handle)
1056     {
1057         sInstance.HandleRXCharWrite(msg);
1058     }
1059     else if (cccd_chipoble_tx == att_wr_data->handle)
1060     {
1061         sInstance.HandleTXCharCCCDWrite(msg);
1062     }
1063
1064     /* TODO: do we need to send the status also for CCCD_WRITTEN? */
1065     if (msg->type != BLE_KW_MSG_ATT_CCCD_WRITTEN)
1066     {
1067         bleResult_t res = GattServer_SendAttributeWrittenStatus(att_wr_data->device_id, att_wr_data->handle, status);
1068
1069         if (res != gBleSuccess_c)
1070         {
1071             ChipLogProgress(DeviceLayer, "GattServer_SendAttributeWrittenStatus returned %d", res);
1072         }
1073     }
1074 }
1075
1076 void BLEManagerImpl::HandleTXCharCCCDWrite(blekw_msg_t * msg)
1077 {
1078     CHIP_ERROR err = CHIP_NO_ERROR;
1079     CHIPoBLEConState * bleConnState;
1080     bool indicationsEnabled;
1081     ChipDeviceEvent event;
1082     blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1083     uint16_t writeLen                      = att_wr_data->length;
1084     uint8_t * data                         = att_wr_data->data;
1085
1086     VerifyOrExit(writeLen != 0, err = CHIP_ERROR_INCORRECT_STATE);
1087     bleConnState = GetConnectionState(att_wr_data->device_id, false);
1088     VerifyOrExit(bleConnState != NULL, err = CHIP_ERROR_NO_MEMORY);
1089
1090     /* Determine if the client is enabling or disabling indications.
1091      * TODO: Check the indications corresponding bit
1092      */
1093     indicationsEnabled = (*data);
1094
1095 #if CHIP_DEVICE_CHIP0BLE_DEBUG
1096     ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", indicationsEnabled ? "subscribe" : "unsubscribe");
1097 #endif
1098
1099     if (indicationsEnabled)
1100     {
1101         // If indications are not already enabled for the connection...
1102         if (!bleConnState->subscribed)
1103         {
1104             bleConnState->subscribed = 1;
1105             /* Post an event to the CHIP queue to process either a CHIPoBLE
1106              * Subscribe or Unsubscribe based on whether the client
1107              * is enabling or disabling indications. */
1108             {
1109                 event.Type                    = DeviceEventType::kCHIPoBLESubscribe;
1110                 event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
1111                 PlatformMgr().PostEvent(&event);
1112             }
1113         }
1114     }
1115     else
1116     {
1117         bleConnState->subscribed      = 0;
1118         event.Type                    = DeviceEventType::kCHIPoBLEUnsubscribe;
1119         event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
1120         PlatformMgr().PostEvent(&event);
1121     }
1122
1123 exit:
1124     if (err != CHIP_NO_ERROR)
1125     {
1126         ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err));
1127     }
1128 }
1129
1130 void BLEManagerImpl::HandleRXCharWrite(blekw_msg_t * msg)
1131 {
1132     CHIP_ERROR err = CHIP_NO_ERROR;
1133     System::PacketBufferHandle buf;
1134     blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1135     uint16_t writeLen                      = att_wr_data->length;
1136     uint8_t * data                         = att_wr_data->data;
1137
1138     // Copy the data to a PacketBuffer.
1139     buf = System::PacketBufferHandle::New(writeLen);
1140     VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);
1141     VerifyOrExit(buf->AvailableDataLength() >= writeLen, err = CHIP_ERROR_BUFFER_TOO_SMALL);
1142     memcpy(buf->Start(), data, writeLen);
1143     buf->SetDataLength(writeLen);
1144
1145 #if CHIP_DEVICE_CHIP0BLE_DEBUG
1146     ChipLogDetail(DeviceLayer,
1147                   "Write request/command received for"
1148                   "CHIPoBLE RX characteristic (con %" PRIu16 ", len %" PRIu16 ")",
1149                   att_wr_data->device_id, buf->DataLength());
1150 #endif
1151
1152     // Post an event to the CHIP queue to deliver the data into the CHIP stack.
1153     {
1154         ChipDeviceEvent event;
1155         event.Type                        = DeviceEventType::kCHIPoBLEWriteReceived;
1156         event.CHIPoBLEWriteReceived.ConId = att_wr_data->device_id;
1157         event.CHIPoBLEWriteReceived.Data  = std::move(buf).UnsafeRelease();
1158         PlatformMgr().PostEvent(&event);
1159     }
1160 exit:
1161     if (err != CHIP_NO_ERROR)
1162     {
1163         ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err));
1164     }
1165 }
1166 /*******************************************************************************
1167  * BLE stack callbacks
1168  *******************************************************************************/
1169 void BLEManagerImpl::blekw_generic_cb(gapGenericEvent_t * pGenericEvent)
1170 {
1171     /* Call BLE Conn Manager */
1172     BleConnManager_GenericEvent(pGenericEvent);
1173
1174     switch (pGenericEvent->eventType)
1175     {
1176     case gInternalError_c:
1177         /* Notify the CHIP that the BLE hardware report fail */
1178         ChipLogProgress(DeviceLayer, "BLE Internal Error: Code 0x%04X, Source 0x%08X, HCI OpCode %d.\n",
1179                         pGenericEvent->eventData.internalError.errorCode, pGenericEvent->eventData.internalError.errorSource,
1180                         pGenericEvent->eventData.internalError.hciCommandOpcode);
1181         (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_ERROR);
1182         break;
1183
1184     case gAdvertisingSetupFailed_c:
1185         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED);
1186         break;
1187
1188     case gAdvertisingParametersSetupComplete_c:
1189         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE);
1190         break;
1191
1192     case gAdvertisingDataSetupComplete_c:
1193         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE);
1194         break;
1195
1196     case gRandomAddressReady_c:
1197         Gap_SetRandomAddress(pGenericEvent->eventData.addrReady.aAddress);
1198         break;
1199
1200     case gRandomAddressSet_c:
1201         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_RND_ADDR_SET);
1202         break;
1203
1204     case gInitializationComplete_c:
1205         /* Common GAP configuration */
1206         BleConnManager_GapCommonConfig();
1207
1208         /* Set the local synchronization event */
1209         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INIT_COMPLETE);
1210         break;
1211     default:
1212         break;
1213     }
1214 }
1215
1216 void BLEManagerImpl::blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent)
1217 {
1218     if (pAdvertisingEvent->eventType == gAdvertisingStateChanged_c)
1219     {
1220         /* Set the local synchronization event */
1221         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_CHANGED);
1222     }
1223     else
1224     {
1225         /* The advertisement start failed */
1226         ChipLogProgress(DeviceLayer, "Advertising failed: event=%d reason=0x%04X\n", pAdvertisingEvent->eventType,
1227                         pAdvertisingEvent->eventData.failReason);
1228
1229         /* Set the local synchronization event */
1230         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_FAILED);
1231     }
1232 }
1233
1234 void BLEManagerImpl::blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent)
1235 {
1236     /* Call BLE Conn Manager */
1237     BleConnManager_GapPeripheralEvent(deviceId, pConnectionEvent);
1238
1239     if (pConnectionEvent->eventType == gConnEvtConnected_c)
1240     {
1241         /* Notify App Task that the BLE is connected now */
1242         (void) blekw_msg_add_u8(BLE_KW_MSG_CONNECTED, (uint8_t) deviceId);
1243     }
1244     else if (pConnectionEvent->eventType == gConnEvtDisconnected_c)
1245     {
1246         blekw_stop_connection_timeout();
1247
1248         /* Notify App Task that the BLE is disconnected now */
1249         (void) blekw_msg_add_u8(BLE_KW_MSG_DISCONNECTED, (uint8_t) deviceId);
1250     }
1251     else if (pConnectionEvent->eventType == gConnEvtPairingRequest_c)
1252     {
1253         /* Reject request for pairing */
1254         Gap_RejectPairing(deviceId, gPairingNotSupported_c);
1255     }
1256     else if (pConnectionEvent->eventType == gConnEvtAuthenticationRejected_c)
1257     {
1258         ChipLogProgress(DeviceLayer, "BLE Authentication rejected (reason:%d).\n",
1259                         pConnectionEvent->eventData.authenticationRejectedEvent.rejectReason);
1260     }
1261 }
1262
1263 /* Called by BLE when a connect is received */
1264 void BLEManagerImpl::BLE_SignalFromISRCallback(void)
1265 {
1266     /* TODO: Low Power */
1267 }
1268
1269 void BLEManagerImpl::blekw_connection_timeout_cb(TimerHandle_t timer)
1270 {
1271     (void) blekw_msg_add_u8(BLE_KW_MSG_FORCE_DISCONNECT, 0);
1272 }
1273
1274 void BLEManagerImpl::blekw_start_connection_timeout(void)
1275 {
1276     xTimerReset(connectionTimeout, 0);
1277 }
1278
1279 void BLEManagerImpl::blekw_stop_connection_timeout(void)
1280 {
1281     ChipLogProgress(DeviceLayer, "Stopped connectionTimeout timer.");
1282     xTimerStop(connectionTimeout, 0);
1283 }
1284
1285 void BLEManagerImpl::blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent)
1286 {
1287     switch (pServerEvent->eventType)
1288     {
1289     case gEvtMtuChanged_c: {
1290         uint16_t tempMtu = 0;
1291
1292         (void) Gatt_GetMtu(deviceId, &tempMtu);
1293         blekw_msg_add_u16(BLE_KW_MSG_MTU_CHANGED, tempMtu);
1294         break;
1295     }
1296
1297     case gEvtAttributeWritten_c:
1298         blekw_msg_add_att_written(BLE_KW_MSG_ATT_WRITTEN, deviceId, pServerEvent->eventData.attributeWrittenEvent.handle,
1299                                   pServerEvent->eventData.attributeWrittenEvent.aValue,
1300                                   pServerEvent->eventData.attributeWrittenEvent.cValueLength);
1301         break;
1302
1303     case gEvtLongCharacteristicWritten_c:
1304         blekw_msg_add_att_written(BLE_KW_MSG_ATT_LONG_WRITTEN, deviceId, pServerEvent->eventData.longCharWrittenEvent.handle,
1305                                   pServerEvent->eventData.longCharWrittenEvent.aValue,
1306                                   pServerEvent->eventData.longCharWrittenEvent.cValueLength);
1307         break;
1308
1309     case gEvtAttributeRead_c:
1310         blekw_msg_add_att_read(BLE_KW_MSG_ATT_READ, deviceId, pServerEvent->eventData.attributeReadEvent.handle);
1311         break;
1312
1313     case gEvtCharacteristicCccdWritten_c: {
1314         uint16_t cccd_val = pServerEvent->eventData.charCccdWrittenEvent.newCccd;
1315
1316         blekw_msg_add_att_written(BLE_KW_MSG_ATT_CCCD_WRITTEN, deviceId, pServerEvent->eventData.charCccdWrittenEvent.handle,
1317                                   (uint8_t *) &cccd_val, 2);
1318         break;
1319     }
1320
1321     case gEvtHandleValueConfirmation_c:
1322         /* Set the local synchronization event */
1323         OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED);
1324         break;
1325
1326     case gEvtError_c:
1327         if (pServerEvent->eventData.procedureError.procedureType == gSendIndication_c)
1328         {
1329             /* Set the local synchronization event */
1330             OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INDICATION_FAILED);
1331         }
1332         else
1333         {
1334             ChipLogProgress(DeviceLayer, "BLE Gatt Server Error: Code 0x%04X, Source %d.\n",
1335                             pServerEvent->eventData.procedureError.error, pServerEvent->eventData.procedureError.procedureType);
1336
1337             /* Notify CHIP BLE App Task that the BLE hardware report fail */
1338             (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_GATT_ERROR);
1339         }
1340         break;
1341
1342     default:
1343         break;
1344     }
1345 }
1346 /*******************************************************************************
1347  * Add to message queue functions
1348  *******************************************************************************/
1349 CHIP_ERROR BLEManagerImpl::blekw_msg_add_att_written(blekw_msg_type_t type, uint8_t device_id, uint16_t handle, uint8_t * data,
1350                                                      uint16_t length)
1351 {
1352     blekw_msg_t * msg = NULL;
1353     blekw_att_written_data_t * att_wr_data;
1354
1355     /* Allocate a buffer with enough space to store the packet */
1356     msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t) + sizeof(blekw_att_written_data_t) + length);
1357
1358     if (!msg)
1359     {
1360         return CHIP_ERROR_NO_MEMORY;
1361         assert(0);
1362     }
1363
1364     msg->type              = type;
1365     msg->length            = sizeof(blekw_att_written_data_t) + length;
1366     att_wr_data            = (blekw_att_written_data_t *) msg->data.data;
1367     att_wr_data->device_id = device_id;
1368     att_wr_data->handle    = handle;
1369     att_wr_data->length    = length;
1370     FLib_MemCpy(att_wr_data->data, data, length);
1371
1372     /* Put message in the queue */
1373     if (gListOk_c != MSG_Queue(&blekw_msg_list, msg))
1374     {
1375         assert(0);
1376     }
1377
1378     /* Notify BLE-APP Task to serve the BLE subsystem */
1379     blekw_new_data_received_notification(LOOP_EV_BLE);
1380
1381     return CHIP_NO_ERROR;
1382 }
1383
1384 CHIP_ERROR BLEManagerImpl::blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle)
1385 {
1386     blekw_msg_t * msg = NULL;
1387     blekw_att_read_data_t * att_rd_data;
1388
1389     /* Allocate a buffer with enough space to store the packet */
1390     msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t) + sizeof(blekw_att_read_data_t));
1391
1392     if (!msg)
1393     {
1394         return CHIP_ERROR_NO_MEMORY;
1395         assert(0);
1396     }
1397
1398     msg->type              = type;
1399     msg->length            = sizeof(blekw_att_read_data_t);
1400     att_rd_data            = (blekw_att_read_data_t *) msg->data.data;
1401     att_rd_data->device_id = device_id;
1402     att_rd_data->handle    = handle;
1403
1404     /* Put message in the queue */
1405     if (gListOk_c != MSG_Queue(&blekw_msg_list, msg))
1406     {
1407         assert(0);
1408     }
1409
1410     /* Notify BLE-APP Task to serve the BLE subsystem */
1411     blekw_new_data_received_notification(LOOP_EV_BLE);
1412
1413     return CHIP_NO_ERROR;
1414 }
1415
1416 CHIP_ERROR BLEManagerImpl::blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data)
1417 {
1418     blekw_msg_t * msg = NULL;
1419
1420     /* Allocate a buffer with enough space to store the packet */
1421     msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t));
1422
1423     if (!msg)
1424     {
1425         return CHIP_ERROR_NO_MEMORY;
1426     }
1427
1428     msg->type    = type;
1429     msg->length  = 0;
1430     msg->data.u8 = data;
1431
1432     /* Put message in the queue */
1433     MSG_Queue(&blekw_msg_list, msg);
1434
1435     /* Notify BLE-APP Task to serve the BLE subsystem */
1436     blekw_new_data_received_notification(LOOP_EV_BLE);
1437
1438     return CHIP_NO_ERROR;
1439 }
1440
1441 CHIP_ERROR BLEManagerImpl::blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data)
1442 {
1443     blekw_msg_t * msg = NULL;
1444
1445     /* Allocate a buffer with enough space to store the packet */
1446     msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t));
1447
1448     if (!msg)
1449     {
1450         return CHIP_ERROR_NO_MEMORY;
1451     }
1452
1453     msg->type     = type;
1454     msg->length   = 0;
1455     msg->data.u16 = data;
1456
1457     /* Put message in the queue */
1458     MSG_Queue(&blekw_msg_list, msg);
1459
1460     /* Notify BLE-APP Task to serve the BLE subsystem */
1461     blekw_new_data_received_notification(LOOP_EV_BLE);
1462
1463     return CHIP_NO_ERROR;
1464 }
1465
1466 /*******************************************************************************
1467  * FreeRTOS Task Management Functions
1468  *******************************************************************************/
1469 void BLEManagerImpl::blekw_new_data_received_notification(uint32_t mask)
1470 {
1471     portBASE_TYPE taskToWake = pdFALSE;
1472
1473     if (__get_IPSR())
1474     {
1475         if (xEventGroupSetBitsFromISR(bleAppTaskLoopEvent, mask, &taskToWake) == pdPASS)
1476         {
1477             /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
1478                    switch should be requested.  The macro used is port specific and will
1479                    be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
1480                    the documentation page for the port being used. */
1481             portYIELD_FROM_ISR(taskToWake);
1482         }
1483     }
1484     else
1485     {
1486         xEventGroupSetBits(bleAppTaskLoopEvent, mask);
1487     }
1488 }
1489
1490 void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer)
1491 {
1492     if (sInstance.mFlags.Has(Flags::kFastAdvertisingEnabled))
1493     {
1494         ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisment");
1495
1496         sInstance.mFlags.Clear(Flags::kFastAdvertisingEnabled);
1497         // stop advertiser, change interval and restart it;
1498         sInstance.StopAdvertising();
1499         sInstance.StartAdvertising();
1500         sInstance.StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT); // Slow advertise for 15 Minutes
1501     }
1502     else if (sInstance._IsAdvertisingEnabled())
1503     {
1504         // advertisement expired. we stop advertissing
1505         ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertisement");
1506         sInstance.StopAdvertising();
1507     }
1508
1509     return;
1510 }
1511
1512 void BLEManagerImpl::CancelBleAdvTimeoutTimer(void)
1513 {
1514     if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL)
1515     {
1516         ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer");
1517     }
1518 }
1519
1520 void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs)
1521 {
1522     if (xTimerIsTimerActive(sbleAdvTimeoutTimer))
1523     {
1524         CancelBleAdvTimeoutTimer();
1525     }
1526
1527     // timer is not active, change its period to required value (== restart).
1528     // FreeRTOS- Block for a maximum of 100 ticks if the change period command
1529     // cannot immediately be sent to the timer command queue.
1530     if (xTimerChangePeriod(sbleAdvTimeoutTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS)
1531     {
1532         ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer");
1533     }
1534 }
1535
1536 } // namespace Internal
1537 } // namespace DeviceLayer
1538 } // namespace chip
1539 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE