diff --git a/scripts/helpers/platforms/iwyu.imp b/scripts/helpers/platforms/iwyu.imp index 5a863b3f3a6208..c3d2210b2886dd 100644 --- a/scripts/helpers/platforms/iwyu.imp +++ b/scripts/helpers/platforms/iwyu.imp @@ -11,6 +11,16 @@ { symbol: [ 'declval', private, '', public ] }, { symbol: [ 'tm', private, '', public ] }, + ## GLib/GIO + { include: [ '"gio/gdbusinterface.h"', private, '', public ] }, + { include: [ '"gio/gdbusinterfaceskeleton.h"', private, '', public ] }, + { include: [ '"gio/gdbusobject.h"', private, '', public ] }, + { include: [ '"gio/gdbusobjectmanager.h"', private, '', public ] }, + { include: [ '"gio/gdbusobjectmanagerclient.h"', private, '', public ] }, + { include: [ '"gio/gdbusobjectmanagerserver.h"', private, '', public ] }, + { include: [ '"gio/gdbusobjectskeleton.h"', private, '', public ] }, + { include: [ '"gobject/gclosure.h"', private, '', public ] }, + ## ble/* { include: [ '"ble/CHIPBleServiceData.h"', private, '', public ] }, { include: [ '@"ble/Ble.*.h"', private, '', public ] }, diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 01a93a29b8a1ed..194598b8581ff6 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -101,8 +101,10 @@ CHIP_ERROR BLEManagerImpl::_Init() void BLEManagerImpl::_Shutdown() { - // ensure scan resources are cleared (e.g. timeout timers) + // Ensure scan resources are cleared (e.g. timeout timers). mDeviceScanner.Shutdown(); + // Stop advertising and free resources. + mBLEAdvertisement.Shutdown(); // Release BLE connection resources (unregister from BlueZ). ShutdownBluezBleLayer(mpEndpoint); mFlags.Clear(Flags::kBluezBLELayerInitialized); @@ -184,32 +186,15 @@ uint16_t BLEManagerImpl::_NumConnections() CHIP_ERROR BLEManagerImpl::ConfigureBle(uint32_t aAdapterId, bool aIsCentral) { - CHIP_ERROR err = CHIP_NO_ERROR; - mBLEAdvConfig.mpBleName = mDeviceName; - mBLEAdvConfig.mAdapterId = aAdapterId; - mBLEAdvConfig.mMajor = 1; - mBLEAdvConfig.mMinor = 1; - mBLEAdvConfig.mVendorId = 1; - mBLEAdvConfig.mProductId = 1; - mBLEAdvConfig.mDeviceId = 1; - mBLEAdvConfig.mDuration = 2; - mBLEAdvConfig.mPairingStatus = 0; - mBLEAdvConfig.mType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE; - mBLEAdvConfig.mpAdvertisingUUID = "0xFFF6"; + mAdapterId = aAdapterId; mIsCentral = aIsCentral; - return err; -} - -CHIP_ERROR BLEManagerImpl::StartBLEAdvertising() -{ - return StartBluezAdv(mpEndpoint); -} + mBLEAdvType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE; + mBLEAdvDurationMs = 2; + mpBLEAdvUUID = "0xFFF6"; -CHIP_ERROR BLEManagerImpl::StopBLEAdvertising() -{ - return StopBluezAdv(mpEndpoint); + return CHIP_NO_ERROR; } void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) @@ -290,12 +275,6 @@ void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEv HandleIndicationReceived(apEvent->Platform.BLEIndicationReceived.mConnection, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX, PacketBufferHandle::Adopt(apEvent->Platform.BLEIndicationReceived.mData)); break; - case DeviceEventType::kPlatformLinuxBLEPeripheralAdvConfiguredComplete: - VerifyOrExit(apEvent->Platform.BLEPeripheralAdvConfiguredComplete.mIsSuccess, err = CHIP_ERROR_INCORRECT_STATE); - sInstance.mFlags.Set(Flags::kAdvertisingConfigured).Clear(Flags::kControlOpInProgress); - controlOpComplete = true; - ChipLogProgress(DeviceLayer, "CHIPoBLE advertising config complete"); - break; case DeviceEventType::kPlatformLinuxBLEPeripheralAdvStartComplete: VerifyOrExit(apEvent->Platform.BLEPeripheralAdvStartComplete.mIsSuccess, err = CHIP_ERROR_INCORRECT_STATE); sInstance.mFlags.Clear(Flags::kControlOpInProgress).Clear(Flags::kAdvertisingRefreshNeeded); @@ -592,7 +571,7 @@ void BLEManagerImpl::DriveBLEState() // Initializes the Bluez BLE layer if needed. if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && !mFlags.Has(Flags::kBluezBLELayerInitialized)) { - err = InitBluezBleLayer(mIsCentral, nullptr, mBLEAdvConfig, mpEndpoint); + err = InitBluezBleLayer(mAdapterId, mIsCentral, nullptr, mDeviceName, mpEndpoint); SuccessOrExit(err); mFlags.Set(Flags::kBluezBLELayerInitialized); } @@ -615,20 +594,19 @@ void BLEManagerImpl::DriveBLEState() { mFlags.Clear(Flags::kAdvertisingRefreshNeeded); - // Configure advertising data if it hasn't been done yet. This is an asynchronous step which - // must complete before advertising can be started. When that happens, this method will - // be called again, and execution will proceed to the code below. + // Configure advertising data if it hasn't been done yet. if (!mFlags.Has(Flags::kAdvertisingConfigured)) { - err = BluezAdvertisementSetup(mpEndpoint); - ExitNow(); + err = mBLEAdvertisement.Init(mpEndpoint, mBLEAdvType, mpBLEAdvUUID, mBLEAdvDurationMs); + SuccessOrExit(err); + mFlags.Set(Flags::kAdvertisingConfigured); } - // Start advertising. This is also an asynchronous step. - err = StartBLEAdvertising(); + // Start advertising. This is an asynchronous step. BLE manager will be notified of + // advertising start completion via a call to NotifyBLEPeripheralAdvStartComplete. + err = mBLEAdvertisement.Start(); SuccessOrExit(err); - - sInstance.mFlags.Set(Flags::kAdvertising); + mFlags.Set(Flags::kControlOpInProgress); ExitNow(); } } @@ -638,7 +616,7 @@ void BLEManagerImpl::DriveBLEState() { if (mFlags.Has(Flags::kAdvertising)) { - err = StopBLEAdvertising(); + err = mBLEAdvertisement.Stop(); SuccessOrExit(err); mFlags.Set(Flags::kControlOpInProgress); @@ -751,15 +729,6 @@ void BLEManagerImpl::NotifyBLEPeripheralRegisterAppComplete(bool aIsSuccess, voi PlatformMgr().PostEventOrDie(&event); } -void BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(bool aIsSuccess, void * apAppstate) -{ - ChipDeviceEvent event; - event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralAdvConfiguredComplete; - event.Platform.BLEPeripheralAdvConfiguredComplete.mIsSuccess = aIsSuccess; - event.Platform.BLEPeripheralAdvConfiguredComplete.mpAppstate = apAppstate; - PlatformMgr().PostEventOrDie(&event); -} - void BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete(bool aIsSuccess, void * apAppstate) { ChipDeviceEvent event; diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index 458bac267db832..2f7cf8fe4f8ae5 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -23,11 +23,13 @@ #pragma once +#include #include #include #include +#include "bluez/BluezAdvertisement.h" #include "bluez/BluezEndpoint.h" #include "bluez/ChipDeviceScanner.h" #include "bluez/Types.h" @@ -38,21 +40,6 @@ namespace Internal { void HandleIncomingBleConnection(Ble::BLEEndPoint * bleEP); -struct BLEAdvConfig -{ - char * mpBleName; - uint32_t mAdapterId; - uint8_t mMajor; - uint8_t mMinor; - uint16_t mVendorId; - uint16_t mProductId; - uint64_t mDeviceId; - uint8_t mPairingStatus; - ChipAdvType mType; - uint16_t mDuration; - const char * mpAdvertisingUUID; -}; - enum class BleScanState : uint8_t { kNotScanning, @@ -106,7 +93,6 @@ class BLEManagerImpl final : public BLEManager, static void HandleTXComplete(BLE_CONNECTION_OBJECT user_data); static void NotifyBLEPeripheralRegisterAppComplete(bool aIsSuccess, void * apAppstate); - static void NotifyBLEPeripheralAdvConfiguredComplete(bool aIsSuccess, void * apAppstate); static void NotifyBLEPeripheralAdvStartComplete(bool aIsSuccess, void * apAppstate); static void NotifyBLEPeripheralAdvStopComplete(bool aIsSuccess, void * apAppstate); @@ -187,9 +173,6 @@ class BLEManagerImpl final : public BLEManager, kMaxAdvertisementDataSetSize = 31 // TODO: verify this }; - CHIP_ERROR StartBLEAdvertising(); - CHIP_ERROR StopBLEAdvertising(); - void DriveBLEState(); static void DriveBLEState(intptr_t arg); @@ -198,13 +181,20 @@ class BLEManagerImpl final : public BLEManager, void CleanScanConfig(); CHIPoBLEServiceMode mServiceMode; - BLEAdvConfig mBLEAdvConfig; - BLEScanConfig mBLEScanConfig; BitFlags mFlags; + + uint32_t mAdapterId = 0; char mDeviceName[kMaxDeviceNameLength + 1]; bool mIsCentral = false; BluezEndpoint * mpEndpoint = nullptr; + + BluezAdvertisement mBLEAdvertisement; + ChipAdvType mBLEAdvType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE; + uint16_t mBLEAdvDurationMs = 20; + const char * mpBLEAdvUUID = nullptr; + ChipDeviceScanner mDeviceScanner; + BLEScanConfig mBLEScanConfig; }; /** diff --git a/src/platform/Linux/BUILD.gn b/src/platform/Linux/BUILD.gn index a2cfa6b39cbaa8..635fd446eb941e 100644 --- a/src/platform/Linux/BUILD.gn +++ b/src/platform/Linux/BUILD.gn @@ -91,6 +91,8 @@ static_library("Linux") { "BlePlatformConfig.h", "bluez/AdapterIterator.cpp", "bluez/AdapterIterator.h", + "bluez/BluezAdvertisement.cpp", + "bluez/BluezAdvertisement.h", "bluez/BluezConnection.cpp", "bluez/BluezConnection.h", "bluez/BluezEndpoint.cpp", diff --git a/src/platform/Linux/CHIPDevicePlatformEvent.h b/src/platform/Linux/CHIPDevicePlatformEvent.h index 009f39148aef92..8618b9ebeaa0a8 100644 --- a/src/platform/Linux/CHIPDevicePlatformEvent.h +++ b/src/platform/Linux/CHIPDevicePlatformEvent.h @@ -53,7 +53,6 @@ enum InternalPlatformSpecificEventTypes kPlatformLinuxBLEC1WriteEvent, kPlatformLinuxBLEOutOfBuffersEvent, kPlatformLinuxBLEPeripheralRegisterAppComplete, - kPlatformLinuxBLEPeripheralAdvConfiguredComplete, kPlatformLinuxBLEPeripheralAdvStartComplete, kPlatformLinuxBLEPeripheralAdvStopComplete }; diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp new file mode 100644 index 00000000000000..16d590d6bab80d --- /dev/null +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -0,0 +1,349 @@ +/* + * + * Copyright (c) 2020-2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BluezAdvertisement.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "BluezEndpoint.h" +#include "Types.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() +{ + BluezLEAdvertisement1 * adv; + BluezObjectSkeleton * object; + GVariant * serviceData; + GVariant * serviceUUID; + GVariantBuilder serviceDataBuilder; + GVariantBuilder serviceUUIDsBuilder; + GAutoPtr debugStr; + const char * localNamePtr; + char localName[32]; + + ChipLogDetail(DeviceLayer, "Create BLE adv object at %s", mpAdvPath); + object = bluez_object_skeleton_new(mpAdvPath); + + adv = bluez_leadvertisement1_skeleton_new(); + + g_variant_builder_init(&serviceDataBuilder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_init(&serviceUUIDsBuilder, G_VARIANT_TYPE("as")); + + g_variant_builder_add(&serviceDataBuilder, "{sv}", mpAdvUUID, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &mDeviceIdInfo, sizeof(mDeviceIdInfo), sizeof(uint8_t))); + g_variant_builder_add(&serviceUUIDsBuilder, "s", mpAdvUUID); + + localNamePtr = mpAdapterName; + if (localNamePtr == nullptr) + { + g_snprintf(localName, sizeof(localName), "%s%04x", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, getpid() & 0xffff); + localNamePtr = localName; + } + + serviceData = g_variant_builder_end(&serviceDataBuilder); + serviceUUID = g_variant_builder_end(&serviceUUIDsBuilder); + + debugStr = GAutoPtr(g_variant_print(serviceData, TRUE)); + ChipLogDetail(DeviceLayer, "SET service data to %s", StringOrNullMarker(debugStr.get())); + + bluez_leadvertisement1_set_type_(adv, (mAdvType & BLUEZ_ADV_TYPE_CONNECTABLE) ? "peripheral" : "broadcast"); + // empty manufacturer data + // empty solicit UUIDs + bluez_leadvertisement1_set_service_data(adv, serviceData); + // empty data + + // Setting "Discoverable" to False on the adapter and to True on the advertisement convinces + // Bluez to set "BR/EDR Not Supported" flag. Bluez doesn't provide API to do that explicitly + // and the flag is necessary to force using LE transport. + bluez_leadvertisement1_set_discoverable(adv, (mAdvType & BLUEZ_ADV_TYPE_SCANNABLE) ? TRUE : FALSE); + if (mAdvType & BLUEZ_ADV_TYPE_SCANNABLE) + bluez_leadvertisement1_set_discoverable_timeout(adv, UINT16_MAX); + + // advertising name corresponding to the PID and object path, for debug purposes + bluez_leadvertisement1_set_local_name(adv, localNamePtr); + bluez_leadvertisement1_set_service_uuids(adv, serviceUUID); + + // 0xffff means no appearance + bluez_leadvertisement1_set_appearance(adv, 0xffff); + + bluez_leadvertisement1_set_duration(adv, mAdvDurationMs); + // empty duration, we don't have a clear notion what it would mean to timeslice between toble and anyone else + bluez_leadvertisement1_set_timeout(adv, 0); + // empty secondary channel for now + + bluez_object_skeleton_set_leadvertisement1(object, adv); + g_signal_connect(adv, "handle-release", + G_CALLBACK(+[](BluezLEAdvertisement1 * aAdv, GDBusMethodInvocation * aInv, BluezAdvertisement * self) { + return self->BluezLEAdvertisement1Release(aAdv, aInv); + }), + this); + + g_dbus_object_manager_server_export(mpRoot, G_DBUS_OBJECT_SKELETON(object)); + g_object_unref(object); + + return adv; +} + +gboolean BluezAdvertisement::BluezLEAdvertisement1Release(BluezLEAdvertisement1 * aAdv, GDBusMethodInvocation * aInvocation) +{ + ChipLogDetail(DeviceLayer, "Release BLE adv object in %s", __func__); + g_dbus_object_manager_server_unexport(mpRoot, mpAdvPath); + g_object_unref(mpAdv); + mpAdv = nullptr; + mIsAdvertising = false; + return TRUE; +} + +CHIP_ERROR BluezAdvertisement::InitImpl() +{ + // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, + // all D-Bus signals will be delivered to the GLib global default main context. + VerifyOrDie(g_main_context_get_thread_default() != nullptr); + + mpAdv = CreateLEAdvertisement(); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, ChipAdvType aAdvType, const char * aAdvUUID, + uint32_t aAdvDurationMs) +{ + GAutoPtr rootPath; + CHIP_ERROR err; + + VerifyOrExit(apEndpoint != nullptr, err = CHIP_ERROR_INCORRECT_STATE; + ChipLogError(DeviceLayer, "FAIL: NULL endpoint in %s", __func__)); + VerifyOrExit(mpAdv == nullptr, err = CHIP_ERROR_INCORRECT_STATE; + ChipLogError(DeviceLayer, "FAIL: BLE advertisement already initialized in %s", __func__)); + + mpRoot = reinterpret_cast(g_object_ref(apEndpoint->mpRoot)); + mpAdapter = reinterpret_cast(g_object_ref(apEndpoint->mpAdapter)); + mpAdapterName = g_strdup(apEndpoint->mpAdapterName); + + g_object_get(G_OBJECT(mpRoot), "object-path", &MakeUniquePointerReceiver(rootPath).Get(), nullptr); + mpAdvPath = g_strdup_printf("%s/advertising", rootPath.get()); + mAdvType = aAdvType; + mpAdvUUID = g_strdup(aAdvUUID); + mAdvDurationMs = aAdvDurationMs; + + err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); + ReturnErrorOnFailure(err); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + mDeviceIdInfo.SetAdditionalDataFlag(true); +#endif + + err = PlatformMgrImpl().GLibMatterContextInvokeSync( + +[](BluezAdvertisement * self) { return self->InitImpl(); }, this); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Ble, "Failed to schedule BLE advertisement Init() on CHIPoBluez thread")); + + mIsInitialized = true; + +exit: + return err; +} + +void BluezAdvertisement::Shutdown() +{ + VerifyOrReturn(mIsInitialized); + + // Make sure that the advertisement is stopped before we start cleaning up. + if (mIsAdvertising) + { + CHIP_ERROR err = Stop(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to stop BLE advertisement before shutdown: %" CHIP_ERROR_FORMAT, err.Format()); + } + } + + // Release resources on the glib thread to synchronize with potential signal handlers + // attached to the advertising object that may run on the glib thread. + PlatformMgrImpl().GLibMatterContextInvokeSync( + +[](BluezAdvertisement * self) { + if (self->mpRoot != nullptr) + { + g_object_unref(self->mpRoot); + self->mpRoot = nullptr; + } + if (self->mpAdapter != nullptr) + { + g_object_unref(self->mpAdapter); + self->mpAdapter = nullptr; + } + if (self->mpAdv != nullptr) + { + g_object_unref(self->mpAdv); + self->mpAdv = nullptr; + } + return CHIP_NO_ERROR; + }, + this); + + g_free(mpAdvPath); + mpAdvPath = nullptr; + g_free(mpAdapterName); + mpAdapterName = nullptr; + g_free(mpAdvUUID); + mpAdvUUID = nullptr; + + mIsInitialized = false; +} + +void BluezAdvertisement::StartDone(GObject * aObject, GAsyncResult * aResult) +{ + BluezLEAdvertisingManager1 * advMgr = BLUEZ_LEADVERTISING_MANAGER1(aObject); + GAutoPtr error; + gboolean success = FALSE; + + success = + bluez_leadvertising_manager1_call_register_advertisement_finish(advMgr, aResult, &MakeUniquePointerReceiver(error).Get()); + if (success == FALSE) + { + g_dbus_object_manager_server_unexport(mpRoot, mpAdvPath); + } + VerifyOrExit(success == TRUE, ChipLogError(DeviceLayer, "FAIL: RegisterAdvertisement : %s", error->message)); + + mIsAdvertising = true; + + ChipLogDetail(DeviceLayer, "RegisterAdvertisement complete"); + +exit: + BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete(success == TRUE, nullptr); +} + +CHIP_ERROR BluezAdvertisement::StartImpl() +{ + GDBusObject * adapter; + BluezLEAdvertisingManager1 * advMgr = nullptr; + GVariantBuilder optionsBuilder; + GVariant * options; + + VerifyOrExit(!mIsAdvertising, ChipLogError(DeviceLayer, "FAIL: Advertising has already been enabled in %s", __func__)); + VerifyOrExit(mpAdapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL mpAdapter in %s", __func__)); + + adapter = g_dbus_interface_get_object(G_DBUS_INTERFACE(mpAdapter)); + VerifyOrExit(adapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL adapter in %s", __func__)); + + advMgr = bluez_object_get_leadvertising_manager1(BLUEZ_OBJECT(adapter)); + VerifyOrExit(advMgr != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL advMgr in %s", __func__)); + + g_variant_builder_init(&optionsBuilder, G_VARIANT_TYPE("a{sv}")); + options = g_variant_builder_end(&optionsBuilder); + + bluez_leadvertising_manager1_call_register_advertisement( + advMgr, mpAdvPath, options, nullptr, + [](GObject * aObject, GAsyncResult * aResult, void * aData) { + reinterpret_cast(aData)->StartDone(aObject, aResult); + }, + this); + +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR BluezAdvertisement::Start() +{ + VerifyOrReturnError(mIsInitialized, CHIP_ERROR_INCORRECT_STATE); + + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync( + +[](BluezAdvertisement * self) { return self->StartImpl(); }, this); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Ble, "Failed to schedule BLE advertisement Start() on CHIPoBluez thread")); + return err; +} + +void BluezAdvertisement::StopDone(GObject * aObject, GAsyncResult * aResult) +{ + BluezLEAdvertisingManager1 * advMgr = BLUEZ_LEADVERTISING_MANAGER1(aObject); + GAutoPtr error; + gboolean success = FALSE; + + success = + bluez_leadvertising_manager1_call_unregister_advertisement_finish(advMgr, aResult, &MakeUniquePointerReceiver(error).Get()); + + if (success == FALSE) + { + g_dbus_object_manager_server_unexport(mpRoot, mpAdvPath); + } + else + { + mIsAdvertising = false; + } + + VerifyOrExit(success == TRUE, ChipLogError(DeviceLayer, "FAIL: UnregisterAdvertisement : %s", error->message)); + + ChipLogDetail(DeviceLayer, "UnregisterAdvertisement complete"); + +exit: + BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete(success == TRUE, nullptr); +} + +CHIP_ERROR BluezAdvertisement::StopImpl() +{ + GDBusObject * adapter; + BluezLEAdvertisingManager1 * advMgr = nullptr; + + VerifyOrExit(mIsAdvertising, ChipLogError(DeviceLayer, "FAIL: Advertising has already been disabled in %s", __func__)); + VerifyOrExit(mpAdapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL mpAdapter in %s", __func__)); + + adapter = g_dbus_interface_get_object(G_DBUS_INTERFACE(mpAdapter)); + VerifyOrExit(adapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL adapter in %s", __func__)); + + advMgr = bluez_object_get_leadvertising_manager1(BLUEZ_OBJECT(adapter)); + VerifyOrExit(advMgr != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL advMgr in %s", __func__)); + + bluez_leadvertising_manager1_call_unregister_advertisement( + advMgr, mpAdvPath, nullptr, + [](GObject * aObject, GAsyncResult * aResult, void * aData) { + reinterpret_cast(aData)->StopDone(aObject, aResult); + }, + this); + +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR BluezAdvertisement::Stop() +{ + VerifyOrReturnError(mIsInitialized, CHIP_ERROR_INCORRECT_STATE); + + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync( + +[](BluezAdvertisement * self) { return self->StopImpl(); }, this); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Ble, "Failed to schedule BLE advertisement Stop() on CHIPoBluez thread")); + return err; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h new file mode 100644 index 00000000000000..7fc01e027d38e0 --- /dev/null +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -0,0 +1,89 @@ +/* + * + * Copyright (c) 2020-2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include +#include + +#include +#include +#include + +#include "Types.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +struct BluezEndpoint; + +class BluezAdvertisement +{ +public: + BluezAdvertisement() = default; + ~BluezAdvertisement() { Shutdown(); } + + CHIP_ERROR Init(BluezEndpoint * apEndpoint, ChipAdvType aAdvType, const char * aAdvUUID, uint32_t aAdvDurationMs); + void Shutdown(); + + /// Start BLE advertising. + /// + /// BLE advertising is started asynchronously. Application will be notified of + /// completion via a call to BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete(). + CHIP_ERROR Start(); + + /// Stop BLE advertising. + /// + /// BLE advertising is stopped asynchronously. Application will be notified of + /// completion via a call to BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete(). + CHIP_ERROR Stop(); + +private: + BluezLEAdvertisement1 * CreateLEAdvertisement(); + gboolean BluezLEAdvertisement1Release(BluezLEAdvertisement1 * aAdv, GDBusMethodInvocation * aInv); + + CHIP_ERROR InitImpl(); + + void StartDone(GObject * aObject, GAsyncResult * aResult); + CHIP_ERROR StartImpl(); + + void StopDone(GObject * aObject, GAsyncResult * aResult); + CHIP_ERROR StopImpl(); + + // Objects (interfaces) used by LE advertisement + GDBusObjectManagerServer * mpRoot = nullptr; + BluezAdapter1 * mpAdapter = nullptr; + BluezLEAdvertisement1 * mpAdv = nullptr; + + bool mIsInitialized = false; + bool mIsAdvertising = false; + + Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; + char * mpAdvPath = nullptr; + char * mpAdapterName = nullptr; + char * mpAdvUUID = nullptr; + ChipAdvType mAdvType; + uint16_t mAdvDurationMs = 0; +}; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index 5621e412edec72..f905422bbf84b2 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -81,217 +81,6 @@ constexpr uint16_t kMaxConnectRetries = 4; static BluezConnection * GetBluezConnectionViaDevice(BluezEndpoint * apEndpoint); -static gboolean BluezAdvertisingRelease(BluezLEAdvertisement1 * aAdv, GDBusMethodInvocation * aInvocation, gpointer apClosure) -{ - bool isSuccess = false; - BluezEndpoint * endpoint = static_cast(apClosure); - VerifyOrExit(endpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); - VerifyOrExit(aAdv != nullptr, ChipLogError(DeviceLayer, "BluezLEAdvertisement1 is NULL in %s", __func__)); - ChipLogDetail(DeviceLayer, "Release adv object in %s", __func__); - - g_dbus_object_manager_server_unexport(endpoint->mpRoot, endpoint->mpAdvPath); - g_object_unref(endpoint->mpAdv); - endpoint->mpAdv = nullptr; - endpoint->mIsAdvertising = false; - isSuccess = true; -exit: - - return isSuccess ? TRUE : FALSE; -} - -static BluezLEAdvertisement1 * BluezAdvertisingCreate(BluezEndpoint * apEndpoint) -{ - BluezLEAdvertisement1 * adv = nullptr; - BluezObjectSkeleton * object; - GVariant * serviceData; - GVariant * serviceUUID; - GAutoPtr localName; - GVariantBuilder serviceDataBuilder; - GVariantBuilder serviceUUIDsBuilder; - GAutoPtr debugStr; - - VerifyOrExit(apEndpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); - if (apEndpoint->mpAdvPath == nullptr) - apEndpoint->mpAdvPath = g_strdup_printf("%s/advertising", apEndpoint->mpRootPath); - - ChipLogDetail(DeviceLayer, "Create adv object at %s", apEndpoint->mpAdvPath); - object = bluez_object_skeleton_new(apEndpoint->mpAdvPath); - - adv = bluez_leadvertisement1_skeleton_new(); - - g_variant_builder_init(&serviceDataBuilder, G_VARIANT_TYPE("a{sv}")); - g_variant_builder_init(&serviceUUIDsBuilder, G_VARIANT_TYPE("as")); - - g_variant_builder_add(&serviceDataBuilder, "{sv}", apEndpoint->mpAdvertisingUUID, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &apEndpoint->mDeviceIdInfo, - sizeof(apEndpoint->mDeviceIdInfo), sizeof(uint8_t))); - g_variant_builder_add(&serviceUUIDsBuilder, "s", apEndpoint->mpAdvertisingUUID); - - if (apEndpoint->mpAdapterName != nullptr) - localName = GAutoPtr(g_strdup_printf("%s", apEndpoint->mpAdapterName)); - else - localName = GAutoPtr(g_strdup_printf("%s%04x", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, getpid() & 0xffff)); - - serviceData = g_variant_builder_end(&serviceDataBuilder); - serviceUUID = g_variant_builder_end(&serviceUUIDsBuilder); - - debugStr = GAutoPtr(g_variant_print(serviceData, TRUE)); - ChipLogDetail(DeviceLayer, "SET service data to %s", StringOrNullMarker(debugStr.get())); - - bluez_leadvertisement1_set_type_(adv, (apEndpoint->mType & BLUEZ_ADV_TYPE_CONNECTABLE) ? "peripheral" : "broadcast"); - // empty manufacturer data - // empty solicit UUIDs - bluez_leadvertisement1_set_service_data(adv, serviceData); - // empty data - - // Setting "Discoverable" to False on the adapter and to True on the advertisement convinces - // Bluez to set "BR/EDR Not Supported" flag. Bluez doesn't provide API to do that explicitly - // and the flag is necessary to force using LE transport. - bluez_leadvertisement1_set_discoverable(adv, (apEndpoint->mType & BLUEZ_ADV_TYPE_SCANNABLE) ? TRUE : FALSE); - if (apEndpoint->mType & BLUEZ_ADV_TYPE_SCANNABLE) - bluez_leadvertisement1_set_discoverable_timeout(adv, UINT16_MAX); - - // advertising name corresponding to the PID and object path, for debug purposes - bluez_leadvertisement1_set_local_name(adv, localName.get()); - bluez_leadvertisement1_set_service_uuids(adv, serviceUUID); - - // 0xffff means no appearance - bluez_leadvertisement1_set_appearance(adv, 0xffff); - - bluez_leadvertisement1_set_duration(adv, apEndpoint->mDuration); - // empty duration, we don't have a clear notion what it would mean to timeslice between toble and anyone else - bluez_leadvertisement1_set_timeout(adv, 0); - // empty secondary channel for now - - bluez_object_skeleton_set_leadvertisement1(object, adv); - g_signal_connect(adv, "handle-release", G_CALLBACK(BluezAdvertisingRelease), apEndpoint); - - g_dbus_object_manager_server_export(apEndpoint->mpRoot, G_DBUS_OBJECT_SKELETON(object)); - g_object_unref(object); - - BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(true, nullptr); - -exit: - return adv; -} - -static void BluezAdvStartDone(GObject * aObject, GAsyncResult * aResult, gpointer apClosure) -{ - BluezLEAdvertisingManager1 * advMgr = BLUEZ_LEADVERTISING_MANAGER1(aObject); - GAutoPtr error; - BluezEndpoint * endpoint = static_cast(apClosure); - gboolean success = FALSE; - - VerifyOrExit(endpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); - - success = - bluez_leadvertising_manager1_call_register_advertisement_finish(advMgr, aResult, &MakeUniquePointerReceiver(error).Get()); - if (success == FALSE) - { - g_dbus_object_manager_server_unexport(endpoint->mpRoot, endpoint->mpAdvPath); - } - VerifyOrExit(success == TRUE, ChipLogError(DeviceLayer, "FAIL: RegisterAdvertisement : %s", error->message)); - - endpoint->mIsAdvertising = true; - - ChipLogDetail(DeviceLayer, "RegisterAdvertisement complete"); - -exit: - BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete(success == TRUE, nullptr); -} - -static void BluezAdvStopDone(GObject * aObject, GAsyncResult * aResult, gpointer apClosure) -{ - BluezLEAdvertisingManager1 * advMgr = BLUEZ_LEADVERTISING_MANAGER1(aObject); - BluezEndpoint * endpoint = static_cast(apClosure); - GAutoPtr error; - gboolean success = FALSE; - - VerifyOrExit(endpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); - - success = - bluez_leadvertising_manager1_call_unregister_advertisement_finish(advMgr, aResult, &MakeUniquePointerReceiver(error).Get()); - - if (success == FALSE) - { - g_dbus_object_manager_server_unexport(endpoint->mpRoot, endpoint->mpAdvPath); - } - else - { - endpoint->mIsAdvertising = false; - } - - VerifyOrExit(success == TRUE, ChipLogError(DeviceLayer, "FAIL: UnregisterAdvertisement : %s", error->message)); - - ChipLogDetail(DeviceLayer, "UnregisterAdvertisement complete"); - -exit: - BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete(success == TRUE, nullptr); -} - -static CHIP_ERROR BluezAdvSetup(BluezEndpoint * endpoint) -{ - VerifyOrExit(endpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); - VerifyOrExit(endpoint->mIsAdvertising == FALSE, ChipLogError(DeviceLayer, "FAIL: Advertising already enabled in %s", __func__)); - VerifyOrExit(endpoint->mpAdapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL endpoint->mpAdapter in %s", __func__)); - - endpoint->mpAdv = BluezAdvertisingCreate(endpoint); - VerifyOrExit(endpoint->mpAdv != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL adv in %s", __func__)); - -exit: - return CHIP_NO_ERROR; -} - -static CHIP_ERROR BluezAdvStart(BluezEndpoint * endpoint) -{ - GDBusObject * adapter; - BluezLEAdvertisingManager1 * advMgr = nullptr; - GVariantBuilder optionsBuilder; - GVariant * options; - - VerifyOrExit(endpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); - VerifyOrExit(!endpoint->mIsAdvertising, - ChipLogError(DeviceLayer, "FAIL: Advertising has already been enabled in %s", __func__)); - VerifyOrExit(endpoint->mpAdapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL endpoint->mpAdapter in %s", __func__)); - - adapter = g_dbus_interface_get_object(G_DBUS_INTERFACE(endpoint->mpAdapter)); - VerifyOrExit(adapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL adapter in %s", __func__)); - - advMgr = bluez_object_get_leadvertising_manager1(BLUEZ_OBJECT(adapter)); - VerifyOrExit(advMgr != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL advMgr in %s", __func__)); - - g_variant_builder_init(&optionsBuilder, G_VARIANT_TYPE("a{sv}")); - options = g_variant_builder_end(&optionsBuilder); - - bluez_leadvertising_manager1_call_register_advertisement(advMgr, endpoint->mpAdvPath, options, nullptr, BluezAdvStartDone, - endpoint); - -exit: - return CHIP_NO_ERROR; -} - -static CHIP_ERROR BluezAdvStop(BluezEndpoint * endpoint) -{ - GDBusObject * adapter; - BluezLEAdvertisingManager1 * advMgr = nullptr; - - VerifyOrExit(endpoint != nullptr, ChipLogError(DeviceLayer, "endpoint is NULL in %s", __func__)); - VerifyOrExit(endpoint->mIsAdvertising, - ChipLogError(DeviceLayer, "FAIL: Advertising has already been disabled in %s", __func__)); - VerifyOrExit(endpoint->mpAdapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL endpoint->mpAdapter in %s", __func__)); - - adapter = g_dbus_interface_get_object(G_DBUS_INTERFACE(endpoint->mpAdapter)); - VerifyOrExit(adapter != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL adapter in %s", __func__)); - - advMgr = bluez_object_get_leadvertising_manager1(BLUEZ_OBJECT(adapter)); - VerifyOrExit(advMgr != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL advMgr in %s", __func__)); - - bluez_leadvertising_manager1_call_unregister_advertisement(advMgr, endpoint->mpAdvPath, nullptr, BluezAdvStopDone, endpoint); - -exit: - return CHIP_NO_ERROR; -} - static gboolean BluezCharacteristicReadValue(BluezGattCharacteristic1 * aChar, GDBusMethodInvocation * aInvocation, GVariant * aOptions) { @@ -719,7 +508,6 @@ static void EndpointCleanup(BluezEndpoint * apEndpoint) g_free(apEndpoint->mpAdapterName); g_free(apEndpoint->mpAdapterAddr); g_free(apEndpoint->mpRootPath); - g_free(apEndpoint->mpAdvPath); g_free(apEndpoint->mpServicePath); if (apEndpoint->mpObjMgr != nullptr) g_object_unref(apEndpoint->mpObjMgr); @@ -737,11 +525,8 @@ static void EndpointCleanup(BluezEndpoint * apEndpoint) g_object_unref(apEndpoint->mpC2); if (apEndpoint->mpC3 != nullptr) g_object_unref(apEndpoint->mpC3); - if (apEndpoint->mpAdv != nullptr) - g_object_unref(apEndpoint->mpAdv); if (apEndpoint->mpConnMap != nullptr) g_hash_table_destroy(apEndpoint->mpConnMap); - g_free(apEndpoint->mpAdvertisingUUID); g_free(apEndpoint->mpPeerDevicePath); if (apEndpoint->mpConnectCancellable != nullptr) g_object_unref(apEndpoint->mpConnectCancellable); @@ -897,30 +682,6 @@ static CHIP_ERROR StartupEndpointBindings(BluezEndpoint * endpoint) return CHIP_NO_ERROR; } -CHIP_ERROR StartBluezAdv(BluezEndpoint * apEndpoint) -{ - CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezAdvStart, apEndpoint); - VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, - ChipLogError(Ble, "Failed to schedule BluezAdvStart() on CHIPoBluez thread")); - return err; -} - -CHIP_ERROR StopBluezAdv(BluezEndpoint * apEndpoint) -{ - CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezAdvStop, apEndpoint); - VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, - ChipLogError(Ble, "Failed to schedule BluezAdvStop() on CHIPoBluez thread")); - return err; -} - -CHIP_ERROR BluezAdvertisementSetup(BluezEndpoint * apEndpoint) -{ - CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezAdvSetup, apEndpoint); - VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, - ChipLogError(Ble, "Failed to schedule BluezAdvSetup() on CHIPoBluez thread")); - return err; -} - CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint) { CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezPeripheralRegisterApp, apEndpoint); @@ -929,37 +690,7 @@ CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint) return err; } -static CHIP_ERROR ConfigureBluezAdv(const BLEAdvConfig & aBleAdvConfig, BluezEndpoint * apEndpoint) -{ - const char * msg = nullptr; - CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(aBleAdvConfig.mpBleName != nullptr, msg = "FAIL: BLE name is NULL"); - VerifyOrExit(aBleAdvConfig.mpAdvertisingUUID != nullptr, msg = "FAIL: BLE mpAdvertisingUUID is NULL"); - - apEndpoint->mpAdapterName = g_strdup(aBleAdvConfig.mpBleName); - apEndpoint->mpAdvertisingUUID = g_strdup(aBleAdvConfig.mpAdvertisingUUID); - apEndpoint->mAdapterId = aBleAdvConfig.mAdapterId; - apEndpoint->mType = aBleAdvConfig.mType; - apEndpoint->mDuration = aBleAdvConfig.mDuration; - apEndpoint->mDuration = aBleAdvConfig.mDuration; - - err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(apEndpoint->mDeviceIdInfo); - SuccessOrExit(err); - -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - apEndpoint->mDeviceIdInfo.SetAdditionalDataFlag(true); -#endif - -exit: - if (nullptr != msg) - { - ChipLogDetail(DeviceLayer, "%s in %s", msg, __func__); - err = CHIP_ERROR_INCORRECT_STATE; - } - return err; -} - -CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BLEAdvConfig & aBleAdvConfig, +CHIP_ERROR InitBluezBleLayer(uint32_t aAdapterId, bool aIsCentral, const char * apBleAddr, const char * apBleName, BluezEndpoint *& apEndpoint) { BluezEndpoint * endpoint = g_new0(BluezEndpoint, 1); @@ -969,16 +700,15 @@ CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BLEA endpoint->mpAdapterAddr = g_strdup(apBleAddr); endpoint->mpConnMap = g_hash_table_new(g_str_hash, g_str_equal); + endpoint->mAdapterId = aAdapterId; endpoint->mIsCentral = aIsCentral; if (!aIsCentral) { - err = ConfigureBluezAdv(aBleAdvConfig, endpoint); - SuccessOrExit(err); + endpoint->mpAdapterName = g_strdup(apBleName); } else { - endpoint->mAdapterId = aBleAdvConfig.mAdapterId; endpoint->mpConnectCancellable = g_cancellable_new(); } diff --git a/src/platform/Linux/bluez/BluezEndpoint.h b/src/platform/Linux/bluez/BluezEndpoint.h index 982eb053be6667..712cbc9ad5657f 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.h +++ b/src/platform/Linux/bluez/BluezEndpoint.h @@ -45,7 +45,7 @@ #pragma once -#include +#include #include #include @@ -60,8 +60,6 @@ namespace chip { namespace DeviceLayer { namespace Internal { -struct BLEAdvConfig; - struct BluezEndpoint { char * mpOwningName; // Bus owning name @@ -72,7 +70,6 @@ struct BluezEndpoint // Paths for objects published by this service char * mpRootPath; - char * mpAdvPath; char * mpServicePath; // Objects (interfaces) subscribed to by this service @@ -88,29 +85,18 @@ struct BluezEndpoint // additional data characteristics BluezGattCharacteristic1 * mpC3; - // Objects (interfaces) used by LE advertisement - BluezLEAdvertisement1 * mpAdv; - // map device path to the connection GHashTable * mpConnMap; uint32_t mAdapterId; bool mIsCentral; - char * mpAdvertisingUUID; - chip::Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; - ChipAdvType mType; ///< Advertisement type. - uint16_t mDuration; ///< Advertisement interval (in ms). - bool mIsAdvertising; char * mpPeerDevicePath; GCancellable * mpConnectCancellable = nullptr; }; -CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BLEAdvConfig & aBleAdvConfig, +CHIP_ERROR InitBluezBleLayer(uint32_t aAdapterId, bool aIsCentral, const char * apBleAddr, const char * apBleName, BluezEndpoint *& apEndpoint); CHIP_ERROR ShutdownBluezBleLayer(BluezEndpoint * apEndpoint); -CHIP_ERROR StartBluezAdv(BluezEndpoint * apEndpoint); -CHIP_ERROR StopBluezAdv(BluezEndpoint * apEndpoint); CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint); -CHIP_ERROR BluezAdvertisementSetup(BluezEndpoint * apEndpoint); CHIP_ERROR ConnectDevice(BluezDevice1 & aDevice, BluezEndpoint * apEndpoint); void CancelConnect(BluezEndpoint * apEndpoint);