3 * Copyright (c) 2020-2021 Project CHIP Authors
4 * Copyright (c) 2018 Nest Labs, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * Provides an implementation of the BLEManager singleton object
22 * for Linux platforms.
24 #include <platform/internal/CHIPDeviceLayerInternal.h>
26 #include <ble/CHIPBleServiceData.h>
28 #include <platform/internal/BLEManager.h>
29 #include <support/CodeUtils.h>
30 #include <support/SafeInt.h>
32 #include <type_traits>
35 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
37 #include "bluez/Helper.h"
40 using namespace ::chip::Ble;
43 namespace DeviceLayer {
48 static constexpr unsigned kNewConnectionScanTimeoutMs = 10000;
50 const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
52 const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
57 BLEManagerImpl BLEManagerImpl::sInstance;
59 void HandleIncomingBleConnection(BLEEndPoint * bleEP)
61 ChipLogProgress(DeviceLayer, "CHIPoBluez con rcvd");
64 CHIP_ERROR BLEManagerImpl::_Init()
68 err = BleLayer::Init(this, this, this, &SystemLayer);
71 mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
72 mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART && !mIsCentral);
75 memset(mDeviceName, 0, sizeof(mDeviceName));
77 OnChipBleConnectReceived = HandleIncomingBleConnection;
79 PlatformMgr().ScheduleWork(DriveBLEState, 0);
85 CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val)
87 CHIP_ERROR err = CHIP_NO_ERROR;
89 VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
90 VerifyOrExit(mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
92 if (val != mServiceMode)
95 PlatformMgr().ScheduleWork(DriveBLEState, 0);
102 CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
104 CHIP_ERROR err = CHIP_NO_ERROR;
106 if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
108 mFlags.Set(Flags::kAdvertisingEnabled, val);
111 PlatformMgr().ScheduleWork(DriveBLEState, 0);
116 CHIP_ERROR BLEManagerImpl::_SetFastAdvertisingEnabled(bool val)
118 CHIP_ERROR err = CHIP_NO_ERROR;
120 VerifyOrExit(mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
122 if (mFlags.Has(Flags::kFastAdvertisingEnabled) != val)
124 mFlags.Set(Flags::kFastAdvertisingEnabled, val);
125 PlatformMgr().ScheduleWork(DriveBLEState, 0);
132 CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
134 if (strlen(mDeviceName) >= bufSize)
136 return CHIP_ERROR_BUFFER_TOO_SMALL;
138 strcpy(buf, mDeviceName);
140 return CHIP_NO_ERROR;
143 CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName)
145 CHIP_ERROR err = CHIP_NO_ERROR;
147 VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
149 if (deviceName != nullptr && deviceName[0] != 0)
151 VerifyOrExit(strlen(deviceName) < kMaxDeviceNameLength, err = CHIP_ERROR_INVALID_ARGUMENT);
152 strcpy(mDeviceName, deviceName);
153 mFlags.Set(Flags::kUseCustomDeviceName);
157 uint16_t discriminator;
158 SuccessOrExit(err = ConfigurationMgr().GetSetupDiscriminator(discriminator));
159 snprintf(mDeviceName, sizeof(mDeviceName), "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator);
160 mDeviceName[kMaxDeviceNameLength] = 0;
161 mFlags.Clear(Flags::kUseCustomDeviceName);
168 uint16_t BLEManagerImpl::_NumConnections()
170 uint16_t numCons = 0;
174 CHIP_ERROR BLEManagerImpl::ConfigureBle(uint32_t aAdapterId, bool aIsCentral)
176 CHIP_ERROR err = CHIP_NO_ERROR;
177 mBLEAdvConfig.mpBleName = mDeviceName;
178 mBLEAdvConfig.mAdapterId = aAdapterId;
179 mBLEAdvConfig.mMajor = 1;
180 mBLEAdvConfig.mMinor = 1;
181 mBLEAdvConfig.mVendorId = 1;
182 mBLEAdvConfig.mProductId = 1;
183 mBLEAdvConfig.mDeviceId = 1;
184 mBLEAdvConfig.mDuration = 2;
185 mBLEAdvConfig.mPairingStatus = 0;
186 mBLEAdvConfig.mType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE;
187 mBLEAdvConfig.mpAdvertisingUUID = "0xFEAF";
189 mIsCentral = aIsCentral;
194 CHIP_ERROR BLEManagerImpl::StartBLEAdvertising()
196 return StartBluezAdv(mpEndpoint);
199 CHIP_ERROR BLEManagerImpl::StopBLEAdvertising()
201 return StopBluezAdv(mpEndpoint);
204 void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
208 case DeviceEventType::kCHIPoBLESubscribe:
209 HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
211 ChipDeviceEvent connectionEvent;
212 connectionEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
213 PlatformMgr().PostEvent(&connectionEvent);
217 case DeviceEventType::kCHIPoBLEUnsubscribe:
218 HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
221 case DeviceEventType::kCHIPoBLEWriteReceived:
222 HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX,
223 PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
226 case DeviceEventType::kCHIPoBLEIndicateConfirm:
227 HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
230 case DeviceEventType::kCHIPoBLEConnectionError:
231 HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
233 case DeviceEventType::kFabricMembershipChange:
234 case DeviceEventType::kServiceProvisioningChange:
235 case DeviceEventType::kAccountPairingChange:
237 // If CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED is enabled, and there is a change to the
238 // device's provisioning state, then automatically disable CHIPoBLE advertising if the device
239 // is now fully provisioned.
240 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
241 if (ConfigurationMgr().IsFullyProvisioned())
243 mFlags.Clear(Flags::kAdvertisingEnabled);
244 ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned");
246 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
248 // Force the advertising configuration to be refreshed to reflect new provisioning state.
249 mFlags.Clear(Flags::kAdvertisingConfigured);
254 HandlePlatformSpecificBLEEvent(event);
259 void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEvent)
261 CHIP_ERROR err = CHIP_NO_ERROR;
262 bool controlOpComplete = false;
263 ChipLogProgress(DeviceLayer, "HandlePlatformSpecificBLEEvent %d", apEvent->Type);
264 switch (apEvent->Type)
266 case DeviceEventType::kPlatformLinuxBLECentralConnected:
267 if (OnConnectionComplete != nullptr)
268 OnConnectionComplete(mBLEScanConfig.mAppState, apEvent->Platform.BLECentralConnected.mConnection);
270 case DeviceEventType::kPlatformLinuxBLEWriteComplete:
271 HandleWriteConfirmation(apEvent->Platform.BLEWriteComplete.mConnection, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX);
273 case DeviceEventType::kPlatformLinuxBLESubscribeOpComplete:
274 if (apEvent->Platform.BLESubscribeOpComplete.mIsSubscribed)
275 HandleSubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &CHIP_BLE_SVC_ID,
276 &ChipUUID_CHIPoBLEChar_TX);
278 HandleUnsubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &CHIP_BLE_SVC_ID,
279 &ChipUUID_CHIPoBLEChar_TX);
281 case DeviceEventType::kPlatformLinuxBLEIndicationReceived:
282 HandleIndicationReceived(apEvent->Platform.BLEIndicationReceived.mConnection, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX,
283 PacketBufferHandle::Adopt(apEvent->Platform.BLEIndicationReceived.mData));
285 case DeviceEventType::kPlatformLinuxBLEPeripheralAdvConfiguredComplete:
286 VerifyOrExit(apEvent->Platform.BLEPeripheralAdvConfiguredComplete.mIsSuccess, err = CHIP_ERROR_INCORRECT_STATE);
287 sInstance.mFlags.Set(Flags::kAdvertisingConfigured).Clear(Flags::kControlOpInProgress);
288 controlOpComplete = true;
289 ChipLogProgress(DeviceLayer, "CHIPoBLE advertising config complete");
291 case DeviceEventType::kPlatformLinuxBLEPeripheralAdvStartComplete:
292 VerifyOrExit(apEvent->Platform.BLEPeripheralAdvStartComplete.mIsSuccess, err = CHIP_ERROR_INCORRECT_STATE);
293 sInstance.mFlags.Clear(Flags::kControlOpInProgress).Clear(Flags::kAdvertisingRefreshNeeded);
295 if (!sInstance.mFlags.Has(Flags::kAdvertising))
297 sInstance.mFlags.Set(Flags::kAdvertising);
301 case DeviceEventType::kPlatformLinuxBLEPeripheralAdvStopComplete:
302 VerifyOrExit(apEvent->Platform.BLEPeripheralAdvStopComplete.mIsSuccess, err = CHIP_ERROR_INCORRECT_STATE);
304 sInstance.mFlags.Clear(Flags::kControlOpInProgress).Clear(Flags::kAdvertisingRefreshNeeded);
306 // Transition to the not Advertising state...
307 if (sInstance.mFlags.Has(Flags::kAdvertising))
309 sInstance.mFlags.Clear(Flags::kAdvertising);
310 ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped");
313 case DeviceEventType::kPlatformLinuxBLEPeripheralRegisterAppComplete:
314 VerifyOrExit(apEvent->Platform.BLEPeripheralRegisterAppComplete.mIsSuccess, err = CHIP_ERROR_INCORRECT_STATE);
315 mFlags.Set(Flags::kAppRegistered);
316 controlOpComplete = true;
323 if (err != CHIP_NO_ERROR)
325 ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
326 mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
327 sInstance.mFlags.Clear(Flags::kControlOpInProgress);
330 if (controlOpComplete)
332 mFlags.Clear(Flags::kControlOpInProgress);
337 uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
339 BluezConnection * connection = static_cast<BluezConnection *>(conId);
340 return (connection != nullptr) ? connection->mMtu : 0;
343 bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
347 VerifyOrExit(Ble::UUIDsMatch(svcId, &CHIP_BLE_SVC_ID),
348 ChipLogError(DeviceLayer, "SubscribeCharacteristic() called with invalid service ID"));
349 VerifyOrExit(Ble::UUIDsMatch(charId, &ChipUUID_CHIPoBLEChar_TX),
350 ChipLogError(DeviceLayer, "SubscribeCharacteristic() called with invalid characteristic ID"));
352 result = BluezSubscribeCharacteristic(conId);
357 bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
361 VerifyOrExit(Ble::UUIDsMatch(svcId, &CHIP_BLE_SVC_ID),
362 ChipLogError(DeviceLayer, "UnsubscribeCharacteristic() called with invalid service ID"));
363 VerifyOrExit(Ble::UUIDsMatch(charId, &ChipUUID_CHIPoBLEChar_TX),
364 ChipLogError(DeviceLayer, "UnsubscribeCharacteristic() called with invalid characteristic ID"));
366 result = BluezUnsubscribeCharacteristic(conId);
371 bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
373 ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %p)", conId);
374 return CloseBluezConnection(conId);
377 bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
378 chip::System::PacketBufferHandle pBuf)
380 return SendBluezIndication(conId, std::move(pBuf));
383 bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
384 chip::System::PacketBufferHandle pBuf)
388 VerifyOrExit(Ble::UUIDsMatch(svcId, &CHIP_BLE_SVC_ID),
389 ChipLogError(DeviceLayer, "SendWriteRequest() called with invalid service ID"));
390 VerifyOrExit(Ble::UUIDsMatch(charId, &ChipUUID_CHIPoBLEChar_RX),
391 ChipLogError(DeviceLayer, "SendWriteRequest() called with invalid characteristic ID"));
393 result = BluezSendWriteRequest(conId, std::move(pBuf));
398 bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
399 chip::System::PacketBufferHandle pBuf)
401 ChipLogError(Ble, "SendReadRequest: Not implemented");
405 bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
406 const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId)
408 ChipLogError(Ble, "SendReadRBluezonse: Not implemented");
412 void BLEManagerImpl::HandleNewConnection(BLE_CONNECTION_OBJECT conId)
414 if (sInstance.mIsCentral)
416 ChipDeviceEvent event;
417 event.Type = DeviceEventType::kPlatformLinuxBLECentralConnected;
418 event.Platform.BLECentralConnected.mConnection = conId;
419 PlatformMgr().PostEvent(&event);
423 void BLEManagerImpl::HandleWriteComplete(BLE_CONNECTION_OBJECT conId)
425 ChipDeviceEvent event;
426 event.Type = DeviceEventType::kPlatformLinuxBLEWriteComplete;
427 event.Platform.BLEWriteComplete.mConnection = conId;
428 PlatformMgr().PostEvent(&event);
431 void BLEManagerImpl::HandleSubscribeOpComplete(BLE_CONNECTION_OBJECT conId, bool subscribed)
433 ChipDeviceEvent event;
434 event.Type = DeviceEventType::kPlatformLinuxBLESubscribeOpComplete;
435 event.Platform.BLESubscribeOpComplete.mConnection = conId;
436 event.Platform.BLESubscribeOpComplete.mIsSubscribed = subscribed;
437 PlatformMgr().PostEvent(&event);
440 void BLEManagerImpl::HandleTXCharChanged(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len)
442 CHIP_ERROR err = CHIP_NO_ERROR;
443 System::PacketBufferHandle buf = System::PacketBufferHandle::NewWithData(value, len);
445 ChipLogProgress(DeviceLayer, "Indication received, conn = %p", conId);
447 VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);
449 ChipDeviceEvent event;
450 event.Type = DeviceEventType::kPlatformLinuxBLEIndicationReceived;
451 event.Platform.BLEIndicationReceived.mConnection = conId;
452 event.Platform.BLEIndicationReceived.mData = std::move(buf).UnsafeRelease();
453 PlatformMgr().PostEvent(&event);
456 if (err != CHIP_NO_ERROR)
457 ChipLogError(DeviceLayer, "HandleTXCharChanged() failed: %s", ErrorStr(err));
460 void BLEManagerImpl::HandleRXCharWrite(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len)
462 CHIP_ERROR err = CHIP_NO_ERROR;
463 System::PacketBufferHandle buf;
465 // Copy the data to a packet buffer.
466 buf = System::PacketBufferHandle::NewWithData(value, len);
467 VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);
469 // Post an event to the Chip queue to deliver the data into the Chip stack.
471 ChipDeviceEvent event;
472 event.Type = DeviceEventType::kCHIPoBLEWriteReceived;
473 ChipLogProgress(Ble, "Write request received debug %p", conId);
474 event.CHIPoBLEWriteReceived.ConId = conId;
475 event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease();
476 PlatformMgr().PostEvent(&event);
480 if (err != CHIP_NO_ERROR)
482 ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err));
486 void BLEManagerImpl::CHIPoBluez_ConnectionClosed(BLE_CONNECTION_OBJECT conId)
488 ChipLogProgress(DeviceLayer, "Bluez notify CHIPoBluez connection disconnected");
490 // If this was a CHIPoBLE connection, post an event to deliver a connection error to the CHIPoBLE layer.
492 ChipDeviceEvent event;
493 event.Type = DeviceEventType::kCHIPoBLEConnectionError;
494 event.CHIPoBLEConnectionError.ConId = conId;
495 event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED;
496 PlatformMgr().PostEvent(&event);
500 void BLEManagerImpl::HandleTXCharCCCDWrite(BLE_CONNECTION_OBJECT conId)
502 CHIP_ERROR err = CHIP_NO_ERROR;
504 BluezConnection * connection = static_cast<BluezConnection *>(conId);
506 VerifyOrExit(connection != nullptr, ChipLogError(DeviceLayer, "Connection is NULL in HandleTXCharCCCDWrite"));
507 VerifyOrExit(connection->mpC2 != nullptr, ChipLogError(DeviceLayer, "C2 is NULL in HandleTXCharCCCDWrite"));
509 // Post an event to the Chip queue to process either a CHIPoBLE Subscribe or Unsubscribe based on
510 // whether the client is enabling or disabling indications.
512 ChipDeviceEvent event;
513 event.Type = connection->mIsNotify ? DeviceEventType::kCHIPoBLESubscribe : DeviceEventType::kCHIPoBLEUnsubscribe;
514 event.CHIPoBLESubscribe.ConId = connection;
515 PlatformMgr().PostEvent(&event);
518 ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", connection->mIsNotify ? "subscribe" : "unsubscribe");
521 if (err != CHIP_NO_ERROR)
523 ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err));
524 // TODO: fail connection
528 void BLEManagerImpl::HandleTXComplete(BLE_CONNECTION_OBJECT conId)
530 // Post an event to the Chip queue to process the indicate confirmation.
531 ChipDeviceEvent event;
532 event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm;
533 event.CHIPoBLEIndicateConfirm.ConId = conId;
534 PlatformMgr().PostEvent(&event);
537 void BLEManagerImpl::DriveBLEState()
539 CHIP_ERROR err = CHIP_NO_ERROR;
541 // Perform any initialization actions that must occur after the Chip task is running.
542 if (!mFlags.Has(Flags::kAsyncInitCompleted))
544 mFlags.Set(Flags::kAsyncInitCompleted);
546 // If CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED is enabled,
547 // disable CHIPoBLE advertising if the device is fully provisioned.
548 #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
549 if (ConfigurationMgr().IsFullyProvisioned())
551 mFlags.Clear(Flags::kAdvertisingEnabled);
552 ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned");
554 #endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
558 // If there's already a control operation in progress, wait until it completes.
559 VerifyOrExit(!mFlags.Has(Flags::kControlOpInProgress), /* */);
561 // Initializes the Bluez BLE layer if needed.
562 if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && !mFlags.Has(Flags::kBluezBLELayerInitialized))
564 err = InitBluezBleLayer(mIsCentral, nullptr, mBLEAdvConfig, mpEndpoint);
566 mFlags.Set(Flags::kBluezBLELayerInitialized);
569 // Register the CHIPoBLE application with the Bluez BLE layer if needed.
570 if (!mIsCentral && mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && !mFlags.Has(Flags::kAppRegistered))
572 err = BluezGattsAppRegister(mpEndpoint);
573 mFlags.Set(Flags::kControlOpInProgress);
577 // If the application has enabled CHIPoBLE and BLE advertising...
578 if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled))
580 // Start/re-start advertising if not already advertising, or if the advertising state of the
581 // Bluez BLE layer needs to be refreshed.
582 if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kAdvertisingRefreshNeeded))
584 // Configure advertising data if it hasn't been done yet. This is an asynchronous step which
585 // must complete before advertising can be started. When that happens, this method will
586 // be called again, and execution will proceed to the code below.
587 if (!mFlags.Has(Flags::kAdvertisingConfigured))
589 err = BluezAdvertisementSetup(mpEndpoint);
593 // Start advertising. This is also an asynchronous step.
594 err = StartBLEAdvertising();
597 sInstance.mFlags.Set(Flags::kAdvertising);
602 // Otherwise stop advertising if needed...
605 if (mFlags.Has(Flags::kAdvertising))
607 err = StopBLEAdvertising();
609 mFlags.Set(Flags::kControlOpInProgress);
616 if (err != CHIP_NO_ERROR)
618 ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
619 mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
623 void BLEManagerImpl::DriveBLEState(intptr_t arg)
625 sInstance.DriveBLEState();
628 void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId)
630 ChipLogProgress(Ble, "Got notification regarding chip connection closure");
633 void BLEManagerImpl::InitiateScan(BleScanState scanType)
637 if (scanType == BleScanState::kNotScanning)
639 OnConnectionError(mBLEScanConfig.mAppState, CHIP_ERROR_INCORRECT_STATE);
640 ChipLogError(Ble, "Invalid scan type requested");
644 if (mpEndpoint == nullptr)
646 OnConnectionError(mBLEScanConfig.mAppState, CHIP_ERROR_INCORRECT_STATE);
647 ChipLogError(Ble, "BLE Layer is not yet initialized");
651 if (mpEndpoint->mpAdapter == nullptr)
653 OnConnectionError(mBLEScanConfig.mAppState, CHIP_ERROR_INCORRECT_STATE);
654 ChipLogError(Ble, "No adapter available for new connection establishment");
658 mDeviceScanner = Internal::ChipDeviceScanner::Create(mpEndpoint->mpAdapter, this);
660 mBLEScanConfig.bleScanState = BleScanState::kScanForDiscriminator;
664 mBLEScanConfig.bleScanState = BleScanState::kNotScanning;
665 OnConnectionError(mBLEScanConfig.mAppState, CHIP_ERROR_INTERNAL);
666 ChipLogError(Ble, "Failed to create a BLE device scanner");
670 CHIP_ERROR err = mDeviceScanner->StartScan(kNewConnectionScanTimeoutMs);
671 if (err != CHIP_NO_ERROR)
673 mBLEScanConfig.bleScanState = BleScanState::kNotScanning;
674 ChipLogError(Ble, "Failed to start a BLE can: %s", chip::ErrorStr(err));
675 OnConnectionError(mBLEScanConfig.mAppState, err);
680 void BLEManagerImpl::InitiateScan(intptr_t arg)
682 sInstance.InitiateScan(static_cast<BleScanState>(arg));
685 void BLEManagerImpl::NewConnection(BleLayer * bleLayer, void * appState, const uint16_t connDiscriminator)
687 mBLEScanConfig.mDiscriminator = connDiscriminator;
688 mBLEScanConfig.mAppState = appState;
690 // Scan initiation performed async, to ensure that the BLE subsystem is initialized.
691 PlatformMgr().ScheduleWork(InitiateScan, static_cast<intptr_t>(BleScanState::kScanForDiscriminator));
694 void BLEManagerImpl::NotifyBLEPeripheralRegisterAppComplete(bool aIsSuccess, void * apAppstate)
696 ChipDeviceEvent event;
697 event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralRegisterAppComplete;
698 event.Platform.BLEPeripheralRegisterAppComplete.mIsSuccess = aIsSuccess;
699 event.Platform.BLEPeripheralRegisterAppComplete.mpAppstate = apAppstate;
700 PlatformMgr().PostEvent(&event);
703 void BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(bool aIsSuccess, void * apAppstate)
705 ChipDeviceEvent event;
706 event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralAdvConfiguredComplete;
707 event.Platform.BLEPeripheralAdvConfiguredComplete.mIsSuccess = aIsSuccess;
708 event.Platform.BLEPeripheralAdvConfiguredComplete.mpAppstate = apAppstate;
709 PlatformMgr().PostEvent(&event);
712 void BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete(bool aIsSuccess, void * apAppstate)
714 ChipDeviceEvent event;
715 event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralAdvStartComplete;
716 event.Platform.BLEPeripheralAdvStartComplete.mIsSuccess = aIsSuccess;
717 event.Platform.BLEPeripheralAdvStartComplete.mpAppstate = apAppstate;
718 PlatformMgr().PostEvent(&event);
721 void BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete(bool aIsSuccess, void * apAppstate)
723 ChipDeviceEvent event;
724 event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralAdvStopComplete;
725 event.Platform.BLEPeripheralAdvStopComplete.mIsSuccess = aIsSuccess;
726 event.Platform.BLEPeripheralAdvStopComplete.mpAppstate = apAppstate;
727 PlatformMgr().PostEvent(&event);
730 void BLEManagerImpl::OnDeviceScanned(BluezDevice1 * device, const chip::Ble::ChipBLEDeviceIdentificationInfo & info)
732 ChipLogProgress(Ble, "New device scanned: %s", bluez_device1_get_address(device));
734 if (mBLEScanConfig.bleScanState == BleScanState::kScanForDiscriminator)
736 if (info.GetDeviceDiscriminator() != mBLEScanConfig.mDiscriminator)
740 ChipLogProgress(Ble, "Device discriminator match. Attempting to connect.");
742 else if (mBLEScanConfig.bleScanState == BleScanState::kScanForAddress)
744 if (strcmp(bluez_device1_get_address(device), mBLEScanConfig.mAddress.c_str()) != 0)
748 ChipLogProgress(Ble, "Device address match. Attempting to connect.");
752 // Internal consistency eerror
753 ChipLogError(Ble, "Unknown discovery type. Ignoring scanned device.");
757 mBLEScanConfig.bleScanState = BleScanState::kNotScanning;
758 mDeviceScanner->StopScan();
760 ConnectDevice(device);
763 void BLEManagerImpl::OnScanComplete()
765 if (mBLEScanConfig.bleScanState == BleScanState::kNotScanning)
767 ChipLogError(Ble, "Scan complete notification without an active scan.");
771 OnConnectionError(mBLEScanConfig.mAppState, CHIP_ERROR_TIMEOUT);
772 mBLEScanConfig.bleScanState = BleScanState::kNotScanning;
775 } // namespace Internal
776 } // namespace DeviceLayer
779 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE