From d25730a90d3f533fc24a28b38bcbb1ddfcac40e1 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Tue, 7 Nov 2023 16:54:24 +0100 Subject: [PATCH 01/11] [Linux] Extract BLE advertisement to separate class --- src/platform/Linux/BLEManagerImpl.cpp | 22 +- src/platform/Linux/BLEManagerImpl.h | 5 +- src/platform/Linux/BUILD.gn | 2 + .../Linux/bluez/BluezAdvertisement.cpp | 374 ++++++++++++++++++ src/platform/Linux/bluez/BluezAdvertisement.h | 84 ++++ src/platform/Linux/bluez/BluezEndpoint.cpp | 235 ----------- src/platform/Linux/bluez/BluezEndpoint.h | 3 - 7 files changed, 469 insertions(+), 256 deletions(-) create mode 100644 src/platform/Linux/bluez/BluezAdvertisement.cpp create mode 100644 src/platform/Linux/bluez/BluezAdvertisement.h diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 01a93a29b8a1ed..cb39b60a896b64 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); @@ -202,16 +204,6 @@ CHIP_ERROR BLEManagerImpl::ConfigureBle(uint32_t aAdapterId, bool aIsCentral) return err; } -CHIP_ERROR BLEManagerImpl::StartBLEAdvertising() -{ - return StartBluezAdv(mpEndpoint); -} - -CHIP_ERROR BLEManagerImpl::StopBLEAdvertising() -{ - return StopBluezAdv(mpEndpoint); -} - void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { switch (event->Type) @@ -620,15 +612,15 @@ void BLEManagerImpl::DriveBLEState() // be called again, and execution will proceed to the code below. if (!mFlags.Has(Flags::kAdvertisingConfigured)) { - err = BluezAdvertisementSetup(mpEndpoint); + err = mBLEAdvertisement.Init(mpEndpoint, mBLEAdvConfig); ExitNow(); } // Start advertising. This is also an asynchronous step. - err = StartBLEAdvertising(); + err = mBLEAdvertisement.Start(); SuccessOrExit(err); - sInstance.mFlags.Set(Flags::kAdvertising); + mFlags.Set(Flags::kAdvertising); ExitNow(); } } @@ -638,7 +630,7 @@ void BLEManagerImpl::DriveBLEState() { if (mFlags.Has(Flags::kAdvertising)) { - err = StopBLEAdvertising(); + err = mBLEAdvertisement.Stop(); SuccessOrExit(err); mFlags.Set(Flags::kControlOpInProgress); diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index 458bac267db832..4ca10945f39d3e 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -28,6 +28,7 @@ #include #include +#include "bluez/BluezAdvertisement.h" #include "bluez/BluezEndpoint.h" #include "bluez/ChipDeviceScanner.h" #include "bluez/Types.h" @@ -187,9 +188,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); @@ -204,6 +202,7 @@ class BLEManagerImpl final : public BLEManager, char mDeviceName[kMaxDeviceNameLength + 1]; bool mIsCentral = false; BluezEndpoint * mpEndpoint = nullptr; + BluezAdvertisement mBLEAdvertisement; ChipDeviceScanner mDeviceScanner; }; 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/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp new file mode 100644 index 00000000000000..0d27d10c9b3ffa --- /dev/null +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -0,0 +1,374 @@ +/* + * + * Copyright (c) 2020-2022 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "BluezConnection.h" +#include "Types.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() +{ + BluezLEAdvertisement1 * adv; + BluezObjectSkeleton * object; + GVariant * serviceData; + GVariant * serviceUUID; + GAutoPtr localName; + GVariantBuilder serviceDataBuilder; + GVariantBuilder serviceUUIDsBuilder; + GAutoPtr debugStr; + + 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}", mpAdvertisingUUID, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &mDeviceIdInfo, sizeof(mDeviceIdInfo), sizeof(uint8_t))); + g_variant_builder_add(&serviceUUIDsBuilder, "s", mpAdvertisingUUID); + + if (mpAdapterName != nullptr) + localName = GAutoPtr(g_strdup_printf("%s", 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, (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, (mType & BLUEZ_ADV_TYPE_SCANNABLE) ? TRUE : FALSE); + if (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, 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(+[](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); + + BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(true, nullptr); + + 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, const BLEAdvConfig & aBleAdvConfig) +{ + 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 = g_object_ref(apEndpoint->mpRoot); + mpAdapter = g_object_ref(apEndpoint->mpAdapter); + + g_object_get(G_OBJECT(mpRoot), "object-path", &MakeUniquePointerReceiver(rootPath).Get(), nullptr); + mpAdvPath = g_strdup_printf("%s/advertising", rootPath.get()); + + err = ConfigureBluezAdv(aBleAdvConfig); + ReturnErrorOnFailure(err); + + 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; + } + return CHIP_NO_ERROR; + }, + this); + + g_free(mpAdvPath); + mpAdvPath = nullptr; + g_free(mpAdapterName); + mpAdapterName = nullptr; + g_free(mpAdvertisingUUID); + mpAdvertisingUUID = 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; +} + +CHIP_ERROR BluezAdvertisement::ConfigureBluezAdv(const BLEAdvConfig & aBleAdvConfig) +{ + 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"); + + mpAdapterName = g_strdup(aBleAdvConfig.mpBleName); + mpAdvertisingUUID = g_strdup(aBleAdvConfig.mpAdvertisingUUID); + mType = aBleAdvConfig.mType; + mDuration = aBleAdvConfig.mDuration; + mDuration = aBleAdvConfig.mDuration; + + err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); + SuccessOrExit(err); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + mDeviceIdInfo.SetAdditionalDataFlag(true); +#endif + +exit: + if (nullptr != msg) + { + ChipLogDetail(DeviceLayer, "%s in %s", msg, __func__); + err = CHIP_ERROR_INCORRECT_STATE; + } + 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..64a4462b637378 --- /dev/null +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -0,0 +1,84 @@ +/* + * + * Copyright (c) 2020 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 "Types.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +struct BLEAdvConfig; +struct BluezEndpoint; + +class BluezAdvertisement +{ +public: + BluezAdvertisement() = default; + ~BluezAdvertisement() { Shutdown(); } + + CHIP_ERROR Init(BluezEndpoint * apEndpoint, const BLEAdvConfig & aBleAdvConfig); + void Shutdown(); + + CHIP_ERROR Start(); + CHIP_ERROR Stop(); + +private: + CHIP_ERROR ConfigureBluezAdv(const BLEAdvConfig & aBleAdvConfig); + + 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; + char * mpAdvPath = nullptr; + char * mpAdapterName = nullptr; + char * mpAdvertisingUUID = nullptr; + chip::Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; + ChipAdvType mType; ///< Advertisement type. + uint16_t mDuration; ///< Advertisement interval (in ms). + bool mIsAdvertising = false; + + // Allow BluezConnection to access our private members + friend class BluezConnection; +}; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index 5621e412edec72..fca9cd54e12238 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) { @@ -897,30 +686,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); diff --git a/src/platform/Linux/bluez/BluezEndpoint.h b/src/platform/Linux/bluez/BluezEndpoint.h index 982eb053be6667..67c0f5785de345 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.h +++ b/src/platform/Linux/bluez/BluezEndpoint.h @@ -107,10 +107,7 @@ struct BluezEndpoint CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BLEAdvConfig & aBleAdvConfig, 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); From 65d4379934f1c2e5914c9b4100f984f7c610e02d Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 09:27:04 +0100 Subject: [PATCH 02/11] Keep BLE adv config in advertisement class --- src/platform/Linux/BLEManagerImpl.h | 21 ++++-------------- .../Linux/bluez/BluezAdvertisement.cpp | 22 +++++++++---------- src/platform/Linux/bluez/BluezAdvertisement.h | 19 ++++++++++++++-- src/platform/Linux/bluez/BluezEndpoint.cpp | 4 ++-- src/platform/Linux/bluez/BluezEndpoint.h | 5 ++--- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index 4ca10945f39d3e..b2faf4900c9d97 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -39,21 +39,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, @@ -196,14 +181,16 @@ class BLEManagerImpl final : public BLEManager, void CleanScanConfig(); CHIPoBLEServiceMode mServiceMode; - BLEAdvConfig mBLEAdvConfig; - BLEScanConfig mBLEScanConfig; BitFlags mFlags; char mDeviceName[kMaxDeviceNameLength + 1]; bool mIsCentral = false; BluezEndpoint * mpEndpoint = nullptr; + BluezAdvertisement mBLEAdvertisement; + BluezAdvertisement::Configuration mBLEAdvConfig; + ChipDeviceScanner mDeviceScanner; + BLEScanConfig mBLEScanConfig; }; /** diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index 0d27d10c9b3ffa..6d28de1243ab1d 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -143,7 +143,7 @@ CHIP_ERROR BluezAdvertisement::InitImpl() return CHIP_NO_ERROR; } -CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, const BLEAdvConfig & aBleAdvConfig) +CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, const Configuration & aConfig) { GAutoPtr rootPath; CHIP_ERROR err; @@ -159,7 +159,7 @@ CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, const BLEAdvConf g_object_get(G_OBJECT(mpRoot), "object-path", &MakeUniquePointerReceiver(rootPath).Get(), nullptr); mpAdvPath = g_strdup_printf("%s/advertising", rootPath.get()); - err = ConfigureBluezAdv(aBleAdvConfig); + err = ConfigureBluezAdv(aConfig); ReturnErrorOnFailure(err); err = PlatformMgrImpl().GLibMatterContextInvokeSync( @@ -340,18 +340,18 @@ CHIP_ERROR BluezAdvertisement::Stop() return err; } -CHIP_ERROR BluezAdvertisement::ConfigureBluezAdv(const BLEAdvConfig & aBleAdvConfig) +CHIP_ERROR BluezAdvertisement::ConfigureBluezAdv(const Configuration & aConfig) { 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"); - - mpAdapterName = g_strdup(aBleAdvConfig.mpBleName); - mpAdvertisingUUID = g_strdup(aBleAdvConfig.mpAdvertisingUUID); - mType = aBleAdvConfig.mType; - mDuration = aBleAdvConfig.mDuration; - mDuration = aBleAdvConfig.mDuration; + VerifyOrExit(aConfig.mpBleName != nullptr, msg = "FAIL: BLE name is NULL"); + VerifyOrExit(aConfig.mpAdvertisingUUID != nullptr, msg = "FAIL: BLE mpAdvertisingUUID is NULL"); + + mpAdapterName = g_strdup(aConfig.mpBleName); + mpAdvertisingUUID = g_strdup(aConfig.mpAdvertisingUUID); + mType = aConfig.mType; + mDuration = aConfig.mDuration; + mDuration = aConfig.mDuration; err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); SuccessOrExit(err); diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h index 64a4462b637378..f2f00aeae06845 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.h +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -38,17 +38,32 @@ struct BluezEndpoint; class BluezAdvertisement { public: + struct Configuration + { + 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; + }; + BluezAdvertisement() = default; ~BluezAdvertisement() { Shutdown(); } - CHIP_ERROR Init(BluezEndpoint * apEndpoint, const BLEAdvConfig & aBleAdvConfig); + CHIP_ERROR Init(BluezEndpoint * apEndpoint, const Configuration & aConfig); void Shutdown(); CHIP_ERROR Start(); CHIP_ERROR Stop(); private: - CHIP_ERROR ConfigureBluezAdv(const BLEAdvConfig & aBleAdvConfig); + CHIP_ERROR ConfigureBluezAdv(const Configuration & aConfig); BluezLEAdvertisement1 * CreateLEAdvertisement(); gboolean BluezLEAdvertisement1Release(BluezLEAdvertisement1 * aAdv, GDBusMethodInvocation * aInv); diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index fca9cd54e12238..ea99bd3383c65c 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -694,7 +694,7 @@ CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint) return err; } -static CHIP_ERROR ConfigureBluezAdv(const BLEAdvConfig & aBleAdvConfig, BluezEndpoint * apEndpoint) +static CHIP_ERROR ConfigureBluezAdv(const BluezAdvertisement::Configuration & aBleAdvConfig, BluezEndpoint * apEndpoint) { const char * msg = nullptr; CHIP_ERROR err = CHIP_NO_ERROR; @@ -724,7 +724,7 @@ static CHIP_ERROR ConfigureBluezAdv(const BLEAdvConfig & aBleAdvConfig, BluezEnd return err; } -CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BLEAdvConfig & aBleAdvConfig, +CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BluezAdvertisement::Configuration & aBleAdvConfig, BluezEndpoint *& apEndpoint) { BluezEndpoint * endpoint = g_new0(BluezEndpoint, 1); diff --git a/src/platform/Linux/bluez/BluezEndpoint.h b/src/platform/Linux/bluez/BluezEndpoint.h index 67c0f5785de345..2e8f309606b4ce 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.h +++ b/src/platform/Linux/bluez/BluezEndpoint.h @@ -53,6 +53,7 @@ #include #include +#include "BluezAdvertisement.h" #include "BluezConnection.h" #include "Types.h" @@ -60,8 +61,6 @@ namespace chip { namespace DeviceLayer { namespace Internal { -struct BLEAdvConfig; - struct BluezEndpoint { char * mpOwningName; // Bus owning name @@ -104,7 +103,7 @@ struct BluezEndpoint GCancellable * mpConnectCancellable = nullptr; }; -CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BLEAdvConfig & aBleAdvConfig, +CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BluezAdvertisement::Configuration & aBleAdvConfig, BluezEndpoint *& apEndpoint); CHIP_ERROR ShutdownBluezBleLayer(BluezEndpoint * apEndpoint); CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint); From e29b2de091558ea3f506934fc7016371844d9fd8 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 09:31:21 +0100 Subject: [PATCH 03/11] Rename mDuration to mDurationMs --- src/platform/Linux/BLEManagerImpl.cpp | 2 +- src/platform/Linux/bluez/BluezAdvertisement.cpp | 5 ++--- src/platform/Linux/bluez/BluezAdvertisement.h | 6 +++--- src/platform/Linux/bluez/BluezEndpoint.cpp | 3 +-- src/platform/Linux/bluez/BluezEndpoint.h | 4 ++-- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index cb39b60a896b64..87442473aada05 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -194,7 +194,7 @@ CHIP_ERROR BLEManagerImpl::ConfigureBle(uint32_t aAdapterId, bool aIsCentral) mBLEAdvConfig.mVendorId = 1; mBLEAdvConfig.mProductId = 1; mBLEAdvConfig.mDeviceId = 1; - mBLEAdvConfig.mDuration = 2; + mBLEAdvConfig.mDurationMs = 2; mBLEAdvConfig.mPairingStatus = 0; mBLEAdvConfig.mType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE; mBLEAdvConfig.mpAdvertisingUUID = "0xFFF6"; diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index 6d28de1243ab1d..5eaca8914b5085 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -103,7 +103,7 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() // 0xffff means no appearance bluez_leadvertisement1_set_appearance(adv, 0xffff); - bluez_leadvertisement1_set_duration(adv, mDuration); + bluez_leadvertisement1_set_duration(adv, mDurationMs); // 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 @@ -350,8 +350,7 @@ CHIP_ERROR BluezAdvertisement::ConfigureBluezAdv(const Configuration & aConfig) mpAdapterName = g_strdup(aConfig.mpBleName); mpAdvertisingUUID = g_strdup(aConfig.mpAdvertisingUUID); mType = aConfig.mType; - mDuration = aConfig.mDuration; - mDuration = aConfig.mDuration; + mDurationMs = aConfig.mDurationMs; err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); SuccessOrExit(err); diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h index f2f00aeae06845..108425bd927441 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.h +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -49,7 +49,7 @@ class BluezAdvertisement uint64_t mDeviceId; uint8_t mPairingStatus; ChipAdvType mType; - uint16_t mDuration; + uint16_t mDurationMs; const char * mpAdvertisingUUID; }; @@ -86,8 +86,8 @@ class BluezAdvertisement char * mpAdapterName = nullptr; char * mpAdvertisingUUID = nullptr; chip::Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; - ChipAdvType mType; ///< Advertisement type. - uint16_t mDuration; ///< Advertisement interval (in ms). + ChipAdvType mType; + uint16_t mDurationMs; bool mIsAdvertising = false; // Allow BluezConnection to access our private members diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index ea99bd3383c65c..8cf8b5e87e8c08 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -705,8 +705,7 @@ static CHIP_ERROR ConfigureBluezAdv(const BluezAdvertisement::Configuration & aB apEndpoint->mpAdvertisingUUID = g_strdup(aBleAdvConfig.mpAdvertisingUUID); apEndpoint->mAdapterId = aBleAdvConfig.mAdapterId; apEndpoint->mType = aBleAdvConfig.mType; - apEndpoint->mDuration = aBleAdvConfig.mDuration; - apEndpoint->mDuration = aBleAdvConfig.mDuration; + apEndpoint->mDurationMs = aBleAdvConfig.mDurationMs; err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(apEndpoint->mDeviceIdInfo); SuccessOrExit(err); diff --git a/src/platform/Linux/bluez/BluezEndpoint.h b/src/platform/Linux/bluez/BluezEndpoint.h index 2e8f309606b4ce..2f94b85dd024a7 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.h +++ b/src/platform/Linux/bluez/BluezEndpoint.h @@ -96,8 +96,8 @@ struct BluezEndpoint bool mIsCentral; char * mpAdvertisingUUID; chip::Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; - ChipAdvType mType; ///< Advertisement type. - uint16_t mDuration; ///< Advertisement interval (in ms). + ChipAdvType mType; + uint16_t mDurationMs; bool mIsAdvertising; char * mpPeerDevicePath; GCancellable * mpConnectCancellable = nullptr; From 69b5ac6b535883bbef4857624939445d0ff1b62a Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 10:18:27 +0100 Subject: [PATCH 04/11] Remove not used members from BluezEndpoint --- src/platform/Linux/bluez/BluezEndpoint.cpp | 34 ++++------------------ src/platform/Linux/bluez/BluezEndpoint.h | 9 ------ 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index 8cf8b5e87e8c08..47c7c975c33eb5 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -508,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); @@ -526,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); @@ -696,31 +692,11 @@ CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint) static CHIP_ERROR ConfigureBluezAdv(const BluezAdvertisement::Configuration & 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->mDurationMs = aBleAdvConfig.mDurationMs; - - 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; + VerifyOrReturnError(aBleAdvConfig.mpBleName != nullptr, CHIP_ERROR_INCORRECT_STATE, + ChipLogDetail(DeviceLayer, "FAIL: BLE name is NULL in %s", __func__)); + apEndpoint->mpAdapterName = g_strdup(aBleAdvConfig.mpBleName); + apEndpoint->mAdapterId = aBleAdvConfig.mAdapterId; + return CHIP_NO_ERROR; } CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BluezAdvertisement::Configuration & aBleAdvConfig, diff --git a/src/platform/Linux/bluez/BluezEndpoint.h b/src/platform/Linux/bluez/BluezEndpoint.h index 2f94b85dd024a7..e80b2d72449b69 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.h +++ b/src/platform/Linux/bluez/BluezEndpoint.h @@ -71,7 +71,6 @@ struct BluezEndpoint // Paths for objects published by this service char * mpRootPath; - char * mpAdvPath; char * mpServicePath; // Objects (interfaces) subscribed to by this service @@ -87,18 +86,10 @@ 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; - uint16_t mDurationMs; - bool mIsAdvertising; char * mpPeerDevicePath; GCancellable * mpConnectCancellable = nullptr; }; From f0a0c1a14e1c0c6ffb47671d3bc14d98c0fdc034 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 11:14:06 +0100 Subject: [PATCH 05/11] Decouple BluezEndpoint and advertisement config --- src/platform/Linux/BLEManagerImpl.cpp | 5 +++-- src/platform/Linux/BLEManagerImpl.h | 3 +++ src/platform/Linux/bluez/BluezEndpoint.cpp | 16 +++------------- src/platform/Linux/bluez/BluezEndpoint.h | 5 ++--- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 87442473aada05..ed506c4ead9284 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -194,11 +194,12 @@ CHIP_ERROR BLEManagerImpl::ConfigureBle(uint32_t aAdapterId, bool aIsCentral) mBLEAdvConfig.mVendorId = 1; mBLEAdvConfig.mProductId = 1; mBLEAdvConfig.mDeviceId = 1; - mBLEAdvConfig.mDurationMs = 2; + mBLEAdvConfig.mDurationMs = 2; mBLEAdvConfig.mPairingStatus = 0; mBLEAdvConfig.mType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE; mBLEAdvConfig.mpAdvertisingUUID = "0xFFF6"; + mAdapterId = aAdapterId; mIsCentral = aIsCentral; return err; @@ -584,7 +585,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); } diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index b2faf4900c9d97..d8259ce33623ca 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -23,6 +23,7 @@ #pragma once +#include #include #include @@ -182,6 +183,8 @@ class BLEManagerImpl final : public BLEManager, CHIPoBLEServiceMode mServiceMode; BitFlags mFlags; + + uint32_t mAdapterId = 0; char mDeviceName[kMaxDeviceNameLength + 1]; bool mIsCentral = false; BluezEndpoint * mpEndpoint = nullptr; diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index 47c7c975c33eb5..f905422bbf84b2 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -690,16 +690,7 @@ CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint) return err; } -static CHIP_ERROR ConfigureBluezAdv(const BluezAdvertisement::Configuration & aBleAdvConfig, BluezEndpoint * apEndpoint) -{ - VerifyOrReturnError(aBleAdvConfig.mpBleName != nullptr, CHIP_ERROR_INCORRECT_STATE, - ChipLogDetail(DeviceLayer, "FAIL: BLE name is NULL in %s", __func__)); - apEndpoint->mpAdapterName = g_strdup(aBleAdvConfig.mpBleName); - apEndpoint->mAdapterId = aBleAdvConfig.mAdapterId; - return CHIP_NO_ERROR; -} - -CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BluezAdvertisement::Configuration & aBleAdvConfig, +CHIP_ERROR InitBluezBleLayer(uint32_t aAdapterId, bool aIsCentral, const char * apBleAddr, const char * apBleName, BluezEndpoint *& apEndpoint) { BluezEndpoint * endpoint = g_new0(BluezEndpoint, 1); @@ -709,16 +700,15 @@ CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const Blue 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 e80b2d72449b69..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 @@ -53,7 +53,6 @@ #include #include -#include "BluezAdvertisement.h" #include "BluezConnection.h" #include "Types.h" @@ -94,7 +93,7 @@ struct BluezEndpoint GCancellable * mpConnectCancellable = nullptr; }; -CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BluezAdvertisement::Configuration & aBleAdvConfig, +CHIP_ERROR InitBluezBleLayer(uint32_t aAdapterId, bool aIsCentral, const char * apBleAddr, const char * apBleName, BluezEndpoint *& apEndpoint); CHIP_ERROR ShutdownBluezBleLayer(BluezEndpoint * apEndpoint); CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint); From f2db824e4d66cac04740a3df123be95c8ce15647 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 11:52:09 +0100 Subject: [PATCH 06/11] Get rid of BluezAdvertisement configuration struct --- src/platform/Linux/BLEManagerImpl.cpp | 20 ++---- src/platform/Linux/BLEManagerImpl.h | 4 +- .../Linux/bluez/BluezAdvertisement.cpp | 63 +++++++------------ src/platform/Linux/bluez/BluezAdvertisement.h | 36 +++-------- 4 files changed, 39 insertions(+), 84 deletions(-) diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index ed506c4ead9284..7811bbfa0ea24e 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -186,23 +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.mDurationMs = 2; - mBLEAdvConfig.mPairingStatus = 0; - mBLEAdvConfig.mType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE; - mBLEAdvConfig.mpAdvertisingUUID = "0xFFF6"; mAdapterId = aAdapterId; mIsCentral = aIsCentral; - return err; + mBLEAdvType = ChipAdvType::BLUEZ_ADV_TYPE_UNDIRECTED_CONNECTABLE_SCANNABLE; + mBLEAdvDurationMs = 2; + mpBLEAdvUUID = "0xFFF6"; + + return CHIP_NO_ERROR; } void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) @@ -613,7 +605,7 @@ void BLEManagerImpl::DriveBLEState() // be called again, and execution will proceed to the code below. if (!mFlags.Has(Flags::kAdvertisingConfigured)) { - err = mBLEAdvertisement.Init(mpEndpoint, mBLEAdvConfig); + err = mBLEAdvertisement.Init(mpEndpoint, mBLEAdvType, mpBLEAdvUUID, mBLEAdvDurationMs); ExitNow(); } diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index d8259ce33623ca..e613bb9a68d1ee 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -190,7 +190,9 @@ class BLEManagerImpl final : public BLEManager, BluezEndpoint * mpEndpoint = nullptr; BluezAdvertisement mBLEAdvertisement; - BluezAdvertisement::Configuration mBLEAdvConfig; + 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/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index 5eaca8914b5085..e85535fcff683d 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -68,9 +68,9 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() 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}", mpAdvertisingUUID, + 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", mpAdvertisingUUID); + g_variant_builder_add(&serviceUUIDsBuilder, "s", mpAdvUUID); if (mpAdapterName != nullptr) localName = GAutoPtr(g_strdup_printf("%s", mpAdapterName)); @@ -83,7 +83,7 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() debugStr = GAutoPtr(g_variant_print(serviceData, TRUE)); ChipLogDetail(DeviceLayer, "SET service data to %s", StringOrNullMarker(debugStr.get())); - bluez_leadvertisement1_set_type_(adv, (mType & BLUEZ_ADV_TYPE_CONNECTABLE) ? "peripheral" : "broadcast"); + 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); @@ -92,8 +92,8 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() // 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, (mType & BLUEZ_ADV_TYPE_SCANNABLE) ? TRUE : FALSE); - if (mType & BLUEZ_ADV_TYPE_SCANNABLE) + 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 @@ -103,7 +103,7 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() // 0xffff means no appearance bluez_leadvertisement1_set_appearance(adv, 0xffff); - bluez_leadvertisement1_set_duration(adv, mDurationMs); + 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 @@ -143,7 +143,8 @@ CHIP_ERROR BluezAdvertisement::InitImpl() return CHIP_NO_ERROR; } -CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, const Configuration & aConfig) +CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, ChipAdvType aAdvType, const char * aAdvUUID, + uint32_t aAdvDurationMs) { GAutoPtr rootPath; CHIP_ERROR err; @@ -153,15 +154,23 @@ CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, const Configurat VerifyOrExit(mpAdv == nullptr, err = CHIP_ERROR_INCORRECT_STATE; ChipLogError(DeviceLayer, "FAIL: BLE advertisement already initialized in %s", __func__)); - mpRoot = g_object_ref(apEndpoint->mpRoot); - mpAdapter = g_object_ref(apEndpoint->mpAdapter); + mpRoot = g_object_ref(apEndpoint->mpRoot); + mpAdapter = 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()); + mpAdvPath = g_strdup_printf("%s/advertising", rootPath.get()); + mAdvType = aAdvType; + mpAdvUUID = g_strdup(aAdvUUID); + mAdvDurationMs = aAdvDurationMs; - err = ConfigureBluezAdv(aConfig); + 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, @@ -209,8 +218,8 @@ void BluezAdvertisement::Shutdown() mpAdvPath = nullptr; g_free(mpAdapterName); mpAdapterName = nullptr; - g_free(mpAdvertisingUUID); - mpAdvertisingUUID = nullptr; + g_free(mpAdvUUID); + mpAdvUUID = nullptr; mIsInitialized = false; } @@ -340,34 +349,6 @@ CHIP_ERROR BluezAdvertisement::Stop() return err; } -CHIP_ERROR BluezAdvertisement::ConfigureBluezAdv(const Configuration & aConfig) -{ - const char * msg = nullptr; - CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(aConfig.mpBleName != nullptr, msg = "FAIL: BLE name is NULL"); - VerifyOrExit(aConfig.mpAdvertisingUUID != nullptr, msg = "FAIL: BLE mpAdvertisingUUID is NULL"); - - mpAdapterName = g_strdup(aConfig.mpBleName); - mpAdvertisingUUID = g_strdup(aConfig.mpAdvertisingUUID); - mType = aConfig.mType; - mDurationMs = aConfig.mDurationMs; - - err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); - SuccessOrExit(err); - -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - mDeviceIdInfo.SetAdditionalDataFlag(true); -#endif - -exit: - if (nullptr != msg) - { - ChipLogDetail(DeviceLayer, "%s in %s", msg, __func__); - err = CHIP_ERROR_INCORRECT_STATE; - } - return err; -} - } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h index 108425bd927441..b7e74b781d8b73 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.h +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -32,39 +32,21 @@ namespace chip { namespace DeviceLayer { namespace Internal { -struct BLEAdvConfig; struct BluezEndpoint; class BluezAdvertisement { public: - struct Configuration - { - 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 mDurationMs; - const char * mpAdvertisingUUID; - }; - BluezAdvertisement() = default; ~BluezAdvertisement() { Shutdown(); } - CHIP_ERROR Init(BluezEndpoint * apEndpoint, const Configuration & aConfig); + CHIP_ERROR Init(BluezEndpoint * apEndpoint, ChipAdvType aAdvType, const char * aAdvUUID, uint32_t aAdvDurationMs); void Shutdown(); CHIP_ERROR Start(); CHIP_ERROR Stop(); private: - CHIP_ERROR ConfigureBluezAdv(const Configuration & aConfig); - BluezLEAdvertisement1 * CreateLEAdvertisement(); gboolean BluezLEAdvertisement1Release(BluezLEAdvertisement1 * aAdv, GDBusMethodInvocation * aInv); @@ -81,17 +63,15 @@ class BluezAdvertisement BluezAdapter1 * mpAdapter = nullptr; BluezLEAdvertisement1 * mpAdv = nullptr; - bool mIsInitialized = false; - char * mpAdvPath = nullptr; - char * mpAdapterName = nullptr; - char * mpAdvertisingUUID = nullptr; - chip::Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; - ChipAdvType mType; - uint16_t mDurationMs; + bool mIsInitialized = false; bool mIsAdvertising = false; - // Allow BluezConnection to access our private members - friend class BluezConnection; + Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; + char * mpAdvPath = nullptr; + char * mpAdapterName = nullptr; + char * mpAdvUUID = nullptr; + ChipAdvType mAdvType; + uint16_t mAdvDurationMs = 0; }; } // namespace Internal From 7e032042e70308bdebbf53c96e53cb643ae2959c Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Tue, 10 Oct 2023 15:34:31 +0200 Subject: [PATCH 07/11] Update includes according to include-what-you-use --- scripts/helpers/platforms/iwyu.imp | 10 ++++++++++ src/platform/Linux/bluez/BluezAdvertisement.cpp | 17 +++-------------- src/platform/Linux/bluez/BluezAdvertisement.h | 1 + 3 files changed, 14 insertions(+), 14 deletions(-) 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/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index e85535fcff683d..614bfac86d783c 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -17,32 +17,21 @@ #include "BluezAdvertisement.h" -#include -#include #include -#include #include #include -#include #include #include -#include -#include #include #include #include -#include -#include #include #include #include -#include -#include -#include -#include "BluezConnection.h" +#include "BluezEndpoint.h" #include "Types.h" namespace chip { @@ -154,8 +143,8 @@ CHIP_ERROR BluezAdvertisement::Init(BluezEndpoint * apEndpoint, ChipAdvType aAdv VerifyOrExit(mpAdv == nullptr, err = CHIP_ERROR_INCORRECT_STATE; ChipLogError(DeviceLayer, "FAIL: BLE advertisement already initialized in %s", __func__)); - mpRoot = g_object_ref(apEndpoint->mpRoot); - mpAdapter = g_object_ref(apEndpoint->mpAdapter); + 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); diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h index b7e74b781d8b73..1aa707f45ba64c 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.h +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -20,6 +20,7 @@ #include #include +#include #include #include From 55740b34391815326d75c26c5ec69a782b4dd049 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 13:32:34 +0100 Subject: [PATCH 08/11] Remove async BLE advertisement init from state machine --- src/platform/Linux/BLEManagerImpl.cpp | 28 ++++--------------- src/platform/Linux/BLEManagerImpl.h | 1 - src/platform/Linux/CHIPDevicePlatformEvent.h | 1 - .../Linux/bluez/BluezAdvertisement.cpp | 2 -- 4 files changed, 6 insertions(+), 26 deletions(-) diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 7811bbfa0ea24e..0eb00bcedafa41 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -275,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); @@ -600,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 = mBLEAdvertisement.Init(mpEndpoint, mBLEAdvType, mpBLEAdvUUID, mBLEAdvDurationMs); - ExitNow(); + SuccessOrExit(err); + mFlags.Set(Flags::kAdvertisingConfigured) } - // Start advertising. This is also an asynchronous step. + // 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); - - mFlags.Set(Flags::kAdvertising); + mFlags.Set(Flags::kControlOpInProgress); ExitNow(); } } @@ -736,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 e613bb9a68d1ee..2f7cf8fe4f8ae5 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -93,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); 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 index 614bfac86d783c..0462d981d3b753 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -107,8 +107,6 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() g_dbus_object_manager_server_export(mpRoot, G_DBUS_OBJECT_SKELETON(object)); g_object_unref(object); - BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(true, nullptr); - return adv; } From 2a20618aec7844b7df6aa04835a8d712117154aa Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 13:44:50 +0100 Subject: [PATCH 09/11] Do not allocate memory for local name string --- src/platform/Linux/BLEManagerImpl.cpp | 2 +- src/platform/Linux/bluez/BluezAdvertisement.cpp | 15 +++++++++------ src/platform/Linux/bluez/BluezAdvertisement.h | 9 +++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 0eb00bcedafa41..194598b8581ff6 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -599,7 +599,7 @@ void BLEManagerImpl::DriveBLEState() { err = mBLEAdvertisement.Init(mpEndpoint, mBLEAdvType, mpBLEAdvUUID, mBLEAdvDurationMs); SuccessOrExit(err); - mFlags.Set(Flags::kAdvertisingConfigured) + mFlags.Set(Flags::kAdvertisingConfigured); } // Start advertising. This is an asynchronous step. BLE manager will be notified of diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index 0462d981d3b753..96beec6495aed5 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -44,10 +44,11 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() BluezObjectSkeleton * object; GVariant * serviceData; GVariant * serviceUUID; - GAutoPtr localName; 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); @@ -61,10 +62,12 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &mDeviceIdInfo, sizeof(mDeviceIdInfo), sizeof(uint8_t))); g_variant_builder_add(&serviceUUIDsBuilder, "s", mpAdvUUID); - if (mpAdapterName != nullptr) - localName = GAutoPtr(g_strdup_printf("%s", mpAdapterName)); - else - localName = GAutoPtr(g_strdup_printf("%s%04x", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, getpid() & 0xffff)); + 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); @@ -86,7 +89,7 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() 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_local_name(adv, localNamePtr); bluez_leadvertisement1_set_service_uuids(adv, serviceUUID); // 0xffff means no appearance diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h index 1aa707f45ba64c..093e0766d189de 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.h +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -44,7 +44,16 @@ class BluezAdvertisement 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: From 6d95d0360d90039048b4e3146b4d1f85327c2366 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 13:55:47 +0100 Subject: [PATCH 10/11] Fix mem leak --- src/platform/Linux/bluez/BluezAdvertisement.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index 96beec6495aed5..dce4417b1ffe7a 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -200,6 +200,11 @@ void BluezAdvertisement::Shutdown() 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); From 016a1923c66e0447352a8db133785c8b635b9f3c Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 Nov 2023 15:00:16 +0100 Subject: [PATCH 11/11] Update date --- src/platform/Linux/bluez/BluezAdvertisement.cpp | 2 +- src/platform/Linux/bluez/BluezAdvertisement.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index dce4417b1ffe7a..16d590d6bab80d 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020-2022 Project CHIP Authors + * 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. diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h index 093e0766d189de..7fc01e027d38e0 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.h +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * 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.