3 * Copyright (c) 2020-2021 Project CHIP Authors
4 * Copyright (c) 2020 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * Provides an implementation of the BLEManager singleton object
23 * for the K32W platforms.
26 /* this file behaves like a config.h, comes first */
27 #include <platform/internal/CHIPDeviceLayerInternal.h>
29 #include <crypto/CHIPCryptoPAL.h>
31 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
33 #include <ble/CHIPBleServiceData.h>
37 #include "gatt_db_app_interface.h"
38 #include "gatt_db_handles.h"
41 /*******************************************************************************
43 *******************************************************************************/
44 extern "C" bool_t Ble_ConfigureHostStackConfig(void);
45 extern "C" void (*pfBLE_SignalFromISR)(void);
46 extern "C" bool_t Ble_CheckMemoryStorage(void);
48 extern osaEventId_t gHost_TaskEvent;
49 extern msgQueue_t gApp2Host_TaskQueue;
50 extern msgQueue_t gHci2Host_TaskQueue;
52 using namespace ::chip;
53 using namespace ::chip::Ble;
56 namespace DeviceLayer {
61 /*******************************************************************************
62 * Macros & Constants definitions
63 *******************************************************************************/
64 /* Timeout of BLE commands */
65 #define CHIP_BLE_KW_EVNT_TIMEOUT 300
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
88 #define LOOP_EV_BLE (0x08)
90 /* controller task configuration */
91 #define CONTROLLER_TASK_PRIORITY (6U)
92 #define CONTROLLER_TASK_STACK_SIZE (gControllerTaskStackSize_c / sizeof(StackType_t))
94 /* host task configuration */
95 #define HOST_TASK_PRIORITY (3U)
96 #define HOST_TASK_STACK_SIZE (gHost_TaskStackSize_c / sizeof(StackType_t))
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)
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)
108 /* Message list used to synchronize asynchronous messages from the KW BLE tasks */
109 anchor_t blekw_msg_list;
111 /* Used to manage asynchronous events from BLE Stack: e.g.: GAP setup finished */
112 osaEventId_t event_msg;
114 osaEventId_t mControllerTaskEvent;
115 TimerHandle_t connectionTimeout;
117 /* Used by BLE App Task to handle asynchronous GATT events */
118 EventGroupHandle_t bleAppTaskLoopEvent;
120 /* keep the device ID of the connected peer */
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,
126 const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
130 BLEManagerImpl BLEManagerImpl::sInstance;
132 CHIP_ERROR BLEManagerImpl::_Init()
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 };
139 mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
141 // Check if BLE stack is initialized
142 VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
144 // Initialize the Chip BleLayer.
145 err = BleLayer::Init(this, this, &SystemLayer);
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);
153 pfBLE_SignalFromISR = BLE_SignalFromISRCallback;
155 /* Set the config structure to the host stack */
156 VerifyOrExit(Ble_ConfigureHostStackConfig() == TRUE, err = CHIP_ERROR_INCORRECT_STATE);
158 /* Prepare callback input queue.*/
159 MSG_InitQueue(&blekw_msg_list);
161 /* Create the connection timeout timer. */
163 xTimerCreate("bleTimeoutTmr", pdMS_TO_TICKS(CHIP_BLE_KW_CONN_TIMEOUT), pdFALSE, (void *) 0, blekw_connection_timeout_cb);
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);
174 XCVR_TemperatureUpdate(BOARD_GetTemperature());
175 VerifyOrExit(XCVR_Init(BLE_MODE, DR_2MBPS) == gXcvrSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);
177 /* Create BLE Controller Task */
178 VerifyOrExit(blekw_controller_init() == CHIP_NO_ERROR, err = CHIP_ERROR_INCORRECT_STATE);
180 /* Create BLE Host Task */
181 VerifyOrExit(blekw_host_init() == CHIP_NO_ERROR, err = CHIP_ERROR_INCORRECT_STATE);
183 /* BLE Host Stack Init */
184 Ble_HostInitialize(blekw_generic_cb, (hciHostToControllerInterface_t) Hci_SendPacketToController);
186 /* Register the GATT server callback */
187 VerifyOrExit(GattServer_RegisterCallback(blekw_gatt_server_cb) == gBleSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);
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) ==
192 err = CHIP_ERROR_INCORRECT_STATE);
194 GattServer_RegisterHandlesForWriteNotifications(1, attChipRxHandle);
196 mFlags.Set(Flags::kK32WBLEStackInitialized);
197 mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false);
198 PlatformMgr().ScheduleWork(DriveBLEState, 0);
204 uint16_t BLEManagerImpl::_NumConnections(void)
206 uint16_t numCons = 0;
207 for (uint16_t i = 0; i < kMaxConnections; i++)
209 if (mBleConnections[i].allocated)
218 bool BLEManagerImpl::_IsAdvertisingEnabled(void)
220 return mFlags.Has(Flags::kAdvertisingEnabled);
223 bool BLEManagerImpl::_IsFastAdvertisingEnabled(void)
225 return mFlags.Has(Flags::kFastAdvertisingEnabled);
228 bool BLEManagerImpl::RemoveConnection(uint8_t connectionHandle)
230 CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true);
233 if (bleConnState != NULL)
235 memset(bleConnState, 0, sizeof(CHIPoBLEConState));
242 void BLEManagerImpl::AddConnection(uint8_t connectionHandle)
244 CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true);
246 if (bleConnState != NULL)
248 memset(bleConnState, 0, sizeof(CHIPoBLEConState));
249 bleConnState->allocated = 1;
250 bleConnState->connectionHandle = connectionHandle;
254 BLEManagerImpl::CHIPoBLEConState * BLEManagerImpl::GetConnectionState(uint8_t connectionHandle, bool allocate)
256 uint8_t freeIndex = kMaxConnections;
258 for (uint8_t i = 0; i < kMaxConnections; i++)
260 if (mBleConnections[i].allocated == 1)
262 if (mBleConnections[i].connectionHandle == connectionHandle)
264 return &mBleConnections[i];
268 else if (i < freeIndex)
276 if (freeIndex < kMaxConnections)
278 return &mBleConnections[freeIndex];
281 ChipLogError(DeviceLayer, "Failed to allocate CHIPoBLEConState");
287 CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val)
289 CHIP_ERROR err = CHIP_NO_ERROR;
291 VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
292 VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
294 if (val != mServiceMode)
297 PlatformMgr().ScheduleWork(DriveBLEState, 0);
304 CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
306 CHIP_ERROR err = CHIP_NO_ERROR;
308 VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
310 if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
312 mFlags.Set(Flags::kAdvertisingEnabled, val);
313 PlatformMgr().ScheduleWork(DriveBLEState, 0);
320 CHIP_ERROR BLEManagerImpl::_SetFastAdvertisingEnabled(bool val)
322 CHIP_ERROR err = CHIP_NO_ERROR;
324 VerifyOrExit(mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
326 if (mFlags.Has(Flags::kFastAdvertisingEnabled) != val)
328 mFlags.Set(Flags::kFastAdvertisingEnabled, val);
329 PlatformMgr().ScheduleWork(DriveBLEState, 0);
336 CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
338 if (strlen(mDeviceName) >= bufSize)
340 return CHIP_ERROR_BUFFER_TOO_SMALL;
342 strcpy(buf, mDeviceName);
343 return CHIP_NO_ERROR;
346 CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName)
348 if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported)
350 return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
352 if (deviceName != NULL && deviceName[0] != 0)
354 if (strlen(deviceName) >= kMaxDeviceNameLength)
356 return CHIP_ERROR_INVALID_ARGUMENT;
358 memset(mDeviceName, 0, kMaxDeviceNameLength);
359 strcpy(mDeviceName, deviceName);
360 mFlags.Set(Flags::kDeviceNameSet);
361 ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName);
366 mFlags.Clear(Flags::kDeviceNameSet);
369 return CHIP_NO_ERROR;
372 void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
376 case DeviceEventType::kCHIPoBLESubscribe:
377 ChipDeviceEvent connEstEvent;
379 HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
380 connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
381 PlatformMgr().PostEvent(&connEstEvent);
384 case DeviceEventType::kCHIPoBLEUnsubscribe:
385 HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
388 case DeviceEventType::kCHIPoBLEWriteReceived:
389 HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX,
390 PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
393 case DeviceEventType::kCHIPoBLEConnectionError:
394 HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
397 case DeviceEventType::kCHIPoBLEIndicateConfirm:
398 HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
401 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
402 case DeviceEventType::kServiceProvisioningChange:
403 ChipLogProgress(DeviceLayer, "_OnPlatformEvent kServiceProvisioningChange");
405 mFlags.Clear(Flags::kAdvertisingEnabled);
406 PlatformMgr().ScheduleWork(DriveBLEState, 0);
408 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
415 bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
417 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported");
421 bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
423 ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported");
427 bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
429 ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId);
431 if (Gap_Disconnect(conId) != gBleSuccess_c)
433 ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
440 uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
442 uint16_t tempMtu = 0;
443 (void) Gatt_GetMtu(conId, &tempMtu);
448 bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
449 PacketBufferHandle pBuf)
451 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported");
455 bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
456 PacketBufferHandle pBuf)
458 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported");
462 bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
463 const ChipBleUUID * svcId, const ChipBleUUID * charId)
465 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported");
469 void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId)
474 bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
475 PacketBufferHandle data)
477 CHIP_ERROR err = CHIP_NO_ERROR;
478 uint16_t cId = (UUIDsMatch(&ChipUUID_CHIPoBLEChar_TX, charId) ? value_chipoble_tx : 0);
479 ChipDeviceEvent event;
483 if (blekw_send_event(conId, cId, data->Start(), data->DataLength()) != BLE_OK)
485 err = CHIP_ERROR_SENDING_BLOCKED;
489 event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm;
490 event.CHIPoBLEIndicateConfirm.ConId = conId;
491 PlatformMgr().PostEvent(&event);
494 if (err != CHIP_NO_ERROR)
496 ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %s", ErrorStr(err));
504 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data, uint32_t len)
506 osaEventFlags_t event_mask;
508 #if CHIP_DEVICE_CHIP0BLE_DEBUG
509 ChipLogProgress(DeviceLayer, "Trying to send event.");
512 if (connection_handle < 0 || handle <= 0)
514 ChipLogProgress(DeviceLayer, "BLE Event - Bad Handle");
518 if (len > 0 && data == NULL)
520 ChipLogProgress(DeviceLayer, "BLE Event - Invalid Data");
524 /************* Send the indication *************/
525 if (OSA_EventClear(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED) != osaStatus_Success)
527 ChipLogProgress(DeviceLayer, "BLE Event - Can't clear OSA Events");
531 if (GattServer_SendInstantValueIndication(connection_handle, handle, len, data) != gBleSuccess_c)
533 ChipLogProgress(DeviceLayer, "BLE Event - Can't sent indication");
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)
540 ChipLogProgress(DeviceLayer, "BLE Event - OSA Event failed");
544 if (event_mask & CHIP_BLE_KW_EVNT_INDICATION_FAILED)
546 ChipLogProgress(DeviceLayer, "BLE Event - Sent Failed");
550 #if CHIP_DEVICE_CHIP0BLE_DEBUG
551 ChipLogProgress(DeviceLayer, "BLE Event - Sent :-) ");
556 /*******************************************************************************
558 *******************************************************************************/
559 CHIP_ERROR BLEManagerImpl::blekw_controller_init(void)
561 mControllerTaskEvent = OSA_EventCreate(TRUE);
563 if (!mControllerTaskEvent)
565 return CHIP_ERROR_NO_MEMORY;
568 Controller_TaskEventInit(mControllerTaskEvent, gUseRtos_c);
572 xTaskCreate(Controller_TaskHandler, "controllerTask", CONTROLLER_TASK_STACK_SIZE, (void *) 0, CONTROLLER_TASK_PRIORITY,
575 return CHIP_ERROR_NO_MEMORY;
578 /* Setup Interrupt priorities of Interrupt handlers that are used
579 * in application to meet requirements of FreeRTOS */
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);
592 /* Check for available memory storage */
593 if (!Ble_CheckMemoryStorage())
595 return CHIP_ERROR_NO_MEMORY;
598 /* BLE Controller Init */
599 if (osaStatus_Success != Controller_Init(Ble_HciRecv))
601 return CHIP_ERROR_NO_MEMORY;
604 return CHIP_NO_ERROR;
607 void BLEManagerImpl::Host_Task(osaTaskParam_t argument)
609 Host_TaskHandler((void *) NULL);
612 CHIP_ERROR BLEManagerImpl::blekw_host_init(void)
614 /* Initialization of task related */
615 gHost_TaskEvent = OSA_EventCreate(TRUE);
616 if (!gHost_TaskEvent)
618 return CHIP_ERROR_NO_MEMORY;
621 /* Initialization of task message queue */
622 MSG_InitQueue(&gApp2Host_TaskQueue);
623 MSG_InitQueue(&gHci2Host_TaskQueue);
626 if (pdPASS != xTaskCreate(Host_Task, "hostTask", HOST_TASK_STACK_SIZE, (void *) 0, HOST_TASK_PRIORITY, NULL))
628 return CHIP_ERROR_NO_MEMORY;
631 return CHIP_NO_ERROR;
634 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_start_advertising(gapAdvertisingParameters_t * adv_params,
635 gapAdvertisingData_t * adv, gapScanResponseData_t * scnrsp)
637 osaEventFlags_t event_mask;
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));
642 /* Set the advertising parameters */
643 if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
647 /* Retry, just to make sure before giving up and sending an error. */
648 if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
650 return BLE_E_SET_ADV_PARAMS;
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)
657 return BLE_E_ADV_PARAMS_FAILED;
660 if (event_mask & CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED)
662 return BLE_E_ADV_PARAMS_FAILED;
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));
668 /* Set the advertising data */
669 if (Gap_SetAdvertisingData(adv, scnrsp) != gBleSuccess_c)
671 return BLE_E_SET_ADV_DATA;
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)
677 return BLE_E_ADV_SETUP_FAILED;
680 if (event_mask & CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED)
682 return BLE_E_ADV_SETUP_FAILED;
685 /************* Start the advertising *************/
686 OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED));
688 /* Start the advertising */
689 if (Gap_StartAdvertising(blekw_gap_advertising_cb, blekw_gap_connection_cb) != gBleSuccess_c)
691 return BLE_E_START_ADV;
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)
697 return BLE_E_START_ADV_FAILED;
700 if (event_mask & CHIP_BLE_KW_EVNT_ADV_FAILED)
702 return BLE_E_START_ADV_FAILED;
705 #if cPWR_UsePowerDownMode
706 PWR_AllowDeviceToSleep();
712 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_stop_advertising(void)
714 osaEventFlags_t event_mask;
717 OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED));
719 /* Stop the advertising data */
720 res = Gap_StopAdvertising();
721 if (res != gBleSuccess_c)
723 ChipLogProgress(DeviceLayer, "Failed to stop advertising %d", res);
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)
730 ChipLogProgress(DeviceLayer, "Stop advertising event timeout.");
731 return BLE_E_ADV_CHANGED;
734 if (event_mask & CHIP_BLE_KW_EVNT_ADV_FAILED)
736 ChipLogProgress(DeviceLayer, "Stop advertising flat out failed.");
737 return BLE_E_ADV_FAILED;
743 CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
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;
760 chipErr = ConfigurationMgr().GetSetupDiscriminator(discriminator);
761 if (chipErr != CHIP_NO_ERROR)
766 if (!mFlags.Has(Flags::kDeviceNameSet))
768 memset(mDeviceName, 0, kMaxDeviceNameLength);
769 snprintf(mDeviceName, kMaxDeviceNameLength, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator);
772 /**************** Prepare advertising data *******************************************/
773 adv.cNumAdStructures = BLEKW_ADV_MAX_NO;
775 chipErr = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo);
776 SuccessOrExit(chipErr);
777 mDeviceIdInfoLength = sizeof(mDeviceIdInfo);
779 if ((mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1) > BLEKW_MAX_ADV_DATA_LEN)
781 return CHIP_ERROR_INCORRECT_STATE;
784 adv_data[0].length = 0x02;
785 adv_data[0].adType = gAdFlags_c;
786 adv_data[0].aData = (uint8_t *) (&chipAdvDataFlags);
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;
794 adv.aAdStructures = adv_data;
795 /**************** Prepare scan response data *******************************************/
796 scanRsp.cNumAdStructures = BLEKW_SCAN_RSP_MAX_NO;
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;
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;
808 scanRsp.aAdStructures = scan_rsp_data;
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;
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;
823 err = blekw_start_advertising(&adv_params, &adv, &scanRsp);
826 ChipLogProgress(DeviceLayer, "Started Advertising.");
830 ChipLogProgress(DeviceLayer, "Advertising error!");
831 return CHIP_ERROR_INCORRECT_STATE;
838 CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
840 mFlags.Set(Flags::kAdvertising);
841 mFlags.Clear(Flags::kRestartAdvertising);
843 return ConfigureAdvertisingData();
846 CHIP_ERROR BLEManagerImpl::StopAdvertising(void)
850 if (mFlags.Has(Flags::kAdvertising))
852 mFlags.Clear(Flags::kAdvertising);
853 mFlags.Clear(Flags::kRestartAdvertising);
855 err = blekw_stop_advertising();
858 return CHIP_ERROR_INCORRECT_STATE;
862 return CHIP_NO_ERROR;
865 void BLEManagerImpl::DriveBLEState(void)
867 CHIP_ERROR err = CHIP_NO_ERROR;
869 // Check if BLE stack is initialized
870 VerifyOrExit(mFlags.Has(Flags::kK32WBLEStackInitialized), /* */);
872 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
873 if (ConfigurationMgr().IsFullyProvisioned())
875 mFlags.Clear(Flags::kAdvertisingEnabled);
876 ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned");
878 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
880 // Start advertising if needed...
881 if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled))
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))
887 err = StartAdvertising();
891 // Otherwise, stop advertising if it is enabled.
892 else if (mFlags.Has(Flags::kAdvertising))
894 err = StopAdvertising();
896 ChipLogProgress(DeviceLayer, "Stopped Advertising");
900 if (err != CHIP_NO_ERROR)
902 ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
903 mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
907 void BLEManagerImpl::DriveBLEState(intptr_t arg)
909 sInstance.DriveBLEState();
912 /*******************************************************************************
913 * BLE App Task Processing
914 *******************************************************************************/
915 void BLEManagerImpl::bleAppTask(void * p_arg)
919 xEventGroupWaitBits(bleAppTaskLoopEvent, LOOP_EV_BLE, true, false, portMAX_DELAY);
921 PlatformMgr().LockChipStack();
923 if (MSG_Pending(&blekw_msg_list))
925 /* There is message from the BLE tasks to solve */
926 blekw_msg_t * msg = (blekw_msg_t *) MSG_DeQueue(&blekw_msg_list);
930 if (msg->type == BLE_KW_MSG_ERROR)
932 ChipLogProgress(DeviceLayer, "BLE Fatal Error: %d.\n", msg->data.u8);
934 else if (msg->type == BLE_KW_MSG_CONNECTED)
936 sInstance.HandleConnectEvent(msg);
938 else if (msg->type == BLE_KW_MSG_DISCONNECTED)
940 sInstance.HandleConnectionCloseEvent(msg);
942 else if (msg->type == BLE_KW_MSG_MTU_CHANGED)
944 blekw_start_connection_timeout();
945 ChipLogProgress(DeviceLayer, "BLE MTU size has been changed to %d.", msg->data.u16);
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)
950 sInstance.HandleWriteEvent(msg);
952 else if (msg->type == BLE_KW_MSG_FORCE_DISCONNECT)
954 ChipLogProgress(DeviceLayer, "BLE connection timeout: Forcing disconnection.");
956 /* Set the advertising parameters */
957 if (Gap_Disconnect(device_id) != gBleSuccess_c)
959 ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
963 /* Freed the message from the queue */
966 PlatformMgr().UnlockChipStack();
970 void BLEManagerImpl::HandleConnectEvent(blekw_msg_t * msg)
972 uint8_t device_id_loc = msg->data.u8;
973 ChipLogProgress(DeviceLayer, "BLE is connected with device: %d.\n", device_id_loc);
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);
982 void BLEManagerImpl::HandleConnectionCloseEvent(blekw_msg_t * msg)
984 uint8_t device_id_loc = msg->data.u8;
985 ChipLogProgress(DeviceLayer, "BLE is disconnected with device: %d.\n", device_id_loc);
987 if (sInstance.RemoveConnection(device_id_loc))
989 ChipDeviceEvent event;
990 event.Type = DeviceEventType::kCHIPoBLEConnectionError;
991 event.CHIPoBLEConnectionError.ConId = device_id_loc;
992 event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED;
994 PlatformMgr().PostEvent(&event);
995 mFlags.Set(Flags::kRestartAdvertising);
996 PlatformMgr().ScheduleWork(DriveBLEState, 0);
1000 void BLEManagerImpl::HandleWriteEvent(blekw_msg_t * msg)
1002 blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1003 attErrorCode_t status = gAttErrCodeNoError_c;
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);
1009 blekw_start_connection_timeout();
1011 if (value_chipoble_rx == att_wr_data->handle)
1013 sInstance.HandleRXCharWrite(msg);
1015 else if (cccd_chipoble_tx == att_wr_data->handle)
1017 sInstance.HandleTXCharCCCDWrite(msg);
1020 /* TODO: do we need to send the status also for CCCD_WRITTEN? */
1021 if (msg->type != BLE_KW_MSG_ATT_CCCD_WRITTEN)
1023 bleResult_t res = GattServer_SendAttributeWrittenStatus(att_wr_data->device_id, att_wr_data->handle, status);
1025 if (res != gBleSuccess_c)
1027 ChipLogProgress(DeviceLayer, "GattServer_SendAttributeWrittenStatus returned %d", res);
1032 void BLEManagerImpl::HandleTXCharCCCDWrite(blekw_msg_t * msg)
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;
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);
1046 /* Determine if the client is enabling or disabling indications.
1047 * TODO: Check the indications corresponding bit
1049 indicationsEnabled = (*data);
1051 #if CHIP_DEVICE_CHIP0BLE_DEBUG
1052 ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", indicationsEnabled ? "subscribe" : "unsubscribe");
1055 if (indicationsEnabled)
1057 // If indications are not already enabled for the connection...
1058 if (!bleConnState->subscribed)
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. */
1065 event.Type = DeviceEventType::kCHIPoBLESubscribe;
1066 event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
1067 PlatformMgr().PostEvent(&event);
1073 bleConnState->subscribed = 0;
1074 event.Type = DeviceEventType::kCHIPoBLEUnsubscribe;
1075 event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
1076 PlatformMgr().PostEvent(&event);
1080 if (err != CHIP_NO_ERROR)
1082 ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err));
1086 void BLEManagerImpl::HandleRXCharWrite(blekw_msg_t * msg)
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;
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);
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());
1108 // Post an event to the CHIP queue to deliver the data into the CHIP stack.
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);
1117 if (err != CHIP_NO_ERROR)
1119 ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err));
1122 /*******************************************************************************
1123 * BLE stack callbacks
1124 *******************************************************************************/
1125 void BLEManagerImpl::blekw_generic_cb(gapGenericEvent_t * pGenericEvent)
1127 /* Call BLE Conn Manager */
1128 BleConnManager_GenericEvent(pGenericEvent);
1130 switch (pGenericEvent->eventType)
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);
1140 case gAdvertisingSetupFailed_c:
1141 /* Set the local synchronization event */
1142 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED);
1145 case gAdvertisingParametersSetupComplete_c:
1146 /* Set the local synchronization event */
1147 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE);
1150 case gAdvertisingDataSetupComplete_c:
1151 /* Set the local synchronization event */
1152 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE);
1155 case gRandomAddressSet_c:
1156 /* Set the local synchronization event */
1157 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_RND_ADDR_SET);
1160 case gInitializationComplete_c:
1161 /* Common GAP configuration */
1162 BleConnManager_GapCommonConfig();
1164 /* Set the local synchronization event */
1165 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INIT_COMPLETE);
1172 void BLEManagerImpl::blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent)
1174 if (pAdvertisingEvent->eventType == gAdvertisingStateChanged_c)
1176 /* Set the local synchronization event */
1177 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_CHANGED);
1181 /* The advertisement start failed */
1182 ChipLogProgress(DeviceLayer, "Advertising failed: event=%d reason=0x%04X\n", pAdvertisingEvent->eventType,
1183 pAdvertisingEvent->eventData.failReason);
1185 /* Set the local synchronization event */
1186 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_FAILED);
1190 void BLEManagerImpl::blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent)
1192 /* Call BLE Conn Manager */
1193 BleConnManager_GapPeripheralEvent(deviceId, pConnectionEvent);
1195 if (pConnectionEvent->eventType == gConnEvtConnected_c)
1197 /* Notify App Task that the BLE is connected now */
1198 (void) blekw_msg_add_u8(BLE_KW_MSG_CONNECTED, (uint8_t) deviceId);
1200 else if (pConnectionEvent->eventType == gConnEvtDisconnected_c)
1202 blekw_stop_connection_timeout();
1204 /* Notify App Task that the BLE is disconnected now */
1205 (void) blekw_msg_add_u8(BLE_KW_MSG_DISCONNECTED, (uint8_t) deviceId);
1207 else if (pConnectionEvent->eventType == gConnEvtPairingRequest_c)
1209 /* Reject request for pairing */
1210 Gap_RejectPairing(deviceId, gPairingNotSupported_c);
1212 else if (pConnectionEvent->eventType == gConnEvtAuthenticationRejected_c)
1214 ChipLogProgress(DeviceLayer, "BLE Authentication rejected (reason:%d).\n",
1215 pConnectionEvent->eventData.authenticationRejectedEvent.rejectReason);
1219 /* Called by BLE when a connect is received */
1220 void BLEManagerImpl::BLE_SignalFromISRCallback(void)
1222 /* TODO: Low Power */
1225 void BLEManagerImpl::blekw_connection_timeout_cb(TimerHandle_t timer)
1227 (void) blekw_msg_add_u8(BLE_KW_MSG_FORCE_DISCONNECT, 0);
1230 void BLEManagerImpl::blekw_start_connection_timeout(void)
1232 xTimerReset(connectionTimeout, 0);
1235 void BLEManagerImpl::blekw_stop_connection_timeout(void)
1237 ChipLogProgress(DeviceLayer, "Stopped connectionTimeout timer.");
1238 xTimerStop(connectionTimeout, 0);
1241 void BLEManagerImpl::blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent)
1243 switch (pServerEvent->eventType)
1245 case gEvtMtuChanged_c: {
1246 uint16_t tempMtu = 0;
1248 (void) Gatt_GetMtu(deviceId, &tempMtu);
1249 blekw_msg_add_u16(BLE_KW_MSG_MTU_CHANGED, tempMtu);
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);
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);
1265 case gEvtAttributeRead_c:
1266 blekw_msg_add_att_read(BLE_KW_MSG_ATT_READ, deviceId, pServerEvent->eventData.attributeReadEvent.handle);
1269 case gEvtCharacteristicCccdWritten_c: {
1270 uint16_t cccd_val = pServerEvent->eventData.charCccdWrittenEvent.newCccd;
1272 blekw_msg_add_att_written(BLE_KW_MSG_ATT_CCCD_WRITTEN, deviceId, pServerEvent->eventData.charCccdWrittenEvent.handle,
1273 (uint8_t *) &cccd_val, 2);
1277 case gEvtHandleValueConfirmation_c:
1278 /* Set the local synchronization event */
1279 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED);
1283 if (pServerEvent->eventData.procedureError.procedureType == gSendIndication_c)
1285 /* Set the local synchronization event */
1286 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INDICATION_FAILED);
1290 ChipLogProgress(DeviceLayer, "BLE Gatt Server Error: Code 0x%04X, Source %d.\n",
1291 pServerEvent->eventData.procedureError.error, pServerEvent->eventData.procedureError.procedureType);
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);
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,
1308 blekw_msg_t * msg = NULL;
1309 blekw_att_written_data_t * att_wr_data;
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);
1316 return CHIP_ERROR_NO_MEMORY;
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);
1328 /* Put message in the queue */
1329 if (gListOk_c != MSG_Queue(&blekw_msg_list, msg))
1334 /* Notify BLE-APP Task to serve the BLE subsystem */
1335 blekw_new_data_received_notification(LOOP_EV_BLE);
1337 return CHIP_NO_ERROR;
1340 CHIP_ERROR BLEManagerImpl::blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle)
1342 blekw_msg_t * msg = NULL;
1343 blekw_att_read_data_t * att_rd_data;
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));
1350 return CHIP_ERROR_NO_MEMORY;
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;
1360 /* Put message in the queue */
1361 if (gListOk_c != MSG_Queue(&blekw_msg_list, msg))
1366 /* Notify BLE-APP Task to serve the BLE subsystem */
1367 blekw_new_data_received_notification(LOOP_EV_BLE);
1369 return CHIP_NO_ERROR;
1372 CHIP_ERROR BLEManagerImpl::blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data)
1374 blekw_msg_t * msg = NULL;
1376 /* Allocate a buffer with enough space to store the packet */
1377 msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t));
1381 return CHIP_ERROR_NO_MEMORY;
1386 msg->data.u8 = data;
1388 /* Put message in the queue */
1389 MSG_Queue(&blekw_msg_list, msg);
1391 /* Notify BLE-APP Task to serve the BLE subsystem */
1392 blekw_new_data_received_notification(LOOP_EV_BLE);
1394 return CHIP_NO_ERROR;
1397 CHIP_ERROR BLEManagerImpl::blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data)
1399 blekw_msg_t * msg = NULL;
1401 /* Allocate a buffer with enough space to store the packet */
1402 msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t));
1406 return CHIP_ERROR_NO_MEMORY;
1411 msg->data.u16 = data;
1413 /* Put message in the queue */
1414 MSG_Queue(&blekw_msg_list, msg);
1416 /* Notify BLE-APP Task to serve the BLE subsystem */
1417 blekw_new_data_received_notification(LOOP_EV_BLE);
1419 return CHIP_NO_ERROR;
1422 /*******************************************************************************
1423 * FreeRTOS Task Management Functions
1424 *******************************************************************************/
1425 void BLEManagerImpl::blekw_new_data_received_notification(uint32_t mask)
1427 portBASE_TYPE taskToWake = pdFALSE;
1431 if (xEventGroupSetBitsFromISR(bleAppTaskLoopEvent, mask, &taskToWake) == pdPASS)
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);
1442 xEventGroupSetBits(bleAppTaskLoopEvent, mask);
1446 } // namespace Internal
1447 } // namespace DeviceLayer
1449 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE