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"
42 #include "RNG_Interface.h"
44 /*******************************************************************************
46 *******************************************************************************/
47 extern "C" bool_t Ble_ConfigureHostStackConfig(void);
48 extern "C" void (*pfBLE_SignalFromISR)(void);
49 extern "C" bool_t Ble_CheckMemoryStorage(void);
51 extern osaEventId_t gHost_TaskEvent;
52 extern msgQueue_t gApp2Host_TaskQueue;
53 extern msgQueue_t gHci2Host_TaskQueue;
55 using namespace ::chip;
56 using namespace ::chip::Ble;
59 namespace DeviceLayer {
64 /*******************************************************************************
65 * Macros & Constants definitions
66 *******************************************************************************/
67 /* Timeout of BLE commands */
68 #define CHIP_BLE_KW_EVNT_TIMEOUT 1000
70 /** BLE advertisment state changed */
71 #define CHIP_BLE_KW_EVNT_ADV_CHANGED 0x0001
72 /** BLE advertisement command failed */
73 #define CHIP_BLE_KW_EVNT_ADV_FAILED 0x0002
74 /** BLE advertisement setup failed */
75 #define CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED 0x0004
76 /** BLE advertisement parameters setup complete */
77 #define CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE 0x0008
78 /** BLE advertisement data setup complete */
79 #define CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE 0x0010
80 /** BLE random address set */
81 #define CHIP_BLE_KW_EVNT_RND_ADDR_SET 0x0020
82 /** BLE Initialization complete */
83 #define CHIP_BLE_KW_EVNT_INIT_COMPLETE 0x0040
84 /** BLE Received a handle value confirmation from the client */
85 #define CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED 0x0080
86 /** BLE send indication failed */
87 #define CHIP_BLE_KW_EVNT_INDICATION_FAILED 0x0100
88 /** Maximal time of connection without activity */
89 #define CHIP_BLE_KW_CONN_TIMEOUT 60000
91 #define LOOP_EV_BLE (0x08)
93 /* controller task configuration */
94 #define CONTROLLER_TASK_PRIORITY (6U)
95 #define CONTROLLER_TASK_STACK_SIZE (gControllerTaskStackSize_c / sizeof(StackType_t))
97 /* host task configuration */
98 #define HOST_TASK_PRIORITY (3U)
99 #define HOST_TASK_STACK_SIZE (gHost_TaskStackSize_c / sizeof(StackType_t))
101 /* ble app task configuration */
102 #define CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY (HOST_TASK_PRIORITY - 1)
103 #define CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE (1024)
105 /* advertising configuration */
106 #define BLEKW_ADV_MAX_NO (2)
107 #define BLEKW_SCAN_RSP_MAX_NO (2)
108 #define BLEKW_MAX_ADV_DATA_LEN (31)
109 #define CHIP_ADV_SHORT_UUID_LEN (2)
111 /* FreeRTOS sw timer */
112 TimerHandle_t sbleAdvTimeoutTimer;
114 /* Message list used to synchronize asynchronous messages from the KW BLE tasks */
115 anchor_t blekw_msg_list;
117 /* Used to manage asynchronous events from BLE Stack: e.g.: GAP setup finished */
118 osaEventId_t event_msg;
120 osaEventId_t mControllerTaskEvent;
121 TimerHandle_t connectionTimeout;
123 /* Used by BLE App Task to handle asynchronous GATT events */
124 EventGroupHandle_t bleAppTaskLoopEvent;
126 /* keep the device ID of the connected peer */
129 const uint8_t ShortUUID_CHIPoBLEService[] = { 0xAF, 0xFE };
130 const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
132 const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
136 BLEManagerImpl BLEManagerImpl::sInstance;
138 CHIP_ERROR BLEManagerImpl::_Init()
140 CHIP_ERROR err = CHIP_NO_ERROR;
141 osaEventFlags_t flags;
142 BaseType_t bleAppCreated = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
143 uint16_t attChipRxHandle[1] = { (uint16_t) value_chipoble_rx };
145 mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
147 // Check if BLE stack is initialized
148 VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
150 // Initialize the Chip BleLayer.
151 err = BleLayer::Init(this, this, &SystemLayer);
155 RNG_SetPseudoRandomNoSeed(NULL);
157 /* Initialization of message wait events -
158 * used for receiving BLE Stack events */
159 event_msg = OSA_EventCreate(TRUE);
160 VerifyOrExit(event_msg != NULL, err = CHIP_ERROR_INCORRECT_STATE);
162 pfBLE_SignalFromISR = BLE_SignalFromISRCallback;
164 /* Set the config structure to the host stack */
165 VerifyOrExit(Ble_ConfigureHostStackConfig() == TRUE, err = CHIP_ERROR_INCORRECT_STATE);
167 /* Prepare callback input queue.*/
168 MSG_InitQueue(&blekw_msg_list);
170 /* Create the connection timeout timer. */
172 xTimerCreate("bleTimeoutTmr", pdMS_TO_TICKS(CHIP_BLE_KW_CONN_TIMEOUT), pdFALSE, (void *) 0, blekw_connection_timeout_cb);
174 /* Create BLE App Task */
175 bleAppTaskLoopEvent = xEventGroupCreate();
176 VerifyOrExit(bleAppTaskLoopEvent != NULL, err = CHIP_ERROR_INCORRECT_STATE);
177 bleAppCreated = xTaskCreate(bleAppTask, CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME,
178 CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE / sizeof(StackType_t), this,
179 CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY, NULL);
180 VerifyOrExit(bleAppCreated == pdPASS, err = CHIP_ERROR_INCORRECT_STATE);
183 XCVR_TemperatureUpdate(BOARD_GetTemperature());
184 VerifyOrExit(XCVR_Init(BLE_MODE, DR_2MBPS) == gXcvrSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);
186 /* Create BLE Controller Task */
187 VerifyOrExit(blekw_controller_init() == CHIP_NO_ERROR, err = CHIP_ERROR_INCORRECT_STATE);
189 /* Create BLE Host Task */
190 VerifyOrExit(blekw_host_init() == CHIP_NO_ERROR, err = CHIP_ERROR_INCORRECT_STATE);
192 /* BLE Host Stack Init */
193 Ble_HostInitialize(blekw_generic_cb, (hciHostToControllerInterface_t) Hci_SendPacketToController);
195 /* Register the GATT server callback */
196 VerifyOrExit(GattServer_RegisterCallback(blekw_gatt_server_cb) == gBleSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);
198 /* Wait until BLE Stack is ready */
199 VerifyOrExit(OSA_EventWait(event_msg, CHIP_BLE_KW_EVNT_INIT_COMPLETE, TRUE, CHIP_BLE_KW_EVNT_TIMEOUT, &flags) ==
201 err = CHIP_ERROR_INCORRECT_STATE);
203 GattServer_RegisterHandlesForWriteNotifications(1, attChipRxHandle);
205 mFlags.Set(Flags::kK32WBLEStackInitialized);
206 mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false);
207 mFlags.Set(Flags::kFastAdvertisingEnabled);
209 // Create FreeRTOS sw timer for BLE timeouts and interval change.
210 sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel
211 1, // == default timer period (mS)
212 false, // no timer reload (==one-shot)
213 (void *) this, // init timer id = ble obj context
214 BleAdvTimeoutHandler // timer callback handler
216 VerifyOrExit(sbleAdvTimeoutTimer != NULL, err = CHIP_ERROR_INCORRECT_STATE);
221 uint16_t BLEManagerImpl::_NumConnections(void)
223 uint16_t numCons = 0;
224 for (uint16_t i = 0; i < kMaxConnections; i++)
226 if (mBleConnections[i].allocated)
235 bool BLEManagerImpl::_IsAdvertisingEnabled(void)
237 return mFlags.Has(Flags::kAdvertisingEnabled);
240 bool BLEManagerImpl::RemoveConnection(uint8_t connectionHandle)
242 CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true);
245 if (bleConnState != NULL)
247 memset(bleConnState, 0, sizeof(CHIPoBLEConState));
254 void BLEManagerImpl::AddConnection(uint8_t connectionHandle)
256 CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true);
258 if (bleConnState != NULL)
260 memset(bleConnState, 0, sizeof(CHIPoBLEConState));
261 bleConnState->allocated = 1;
262 bleConnState->connectionHandle = connectionHandle;
266 BLEManagerImpl::CHIPoBLEConState * BLEManagerImpl::GetConnectionState(uint8_t connectionHandle, bool allocate)
268 uint8_t freeIndex = kMaxConnections;
270 for (uint8_t i = 0; i < kMaxConnections; i++)
272 if (mBleConnections[i].allocated == 1)
274 if (mBleConnections[i].connectionHandle == connectionHandle)
276 return &mBleConnections[i];
280 else if (i < freeIndex)
288 if (freeIndex < kMaxConnections)
290 return &mBleConnections[freeIndex];
293 ChipLogError(DeviceLayer, "Failed to allocate CHIPoBLEConState");
299 CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val)
301 CHIP_ERROR err = CHIP_NO_ERROR;
303 VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
304 VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
306 if (val != mServiceMode)
309 PlatformMgr().ScheduleWork(DriveBLEState, 0);
316 CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
318 CHIP_ERROR err = CHIP_NO_ERROR;
320 VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
322 if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
324 mFlags.Set(Flags::kAdvertisingEnabled, val);
325 PlatformMgr().ScheduleWork(DriveBLEState, 0);
332 CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
336 case BLEAdvertisingMode::kFastAdvertising:
337 mFlags.Set(Flags::kFastAdvertisingEnabled, true);
339 case BLEAdvertisingMode::kSlowAdvertising:
340 mFlags.Set(Flags::kFastAdvertisingEnabled, false);
343 return CHIP_ERROR_INVALID_ARGUMENT;
345 mFlags.Set(Flags::kRestartAdvertising);
346 PlatformMgr().ScheduleWork(DriveBLEState, 0);
347 return CHIP_NO_ERROR;
350 CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
352 if (strlen(mDeviceName) >= bufSize)
354 return CHIP_ERROR_BUFFER_TOO_SMALL;
356 strcpy(buf, mDeviceName);
357 return CHIP_NO_ERROR;
360 CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName)
362 if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported)
364 return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
366 if (deviceName != NULL && deviceName[0] != 0)
368 if (strlen(deviceName) >= kMaxDeviceNameLength)
370 return CHIP_ERROR_INVALID_ARGUMENT;
372 memset(mDeviceName, 0, kMaxDeviceNameLength);
373 strcpy(mDeviceName, deviceName);
374 mFlags.Set(Flags::kDeviceNameSet);
375 ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName);
380 mFlags.Clear(Flags::kDeviceNameSet);
383 return CHIP_NO_ERROR;
386 void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
390 case DeviceEventType::kCHIPoBLESubscribe:
391 ChipDeviceEvent connEstEvent;
393 HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
394 connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
395 PlatformMgr().PostEvent(&connEstEvent);
398 case DeviceEventType::kCHIPoBLEUnsubscribe:
399 HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
402 case DeviceEventType::kCHIPoBLEWriteReceived:
403 HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX,
404 PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
407 case DeviceEventType::kCHIPoBLEConnectionError:
408 HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
411 case DeviceEventType::kCHIPoBLEIndicateConfirm:
412 HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
415 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
416 case DeviceEventType::kServiceProvisioningChange:
417 ChipLogProgress(DeviceLayer, "_OnPlatformEvent kServiceProvisioningChange");
419 mFlags.Clear(Flags::kAdvertisingEnabled);
420 PlatformMgr().ScheduleWork(DriveBLEState, 0);
422 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
429 bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
431 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported");
435 bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
437 ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported");
441 bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
443 ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId);
445 if (Gap_Disconnect(conId) != gBleSuccess_c)
447 ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
454 uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
456 uint16_t tempMtu = 0;
457 (void) Gatt_GetMtu(conId, &tempMtu);
462 bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
463 PacketBufferHandle pBuf)
465 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported");
469 bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
470 PacketBufferHandle pBuf)
472 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported");
476 bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
477 const ChipBleUUID * svcId, const ChipBleUUID * charId)
479 ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported");
483 void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId)
488 bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
489 PacketBufferHandle data)
491 CHIP_ERROR err = CHIP_NO_ERROR;
492 uint16_t cId = (UUIDsMatch(&ChipUUID_CHIPoBLEChar_TX, charId) ? value_chipoble_tx : 0);
493 ChipDeviceEvent event;
497 if (blekw_send_event(conId, cId, data->Start(), data->DataLength()) != BLE_OK)
499 err = CHIP_ERROR_SENDING_BLOCKED;
503 event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm;
504 event.CHIPoBLEIndicateConfirm.ConId = conId;
505 PlatformMgr().PostEvent(&event);
508 if (err != CHIP_NO_ERROR)
510 ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %s", ErrorStr(err));
518 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data, uint32_t len)
520 osaEventFlags_t event_mask;
522 #if CHIP_DEVICE_CHIP0BLE_DEBUG
523 ChipLogProgress(DeviceLayer, "Trying to send event.");
526 if (connection_handle < 0 || handle <= 0)
528 ChipLogProgress(DeviceLayer, "BLE Event - Bad Handle");
532 if (len > 0 && data == NULL)
534 ChipLogProgress(DeviceLayer, "BLE Event - Invalid Data");
538 /************* Send the indication *************/
539 if (OSA_EventClear(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED) != osaStatus_Success)
541 ChipLogProgress(DeviceLayer, "BLE Event - Can't clear OSA Events");
545 if (GattServer_SendInstantValueIndication(connection_handle, handle, len, data) != gBleSuccess_c)
547 ChipLogProgress(DeviceLayer, "BLE Event - Can't sent indication");
551 if (OSA_EventWait(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED, FALSE,
552 CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
554 ChipLogProgress(DeviceLayer, "BLE Event - OSA Event failed");
558 if (event_mask & CHIP_BLE_KW_EVNT_INDICATION_FAILED)
560 ChipLogProgress(DeviceLayer, "BLE Event - Sent Failed");
564 #if CHIP_DEVICE_CHIP0BLE_DEBUG
565 ChipLogProgress(DeviceLayer, "BLE Event - Sent :-) ");
570 /*******************************************************************************
572 *******************************************************************************/
573 CHIP_ERROR BLEManagerImpl::blekw_controller_init(void)
575 mControllerTaskEvent = OSA_EventCreate(TRUE);
577 if (!mControllerTaskEvent)
579 return CHIP_ERROR_NO_MEMORY;
582 Controller_TaskEventInit(mControllerTaskEvent, gUseRtos_c);
586 xTaskCreate(Controller_TaskHandler, "controllerTask", CONTROLLER_TASK_STACK_SIZE, (void *) 0, CONTROLLER_TASK_PRIORITY,
589 return CHIP_ERROR_NO_MEMORY;
592 /* Setup Interrupt priorities of Interrupt handlers that are used
593 * in application to meet requirements of FreeRTOS */
596 NVIC_SetPriority(BLE_DP_IRQn, configMAX_PRIORITIES - 1);
597 // BLE_DP0_IRQHandler
598 NVIC_SetPriority(BLE_DP0_IRQn, configMAX_PRIORITIES - 1);
599 // BLE_DP1_IRQHandler
600 NVIC_SetPriority(BLE_DP1_IRQn, configMAX_PRIORITIES - 1);
601 // BLE_DP2_IRQHandler
602 NVIC_SetPriority(BLE_DP2_IRQn, configMAX_PRIORITIES - 1);
603 // BLE_LL_ALL_IRQHandler
604 NVIC_SetPriority(BLE_LL_ALL_IRQn, configMAX_PRIORITIES - 1);
606 /* Check for available memory storage */
607 if (!Ble_CheckMemoryStorage())
609 return CHIP_ERROR_NO_MEMORY;
612 /* BLE Controller Init */
613 if (osaStatus_Success != Controller_Init(Ble_HciRecv))
615 return CHIP_ERROR_NO_MEMORY;
618 return CHIP_NO_ERROR;
621 void BLEManagerImpl::Host_Task(osaTaskParam_t argument)
623 Host_TaskHandler((void *) NULL);
626 CHIP_ERROR BLEManagerImpl::blekw_host_init(void)
628 /* Initialization of task related */
629 gHost_TaskEvent = OSA_EventCreate(TRUE);
630 if (!gHost_TaskEvent)
632 return CHIP_ERROR_NO_MEMORY;
635 /* Initialization of task message queue */
636 MSG_InitQueue(&gApp2Host_TaskQueue);
637 MSG_InitQueue(&gHci2Host_TaskQueue);
640 if (pdPASS != xTaskCreate(Host_Task, "hostTask", HOST_TASK_STACK_SIZE, (void *) 0, HOST_TASK_PRIORITY, NULL))
642 return CHIP_ERROR_NO_MEMORY;
645 return CHIP_NO_ERROR;
648 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_start_advertising(gapAdvertisingParameters_t * adv_params,
649 gapAdvertisingData_t * adv, gapScanResponseData_t * scnrsp)
651 osaEventFlags_t event_mask;
653 /************* Set the advertising parameters *************/
654 OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE));
656 /* Set the advertising parameters */
657 if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
661 /* Retry, just to make sure before giving up and sending an error. */
662 if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
664 return BLE_E_SET_ADV_PARAMS;
668 if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE), FALSE,
669 CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
671 return BLE_E_ADV_PARAMS_FAILED;
674 if (event_mask & CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED)
676 return BLE_E_ADV_PARAMS_FAILED;
679 /************* Set the advertising data *************/
680 OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE));
682 /* Set the advertising data */
683 if (Gap_SetAdvertisingData(adv, scnrsp) != gBleSuccess_c)
685 return BLE_E_SET_ADV_DATA;
688 if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE), FALSE,
689 CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
691 return BLE_E_ADV_SETUP_FAILED;
694 if (event_mask & CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED)
696 return BLE_E_ADV_SETUP_FAILED;
699 /************* Start the advertising *************/
700 OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED));
702 if (gBleSuccess_c != Gap_CreateRandomDeviceAddress(NULL, NULL))
704 return BLE_E_SET_ADV_PARAMS;
707 if (OSA_EventWait(event_msg, CHIP_BLE_KW_EVNT_RND_ADDR_SET, FALSE, CHIP_BLE_KW_EVNT_TIMEOUT, &event_mask) != osaStatus_Success)
709 return BLE_E_ADV_PARAMS_FAILED;
712 /* Start the advertising */
713 if (Gap_StartAdvertising(blekw_gap_advertising_cb, blekw_gap_connection_cb) != gBleSuccess_c)
715 return BLE_E_START_ADV;
718 if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED), FALSE, CHIP_BLE_KW_EVNT_TIMEOUT,
719 &event_mask) != osaStatus_Success)
721 return BLE_E_START_ADV_FAILED;
724 if (event_mask & CHIP_BLE_KW_EVNT_ADV_FAILED)
726 return BLE_E_START_ADV_FAILED;
729 #if cPWR_UsePowerDownMode
730 PWR_AllowDeviceToSleep();
736 BLEManagerImpl::ble_err_t BLEManagerImpl::blekw_stop_advertising(void)
738 osaEventFlags_t event_mask;
741 OSA_EventClear(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED));
743 /* Stop the advertising data */
744 res = Gap_StopAdvertising();
745 if (res != gBleSuccess_c)
747 ChipLogProgress(DeviceLayer, "Failed to stop advertising %d", res);
751 if (OSA_EventWait(event_msg, (CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED), FALSE, CHIP_BLE_KW_EVNT_TIMEOUT,
752 &event_mask) != osaStatus_Success)
754 ChipLogProgress(DeviceLayer, "Stop advertising event timeout.");
755 return BLE_E_ADV_CHANGED;
758 if (event_mask & CHIP_BLE_KW_EVNT_ADV_FAILED)
760 ChipLogProgress(DeviceLayer, "Stop advertising flat out failed.");
761 return BLE_E_ADV_FAILED;
767 CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
771 uint16_t discriminator;
772 uint16_t advInterval = 0;
773 gapAdvertisingData_t adv = { 0 };
774 gapAdStructure_t adv_data[BLEKW_ADV_MAX_NO] = { 0 };
775 gapAdStructure_t scan_rsp_data[BLEKW_SCAN_RSP_MAX_NO] = { 0 };
776 uint8_t advPayload[BLEKW_MAX_ADV_DATA_LEN] = { 0 };
777 gapScanResponseData_t scanRsp = { 0 };
778 gapAdvertisingParameters_t adv_params = { 0 };
779 uint8_t chipAdvDataFlags = (gLeGeneralDiscoverableMode_c | gBrEdrNotSupported_c);
780 uint8_t chipOverBleService[2];
781 ChipBLEDeviceIdentificationInfo mDeviceIdInfo = { 0 };
782 uint8_t mDeviceIdInfoLength = 0;
784 chipErr = ConfigurationMgr().GetSetupDiscriminator(discriminator);
785 if (chipErr != CHIP_NO_ERROR)
790 if (!mFlags.Has(Flags::kDeviceNameSet))
792 memset(mDeviceName, 0, kMaxDeviceNameLength);
793 snprintf(mDeviceName, kMaxDeviceNameLength, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator);
796 /**************** Prepare advertising data *******************************************/
797 adv.cNumAdStructures = BLEKW_ADV_MAX_NO;
799 chipErr = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo);
800 SuccessOrExit(chipErr);
801 mDeviceIdInfoLength = sizeof(mDeviceIdInfo);
803 if ((mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1) > BLEKW_MAX_ADV_DATA_LEN)
805 return CHIP_ERROR_INCORRECT_STATE;
808 adv_data[0].length = 0x02;
809 adv_data[0].adType = gAdFlags_c;
810 adv_data[0].aData = (uint8_t *) (&chipAdvDataFlags);
812 adv_data[1].length = static_cast<uint8_t>(mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1);
813 adv_data[1].adType = gAdServiceData16bit_c;
814 memcpy(advPayload, ShortUUID_CHIPoBLEService, CHIP_ADV_SHORT_UUID_LEN);
815 memcpy(&advPayload[CHIP_ADV_SHORT_UUID_LEN], (void *) &mDeviceIdInfo, mDeviceIdInfoLength);
816 adv_data[1].aData = advPayload;
818 adv.aAdStructures = adv_data;
819 /**************** Prepare scan response data *******************************************/
820 scanRsp.cNumAdStructures = BLEKW_SCAN_RSP_MAX_NO;
822 scan_rsp_data[0].length = static_cast<uint8_t>(strlen(mDeviceName) + 1);
823 scan_rsp_data[0].adType = gAdCompleteLocalName_c;
824 scan_rsp_data[0].aData = (uint8_t *) mDeviceName;
826 scan_rsp_data[1].length = sizeof(chipOverBleService) + 1;
827 scan_rsp_data[1].adType = gAdComplete16bitServiceList_c;
828 chipOverBleService[0] = ShortUUID_CHIPoBLEService[0];
829 chipOverBleService[1] = ShortUUID_CHIPoBLEService[1];
830 scan_rsp_data[1].aData = (uint8_t *) chipOverBleService;
832 scanRsp.aAdStructures = scan_rsp_data;
834 /**************** Prepare advertising parameters *************************************/
835 if (mFlags.Has(Flags::kFastAdvertisingEnabled))
837 advInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX;
841 advInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
844 adv_params.minInterval = adv_params.maxInterval = advInterval;
845 adv_params.advertisingType = gAdvConnectableUndirected_c;
846 adv_params.ownAddressType = gBleAddrTypePublic_c;
847 adv_params.peerAddressType = gBleAddrTypePublic_c;
848 memset(adv_params.peerAddress, 0, gcBleDeviceAddressSize_c);
849 adv_params.channelMap = (gapAdvertisingChannelMapFlags_t)(gAdvChanMapFlag37_c | gAdvChanMapFlag38_c | gAdvChanMapFlag39_c);
850 adv_params.filterPolicy = gProcessAll_c;
852 err = blekw_start_advertising(&adv_params, &adv, &scanRsp);
855 ChipLogProgress(DeviceLayer, "Started Advertising.");
859 ChipLogProgress(DeviceLayer, "Advertising error!");
860 return CHIP_ERROR_INCORRECT_STATE;
867 CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
869 uint32_t bleAdvTimeoutMs = 0;
871 mFlags.Set(Flags::kAdvertising);
872 mFlags.Clear(Flags::kRestartAdvertising);
874 if (mFlags.Has(Flags::kFastAdvertisingEnabled))
876 bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT;
880 bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT;
882 StartBleAdvTimeoutTimer(bleAdvTimeoutMs);
884 return ConfigureAdvertisingData();
887 CHIP_ERROR BLEManagerImpl::StopAdvertising(void)
891 if (mFlags.Has(Flags::kAdvertising))
893 mFlags.Clear(Flags::kAdvertising);
894 mFlags.Clear(Flags::kFastAdvertisingEnabled);
895 mFlags.Clear(Flags::kRestartAdvertising);
897 err = blekw_stop_advertising();
900 return CHIP_ERROR_INCORRECT_STATE;
903 CancelBleAdvTimeoutTimer();
905 return CHIP_NO_ERROR;
908 void BLEManagerImpl::DriveBLEState(void)
910 CHIP_ERROR err = CHIP_NO_ERROR;
912 // Check if BLE stack is initialized
913 VerifyOrExit(mFlags.Has(Flags::kK32WBLEStackInitialized), /* */);
915 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
916 if (ConfigurationMgr().IsFullyProvisioned())
918 mFlags.Clear(Flags::kAdvertisingEnabled);
919 ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned");
921 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
923 // Start advertising if needed...
924 if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled))
926 // Start/re-start advertising if not already started, or if there is a pending change
927 // to the advertising configuration.
928 if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kRestartAdvertising))
930 err = StartAdvertising();
934 // Otherwise, stop advertising if it is enabled.
935 else if (mFlags.Has(Flags::kAdvertising))
937 err = StopAdvertising();
939 ChipLogProgress(DeviceLayer, "Stopped Advertising");
943 if (err != CHIP_NO_ERROR)
945 ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
946 mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
950 void BLEManagerImpl::DriveBLEState(intptr_t arg)
952 sInstance.DriveBLEState();
955 /*******************************************************************************
956 * BLE App Task Processing
957 *******************************************************************************/
958 void BLEManagerImpl::bleAppTask(void * p_arg)
962 xEventGroupWaitBits(bleAppTaskLoopEvent, LOOP_EV_BLE, true, false, portMAX_DELAY);
964 PlatformMgr().LockChipStack();
966 if (MSG_Pending(&blekw_msg_list))
968 /* There is message from the BLE tasks to solve */
969 blekw_msg_t * msg = (blekw_msg_t *) MSG_DeQueue(&blekw_msg_list);
973 if (msg->type == BLE_KW_MSG_ERROR)
975 ChipLogProgress(DeviceLayer, "BLE Fatal Error: %d.\n", msg->data.u8);
977 else if (msg->type == BLE_KW_MSG_CONNECTED)
979 sInstance.HandleConnectEvent(msg);
981 else if (msg->type == BLE_KW_MSG_DISCONNECTED)
983 sInstance.HandleConnectionCloseEvent(msg);
985 else if (msg->type == BLE_KW_MSG_MTU_CHANGED)
987 blekw_start_connection_timeout();
988 ChipLogProgress(DeviceLayer, "BLE MTU size has been changed to %d.", msg->data.u16);
990 else if (msg->type == BLE_KW_MSG_ATT_WRITTEN || msg->type == BLE_KW_MSG_ATT_LONG_WRITTEN ||
991 msg->type == BLE_KW_MSG_ATT_CCCD_WRITTEN)
993 sInstance.HandleWriteEvent(msg);
995 else if (msg->type == BLE_KW_MSG_FORCE_DISCONNECT)
997 ChipLogProgress(DeviceLayer, "BLE connection timeout: Forcing disconnection.");
999 /* Set the advertising parameters */
1000 if (Gap_Disconnect(device_id) != gBleSuccess_c)
1002 ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
1006 /* Freed the message from the queue */
1009 PlatformMgr().UnlockChipStack();
1013 void BLEManagerImpl::HandleConnectEvent(blekw_msg_t * msg)
1015 uint8_t device_id_loc = msg->data.u8;
1016 ChipLogProgress(DeviceLayer, "BLE is connected with device: %d.\n", device_id_loc);
1018 device_id = device_id_loc;
1019 blekw_start_connection_timeout();
1020 sInstance.AddConnection(device_id_loc);
1021 mFlags.Set(Flags::kRestartAdvertising);
1022 PlatformMgr().ScheduleWork(DriveBLEState, 0);
1025 void BLEManagerImpl::HandleConnectionCloseEvent(blekw_msg_t * msg)
1027 uint8_t device_id_loc = msg->data.u8;
1028 ChipLogProgress(DeviceLayer, "BLE is disconnected with device: %d.\n", device_id_loc);
1030 if (sInstance.RemoveConnection(device_id_loc))
1032 ChipDeviceEvent event;
1033 event.Type = DeviceEventType::kCHIPoBLEConnectionError;
1034 event.CHIPoBLEConnectionError.ConId = device_id_loc;
1035 event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED;
1037 PlatformMgr().PostEvent(&event);
1038 mFlags.Set(Flags::kRestartAdvertising);
1039 mFlags.Set(Flags::kFastAdvertisingEnabled);
1040 PlatformMgr().ScheduleWork(DriveBLEState, 0);
1044 void BLEManagerImpl::HandleWriteEvent(blekw_msg_t * msg)
1046 blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1047 attErrorCode_t status = gAttErrCodeNoError_c;
1049 #if CHIP_DEVICE_CHIP0BLE_DEBUG
1050 ChipLogProgress(DeviceLayer, "Attribute write request(device: %d,handle: %d).", att_wr_data->device_id, att_wr_data->handle);
1053 blekw_start_connection_timeout();
1055 if (value_chipoble_rx == att_wr_data->handle)
1057 sInstance.HandleRXCharWrite(msg);
1059 else if (cccd_chipoble_tx == att_wr_data->handle)
1061 sInstance.HandleTXCharCCCDWrite(msg);
1064 /* TODO: do we need to send the status also for CCCD_WRITTEN? */
1065 if (msg->type != BLE_KW_MSG_ATT_CCCD_WRITTEN)
1067 bleResult_t res = GattServer_SendAttributeWrittenStatus(att_wr_data->device_id, att_wr_data->handle, status);
1069 if (res != gBleSuccess_c)
1071 ChipLogProgress(DeviceLayer, "GattServer_SendAttributeWrittenStatus returned %d", res);
1076 void BLEManagerImpl::HandleTXCharCCCDWrite(blekw_msg_t * msg)
1078 CHIP_ERROR err = CHIP_NO_ERROR;
1079 CHIPoBLEConState * bleConnState;
1080 bool indicationsEnabled;
1081 ChipDeviceEvent event;
1082 blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1083 uint16_t writeLen = att_wr_data->length;
1084 uint8_t * data = att_wr_data->data;
1086 VerifyOrExit(writeLen != 0, err = CHIP_ERROR_INCORRECT_STATE);
1087 bleConnState = GetConnectionState(att_wr_data->device_id, false);
1088 VerifyOrExit(bleConnState != NULL, err = CHIP_ERROR_NO_MEMORY);
1090 /* Determine if the client is enabling or disabling indications.
1091 * TODO: Check the indications corresponding bit
1093 indicationsEnabled = (*data);
1095 #if CHIP_DEVICE_CHIP0BLE_DEBUG
1096 ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", indicationsEnabled ? "subscribe" : "unsubscribe");
1099 if (indicationsEnabled)
1101 // If indications are not already enabled for the connection...
1102 if (!bleConnState->subscribed)
1104 bleConnState->subscribed = 1;
1105 /* Post an event to the CHIP queue to process either a CHIPoBLE
1106 * Subscribe or Unsubscribe based on whether the client
1107 * is enabling or disabling indications. */
1109 event.Type = DeviceEventType::kCHIPoBLESubscribe;
1110 event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
1111 PlatformMgr().PostEvent(&event);
1117 bleConnState->subscribed = 0;
1118 event.Type = DeviceEventType::kCHIPoBLEUnsubscribe;
1119 event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
1120 PlatformMgr().PostEvent(&event);
1124 if (err != CHIP_NO_ERROR)
1126 ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err));
1130 void BLEManagerImpl::HandleRXCharWrite(blekw_msg_t * msg)
1132 CHIP_ERROR err = CHIP_NO_ERROR;
1133 System::PacketBufferHandle buf;
1134 blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1135 uint16_t writeLen = att_wr_data->length;
1136 uint8_t * data = att_wr_data->data;
1138 // Copy the data to a PacketBuffer.
1139 buf = System::PacketBufferHandle::New(writeLen);
1140 VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);
1141 VerifyOrExit(buf->AvailableDataLength() >= writeLen, err = CHIP_ERROR_BUFFER_TOO_SMALL);
1142 memcpy(buf->Start(), data, writeLen);
1143 buf->SetDataLength(writeLen);
1145 #if CHIP_DEVICE_CHIP0BLE_DEBUG
1146 ChipLogDetail(DeviceLayer,
1147 "Write request/command received for"
1148 "CHIPoBLE RX characteristic (con %" PRIu16 ", len %" PRIu16 ")",
1149 att_wr_data->device_id, buf->DataLength());
1152 // Post an event to the CHIP queue to deliver the data into the CHIP stack.
1154 ChipDeviceEvent event;
1155 event.Type = DeviceEventType::kCHIPoBLEWriteReceived;
1156 event.CHIPoBLEWriteReceived.ConId = att_wr_data->device_id;
1157 event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease();
1158 PlatformMgr().PostEvent(&event);
1161 if (err != CHIP_NO_ERROR)
1163 ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err));
1166 /*******************************************************************************
1167 * BLE stack callbacks
1168 *******************************************************************************/
1169 void BLEManagerImpl::blekw_generic_cb(gapGenericEvent_t * pGenericEvent)
1171 /* Call BLE Conn Manager */
1172 BleConnManager_GenericEvent(pGenericEvent);
1174 switch (pGenericEvent->eventType)
1176 case gInternalError_c:
1177 /* Notify the CHIP that the BLE hardware report fail */
1178 ChipLogProgress(DeviceLayer, "BLE Internal Error: Code 0x%04X, Source 0x%08X, HCI OpCode %d.\n",
1179 pGenericEvent->eventData.internalError.errorCode, pGenericEvent->eventData.internalError.errorSource,
1180 pGenericEvent->eventData.internalError.hciCommandOpcode);
1181 (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_ERROR);
1184 case gAdvertisingSetupFailed_c:
1185 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED);
1188 case gAdvertisingParametersSetupComplete_c:
1189 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE);
1192 case gAdvertisingDataSetupComplete_c:
1193 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE);
1196 case gRandomAddressReady_c:
1197 Gap_SetRandomAddress(pGenericEvent->eventData.addrReady.aAddress);
1200 case gRandomAddressSet_c:
1201 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_RND_ADDR_SET);
1204 case gInitializationComplete_c:
1205 /* Common GAP configuration */
1206 BleConnManager_GapCommonConfig();
1208 /* Set the local synchronization event */
1209 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INIT_COMPLETE);
1216 void BLEManagerImpl::blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent)
1218 if (pAdvertisingEvent->eventType == gAdvertisingStateChanged_c)
1220 /* Set the local synchronization event */
1221 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_CHANGED);
1225 /* The advertisement start failed */
1226 ChipLogProgress(DeviceLayer, "Advertising failed: event=%d reason=0x%04X\n", pAdvertisingEvent->eventType,
1227 pAdvertisingEvent->eventData.failReason);
1229 /* Set the local synchronization event */
1230 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_ADV_FAILED);
1234 void BLEManagerImpl::blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent)
1236 /* Call BLE Conn Manager */
1237 BleConnManager_GapPeripheralEvent(deviceId, pConnectionEvent);
1239 if (pConnectionEvent->eventType == gConnEvtConnected_c)
1241 /* Notify App Task that the BLE is connected now */
1242 (void) blekw_msg_add_u8(BLE_KW_MSG_CONNECTED, (uint8_t) deviceId);
1244 else if (pConnectionEvent->eventType == gConnEvtDisconnected_c)
1246 blekw_stop_connection_timeout();
1248 /* Notify App Task that the BLE is disconnected now */
1249 (void) blekw_msg_add_u8(BLE_KW_MSG_DISCONNECTED, (uint8_t) deviceId);
1251 else if (pConnectionEvent->eventType == gConnEvtPairingRequest_c)
1253 /* Reject request for pairing */
1254 Gap_RejectPairing(deviceId, gPairingNotSupported_c);
1256 else if (pConnectionEvent->eventType == gConnEvtAuthenticationRejected_c)
1258 ChipLogProgress(DeviceLayer, "BLE Authentication rejected (reason:%d).\n",
1259 pConnectionEvent->eventData.authenticationRejectedEvent.rejectReason);
1263 /* Called by BLE when a connect is received */
1264 void BLEManagerImpl::BLE_SignalFromISRCallback(void)
1266 /* TODO: Low Power */
1269 void BLEManagerImpl::blekw_connection_timeout_cb(TimerHandle_t timer)
1271 (void) blekw_msg_add_u8(BLE_KW_MSG_FORCE_DISCONNECT, 0);
1274 void BLEManagerImpl::blekw_start_connection_timeout(void)
1276 xTimerReset(connectionTimeout, 0);
1279 void BLEManagerImpl::blekw_stop_connection_timeout(void)
1281 ChipLogProgress(DeviceLayer, "Stopped connectionTimeout timer.");
1282 xTimerStop(connectionTimeout, 0);
1285 void BLEManagerImpl::blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent)
1287 switch (pServerEvent->eventType)
1289 case gEvtMtuChanged_c: {
1290 uint16_t tempMtu = 0;
1292 (void) Gatt_GetMtu(deviceId, &tempMtu);
1293 blekw_msg_add_u16(BLE_KW_MSG_MTU_CHANGED, tempMtu);
1297 case gEvtAttributeWritten_c:
1298 blekw_msg_add_att_written(BLE_KW_MSG_ATT_WRITTEN, deviceId, pServerEvent->eventData.attributeWrittenEvent.handle,
1299 pServerEvent->eventData.attributeWrittenEvent.aValue,
1300 pServerEvent->eventData.attributeWrittenEvent.cValueLength);
1303 case gEvtLongCharacteristicWritten_c:
1304 blekw_msg_add_att_written(BLE_KW_MSG_ATT_LONG_WRITTEN, deviceId, pServerEvent->eventData.longCharWrittenEvent.handle,
1305 pServerEvent->eventData.longCharWrittenEvent.aValue,
1306 pServerEvent->eventData.longCharWrittenEvent.cValueLength);
1309 case gEvtAttributeRead_c:
1310 blekw_msg_add_att_read(BLE_KW_MSG_ATT_READ, deviceId, pServerEvent->eventData.attributeReadEvent.handle);
1313 case gEvtCharacteristicCccdWritten_c: {
1314 uint16_t cccd_val = pServerEvent->eventData.charCccdWrittenEvent.newCccd;
1316 blekw_msg_add_att_written(BLE_KW_MSG_ATT_CCCD_WRITTEN, deviceId, pServerEvent->eventData.charCccdWrittenEvent.handle,
1317 (uint8_t *) &cccd_val, 2);
1321 case gEvtHandleValueConfirmation_c:
1322 /* Set the local synchronization event */
1323 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED);
1327 if (pServerEvent->eventData.procedureError.procedureType == gSendIndication_c)
1329 /* Set the local synchronization event */
1330 OSA_EventSet(event_msg, CHIP_BLE_KW_EVNT_INDICATION_FAILED);
1334 ChipLogProgress(DeviceLayer, "BLE Gatt Server Error: Code 0x%04X, Source %d.\n",
1335 pServerEvent->eventData.procedureError.error, pServerEvent->eventData.procedureError.procedureType);
1337 /* Notify CHIP BLE App Task that the BLE hardware report fail */
1338 (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_GATT_ERROR);
1346 /*******************************************************************************
1347 * Add to message queue functions
1348 *******************************************************************************/
1349 CHIP_ERROR BLEManagerImpl::blekw_msg_add_att_written(blekw_msg_type_t type, uint8_t device_id, uint16_t handle, uint8_t * data,
1352 blekw_msg_t * msg = NULL;
1353 blekw_att_written_data_t * att_wr_data;
1355 /* Allocate a buffer with enough space to store the packet */
1356 msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t) + sizeof(blekw_att_written_data_t) + length);
1360 return CHIP_ERROR_NO_MEMORY;
1365 msg->length = sizeof(blekw_att_written_data_t) + length;
1366 att_wr_data = (blekw_att_written_data_t *) msg->data.data;
1367 att_wr_data->device_id = device_id;
1368 att_wr_data->handle = handle;
1369 att_wr_data->length = length;
1370 FLib_MemCpy(att_wr_data->data, data, length);
1372 /* Put message in the queue */
1373 if (gListOk_c != MSG_Queue(&blekw_msg_list, msg))
1378 /* Notify BLE-APP Task to serve the BLE subsystem */
1379 blekw_new_data_received_notification(LOOP_EV_BLE);
1381 return CHIP_NO_ERROR;
1384 CHIP_ERROR BLEManagerImpl::blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle)
1386 blekw_msg_t * msg = NULL;
1387 blekw_att_read_data_t * att_rd_data;
1389 /* Allocate a buffer with enough space to store the packet */
1390 msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t) + sizeof(blekw_att_read_data_t));
1394 return CHIP_ERROR_NO_MEMORY;
1399 msg->length = sizeof(blekw_att_read_data_t);
1400 att_rd_data = (blekw_att_read_data_t *) msg->data.data;
1401 att_rd_data->device_id = device_id;
1402 att_rd_data->handle = handle;
1404 /* Put message in the queue */
1405 if (gListOk_c != MSG_Queue(&blekw_msg_list, msg))
1410 /* Notify BLE-APP Task to serve the BLE subsystem */
1411 blekw_new_data_received_notification(LOOP_EV_BLE);
1413 return CHIP_NO_ERROR;
1416 CHIP_ERROR BLEManagerImpl::blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data)
1418 blekw_msg_t * msg = NULL;
1420 /* Allocate a buffer with enough space to store the packet */
1421 msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t));
1425 return CHIP_ERROR_NO_MEMORY;
1430 msg->data.u8 = data;
1432 /* Put message in the queue */
1433 MSG_Queue(&blekw_msg_list, msg);
1435 /* Notify BLE-APP Task to serve the BLE subsystem */
1436 blekw_new_data_received_notification(LOOP_EV_BLE);
1438 return CHIP_NO_ERROR;
1441 CHIP_ERROR BLEManagerImpl::blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data)
1443 blekw_msg_t * msg = NULL;
1445 /* Allocate a buffer with enough space to store the packet */
1446 msg = (blekw_msg_t *) MSG_Alloc(sizeof(blekw_msg_t));
1450 return CHIP_ERROR_NO_MEMORY;
1455 msg->data.u16 = data;
1457 /* Put message in the queue */
1458 MSG_Queue(&blekw_msg_list, msg);
1460 /* Notify BLE-APP Task to serve the BLE subsystem */
1461 blekw_new_data_received_notification(LOOP_EV_BLE);
1463 return CHIP_NO_ERROR;
1466 /*******************************************************************************
1467 * FreeRTOS Task Management Functions
1468 *******************************************************************************/
1469 void BLEManagerImpl::blekw_new_data_received_notification(uint32_t mask)
1471 portBASE_TYPE taskToWake = pdFALSE;
1475 if (xEventGroupSetBitsFromISR(bleAppTaskLoopEvent, mask, &taskToWake) == pdPASS)
1477 /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
1478 switch should be requested. The macro used is port specific and will
1479 be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
1480 the documentation page for the port being used. */
1481 portYIELD_FROM_ISR(taskToWake);
1486 xEventGroupSetBits(bleAppTaskLoopEvent, mask);
1490 void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer)
1492 if (sInstance.mFlags.Has(Flags::kFastAdvertisingEnabled))
1494 ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisment");
1496 sInstance.mFlags.Clear(Flags::kFastAdvertisingEnabled);
1497 // stop advertiser, change interval and restart it;
1498 sInstance.StopAdvertising();
1499 sInstance.StartAdvertising();
1500 sInstance.StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT); // Slow advertise for 15 Minutes
1502 else if (sInstance._IsAdvertisingEnabled())
1504 // advertisement expired. we stop advertissing
1505 ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertisement");
1506 sInstance.StopAdvertising();
1512 void BLEManagerImpl::CancelBleAdvTimeoutTimer(void)
1514 if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL)
1516 ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer");
1520 void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs)
1522 if (xTimerIsTimerActive(sbleAdvTimeoutTimer))
1524 CancelBleAdvTimeoutTimer();
1527 // timer is not active, change its period to required value (== restart).
1528 // FreeRTOS- Block for a maximum of 100 ticks if the change period command
1529 // cannot immediately be sent to the timer command queue.
1530 if (xTimerChangePeriod(sbleAdvTimeoutTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS)
1532 ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer");
1536 } // namespace Internal
1537 } // namespace DeviceLayer
1539 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE