mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
ran ble_v2 through formatter. added GC only handling to bwu
This commit is contained in:
@@ -217,6 +217,20 @@ void BwuManager::InitiateBwuForEndpoint(ClientProxy* client,
|
||||
endpoint_id,
|
||||
client->GetUpgradeMediums(endpoint_id).GetMediums(true))
|
||||
: new_medium;
|
||||
if (proposed_medium == Medium::WIFI_DIRECT &&
|
||||
mediums_->GetWifiDirect().IsGCONly()) {
|
||||
std::vector<Medium> fallback_mediums =
|
||||
client->GetUpgradeMediums(endpoint_id).GetMediums(true);
|
||||
fallback_mediums.erase(
|
||||
std::remove(fallback_mediums.begin(), fallback_mediums.end(),
|
||||
Medium::WIFI_DIRECT),
|
||||
fallback_mediums.end());
|
||||
proposed_medium = ChooseBestUpgradeMedium(endpoint_id, fallback_mediums);
|
||||
LOG(INFO) << "Wi-Fi Direct is GC-only; selected fallback medium "
|
||||
<< location::nearby::proto::connections::Medium_Name(
|
||||
proposed_medium)
|
||||
<< " for endpoint " << endpoint_id;
|
||||
}
|
||||
|
||||
RunOnBwuManagerThread("bwu-init", [this, client, endpoint_id,
|
||||
proposed_medium]() {
|
||||
@@ -800,7 +814,12 @@ void BwuManager::ProcessBwuPathAvailableEvent(
|
||||
|
||||
bool abort_bwu = false;
|
||||
if (client->IsIncomingConnection(endpoint_id)) {
|
||||
if (!is_dynamic_role_switch_enabled_) {
|
||||
if (upgrade_medium == Medium::WIFI_DIRECT &&
|
||||
mediums_->GetWifiDirect().IsGCONly()) {
|
||||
// A GC-only device can consume a standard path offered by a peer GO,
|
||||
// regardless of which side initiated the original connection.
|
||||
abort_bwu = false;
|
||||
} else if (!is_dynamic_role_switch_enabled_) {
|
||||
abort_bwu = true;
|
||||
} else {
|
||||
auto medium_role = client->GetMediumRole(endpoint_id);
|
||||
|
||||
@@ -271,6 +271,118 @@ TEST(BwuManagerBaseTest, AllowToUpgradeMedium) {
|
||||
bwu_manager->Shutdown();
|
||||
}
|
||||
|
||||
TEST(BwuManagerBaseTest, GcOnlyDoesNotInitializeWifiDirectAsGO) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableWifiDirect,
|
||||
true);
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirectGcOnly,
|
||||
true);
|
||||
{
|
||||
ClientProxy client;
|
||||
EndpointChannelManager ecm;
|
||||
EndpointManager em(&ecm);
|
||||
Mediums mediums;
|
||||
auto fake_wifi_direct =
|
||||
std::make_unique<FakeBwuHandler>(Medium::WIFI_DIRECT);
|
||||
FakeBwuHandler* fake_wifi_direct_ptr = fake_wifi_direct.get();
|
||||
absl::flat_hash_map<Medium, std::unique_ptr<BwuHandler>> handlers;
|
||||
handlers.emplace(Medium::WIFI_DIRECT, std::move(fake_wifi_direct));
|
||||
BwuManager::Config config;
|
||||
config.allow_upgrade_to.wifi_direct = true;
|
||||
auto bwu_manager = std::make_unique<BwuManager>(
|
||||
mediums, em, ecm, std::move(handlers), config);
|
||||
bwu_manager->MakeSingleThreadedForTesting();
|
||||
|
||||
ConnectionOptions options;
|
||||
options.allowed.wifi_direct = true;
|
||||
client.OnConnectionInitiated(
|
||||
std::string(kEndpointId1),
|
||||
{.remote_endpoint_info = ByteArray("remote endpoint")}, options, {},
|
||||
"");
|
||||
client.OnConnectionAccepted(std::string(kEndpointId1));
|
||||
ecm.RegisterChannelForEndpoint(
|
||||
&client, std::string(kEndpointId1),
|
||||
std::make_unique<FakeEndpointChannel>(Medium::BLUETOOTH,
|
||||
std::string(kServiceIdA)));
|
||||
|
||||
bwu_manager->InitiateBwuForEndpoint(&client, std::string(kEndpointId1),
|
||||
Medium::WIFI_DIRECT);
|
||||
|
||||
EXPECT_TRUE(fake_wifi_direct_ptr->handle_initialize_calls().empty());
|
||||
ecm.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
SafeDisconnectionResult::kSafeDisconnection);
|
||||
bwu_manager->Shutdown();
|
||||
}
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirectGcOnly,
|
||||
false);
|
||||
}
|
||||
|
||||
TEST(BwuManagerBaseTest, GcOnlyAcceptsPeerOfferedWifiDirectPath) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableWifiDirect,
|
||||
true);
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirectGcOnly,
|
||||
true);
|
||||
{
|
||||
ClientProxy client;
|
||||
EndpointChannelManager ecm;
|
||||
EndpointManager em(&ecm);
|
||||
Mediums mediums;
|
||||
auto fake_wifi_direct =
|
||||
std::make_unique<FakeBwuHandler>(Medium::WIFI_DIRECT);
|
||||
FakeBwuHandler* fake_wifi_direct_ptr = fake_wifi_direct.get();
|
||||
absl::flat_hash_map<Medium, std::unique_ptr<BwuHandler>> handlers;
|
||||
handlers.emplace(Medium::WIFI_DIRECT, std::move(fake_wifi_direct));
|
||||
BwuManager::Config config;
|
||||
config.allow_upgrade_to.wifi_direct = true;
|
||||
auto bwu_manager = std::make_unique<BwuManager>(
|
||||
mediums, em, ecm, std::move(handlers), config);
|
||||
bwu_manager->MakeSingleThreadedForTesting();
|
||||
|
||||
ConnectionResponseInfo response_info{
|
||||
.remote_endpoint_info = ByteArray("remote endpoint"),
|
||||
.is_incoming_connection = true,
|
||||
};
|
||||
client.OnConnectionInitiated(std::string(kEndpointId1), response_info, {},
|
||||
{}, "");
|
||||
client.OnConnectionAccepted(std::string(kEndpointId1));
|
||||
ecm.RegisterChannelForEndpoint(
|
||||
&client, std::string(kEndpointId1),
|
||||
std::make_unique<FakeEndpointChannel>(Medium::BLUETOOTH,
|
||||
std::string(kServiceIdA)));
|
||||
|
||||
ExceptionOr<OfflineFrame> path_available =
|
||||
parser::FromBytes(parser::ForBwuWifiDirectPathAvailable(
|
||||
/*ssid=*/"", /*password=*/"", /*port=*/2143,
|
||||
/*frequency=*/2412, /*supports_disabling_encryption=*/false,
|
||||
/*gateway=*/"123.234.23.1",
|
||||
/*device_name=*/"NC-WifiDirectTest", /*pin=*/"b592f7d3"));
|
||||
EXPECT_TRUE(path_available.ok());
|
||||
if (path_available.ok()) {
|
||||
bwu_manager->OnIncomingFrame(path_available.result(),
|
||||
std::string(kEndpointId1), &client,
|
||||
Medium::BLUETOOTH);
|
||||
}
|
||||
|
||||
EXPECT_EQ(fake_wifi_direct_ptr->create_calls().size(), 1u);
|
||||
ecm.UnregisterChannelForEndpoint(
|
||||
std::string(kEndpointId1), DisconnectionReason::LOCAL_DISCONNECTION,
|
||||
SafeDisconnectionResult::kSafeDisconnection);
|
||||
bwu_manager->Shutdown();
|
||||
}
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirectGcOnly,
|
||||
false);
|
||||
}
|
||||
|
||||
TEST(BwuManagerBaseTest, InitiateBwu_NeedToSwitchRole_Success) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
|
||||
@@ -77,6 +77,9 @@ constexpr auto kEnableStopBleScanningOnWifiUpgrade =
|
||||
// Enable/Disable Wi-Fi Direct in Nearby connections SDK.
|
||||
constexpr auto kEnableWifiDirect =
|
||||
flags::Flag<bool>(kConfigPackage, "45741157", false);
|
||||
// When true, Wi-Fi Direct can only operate as a Group Client.
|
||||
constexpr auto kEnableWifiDirectGcOnly =
|
||||
flags::Flag<bool>(kConfigPackage, "45741158", false);
|
||||
// by default, enable Wi-Fi Hotspot client.
|
||||
constexpr auto kEnableWifiHotspotClient =
|
||||
flags::Flag<bool>(kConfigPackage, "45648734", true);
|
||||
|
||||
@@ -14,15 +14,17 @@
|
||||
|
||||
#include "connections/implementation/mediums/wifi_direct.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "connections/implementation/bwu_handler.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/mediums/wifi_direct_bwu_handler.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/expected.h"
|
||||
#include "internal/platform/logging.h"
|
||||
@@ -36,7 +38,12 @@ namespace {
|
||||
using ::location::nearby::proto::connections::OperationResultCode;
|
||||
} // namespace
|
||||
|
||||
WifiDirect::WifiDirect() : is_go_started_(false), is_connected_to_go_(false) {
|
||||
WifiDirect::WifiDirect()
|
||||
: is_go_started_(false),
|
||||
is_connected_to_go_(false),
|
||||
is_gc_only_(NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirectGcOnly)) {
|
||||
supported_wifi_direct_auth_types_ = medium_.GetSupportedWifiDirectAuthTypes();
|
||||
if (!supported_wifi_direct_auth_types_.empty()) {
|
||||
preferred_wifi_direct_auth_type_ =
|
||||
@@ -63,6 +70,7 @@ bool WifiDirect::IsGOAvailable() const {
|
||||
}
|
||||
|
||||
bool WifiDirect::IsGOAvailableLocked() const {
|
||||
if (is_gc_only_) return false;
|
||||
if (medium_.IsValid()) return medium_.IsInterfaceValid();
|
||||
return false;
|
||||
}
|
||||
@@ -88,6 +96,10 @@ bool WifiDirect::IsGOStarted() {
|
||||
// connect
|
||||
bool WifiDirect::StartWifiDirect() {
|
||||
MutexLock lock(&mutex_);
|
||||
if (is_gc_only_) {
|
||||
LOG(INFO) << "Can't start WifiDirect GO in GC-only mode.";
|
||||
return false;
|
||||
}
|
||||
if (is_go_started_) {
|
||||
LOG(INFO) << "No need to start GO because it is already started.";
|
||||
return true;
|
||||
|
||||
@@ -53,6 +53,8 @@ class WifiDirect {
|
||||
bool IsGOAvailable() const ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
// Returns true, if WifiDirect Group Client is supported by a platform.
|
||||
bool IsGCAvailable() const ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
// Returns true if this medium is restricted to the Group Client role.
|
||||
bool IsGCONly() const { return is_gc_only_; }
|
||||
|
||||
// If WifiDirect Group Owner started
|
||||
bool IsGOStarted() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
@@ -127,6 +129,7 @@ class WifiDirect {
|
||||
|
||||
bool is_go_started_ ABSL_GUARDED_BY(mutex_);
|
||||
bool is_connected_to_go_ ABSL_GUARDED_BY(mutex_);
|
||||
const bool is_gc_only_;
|
||||
WifiDirectMedium medium_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
// A thread pool dedicated to running all the accept loops from
|
||||
|
||||
@@ -58,6 +58,10 @@ class WifiDirectTest : public testing::TestWithParam<FeatureFlags> {
|
||||
connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirect,
|
||||
true);
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirectGcOnly,
|
||||
false);
|
||||
env_.Start();
|
||||
}
|
||||
~WifiDirectTest() override { env_.Stop(); }
|
||||
@@ -72,6 +76,8 @@ TEST_F(WifiDirectTest, ConstructorDestructorWorks) {
|
||||
WifiDirect wifi_direct_a, wifi_direct_b;
|
||||
|
||||
EXPECT_NE(&wifi_direct_a, &wifi_direct_b);
|
||||
EXPECT_FALSE(wifi_direct_a.IsGCONly());
|
||||
EXPECT_FALSE(wifi_direct_b.IsGCONly());
|
||||
EXPECT_TRUE(wifi_direct_a.IsGCAvailable());
|
||||
EXPECT_TRUE(wifi_direct_b.IsGCAvailable());
|
||||
}
|
||||
@@ -91,6 +97,22 @@ TEST_F(WifiDirectTest, CanStartStopGO) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectTest, GcOnlyCannotStartGO) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirectGcOnly,
|
||||
true);
|
||||
WifiDirect wifi_direct;
|
||||
|
||||
EXPECT_TRUE(wifi_direct.IsGCONly());
|
||||
EXPECT_TRUE(wifi_direct.IsGCAvailable());
|
||||
EXPECT_FALSE(wifi_direct.IsGOAvailable());
|
||||
EXPECT_FALSE(wifi_direct.StartWifiDirect());
|
||||
EXPECT_FALSE(
|
||||
wifi_direct.StartAcceptingConnections(std::string(kServiceID), {}));
|
||||
EXPECT_FALSE(wifi_direct.IsGOStarted());
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectTest, GCCanConnectDisconnectGO) {
|
||||
WifiDirectCredentials wifi_direct_credentials;
|
||||
std::string device_name(kDeviceName);
|
||||
|
||||
@@ -64,6 +64,7 @@ cc_library(
|
||||
"linux_flags.h",
|
||||
#"log_message.h",
|
||||
"utils.h",
|
||||
"test_data.h"
|
||||
],
|
||||
copts = ["-lrt"],
|
||||
visibility = ["//third_party/nearby/sharing/internal/impl/linux:__pkg__"],
|
||||
@@ -316,7 +317,7 @@ cc_test(
|
||||
# "http_loader_test.cc",
|
||||
# "preferences_manager_test.cc",
|
||||
# "preferences_repository_test.cc",
|
||||
# "scheduled_executor_test.cc",
|
||||
"scheduled_executor_test.cc",
|
||||
# "submittable_executor_test.cc",
|
||||
# "thread_pool_test.cc",
|
||||
"timer_test.cc",
|
||||
|
||||
@@ -53,35 +53,51 @@ namespace nearby {
|
||||
namespace linux {
|
||||
|
||||
namespace {
|
||||
using nearby::connections::config_package_nearby::nearby_connections_feature::kRefactorBleL2cap;
|
||||
using nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kRefactorBleL2cap;
|
||||
|
||||
} // namespace
|
||||
BleV2Medium::~BleV2Medium() {
|
||||
|
||||
BleV2Medium::BleV2Medium(BluetoothAdapter &adapter)
|
||||
: system_bus_(adapter.GetConnection()),
|
||||
adapter_(adapter),
|
||||
observers_(std::make_shared<ObserverList<api::BluetoothClassicMedium::Observer>>()),
|
||||
devices_(std::make_unique<BluetoothDevices>(
|
||||
system_bus_, adapter_.GetObjectPath(), *observers_)),
|
||||
gatt_discovery_(std::make_shared<BluezGattDiscovery>(system_bus_)),
|
||||
root_object_manager_(std::make_unique<RootObjectManager>(*system_bus_, sdbus::ObjectPath("/com/google/nearby/medium/ble/advertisement/monitor"))),
|
||||
adv_monitor_manager_(
|
||||
bluez::AdvertisementMonitorManager::
|
||||
DiscoverAdvertisementMonitorManager(*system_bus_, adapter_)),
|
||||
adv_manager_(std::make_unique<bluez::LEAdvertisementManager>(*system_bus_,
|
||||
adapter)),
|
||||
cur_adv_(nullptr) {
|
||||
LOG(INFO) << __func__ << ": BleV2Medium cleanup ";
|
||||
try {
|
||||
StopAdvertising();
|
||||
} catch (const std::exception& error) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": Failed to stop advertising: " <<
|
||||
error.what();
|
||||
}
|
||||
}
|
||||
|
||||
BleV2Medium::BleV2Medium(BluetoothAdapter& adapter)
|
||||
: system_bus_(adapter.GetConnection()),
|
||||
adapter_(adapter),
|
||||
observers_(std::make_shared<
|
||||
ObserverList<api::BluetoothClassicMedium::Observer>>()),
|
||||
devices_(std::make_unique<BluetoothDevices>(
|
||||
system_bus_, adapter_.GetObjectPath(), *observers_)),
|
||||
gatt_discovery_(std::make_shared<BluezGattDiscovery>(system_bus_)),
|
||||
root_object_manager_(std::make_unique<RootObjectManager>(
|
||||
*system_bus_,
|
||||
sdbus::ObjectPath(
|
||||
"/com/google/nearby/medium/ble/advertisement/monitor"))),
|
||||
adv_monitor_manager_(
|
||||
bluez::AdvertisementMonitorManager::
|
||||
DiscoverAdvertisementMonitorManager(*system_bus_, adapter_)),
|
||||
adv_manager_(std::make_unique<bluez::LEAdvertisementManager>(*system_bus_,
|
||||
adapter)),
|
||||
cur_adv_(nullptr) {
|
||||
if (!gatt_discovery_->InitializeKnownServices()) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": Failed to initialize known GATT services cache.";
|
||||
}
|
||||
|
||||
|
||||
if (adv_monitor_manager_) {
|
||||
LOG(INFO)
|
||||
<< __func__
|
||||
<< ": Registering path /com/google/nearby/medium/ble/advertisement/monitor with AdvertisementMonitorManager at "
|
||||
<< adv_monitor_manager_->getProxy().getObjectPath();
|
||||
LOG(INFO) << __func__
|
||||
<< ": Registering path "
|
||||
"/com/google/nearby/medium/ble/advertisement/monitor with "
|
||||
"AdvertisementMonitorManager at "
|
||||
<< adv_monitor_manager_->getProxy().getObjectPath();
|
||||
adv_monitor_manager_->SetRegisterMonitorReplyCallback(
|
||||
[this](std::optional<sdbus::Error> error) {
|
||||
OnRegisterMonitorReply(std::move(error));
|
||||
@@ -126,67 +142,70 @@ bool BleV2Medium::WaitForAdvertisementMonitorManager() {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG(WARNING) << __func__
|
||||
<< ": AdvertisementMonitorManager registration failed with name '"
|
||||
<< adv_monitor_manager_error_name_ << "' and message '"
|
||||
<< adv_monitor_manager_error_message_ << "'";
|
||||
LOG(WARNING)
|
||||
<< __func__
|
||||
<< ": AdvertisementMonitorManager registration failed with name '"
|
||||
<< adv_monitor_manager_error_name_ << "' and message '"
|
||||
<< adv_monitor_manager_error_message_ << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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(
|
||||
const api::ble::BleAdvertisementData &advertising_data,
|
||||
// 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(
|
||||
const api::ble::BleAdvertisementData& advertising_data,
|
||||
api::ble::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 "
|
||||
"bluetooth adapter is not enabled.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (advertising_data.service_data.empty()) {
|
||||
LOG(WARNING)
|
||||
<< "BLE cannot start to advertise due to invalid service data.";
|
||||
return false;
|
||||
}
|
||||
|
||||
absl::MutexLock l (&advs_mutex_);
|
||||
advs_.push_front(bluez::LEAdvertisement::CreateLEAdvertisement(
|
||||
*system_bus_, advertising_data, advertise_set_parameters));
|
||||
auto it = advs_.begin();
|
||||
|
||||
|
||||
LOG(INFO) << __func__ << ": Registering advertisement, is_extended: " << advertising_data.is_extended_advertisement
|
||||
<< " " << (*it) -> getObject().getObjectPath() << " on bluetooth adapter "
|
||||
<< adapter_.GetObjectPath();
|
||||
|
||||
try {
|
||||
adv_manager_->RegisterAdvertisementSync((*it)->getObject().getObjectPath(), {});
|
||||
} catch (const sdbus::Error &e) {
|
||||
advs_.erase(it);
|
||||
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisementSync", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
// 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;
|
||||
}
|
||||
|
||||
//async api
|
||||
// runs with nearby presence
|
||||
if (advertising_data.service_data.empty()) {
|
||||
LOG(WARNING)
|
||||
<< "BLE cannot start to advertise due to invalid service data.";
|
||||
return false;
|
||||
}
|
||||
|
||||
absl::MutexLock l(&advs_mutex_);
|
||||
advs_.push_front(bluez::LEAdvertisement::CreateLEAdvertisement(
|
||||
*system_bus_, advertising_data, advertise_set_parameters));
|
||||
auto it = advs_.begin();
|
||||
|
||||
LOG(INFO) << __func__ << ": Registering advertisement, is_extended: "
|
||||
<< advertising_data.is_extended_advertisement << " "
|
||||
<< (*it)->getObject().getObjectPath() << " on bluetooth adapter "
|
||||
<< adapter_.GetObjectPath();
|
||||
|
||||
try {
|
||||
adv_manager_->RegisterAdvertisementSync((*it)->getObject().getObjectPath(),
|
||||
{});
|
||||
} catch (const sdbus::Error& e) {
|
||||
advs_.erase(it);
|
||||
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisementSync", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// async api
|
||||
// runs with nearby presence
|
||||
std::unique_ptr<api::ble::BleMedium::AdvertisingSession>
|
||||
BleV2Medium::StartAdvertising(
|
||||
const api::ble::BleAdvertisementData &advertising_data,
|
||||
api::ble::AdvertiseParameters advertise_set_parameters,
|
||||
AdvertisingCallback callback) {
|
||||
const api::ble::BleAdvertisementData& advertising_data,
|
||||
api::ble::AdvertiseParameters advertise_set_parameters,
|
||||
AdvertisingCallback callback) {
|
||||
if (!adapter_.IsEnabled()) {
|
||||
LOG(WARNING) << ": BLE cannot start advertising because the "
|
||||
"bluetooth adapter is not enabled.";
|
||||
"bluetooth adapter is not enabled.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -197,19 +216,20 @@ BleV2Medium::StartAdvertising(
|
||||
}
|
||||
|
||||
std::shared_ptr<AdvertisingCallback> shared_cb =
|
||||
std::make_shared<AdvertisingCallback>(std::move(callback));
|
||||
std::make_shared<AdvertisingCallback>(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();
|
||||
|
||||
// Keep async API surface, but register using the same typed DBus path as the
|
||||
// working sync implementation to avoid signature mismatch (oa{sv} vs sa{sv}).
|
||||
try {
|
||||
adv_manager_->RegisterAdvertisementSync((*adv_it)->getObject().getObjectPath(), {});
|
||||
adv_manager_->RegisterAdvertisementSync(
|
||||
(*adv_it)->getObject().getObjectPath(), {});
|
||||
shared_cb->start_advertising_result(absl::OkStatus());
|
||||
} catch (const sdbus::Error &e) {
|
||||
} catch (const sdbus::Error& e) {
|
||||
advs_.erase(adv_it);
|
||||
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisementSync", e);
|
||||
auto name = e.getName();
|
||||
@@ -231,44 +251,46 @@ BleV2Medium::StartAdvertising(
|
||||
|
||||
absl::AnyInvocable<absl::Status()> stop_adv = [&, adv_it]() {
|
||||
LOG(INFO) << __func__ << ": Unregistering advertisement object "
|
||||
<< (*adv_it)->getObject().getObjectPath();
|
||||
<< (*adv_it)->getObject().getObjectPath();
|
||||
absl::MutexLock lock(&advs_mutex_);
|
||||
try {
|
||||
adv_manager_->UnregisterAdvertisementSync((*adv_it)->getObject().getObjectPath());
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisementSync", e);
|
||||
adv_manager_->UnregisterAdvertisementSync(
|
||||
(*adv_it)->getObject().getObjectPath());
|
||||
} catch (const sdbus::Error& e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisementSync",
|
||||
e);
|
||||
return absl::UnknownError(e.getMessage());
|
||||
}
|
||||
advs_.erase(adv_it);
|
||||
return absl::OkStatus();
|
||||
};
|
||||
return std::make_unique<api::ble::BleMedium::AdvertisingSession>(
|
||||
api::ble::BleMedium::AdvertisingSession{std::move(stop_adv)});
|
||||
api::ble::BleMedium::AdvertisingSession{std::move(stop_adv)});
|
||||
}
|
||||
|
||||
bool BleV2Medium::StopAdvertising() {
|
||||
absl::MutexLock l(&advs_mutex_);
|
||||
try {
|
||||
for (auto& adv: advs_)
|
||||
{
|
||||
adv_manager_->UnregisterAdvertisementSync(adv->getObject().getObjectPath());
|
||||
}
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisementSync", e);
|
||||
return false;
|
||||
bool BleV2Medium::StopAdvertising() {
|
||||
LOG(INFO) << __func__ << ": Stop advertising called";
|
||||
absl::MutexLock l(&advs_mutex_);
|
||||
try {
|
||||
for (auto& adv : advs_) {
|
||||
adv_manager_->UnregisterAdvertisementSync(
|
||||
adv->getObject().getObjectPath());
|
||||
}
|
||||
|
||||
advs_.clear();
|
||||
return true;
|
||||
} catch (const sdbus::Error& e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisementSync", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BleV2Medium::StartScanning(const Uuid &service_uuid,
|
||||
advs_.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BleV2Medium::StartScanning(const Uuid& service_uuid,
|
||||
api::ble::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_};
|
||||
LOG(ERROR) << __func__ << ": A sync scanning session is already active for "
|
||||
<< std::string{*cur_monitored_service_uuid_};
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -288,59 +310,58 @@ bool BleV2Medium::StartScanning(const Uuid &service_uuid,
|
||||
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";
|
||||
<< std::string{service_uuid} << " already exists";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto monitor = std::make_unique<bluez::AdvertisementMonitor>(
|
||||
*system_bus_, service_uuid, tx_power_level, "or_patterns", devices_,
|
||||
std::move(callback));
|
||||
*system_bus_, service_uuid, tx_power_level, "or_patterns", devices_,
|
||||
std::move(callback));
|
||||
try {
|
||||
// why is this emitted?
|
||||
monitor->emitInterfacesAddedSignal(
|
||||
{sdbus::InterfaceName(org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
monitor->emitInterfacesAddedSignal({sdbus::InterfaceName(
|
||||
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
|
||||
// adv_monitor_manager_ -> RegisterMonitor(monitor -> getObject().getObjectPath());
|
||||
LOG(INFO)<< __func__ << ": Registered advertisement monitor with path " << monitor -> getObject().getObjectPath();
|
||||
} catch (const sdbus::Error &e) {
|
||||
LOG(ERROR)
|
||||
<< __func__
|
||||
<< ": error emitting InterfacesAdded signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '" << e.getName()
|
||||
<< "' and message '" << e.getMessage() << "'";
|
||||
// adv_monitor_manager_ -> RegisterMonitor(monitor ->
|
||||
// getObject().getObjectPath());
|
||||
LOG(INFO) << __func__ << ": Registered advertisement monitor with path "
|
||||
<< monitor->getObject().getObjectPath();
|
||||
} catch (const sdbus::Error& e) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": error emitting InterfacesAdded signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '"
|
||||
<< e.getName() << "' and message '" << e.getMessage() << "'";
|
||||
return false;
|
||||
}
|
||||
auto device_watcher = std::make_unique<DeviceWatcher>(
|
||||
*system_bus_, adapter_.GetObjectPath(), adapter_, devices_);
|
||||
*system_bus_, adapter_.GetObjectPath(), adapter_, devices_);
|
||||
if (!StartLEDiscovery()) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": Could not start LE discovery on adapter "
|
||||
<< adapter_.GetObjectPath();
|
||||
LOG(ERROR) << __func__ << ": Could not start LE discovery on adapter "
|
||||
<< adapter_.GetObjectPath();
|
||||
device_watcher = nullptr;
|
||||
try {
|
||||
monitor->emitInterfacesRemovedSignal(
|
||||
{sdbus::InterfaceName(org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error &e) {
|
||||
LOG(ERROR)
|
||||
<< __func__
|
||||
<< ": error emitting InterfacesRemoved signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '" << e.getName()
|
||||
<< "' and message '" << e.getMessage() << "'";
|
||||
monitor->emitInterfacesRemovedSignal({sdbus::InterfaceName(
|
||||
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error& e) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": error emitting InterfacesRemoved signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '"
|
||||
<< e.getName() << "' and message '" << e.getMessage() << "'";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
LOG(INFO) << __func__ << " :Started monitoring for service UUID: " << std::string(service_uuid);
|
||||
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));
|
||||
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.";
|
||||
LOG(ERROR) << __func__ << ": No sync scanning session is currently active.";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -349,12 +370,13 @@ bool BleV2Medium::StopScanning() {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &adapter = adapter_.GetBluezAdapterObject();
|
||||
auto& adapter = adapter_.GetBluezAdapterObject();
|
||||
LOG(INFO) << __func__ << ": Stopping discovery for adapter "
|
||||
<< adapter.getProxy().getObjectPath();
|
||||
<< adapter.getProxy().getObjectPath();
|
||||
try {
|
||||
adapter.StopDiscovery(); // this will stop bluetooth classic discovery as well. do we want this?
|
||||
} catch (const sdbus::Error &e) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -362,120 +384,116 @@ bool BleV2Medium::StopScanning() {
|
||||
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;
|
||||
auto& [_uuid, session] = *monitor_it;
|
||||
auto& [adv_monitor, _watcher] = session;
|
||||
|
||||
LOG(INFO) << __func__ << ": Removing advertising monitor "
|
||||
<< adv_monitor->getObject().getObjectPath();
|
||||
adv_monitor->emitInterfacesRemovedSignal(
|
||||
{sdbus::InterfaceName(org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
<< adv_monitor->getObject().getObjectPath();
|
||||
adv_monitor->emitInterfacesRemovedSignal({sdbus::InterfaceName(
|
||||
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
}
|
||||
active_adv_monitors_.erase(monitor_it);
|
||||
cur_monitored_service_uuid_ = std::nullopt;
|
||||
|
||||
return true;
|
||||
}
|
||||
std::unique_ptr<api::ble::BleMedium::ScanningSession>
|
||||
BleV2Medium::StartScanning(const Uuid &service_uuid,
|
||||
api::ble::TxPowerLevel tx_power_level,
|
||||
ScanningCallback callback) {
|
||||
if (!WaitForAdvertisementMonitorManager()) {
|
||||
// TODO: Implement manual monitoring.
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<api::ble::BleMedium::ScanningSession>
|
||||
BleV2Medium::StartScanning(const Uuid& service_uuid,
|
||||
api::ble::TxPowerLevel tx_power_level,
|
||||
ScanningCallback callback) {
|
||||
if (!WaitForAdvertisementMonitorManager()) {
|
||||
// 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;
|
||||
}
|
||||
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<bluez::AdvertisementMonitor>(
|
||||
auto monitor = std::make_unique<bluez::AdvertisementMonitor>(
|
||||
*system_bus_, service_uuid, tx_power_level, "or_patterns", devices_,
|
||||
std::move(callback));
|
||||
try {
|
||||
monitor->emitInterfacesAddedSignal({sdbus::InterfaceName(
|
||||
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error& e) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": error emitting InterfacesAdded signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '"
|
||||
<< e.getName() << "' and message '" << e.getMessage() << "'";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto device_watcher = std::make_unique<DeviceWatcher>(
|
||||
*system_bus_, adapter_.GetObjectPath(), adapter_, devices_);
|
||||
if (!StartLEDiscovery()) {
|
||||
LOG(ERROR) << __func__ << ": Could not start LE discovery on adapter "
|
||||
<< adapter_.GetObjectPath();
|
||||
try {
|
||||
monitor->emitInterfacesAddedSignal(
|
||||
{sdbus::InterfaceName(org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error &e) {
|
||||
LOG(ERROR)
|
||||
<< __func__
|
||||
<< ": error emitting InterfacesAdded signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '" << e.getName()
|
||||
<< "' and message '" << e.getMessage() << "'";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto device_watcher = std::make_unique<DeviceWatcher>(
|
||||
*system_bus_, adapter_.GetObjectPath(),adapter_, devices_);
|
||||
if (!StartLEDiscovery()) {
|
||||
monitor->emitInterfacesRemovedSignal({sdbus::InterfaceName(
|
||||
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error& e) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": Could not start LE discovery on adapter "
|
||||
<< adapter_.GetObjectPath();
|
||||
try {
|
||||
monitor->emitInterfacesRemovedSignal(
|
||||
{sdbus::InterfaceName(org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error &e) {
|
||||
LOG(ERROR)
|
||||
<< __func__
|
||||
<< ": error emitting InterfacesRemoved signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '" << e.getName()
|
||||
<< "' and message '" << e.getMessage() << "'";
|
||||
}
|
||||
return nullptr;
|
||||
<< ": error emitting InterfacesRemoved signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '"
|
||||
<< e.getName() << "' and message '" << e.getMessage() << "'";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
active_adv_monitors_[service_uuid] =
|
||||
active_adv_monitors_[service_uuid] =
|
||||
std::make_pair(std::move(monitor), std::move(device_watcher));
|
||||
|
||||
return std::make_unique<ScanningSession>(
|
||||
return std::make_unique<ScanningSession>(
|
||||
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";
|
||||
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");
|
||||
"Advertising monitor for this service does not exist");
|
||||
}
|
||||
|
||||
auto &[monitor, watcher] = active_adv_monitors_[service_uuid];
|
||||
auto& [monitor, watcher] = active_adv_monitors_[service_uuid];
|
||||
try {
|
||||
monitor->emitInterfacesRemovedSignal(
|
||||
{sdbus::InterfaceName(org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error &e) {
|
||||
monitor->emitInterfacesRemovedSignal({sdbus::InterfaceName(
|
||||
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME)});
|
||||
} catch (const sdbus::Error& e) {
|
||||
LOG(ERROR)
|
||||
<< __func__
|
||||
<< ": error emitting InterfacesRemoved signal for object path "
|
||||
<< monitor->getObject().getObjectPath() << " with name '" << e.getName()
|
||||
<< "' and message '" << e.getMessage() << "'";
|
||||
<< monitor->getObject().getObjectPath() << " with name '"
|
||||
<< e.getName() << "' and message '" << e.getMessage() << "'";
|
||||
}
|
||||
|
||||
auto &adapter = adapter_.GetBluezAdapterObject();
|
||||
auto& adapter = adapter_.GetBluezAdapterObject();
|
||||
absl::Status status;
|
||||
try {
|
||||
adapter.StopDiscovery();
|
||||
status = absl::OkStatus();
|
||||
} catch (const sdbus::Error &e) {
|
||||
} 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<api::ble::GattServer> BleV2Medium::StartGattServer(
|
||||
api::ble::ServerGattConnectionCallback callback) {
|
||||
api::ble::ServerGattConnectionCallback callback) {
|
||||
LOG(INFO) << __func__ << ": Starting Linux GATT server.";
|
||||
return std::make_unique<GattServer>(*system_bus_, adapter_, devices_,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble::GattClient> BleV2Medium::ConnectToGattServer(
|
||||
api::ble::BlePeripheral::UniqueId peripheral_id,
|
||||
api::ble::TxPowerLevel tx_power_level,
|
||||
api::ble::ClientGattConnectionCallback callback) {
|
||||
api::ble::BlePeripheral::UniqueId peripheral_id,
|
||||
api::ble::TxPowerLevel tx_power_level,
|
||||
api::ble::ClientGattConnectionCallback callback) {
|
||||
auto device = devices_->get_device_by_unique_id(peripheral_id);
|
||||
if (!device) {
|
||||
LOG(ERROR) << __func__ << ": Failed to find device with unique ID "
|
||||
@@ -495,29 +513,29 @@ std::unique_ptr<api::ble::GattClient> BleV2Medium::ConnectToGattServer(
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble::BleServerSocket> BleV2Medium::OpenServerSocket(
|
||||
const std::string &service_id) {
|
||||
const std::string& service_id) {
|
||||
LOG(INFO) << __func__ << ": Opening BLE server socket for service "
|
||||
<< service_id;
|
||||
return std::make_unique<BleV2ServerSocket>(service_id);
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble::BleL2capServerSocket>
|
||||
BleV2Medium::OpenL2capServerSocket(const std::string &service_id) {
|
||||
BleV2Medium::OpenL2capServerSocket(const std::string& service_id) {
|
||||
// return nullptr;
|
||||
LOG(INFO) << __func__ << ": Opening L2CAP server socket for service "
|
||||
<< service_id;
|
||||
|
||||
auto server_socket = std::make_unique<linux::BleL2capServerSocket>(
|
||||
psm_, service_id);
|
||||
auto server_socket =
|
||||
std::make_unique<linux::BleL2capServerSocket>(psm_, service_id);
|
||||
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
// This is supposed to be for a socket on top of Weave protocol.
|
||||
std::unique_ptr<api::ble::BleSocket> BleV2Medium::Connect(
|
||||
const std::string &service_id, api::ble::TxPowerLevel tx_power_level,
|
||||
api::ble::BlePeripheral::UniqueId peripheral_id,
|
||||
CancellationFlag *cancellation_flag) {
|
||||
const std::string& service_id, api::ble::TxPowerLevel tx_power_level,
|
||||
api::ble::BlePeripheral::UniqueId peripheral_id,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
LOG(INFO) << __func__ << ": Not implemented on linux ";
|
||||
return nullptr;
|
||||
}
|
||||
@@ -526,7 +544,7 @@ bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
|
||||
try {
|
||||
auto supported_channels = adv_manager_->SupportedSecondaryChannels();
|
||||
return !supported_channels.empty();
|
||||
} catch (const sdbus::Error &e) {
|
||||
} catch (const sdbus::Error& e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(adv_manager_, "SupportedSecondaryChannels", e);
|
||||
return false;
|
||||
}
|
||||
@@ -536,20 +554,20 @@ bool BleV2Medium::StartLEDiscovery() {
|
||||
std::map<std::string, sdbus::Variant> filter;
|
||||
filter["Transport"] = sdbus::Variant("auto");
|
||||
filter["DuplicateData"] = sdbus::Variant(true);
|
||||
auto &adapter = adapter_.GetBluezAdapterObject();
|
||||
auto& adapter = adapter_.GetBluezAdapterObject();
|
||||
|
||||
try {
|
||||
adapter.SetDiscoveryFilter(filter);
|
||||
} catch (const sdbus::Error &e) {
|
||||
} catch (const sdbus::Error& e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(&adapter, "SetDiscoveryFilter", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
LOG(INFO) << __func__ << ": Starting LE discovery on "
|
||||
<< adapter.getProxy().getObjectPath();
|
||||
<< adapter.getProxy().getObjectPath();
|
||||
adapter.StartDiscovery();
|
||||
} catch (const sdbus::Error &e) {
|
||||
} catch (const sdbus::Error& e) {
|
||||
if (e.getName() != "org.bluez.Error.InProgress") {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StartDiscovery", e);
|
||||
return false;
|
||||
@@ -563,15 +581,15 @@ bool BleV2Medium::StartLEDiscovery() {
|
||||
// const std::string &service_id, api::ble::TxPowerLevel tx_power_level,
|
||||
// api::ble::BlePeripheral &peripheral,
|
||||
// CancellationFlag *cancellation_flag) {
|
||||
// LOG(WARNING) << __func__ << ": BLE socket connections not implemented on Linux";
|
||||
// return nullptr;
|
||||
// LOG(WARNING) << __func__ << ": BLE socket connections not implemented on
|
||||
// Linux"; return nullptr;
|
||||
// }
|
||||
|
||||
std::unique_ptr<api::ble::BleL2capSocket> BleV2Medium::ConnectOverL2cap(
|
||||
int psm, const std::string &service_id,
|
||||
int psm, const std::string& service_id,
|
||||
api::ble::TxPowerLevel tx_power_level,
|
||||
api::ble::BlePeripheral::UniqueId peripheral_id,
|
||||
CancellationFlag *cancellation_flag) {
|
||||
CancellationFlag* cancellation_flag) {
|
||||
// return nullptr;
|
||||
auto device = devices_->get_device_by_unique_id(peripheral_id);
|
||||
if (!device) {
|
||||
@@ -580,40 +598,39 @@ std::unique_ptr<api::ble::BleL2capSocket> BleV2Medium::ConnectOverL2cap(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Connecting to L2CAP PSM " << psm
|
||||
<< " on device " << device->GetMacAddress().ToString();
|
||||
|
||||
LOG(INFO) << __func__ << ": Connecting to L2CAP PSM " << psm << " on device "
|
||||
<< device->GetMacAddress().ToString();
|
||||
|
||||
int fd = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
|
||||
if (fd < 0) {
|
||||
LOG(ERROR) << __func__ << ": Failed to create L2CAP socket: "
|
||||
<< std::strerror(errno);
|
||||
LOG(ERROR) << __func__
|
||||
<< ": Failed to create L2CAP socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Set receive MTU before connect (for LE CoC)
|
||||
|
||||
|
||||
struct sockaddr_l2 addr;
|
||||
std::memset(&addr, 0, sizeof(addr));
|
||||
addr.l2_family = AF_BLUETOOTH;
|
||||
addr.l2_psm = htobs(psm);
|
||||
if (device -> GetAddressType() == "random") {
|
||||
if (device->GetAddressType() == "random") {
|
||||
addr.l2_bdaddr_type = BDADDR_LE_RANDOM;
|
||||
}else {
|
||||
} else {
|
||||
addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
|
||||
}
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
LOG(INFO) << "Failed to bind L2CAP socket";
|
||||
}
|
||||
|
||||
struct l2cap_options opts;
|
||||
opts.omtu = 0;
|
||||
opts.imtu = 672;
|
||||
if (setsockopt(fd, SOL_BLUETOOTH, BT_RCVMTU, &opts.imtu, sizeof(opts.imtu)) < 0) {
|
||||
LOG(WARNING) << __func__ << ": Failed to set BT_RCVMTU: "
|
||||
<< std::strerror(errno);
|
||||
if (setsockopt(fd, SOL_BLUETOOTH, BT_RCVMTU, &opts.imtu, sizeof(opts.imtu)) <
|
||||
0) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": Failed to set BT_RCVMTU: " << std::strerror(errno);
|
||||
}
|
||||
std::string mac_addr = device->GetMacAddress().ToString();
|
||||
if (str2ba(mac_addr.c_str(), &addr.l2_bdaddr) < 0) {
|
||||
@@ -630,13 +647,12 @@ std::unique_ptr<api::ble::BleL2capSocket> BleV2Medium::ConnectOverL2cap(
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Successfully connected to L2CAP socket";
|
||||
auto socket = std::make_unique<BleL2capSocket>(
|
||||
fd, peripheral_id, service_id);
|
||||
auto socket = std::make_unique<BleL2capSocket>(fd, peripheral_id, service_id);
|
||||
return socket;
|
||||
}
|
||||
|
||||
bool BleV2Medium::StartMultipleServicesScanning(
|
||||
const std::vector<Uuid> &service_uuids,
|
||||
const std::vector<Uuid>& service_uuids,
|
||||
api::ble::TxPowerLevel tx_power_level, ScanCallback callback) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": Multiple services scanning not implemented on Linux. "
|
||||
@@ -645,24 +661,27 @@ bool BleV2Medium::StartMultipleServicesScanning(
|
||||
}
|
||||
|
||||
bool BleV2Medium::PauseMediumScanning() {
|
||||
LOG(INFO) << __func__ << ": Pause scanning not implemented, returning success";
|
||||
LOG(INFO) << __func__
|
||||
<< ": Pause scanning not implemented, returning success";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BleV2Medium::ResumeMediumScanning() {
|
||||
LOG(INFO) << __func__ << ": Resume scanning not implemented, returning success";
|
||||
LOG(INFO) << __func__
|
||||
<< ": Resume scanning not implemented, returning success";
|
||||
return true;
|
||||
}
|
||||
|
||||
void BleV2Medium::AddAlternateUuidForService(uint16_t uuid,
|
||||
const std::string &service_id) {
|
||||
LOG(INFO) << __func__ << ": Alternate UUID mapping not implemented. UUID: "
|
||||
<< uuid << ", service_id: " << service_id;
|
||||
const std::string& service_id) {
|
||||
LOG(INFO) << __func__
|
||||
<< ": Alternate UUID mapping not implemented. UUID: " << uuid
|
||||
<< ", service_id: " << service_id;
|
||||
}
|
||||
|
||||
std::optional<api::ble::BlePeripheral::UniqueId>
|
||||
BleV2Medium::RetrieveBlePeripheralIdFromNativeId(
|
||||
const std::string &ble_peripheral_native_id) {
|
||||
const std::string& ble_peripheral_native_id) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": Retrieval from native ID not implemented. Native ID: "
|
||||
<< ble_peripheral_native_id;
|
||||
|
||||
@@ -50,7 +50,7 @@ class BleV2Medium final : public api::ble::BleMedium {
|
||||
BleV2Medium &operator=(BleV2Medium &&) = delete;
|
||||
|
||||
explicit BleV2Medium(BluetoothAdapter &adapter);
|
||||
~BleV2Medium() override = default;
|
||||
~BleV2Medium() override;
|
||||
|
||||
bool StartAdvertising(
|
||||
const api::ble::BleAdvertisementData &advertising_data,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define PLATFORM_IMPL_LINUX_API_BLUEZ_BLE_ADVERTISEMENT_H_
|
||||
|
||||
#include <future>
|
||||
#include <absl/log/log.h>
|
||||
#include <sdbus-c++/AdaptorInterfaces.h>
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/ProxyInterfaces.h>
|
||||
@@ -54,7 +55,9 @@ class LEAdvertisement final
|
||||
return std::make_unique<LEAdvertisement>(
|
||||
system_bus, object_path, advertising_data, advertising_parameters);
|
||||
}
|
||||
~LEAdvertisement() { unregisterAdaptor(); }
|
||||
~LEAdvertisement() {
|
||||
LOG(INFO) << __func__ << "Unregistering advertisement adaptor";
|
||||
unregisterAdaptor(); }
|
||||
|
||||
private:
|
||||
// Methods
|
||||
|
||||
Reference in New Issue
Block a user