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