diff --git a/internal/platform/implementation/linux/BUILD b/internal/platform/implementation/linux/BUILD index f367abf3..433efd6e 100644 --- a/internal/platform/implementation/linux/BUILD +++ b/internal/platform/implementation/linux/BUILD @@ -56,7 +56,7 @@ cc_library( hdrs = [ "avahi.h", "ble_gatt_server.h", -# "ble_gatt_client.h", + "ble_gatt_client.h", # "ble_medium.h", "ble_v2_medium.h", "ble_v2_server_socket.h", @@ -74,11 +74,11 @@ cc_library( # "bluez_agent.h", "bluez_advertisement_monitor.h", "bluez_advertisement_monitor_manager.h", -# "bluez_gatt_characteristic_client.h", + "bluez_gatt_characteristic_client.h", "bluez_gatt_characteristic_server.h", "bluez_gatt_manager.h", "bluez_gatt_profile.h", -# "bluez_gatt_service_client.h", + "bluez_gatt_service_client.h", "bluez_gatt_service_server.h", "bluez_le_advertisement.h", "dbus.h", @@ -142,7 +142,7 @@ cc_library( name = "linux", srcs = [ "avahi.cc", -# "ble_gatt_client.cc", + "ble_gatt_client.cc", "ble_gatt_server.cc", # "ble_medium.cc", "ble_v2_medium.cc", @@ -159,7 +159,7 @@ cc_library( "bluez.cc", #"bluez_agent.cc", "bluez_advertisement_monitor.cc", -# "bluez_gatt_characteristic_client.cc", + "bluez_gatt_characteristic_client.cc", "bluez_gatt_characteristic_server.cc", "bluez_gatt_service_server.cc", "bluez_le_advertisement.cc", diff --git a/internal/platform/implementation/linux/ble_v2_medium.cc b/internal/platform/implementation/linux/ble_v2_medium.cc index 2be204b0..31a50420 100644 --- a/internal/platform/implementation/linux/ble_v2_medium.cc +++ b/internal/platform/implementation/linux/ble_v2_medium.cc @@ -33,15 +33,13 @@ #include "ble_gatt_client.h" #include "ble_gatt_server.h" -#include "ble_l2cap_server_socket.h" -#include "ble_l2cap_socket.h" -#include "bluez_le_bearer_client.h" #include "internal/platform/implementation/linux/bluetooth_classic_device.h" #include "internal/platform/implementation/linux/bluetooth_devices.h" #include "internal/platform/implementation/linux/bluez.h" #include "internal/platform/mac_address.h" #include "internal/platform/prng.h" #include "absl/types/span.h" +#include "internal/base/observer_list.h" #include "internal/platform/implementation/linux/bluez_advertisement_monitor.h" #include "internal/platform/implementation/linux/bluez_advertisement_monitor_manager.h" #include "internal/platform/implementation/linux/bluez_le_advertisement.h" @@ -52,18 +50,19 @@ namespace nearby { namespace linux { BleV2Medium::BleV2Medium(BluetoothAdapter &adapter) - : system_bus_(adapter.GetConnection()), - adapter_(adapter), - devices_(std::make_unique( - system_bus_, adapter_.GetObjectPath(), observers_)), - // 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_( - bluez::AdvertisementMonitorManager:: - DiscoverAdvertisementMonitorManager(*system_bus_, adapter_)), - adv_manager_(std::make_unique(*system_bus_, - adapter)), - cur_adv_(nullptr) { + : system_bus_(adapter.GetConnection()), + adapter_(adapter), + // gatt_discovery_(std::make_shared(system_bus_)), + observers_(std::make_shared>()), + devices_(std::make_unique( + system_bus_, adapter_.GetObjectPath(), *observers_)), + root_object_manager_(std::make_unique(*system_bus_, "/com/google/nearby/medium/ble/advertisement/monitor")), + adv_monitor_manager_( + bluez::AdvertisementMonitorManager:: + DiscoverAdvertisementMonitorManager(*system_bus_, adapter_)), + adv_manager_(std::make_unique(*system_bus_, + adapter)), + cur_adv_(nullptr) { if (adv_monitor_manager_) { LOG(INFO) << __func__ @@ -84,70 +83,54 @@ BleV2Medium::BleV2Medium(BluetoothAdapter &adapter) // sync api // called twice. Once with extended regular advertisement ( when IsExtendedAdvertisementsAvailable() == true ) // and another for GATT-backed header advertisement for legacy devices -bool BleV2Medium::StartAdvertising( + bool BleV2Medium::StartAdvertising( const api::ble_v2::BleAdvertisementData &advertising_data, api::ble_v2::AdvertiseParameters advertise_set_parameters) { - if (!advertising_data.is_extended_advertisement) - { - // can't send two LE advertisements at the same - return true; - } - if (!adapter_.IsEnabled()) { - LOG(WARNING) << "BLE cannot start advertising because the " + if (!advertising_data.is_extended_advertisement) + { + // can't send two LE advertisements at the same + return true; + } + if (!adapter_.IsEnabled()) { + LOG(WARNING) << "BLE cannot start advertising because the " "bluetooth adapter is not enabled."; - return false; - } + return false; + } - if (advertising_data.service_data.empty()) { - LOG(WARNING) + if (advertising_data.service_data.empty()) { + LOG(WARNING) << "BLE cannot start to advertise due to invalid service data."; - return false; - } + return false; + } - absl::MutexLock l (&advs_mutex_); - advs_.push_front(bluez::LEAdvertisement::CreateLEAdvertisement( + absl::MutexLock l (&advs_mutex_); + advs_.push_front(bluez::LEAdvertisement::CreateLEAdvertisement( *system_bus_, advertising_data, advertise_set_parameters)); - auto it = advs_.begin(); + auto it = advs_.begin(); - LOG(INFO) << __func__ << ": Registering advertisement, is_extended: " << advertising_data.is_extended_advertisement + LOG(INFO) << __func__ << ": Registering advertisement, is_extended: " << advertising_data.is_extended_advertisement << " " << (*it) -> getObjectPath() << " on bluetooth adapter " << adapter_.GetObjectPath(); - try { - adv_manager_->RegisterAdvertisement((*it)->getObjectPath(), {}); - } catch (const sdbus::Error &e) { - advs_.erase(it); - DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisement", e); - return false; - } - - return true; -} - -bool BleV2Medium::StopAdvertising() { - absl::MutexLock l(&advs_mutex_); - try { - for (auto& adv: advs_) - { - adv_manager_->UnregisterAdvertisement(adv->getObjectPath()); + try { + adv_manager_->RegisterAdvertisement((*it)->getObjectPath(), {}); + } catch (const sdbus::Error &e) { + advs_.erase(it); + DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisement", e); + return false; } - } catch (const sdbus::Error &e) { - DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisement", e); - return false; + + return true; } - advs_.clear(); - return true; -} - - //async api - // this doesn't run. wonder why +//async api +// this doesn't run. wonder why std::unique_ptr BleV2Medium::StartAdvertising( - const api::ble_v2::BleAdvertisementData &advertising_data, - api::ble_v2::AdvertiseParameters advertise_set_parameters, - AdvertisingCallback callback) { + const api::ble_v2::BleAdvertisementData &advertising_data, + api::ble_v2::AdvertiseParameters advertise_set_parameters, + AdvertisingCallback callback) { if (!adapter_.IsEnabled()) { LOG(WARNING) << ": BLE cannot start advertising because the " "bluetooth adapter is not enabled."; @@ -161,50 +144,50 @@ BleV2Medium::StartAdvertising( } std::shared_ptr proxy = - sdbus::createProxy(*system_bus_, "org.bluez", adapter_.GetObjectPath()); + sdbus::createProxy(*system_bus_, "org.bluez", adapter_.GetObjectPath()); proxy->finishRegistration(); std::shared_ptr shared_cb = - std::make_shared(std::move(callback)); + std::make_shared(std::move(callback)); absl::MutexLock lock(&advs_mutex_); advs_.push_front(bluez::LEAdvertisement::CreateLEAdvertisement( - *system_bus_, advertising_data, advertise_set_parameters)); + *system_bus_, advertising_data, advertise_set_parameters)); auto adv_it = advs_.begin(); auto pending_call = - proxy->callMethodAsync("RegisterAdvertisement") - .onInterface(org::bluez::LEAdvertisingManager1_proxy::INTERFACE_NAME) - .withArguments((*adv_it)->getObjectPath(), - std::map{}) - .uponReplyInvoke( - [this, proxy, shared_cb, adv_it](const sdbus::Error *error) { - if (error != nullptr && error->isValid()) { - { - absl::MutexLock lock(&advs_mutex_); - advs_.erase(adv_it); - } - DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, - "RegisterAdvertisement", *error); - auto name = error->getName(); - std::string msg = error->getMessage(); - absl::Status status; + proxy->callMethodAsync("RegisterAdvertisement") + .onInterface(org::bluez::LEAdvertisingManager1_proxy::INTERFACE_NAME) + .withArguments((*adv_it)->getObjectPath(), + std::map{}) + .uponReplyInvoke( + [this, proxy, shared_cb, adv_it](const sdbus::Error *error) { + if (error != nullptr && error->isValid()) { + { + absl::MutexLock lock(&advs_mutex_); + advs_.erase(adv_it); + } + DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, + "RegisterAdvertisement", *error); + auto name = error->getName(); + std::string msg = error->getMessage(); + absl::Status status; - if (name == "org.bluez.Error.InvalidArguments" || - name == "org.bluez.Error.InvalidLength") { - status = absl::InvalidArgumentError(msg); - } else if (name == "org.bluez.Error.AlreadyExists") { - status = absl::AlreadyExistsError(msg); - } else if (name == "org.bluez.Error.NotPermitted") { - status = absl::ResourceExhaustedError(msg); - } else { - status = absl::UnknownError(msg); - } - shared_cb->start_advertising_result(std::move(status)); - } else { - shared_cb->start_advertising_result(absl::OkStatus()); - } - }); + if (name == "org.bluez.Error.InvalidArguments" || + name == "org.bluez.Error.InvalidLength") { + status = absl::InvalidArgumentError(msg); + } else if (name == "org.bluez.Error.AlreadyExists") { + status = absl::AlreadyExistsError(msg); + } else if (name == "org.bluez.Error.NotPermitted") { + status = absl::ResourceExhaustedError(msg); + } else { + status = absl::UnknownError(msg); + } + shared_cb->start_advertising_result(std::move(status)); + } else { + shared_cb->start_advertising_result(absl::OkStatus()); + } + }); absl::AnyInvocable stop_adv = [&, adv_it]() { LOG(INFO) << __func__ << ": Unregistering advertisement object " @@ -220,23 +203,244 @@ BleV2Medium::StartAdvertising( return absl::OkStatus(); }; return std::make_unique( - api::ble_v2::BleMedium::AdvertisingSession{std::move(stop_adv)}); + api::ble_v2::BleMedium::AdvertisingSession{std::move(stop_adv)}); } + bool BleV2Medium::StopAdvertising() { + absl::MutexLock l(&advs_mutex_); + try { + for (auto& adv: advs_) + { + adv_manager_->UnregisterAdvertisement(adv->getObjectPath()); + } + } catch (const sdbus::Error &e) { + DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisement", e); + return false; + } + + advs_.clear(); + return true; + } + +bool BleV2Medium::StartScanning(const Uuid &service_uuid, + api::ble_v2::TxPowerLevel tx_power_level, + ScanCallback callback) { + if (cur_monitored_service_uuid_.has_value()) { + LOG(ERROR) << __func__ + << ": A sync scanning session is already active for " + << std::string{*cur_monitored_service_uuid_}; + return false; + } + + if (adv_monitor_manager_ == nullptr) { + LOG(WARNING) << __func__ + << ": Advertising monitor not supported by BlueZ"; + // TODO: Implement manual monitoring. + return false; + } + + if (!MonitorManagerSupportsOr()) { + LOG(WARNING) + << __func__ + << ": \"or_patterns\" not supported by AdvertisementMonitorManager"; + // TODO: Implement manual monitoring. + return false; + } + + absl::MutexLock lock(&active_adv_monitors_mutex_); + if (active_adv_monitors_.count(service_uuid) == 1) { + LOG(ERROR) << __func__ << ": an advertising session for service " + << std::string{service_uuid} << " already exists"; + return false; + } + + auto monitor = std::make_unique( + *system_bus_, service_uuid, tx_power_level, "or_patterns", devices_, + std::move(callback)); + try { + // why is this emitted? + monitor->emitInterfacesAddedSignal( + {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); + + // adv_monitor_manager_ -> RegisterMonitor(monitor -> getObjectPath()); + LOG(INFO)<< __func__ << ": Registered advertisement monitor with path " << monitor -> getObjectPath(); + } catch (const sdbus::Error &e) { + LOG(ERROR) + << __func__ + << ": error emitting InterfacesAdded signal for object path " + << monitor->getObjectPath() << " with name '" << e.getName() + << "' and message '" << e.getMessage() << "'"; + return false; + } + auto device_watcher = std::make_unique( + *system_bus_, adapter_.GetObjectPath(), adapter_, devices_); + if (!StartLEDiscovery()) { + LOG(ERROR) << __func__ + << ": Could not start LE discovery on adapter " + << adapter_.GetObjectPath(); + device_watcher = nullptr; + try { + monitor->emitInterfacesRemovedSignal( + {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); + } catch (const sdbus::Error &e) { + LOG(ERROR) + << __func__ + << ": error emitting InterfacesRemoved signal for object path " + << monitor->getObjectPath() << " with name '" << e.getName() + << "' and message '" << e.getMessage() << "'"; + } + return false; + } + LOG(INFO) << __func__ << " :Started monitoring for service UUID: " << std::string(service_uuid); + + active_adv_monitors_[service_uuid] = + std::make_pair(std::move(monitor), std::move(device_watcher)); + cur_monitored_service_uuid_ = service_uuid; + return true; +} + +bool BleV2Medium::StopScanning() { + if (!cur_monitored_service_uuid_.has_value()) { + LOG(ERROR) << __func__ + << ": No sync scanning session is currently active."; + return false; + } + + if (adv_monitor_manager_ == nullptr) { + // TODO: Implement manual monitoring. + return false; + } + + auto &adapter = adapter_.GetBluezAdapterObject(); + LOG(INFO) << __func__ << ": Stopping discovery for adapter " + << adapter.getObjectPath(); + try { + adapter.StopDiscovery(); // this will stop bluetooth classic discovery as well. do we want this? + } catch (const sdbus::Error &e) { + DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StopDiscovery", e); + } + + absl::MutexLock lock(&active_adv_monitors_mutex_); + auto monitor_it = active_adv_monitors_.find(*cur_monitored_service_uuid_); + assert(monitor_it != active_adv_monitors_.end()); + { + auto &[_uuid, session] = *monitor_it; + auto &[adv_monitor, _watcher] = session; + + LOG(INFO) << __func__ << ": Removing advertising monitor " + << adv_monitor->getObjectPath(); + adv_monitor->emitInterfacesRemovedSignal( + {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); + } + active_adv_monitors_.erase(monitor_it); + cur_monitored_service_uuid_ = std::nullopt; + + return true; +} + std::unique_ptr + BleV2Medium::StartScanning(const Uuid &service_uuid, + api::ble_v2::TxPowerLevel tx_power_level, + ScanningCallback callback) { + if (adv_monitor_manager_ == nullptr) { + // TODO: Implement manual monitoring. + return nullptr; + } + + absl::MutexLock lock(&active_adv_monitors_mutex_); + if (active_adv_monitors_.count(service_uuid) == 1) { + LOG(ERROR) << __func__ << ": Service " << std::string{service_uuid} + << " is already being advertised"; + return nullptr; + } + + auto monitor = std::make_unique( + *system_bus_, service_uuid, tx_power_level, "or_patterns", devices_, + std::move(callback)); + try { + monitor->emitInterfacesAddedSignal( + {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); + } catch (const sdbus::Error &e) { + LOG(ERROR) + << __func__ + << ": error emitting InterfacesAdded signal for object path " + << monitor->getObjectPath() << " with name '" << e.getName() + << "' and message '" << e.getMessage() << "'"; + return nullptr; + } + + auto device_watcher = std::make_unique( + *system_bus_, adapter_.GetObjectPath(),adapter_, devices_); + if (!StartLEDiscovery()) { + LOG(ERROR) << __func__ + << ": Could not start LE discovery on adapter " + << adapter_.GetObjectPath(); + try { + monitor->emitInterfacesRemovedSignal( + {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); + } catch (const sdbus::Error &e) { + LOG(ERROR) + << __func__ + << ": error emitting InterfacesRemoved signal for object path " + << monitor->getObjectPath() << " with name '" << e.getName() + << "' and message '" << e.getMessage() << "'"; + } + return nullptr; + } + + active_adv_monitors_[service_uuid] = + std::make_pair(std::move(monitor), std::move(device_watcher)); + + return std::make_unique( + ScanningSession{.stop_scanning = [this, service_uuid]() { + absl::MutexLock lock(&active_adv_monitors_mutex_); + if (active_adv_monitors_.count(service_uuid) == 0) { + LOG(ERROR) + << __func__ << ": Advertising monitor for service " + << std::string{service_uuid} << " does not exist anymore"; + return absl::NotFoundError( + "Advertising monitor for this service does not exist"); + } + + auto &[monitor, watcher] = active_adv_monitors_[service_uuid]; + try { + monitor->emitInterfacesRemovedSignal( + {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); + } catch (const sdbus::Error &e) { + LOG(ERROR) + << __func__ + << ": error emitting InterfacesRemoved signal for object path " + << monitor->getObjectPath() << " with name '" << e.getName() + << "' and message '" << e.getMessage() << "'"; + } + + auto &adapter = adapter_.GetBluezAdapterObject(); + absl::Status status; + try { + adapter.StopDiscovery(); + status = absl::OkStatus(); + } catch (const sdbus::Error &e) { + DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StopDiscovery", e); + status = absl::InternalError(e.getMessage()); + } + active_adv_monitors_.erase(service_uuid); + return status; + }}); + } + std::unique_ptr BleV2Medium::StartGattServer( - api::ble_v2::ServerGattConnectionCallback callback) { + api::ble_v2::ServerGattConnectionCallback callback) { (void)callback; return nullptr; return std::make_unique( - *system_bus_, adapter_, devices_,std::move(callback) + *system_bus_, adapter_, devices_,std::move(callback) ); } std::unique_ptr BleV2Medium::ConnectToGattServer( - api::ble_v2::BlePeripheral::UniqueId peripheral_id, - api::ble_v2::TxPowerLevel tx_power_level, - api::ble_v2::ClientGattConnectionCallback callback) { + api::ble_v2::BlePeripheral::UniqueId peripheral_id, + api::ble_v2::TxPowerLevel tx_power_level, + api::ble_v2::ClientGattConnectionCallback callback) { (void)peripheral_id; (void)tx_power_level; (void)callback; @@ -244,11 +448,34 @@ std::unique_ptr BleV2Medium::ConnectToGattServer( << ": GATT client connection is not supported on Linux yet."; return nullptr; } - // This is supposed to be for a socket on top of Weave protocol. + +std::unique_ptr BleV2Medium::OpenServerSocket( + const std::string &service_id) { + LOG(INFO) << __func__ << ": Opening BLE server socket for service " + << service_id; + return std::make_unique(service_id); +} + +std::unique_ptr +BleV2Medium::OpenL2capServerSocket(const std::string &service_id) { + 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; +} + +// This is supposed to be for a socket on top of Weave protocol. std::unique_ptr BleV2Medium::Connect( - const std::string &service_id, api::ble_v2::TxPowerLevel tx_power_level, - api::ble_v2::BlePeripheral::UniqueId peripheral_id, - CancellationFlag *cancellation_flag) { + const std::string &service_id, api::ble_v2::TxPowerLevel tx_power_level, + api::ble_v2::BlePeripheral::UniqueId peripheral_id, + CancellationFlag *cancellation_flag) { LOG(INFO) << __func__ << ": Not implemented on linux "; return nullptr; } @@ -290,233 +517,6 @@ bool BleV2Medium::StartLEDiscovery() { return true; } -bool BleV2Medium::StartScanning(const Uuid &service_uuid, - api::ble_v2::TxPowerLevel tx_power_level, - ScanCallback callback) { - if (cur_monitored_service_uuid_.has_value()) { - LOG(ERROR) << __func__ - << ": A sync scanning session is already active for " - << std::string{*cur_monitored_service_uuid_}; - return false; - } - - if (adv_monitor_manager_ == nullptr) { - LOG(WARNING) << __func__ - << ": Advertising monitor not supported by BlueZ"; - // TODO: Implement manual monitoring. - return false; - } - - if (!MonitorManagerSupportsOr()) { - LOG(WARNING) - << __func__ - << ": \"or_patterns\" not supported by AdvertisementMonitorManager"; - // TODO: Implement manual monitoring. - return false; - } - - absl::MutexLock lock(&active_adv_monitors_mutex_); - if (active_adv_monitors_.count(service_uuid) == 1) { - LOG(ERROR) << __func__ << ": an advertising session for service " - << std::string{service_uuid} << " already exists"; - return false; - } - - auto monitor = std::make_unique( - *system_bus_, service_uuid, tx_power_level, "or_patterns", devices_, - std::move(callback)); - try { - // why is this emitted? - monitor->emitInterfacesAddedSignal( - {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); - - // adv_monitor_manager_ -> RegisterMonitor(monitor -> getObjectPath()); - LOG(INFO)<< __func__ << ": Registered advertisement monitor with path " << monitor -> getObjectPath(); - } catch (const sdbus::Error &e) { - LOG(ERROR) - << __func__ - << ": error emitting InterfacesAdded signal for object path " - << monitor->getObjectPath() << " with name '" << e.getName() - << "' and message '" << e.getMessage() << "'"; - return false; - } - auto device_watcher = std::make_unique( - *system_bus_, adapter_.GetObjectPath(), adapter_, devices_); - if (!StartLEDiscovery()) { - LOG(ERROR) << __func__ - << ": Could not start LE discovery on adapter " - << adapter_.GetObjectPath(); - device_watcher = nullptr; - try { - monitor->emitInterfacesRemovedSignal( - {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); - } catch (const sdbus::Error &e) { - LOG(ERROR) - << __func__ - << ": error emitting InterfacesRemoved signal for object path " - << monitor->getObjectPath() << " with name '" << e.getName() - << "' and message '" << e.getMessage() << "'"; - } - return false; - } - LOG(INFO) << __func__ << " :Started monitoring for service UUID: " << std::string(service_uuid); - - active_adv_monitors_[service_uuid] = - std::make_pair(std::move(monitor), std::move(device_watcher)); - cur_monitored_service_uuid_ = service_uuid; - return true; -} - -bool BleV2Medium::StopScanning() { - if (!cur_monitored_service_uuid_.has_value()) { - LOG(ERROR) << __func__ - << ": No sync scanning session is currently active."; - return false; - } - - if (adv_monitor_manager_ == nullptr) { - // TODO: Implement manual monitoring. - return false; - } - - auto &adapter = adapter_.GetBluezAdapterObject(); - LOG(INFO) << __func__ << ": Stopping discovery for adapter " - << adapter.getObjectPath(); - try { - adapter.StopDiscovery(); // this will stop bluetooth classic discovery as well. do we want this? - } catch (const sdbus::Error &e) { - DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StopDiscovery", e); - } - - absl::MutexLock lock(&active_adv_monitors_mutex_); - auto monitor_it = active_adv_monitors_.find(*cur_monitored_service_uuid_); - assert(monitor_it != active_adv_monitors_.end()); - { - auto &[_uuid, session] = *monitor_it; - auto &[adv_monitor, _watcher] = session; - - LOG(INFO) << __func__ << ": Removing advertising monitor " - << adv_monitor->getObjectPath(); - adv_monitor->emitInterfacesRemovedSignal( - {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); - } - active_adv_monitors_.erase(monitor_it); - cur_monitored_service_uuid_ = std::nullopt; - - return true; -} - -std::unique_ptr -BleV2Medium::StartScanning(const Uuid &service_uuid, - api::ble_v2::TxPowerLevel tx_power_level, - ScanningCallback callback) { - if (adv_monitor_manager_ == nullptr) { - // TODO: Implement manual monitoring. - return nullptr; - } - - absl::MutexLock lock(&active_adv_monitors_mutex_); - if (active_adv_monitors_.count(service_uuid) == 1) { - LOG(ERROR) << __func__ << ": Service " << std::string{service_uuid} - << " is already being advertised"; - return nullptr; - } - - auto monitor = std::make_unique( - *system_bus_, service_uuid, tx_power_level, "or_patterns", devices_, - std::move(callback)); - try { - monitor->emitInterfacesAddedSignal( - {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); - } catch (const sdbus::Error &e) { - LOG(ERROR) - << __func__ - << ": error emitting InterfacesAdded signal for object path " - << monitor->getObjectPath() << " with name '" << e.getName() - << "' and message '" << e.getMessage() << "'"; - return nullptr; - } - - auto device_watcher = std::make_unique( - *system_bus_, adapter_.GetObjectPath(),adapter_, devices_); - if (!StartLEDiscovery()) { - LOG(ERROR) << __func__ - << ": Could not start LE discovery on adapter " - << adapter_.GetObjectPath(); - try { - monitor->emitInterfacesRemovedSignal( - {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); - } catch (const sdbus::Error &e) { - LOG(ERROR) - << __func__ - << ": error emitting InterfacesRemoved signal for object path " - << monitor->getObjectPath() << " with name '" << e.getName() - << "' and message '" << e.getMessage() << "'"; - } - return nullptr; - } - - active_adv_monitors_[service_uuid] = - std::make_pair(std::move(monitor), std::move(device_watcher)); - - return std::make_unique( - ScanningSession{.stop_scanning = [this, service_uuid]() { - absl::MutexLock lock(&active_adv_monitors_mutex_); - if (active_adv_monitors_.count(service_uuid) == 0) { - LOG(ERROR) - << __func__ << ": Advertising monitor for service " - << std::string{service_uuid} << " does not exist anymore"; - return absl::NotFoundError( - "Advertising monitor for this service does not exist"); - } - - auto &[monitor, watcher] = active_adv_monitors_[service_uuid]; - try { - monitor->emitInterfacesRemovedSignal( - {org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}); - } catch (const sdbus::Error &e) { - LOG(ERROR) - << __func__ - << ": error emitting InterfacesRemoved signal for object path " - << monitor->getObjectPath() << " with name '" << e.getName() - << "' and message '" << e.getMessage() << "'"; - } - - auto &adapter = adapter_.GetBluezAdapterObject(); - absl::Status status; - try { - adapter.StopDiscovery(); - status = absl::OkStatus(); - } catch (const sdbus::Error &e) { - DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StopDiscovery", e); - status = absl::InternalError(e.getMessage()); - } - active_adv_monitors_.erase(service_uuid); - return status; - }}); -} - -std::unique_ptr BleV2Medium::OpenServerSocket( - const std::string &service_id) { - LOG(INFO) << __func__ << ": Opening BLE server socket for service " - << service_id; - return std::make_unique(service_id); -} - -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; -} - // std::unique_ptr BleV2Medium::Connect( // const std::string &service_id, api::ble_v2::TxPowerLevel tx_power_level, // api::ble_v2::BlePeripheral &peripheral, @@ -530,47 +530,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..5d3af920 100644 --- a/internal/platform/implementation/linux/ble_v2_medium.h +++ b/internal/platform/implementation/linux/ble_v2_medium.h @@ -28,8 +28,6 @@ // #include "internal/platform/implementation/linux/ble_gatt_client.h" #include "ble_gatt_client.h" #include "bluez_gatt_manager.h" -#include "internal/platform/implementation/linux/ble_l2cap_server_socket.h" -#include "internal/platform/implementation/linux/ble_l2cap_socket.h" #include "internal/platform/implementation/linux/ble_v2_server_socket.h" #include "internal/platform/implementation/linux/bluetooth_adapter.h" #include "internal/platform/implementation/linux/bluetooth_devices.h" @@ -142,7 +140,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_;