From d12be6731954a8dad0cc66f20ff46bff2daba399 Mon Sep 17 00:00:00 2001 From: kidfromjupiter Date: Sat, 17 Jan 2026 08:46:49 +0000 Subject: [PATCH] Made ble_v2_medium and bluetooth_classic_medium share a devices_ --- .../implementation/linux/ble_v2_medium.cc | 118 ++++++++++-------- .../implementation/linux/ble_v2_medium.h | 4 +- .../linux/bluetooth_classic_medium.cc | 26 ++-- .../implementation/linux/bluetooth_devices.cc | 25 ++++ .../implementation/linux/bluetooth_devices.h | 10 ++ 5 files changed, 118 insertions(+), 65 deletions(-) diff --git a/internal/platform/implementation/linux/ble_v2_medium.cc b/internal/platform/implementation/linux/ble_v2_medium.cc index 2be204b0..d04f5181 100644 --- a/internal/platform/implementation/linux/ble_v2_medium.cc +++ b/internal/platform/implementation/linux/ble_v2_medium.cc @@ -54,8 +54,7 @@ namespace linux { BleV2Medium::BleV2Medium(BluetoothAdapter &adapter) : system_bus_(adapter.GetConnection()), adapter_(adapter), - devices_(std::make_unique( - system_bus_, adapter_.GetObjectPath(), observers_)), + devices_(nullptr), // gatt_discovery_(std::make_shared(system_bus_)), root_object_manager_(std::make_unique(*system_bus_, "/com/google/nearby/medium/ble/advertisement/monitor")), adv_monitor_manager_( @@ -64,6 +63,10 @@ BleV2Medium::BleV2Medium(BluetoothAdapter &adapter) adv_manager_(std::make_unique(*system_bus_, adapter)), cur_adv_(nullptr) { + auto shared = + GetSharedBluetoothDevices(system_bus_, adapter_.GetObjectPath()); + observers_ = shared->observers; + devices_ = shared->devices; if (adv_monitor_manager_) { LOG(INFO) << __func__ @@ -279,7 +282,12 @@ bool BleV2Medium::StartLEDiscovery() { try { LOG(INFO) << __func__ << ": Starting LE discovery on " << adapter.getObjectPath(); - adapter.StartDiscovery(); + if (!adapter.Discovering()) + { + LOG(INFO)<< __func__ << ": Not discovering. Starting discovery"; + adapter.StartDiscovery(); + } + } catch (const sdbus::Error &e) { if (e.getName() != "org.bluez.Error.InProgress") { DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StartDiscovery", e); @@ -505,16 +513,17 @@ std::unique_ptr BleV2Medium::OpenServerSocket( std::unique_ptr BleV2Medium::OpenL2capServerSocket(const std::string &service_id) { - LOG(INFO) << __func__ << ": Opening L2CAP server socket for service " - << service_id; - - Prng prng; - auto psm = 0x80 + (prng.NextUint32() % 0x80); - auto server_socket = std::make_unique(psm); - - LOG(INFO) << __func__ << ": L2CAP server socket created with PSM: " - << server_socket->GetPSM(); - return server_socket; + return nullptr; + // LOG(INFO) << __func__ << ": Opening L2CAP server socket for service " + // << service_id; + // + // Prng prng; + // auto psm = 0x80 + (prng.NextUint32() % 0x80); + // auto server_socket = std::make_unique(psm); + // + // LOG(INFO) << __func__ << ": L2CAP server socket created with PSM: " + // << server_socket->GetPSM(); + // return server_socket; } // std::unique_ptr BleV2Medium::Connect( @@ -530,47 +539,48 @@ std::unique_ptr BleV2Medium::ConnectOverL2cap( api::ble_v2::TxPowerLevel tx_power_level, api::ble_v2::BlePeripheral::UniqueId peripheral_id, CancellationFlag *cancellation_flag) { - auto device = devices_->get_device_by_unique_id(peripheral_id); - if (!device) { - LOG(ERROR) << __func__ << ": Failed to find device with unique ID " - << peripheral_id; - return nullptr; - } - - LOG(INFO) << __func__ << ": Connecting to L2CAP PSM " << psm - << " on device " << device->GetMacAddress(); - - - int fd = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (fd < 0) { - LOG(ERROR) << __func__ << ": Failed to create L2CAP socket: " - << std::strerror(errno); - return nullptr; - } - - struct sockaddr_l2 addr; - std::memset(&addr, 0, sizeof(addr)); - addr.l2_family = AF_BLUETOOTH; - addr.l2_psm = htobs(psm); - addr.l2_cid = 0; - addr.l2_bdaddr_type = BDADDR_LE_PUBLIC; - - std::string mac_addr = device->GetMacAddress(); - if (str2ba(mac_addr.c_str(), &addr.l2_bdaddr) < 0) { - LOG(ERROR) << __func__ << ": Invalid Bluetooth address: " << mac_addr; - close(fd); - return nullptr; - } - - if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOG(ERROR) << __func__ << ": Failed to connect to L2CAP socket: " - << std::strerror(errno); - close(fd); - return nullptr; - } - - LOG(INFO) << __func__ << ": Successfully connected to L2CAP socket"; - return std::make_unique(fd, peripheral_id); + return nullptr; + // auto device = devices_->get_device_by_unique_id(peripheral_id); + // if (!device) { + // LOG(ERROR) << __func__ << ": Failed to find device with unique ID " + // << peripheral_id; + // return nullptr; + // } + // + // LOG(INFO) << __func__ << ": Connecting to L2CAP PSM " << psm + // << " on device " << device->GetMacAddress(); + // + // + // int fd = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + // if (fd < 0) { + // LOG(ERROR) << __func__ << ": Failed to create L2CAP socket: " + // << std::strerror(errno); + // return nullptr; + // } + // + // struct sockaddr_l2 addr; + // std::memset(&addr, 0, sizeof(addr)); + // addr.l2_family = AF_BLUETOOTH; + // addr.l2_psm = htobs(psm); + // addr.l2_cid = 0; + // addr.l2_bdaddr_type = BDADDR_LE_PUBLIC; + // + // std::string mac_addr = device->GetMacAddress(); + // if (str2ba(mac_addr.c_str(), &addr.l2_bdaddr) < 0) { + // LOG(ERROR) << __func__ << ": Invalid Bluetooth address: " << mac_addr; + // close(fd); + // return nullptr; + // } + // + // if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + // LOG(ERROR) << __func__ << ": Failed to connect to L2CAP socket: " + // << std::strerror(errno); + // close(fd); + // return nullptr; + // } + // + // LOG(INFO) << __func__ << ": Successfully connected to L2CAP socket"; + // return std::make_unique(fd, peripheral_id); } bool BleV2Medium::StartMultipleServicesScanning( diff --git a/internal/platform/implementation/linux/ble_v2_medium.h b/internal/platform/implementation/linux/ble_v2_medium.h index fdbcce1b..01be22f2 100644 --- a/internal/platform/implementation/linux/ble_v2_medium.h +++ b/internal/platform/implementation/linux/ble_v2_medium.h @@ -142,7 +142,9 @@ class BleV2Medium final : public api::ble_v2::BleMedium { std::shared_ptr system_bus_; BluetoothAdapter adapter_; - ObserverList observers_ = {}; + // Why do we have observers her + std::shared_ptr> + observers_; std::shared_ptr devices_; std::shared_ptr gatt_discovery_; diff --git a/internal/platform/implementation/linux/bluetooth_classic_medium.cc b/internal/platform/implementation/linux/bluetooth_classic_medium.cc index 85e59aa1..cd854b22 100644 --- a/internal/platform/implementation/linux/bluetooth_classic_medium.cc +++ b/internal/platform/implementation/linux/bluetooth_classic_medium.cc @@ -34,16 +34,21 @@ namespace nearby { namespace linux { -BluetoothClassicMedium::BluetoothClassicMedium(BluetoothAdapter &adapter) - : system_bus_(adapter.GetConnection()), - adapter_(adapter), - observers_(std::make_shared>()), - devices_(std::make_shared( - system_bus_, adapter.GetObjectPath(), *observers_)), - device_watcher_(nullptr), - // agent_manager_(std::make_unique(*system_bus_)), - profile_manager_( - std::make_unique(*system_bus_, *devices_)) {} +BluetoothClassicMedium::BluetoothClassicMedium(BluetoothAdapter &adapter) + : system_bus_(adapter.GetConnection()), + adapter_(adapter), + observers_(nullptr), + devices_(nullptr), + device_watcher_(nullptr), + // agent_manager_(std::make_unique(*system_bus_)), + profile_manager_(nullptr) { + auto shared = + GetSharedBluetoothDevices(system_bus_, adapter_.GetObjectPath()); + observers_ = shared->observers; + devices_ = shared->devices; + profile_manager_ = + std::make_unique(*system_bus_, *devices_); +} bool BluetoothClassicMedium::StartDiscovery( DiscoveryCallback discovery_callback) { @@ -160,6 +165,7 @@ BluetoothClassicMedium::ListenForService(const std::string &service_name, api::BluetoothDevice *BluetoothClassicMedium::GetRemoteDevice( MacAddress mac_address) { + // When BLE is discovering, it looks for remote devices to connect to using BT classic. If only auto device = devices_->get_device_by_address(mac_address.ToString()); if (device == nullptr) return nullptr; diff --git a/internal/platform/implementation/linux/bluetooth_devices.cc b/internal/platform/implementation/linux/bluetooth_devices.cc index 12ccce89..b702556c 100644 --- a/internal/platform/implementation/linux/bluetooth_devices.cc +++ b/internal/platform/implementation/linux/bluetooth_devices.cc @@ -16,9 +16,11 @@ #include #include #include +#include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/substitute.h" #include "absl/synchronization/mutex.h" #include "internal/platform/implementation/linux/bluetooth_adapter.h" @@ -32,6 +34,29 @@ namespace nearby { namespace linux { static constexpr std::chrono::minutes kLostPeripheralsCleanupMinFreq(5); +absl::Mutex g_shared_devices_lock; +absl::flat_hash_map> + g_shared_devices ABSL_GUARDED_BY(g_shared_devices_lock); + +std::shared_ptr GetSharedBluetoothDevices( + std::shared_ptr system_bus, + const sdbus::ObjectPath& adapter_object_path) { + const std::string key = adapter_object_path; + absl::MutexLock lock(&g_shared_devices_lock); + auto it = g_shared_devices.find(key); + if (it != g_shared_devices.end()) { + if (auto existing = it->second.lock()) { + return existing; + } + } + auto shared = std::make_shared(); + shared->observers = + std::make_shared>(); + shared->devices = std::make_shared( + std::move(system_bus), adapter_object_path, *shared->observers); + g_shared_devices[key] = shared; + return shared; +} std::shared_ptr BluetoothDevices::get_device_by_path( const sdbus::ObjectPath &device_object_path) { diff --git a/internal/platform/implementation/linux/bluetooth_devices.h b/internal/platform/implementation/linux/bluetooth_devices.h index 45c8dc16..9454ed37 100644 --- a/internal/platform/implementation/linux/bluetooth_devices.h +++ b/internal/platform/implementation/linux/bluetooth_devices.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -83,6 +84,15 @@ class BluetoothDevices final { ABSL_GUARDED_BY(devices_by_path_lock_); }; +struct SharedBluetoothDevices { + std::shared_ptr devices; + std::shared_ptr> observers; +}; + +std::shared_ptr GetSharedBluetoothDevices( + std::shared_ptr system_bus, + const sdbus::ObjectPath& adapter_object_path); + class DeviceWatcher final : sdbus::ProxyInterfaces { public: DeviceWatcher(const DeviceWatcher &) = delete;