bugfixes and fixes to race conditions. bluetooth advertising only / discovery only works now. linux -> android conn. initiation works. android -> linux doesnt work. android doesn't seem to recognise linux. linux <-> linux works. but each devices have to be in discover/advert modes. can't be both

This commit is contained in:
kidfromjupiter
2026-01-02 12:29:54 +00:00
parent 8f6086345d
commit dd21d80dc8
10 changed files with 183 additions and 137 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ cc_library(
hdrs = glob([
"include/nlohmann/**/*.hpp",
]),
includes = ["include"],
strip_include_prefix = "include",
visibility = ["//visibility:public"],
alwayslink = True,
)""",
+25 -24
View File
@@ -79,22 +79,22 @@ cc_library(
# "bluez_gatt_service_server.h",
# "bluez_le_advertisement.h",
"dbus.h",
"network_manager.h",
"network_manager_active_connection.h",
"network_manager_access_point.h",
# "network_manager.h",
# "network_manager_active_connection.h",
# "network_manager_access_point.h",
"stream.h",
"tcp_server_socket.h",
"wifi_direct.h",
"wifi_direct_server_socket.h",
"wifi_direct_socket.h",
"wifi_hotspot.h",
"wifi_hotspot_server_socket.h",
"wifi_hotspot_socket.h",
"wifi_lan.h",
"wifi_lan_server_socket.h",
"wifi_lan_socket.h",
"wifi_medium.h",
"wifi_socket.h",
# "tcp_server_socket.h",
# "wifi_direct.h",
# "wifi_direct_server_socket.h",
# "wifi_direct_socket.h",
# "wifi_hotspot.h",
# "wifi_hotspot_server_socket.h",
# "wifi_hotspot_socket.h",
# "wifi_lan.h",
# "wifi_lan_server_socket.h",
# "wifi_lan_socket.h",
# "wifi_medium.h",
# "wifi_socket.h",
],
deps = [
"//internal/platform:base",
@@ -157,8 +157,8 @@ cc_library(
# "bluez_le_advertisement.cc",
"dbus.cc",
"executor.cc",
"network_manager.cc",
"network_manager_active_connection.cc",
# "network_manager.cc",
# "network_manager_active_connection.cc",
"platform.cc",
"preferences_manager.cc",
"preferences_repository.cc",
@@ -168,14 +168,15 @@ cc_library(
"system_clock.cc",
"thread_pool.cc",
"utils.cc",
"wifi_direct.cc",
"wifi_direct_server_socket.cc",
"wifi_hotspot.cc",
"wifi_hotspot_server_socket.cc",
"wifi_lan.cc",
"wifi_lan_server_socket.cc",
"wifi_medium.cc",
# "wifi_direct.cc",
# "wifi_direct_server_socket.cc",
# "wifi_hotspot.cc",
# "wifi_hotspot_server_socket.cc",
# "wifi_lan.cc",
# "wifi_lan_server_socket.cc",
# "wifi_medium.cc",
],
linkopts = ["-lcurl"],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
@@ -33,6 +33,7 @@
#include "internal/platform/implementation/linux/bluetooth_devices.h"
#include "internal/platform/implementation/linux/bluez.h"
#include "internal/platform/logging.h"
#include "absl/strings/str_cat.h"
namespace nearby {
namespace linux {
@@ -70,12 +71,20 @@ void Profile::NewConnection(
auto alias = device->GetName();
auto mac_addr = device->GetAddress();
LOG(INFO) << __func__ << ": " << getObjectPath()
<< ": Connected to " << mac_addr;
<< ": Connected to " << mac_addr.ToString();
FDProperties props(fd_props);
absl::MutexLock l(&connections_lock_);
connections_[mac_addr].push_back(std::pair(fd, props));
LOG(INFO) << "PUSH key(GetAddress.ToString)=" << mac_addr.ToString()
<< " alias=" << alias;
LOG(INFO) << "PUSH_ENTER profile=" << this
<< " mutex=" << &connections_lock_
<< " obj=" << getObjectPath()
<< " path=" << device_object_path;
{
absl::MutexLock l(&connections_lock_);
connections_[mac_addr.ToString()].push_back(std::pair(fd, props));
}
}
void Profile::RequestDisconnection(
@@ -100,7 +109,6 @@ void Profile::RequestDisconnection(
<< ": Disconnection requested, but we are not connected to this device";
return;
}
connections_.erase(mac_addr);
}
@@ -185,24 +193,35 @@ std::optional<sdbus::UnixFd> ProfileManager::GetServiceRecordFD(
std::unique_ptr<CancellationFlagListener> cancel_listener;
if (cancellation_flag != nullptr)
cancel_listener = std::make_unique<CancellationFlagListener>(
cancellation_flag, [&profile]() {
profile->connections_lock_.Lock();
profile->connections_lock_.Unlock();
});
cancellation_flag, [profile]() {
if (profile->connections_lock_.TryLock()) {
profile->connections_lock_.Unlock();
}
}
);
LOG(INFO) << __func__ << ": " << profile->getObjectPath()
<< ": Attempting to get a FD for service "
<< service_uuid << " on device " << mac_addr;
LOG(INFO) << "WAIT profile=" << profile.get()
<< " mutex=" << &profile->connections_lock_
<< " obj=" << profile->getObjectPath()
<< " key=" << mac_addr;
auto cond = [mac_addr, profile, cancellation_flag]() {
profile->connections_lock_.AssertReaderHeld();
profile->connections_lock_.AssertHeld();
LOG(INFO) << "connections_lock_ is held by: " << mac_addr;
return profile->connections_.count(mac_addr) != 0 ||
(cancellation_flag != nullptr && cancellation_flag->Cancelled());
};
// BUG: Race condition. Hangs here
LOG(INFO) << "WAIT key(GetMacAddress)=" << mac_addr;
LOG(INFO) << "connections_ size" << profile -> connections_.size();
absl::MutexLock connections_lock(&profile->connections_lock_,
absl::Condition(&cond));
LOG(INFO) << "WAIT_ACQUIRED "
<< " map_size=" << profile->connections_.size();
if (cancellation_flag != nullptr && cancellation_flag->Cancelled()) {
LOG(INFO)
<< __func__ << ": " << profile->getObjectPath() << ": "
@@ -214,7 +233,9 @@ std::optional<sdbus::UnixFd> ProfileManager::GetServiceRecordFD(
auto [fd, properties] = profile->connections_[mac_addr].back();
profile->connections_[mac_addr].pop_back();
if (profile->connections_[mac_addr].empty())
profile->connections_.erase(mac_addr);
return std::move(fd);
@@ -29,6 +29,7 @@ namespace nearby {
namespace linux {
BluetoothDevice::BluetoothDevice(std::shared_ptr<bluez::Device> device)
: lost_(false), device_(device) {
LOG(INFO) << "Created BluetoothDevice for: " << device -> Address();
try {
last_known_name_ = device->Alias();
} catch (const sdbus::Error &e) {
@@ -43,7 +44,7 @@ BluetoothDevice::BluetoothDevice(std::shared_ptr<bluez::Device> device)
}
std::string BluetoothDevice::GetName() const {
auto device = device_.lock();
auto device = device_;
if (device == nullptr) {
absl::ReaderMutexLock l(&properties_mutex_);
return last_known_name_;
@@ -63,7 +64,7 @@ std::string BluetoothDevice::GetName() const {
}
std::string BluetoothDevice::GetMacAddress() const {
auto device = device_.lock();
auto device = device_;
if (device == nullptr) {
absl::ReaderMutexLock l(&properties_mutex_);
return last_known_name_;
@@ -83,7 +84,7 @@ std::string BluetoothDevice::GetMacAddress() const {
}
bool BluetoothDevice::ConnectToProfile(absl::string_view service_uuid) {
auto device = device_.lock();
auto device = device_;
if (device == nullptr) return false;
try {
device->ConnectProfile(std::string(service_uuid));
@@ -98,7 +99,7 @@ MonitoredBluetoothDevice::MonitoredBluetoothDevice(
std::shared_ptr<sdbus::IConnection> system_bus,
std::shared_ptr<bluez::Device> device,
ObserverList<api::BluetoothClassicMedium::Observer> &observers)
: BluetoothDevice(std::move(device)),
: BluetoothDevice(device),
ProxyInterfaces<sdbus::Properties_proxy>(*system_bus, bluez::SERVICE_DEST,
device->getObjectPath()),
system_bus_(std::move(system_bus)),
@@ -40,8 +40,7 @@ namespace linux {
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
// TODO: This used to inherit from ble_v2::BlePeripheral. Removed that since APIs have now changed
class BluetoothDevice : public api::BluetoothDevice
{
class BluetoothDevice : public api::BluetoothDevice {
public:
using UniqueId = std::uint64_t;
@@ -49,21 +48,17 @@ class BluetoothDevice : public api::BluetoothDevice
BluetoothDevice(BluetoothDevice &&) = delete;
BluetoothDevice &operator=(const BluetoothDevice &) = delete;
BluetoothDevice &operator=(BluetoothDevice &&) = delete;
explicit BluetoothDevice(std::shared_ptr<bluez::Device> device);
// BluetoothDevice methods
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getName()
std::string GetName() const override;
// Returns BT MAC address assigned to this device.
std::string GetMacAddress() const override;
MacAddress GetAddress() const override { return last_known_address_; }
// BlePeripheral methods
//UniqueId GetUniqueId() const override { return unique_id_; };
std::optional<std::map<std::string, sdbus::Variant>> ServiceData() {
auto device = device_.lock();
if (device == nullptr) return std::nullopt;
auto device = device_;
if (!device) return std::nullopt;
try {
return device->ServiceData();
@@ -72,9 +67,10 @@ class BluetoothDevice : public api::BluetoothDevice
return std::nullopt;
}
}
bool Bonded() {
auto device = device_.lock();
if (device == nullptr) return false;
auto device = device_;
if (!device) return false;
try {
return device->Bonded();
@@ -85,8 +81,8 @@ class BluetoothDevice : public api::BluetoothDevice
}
std::optional<sdbus::PendingAsyncCall> Pair() {
auto device = device_.lock();
if (device == nullptr) return std::nullopt;
auto device = device_;
if (!device) return std::nullopt;
try {
return device->Pair();
@@ -97,8 +93,8 @@ class BluetoothDevice : public api::BluetoothDevice
}
bool CancelPairing() {
auto device = device_.lock();
if (device == nullptr) return false;
auto device = device_;
if (!device) return false;
try {
device->CancelPairing();
@@ -110,8 +106,8 @@ class BluetoothDevice : public api::BluetoothDevice
}
void SetPairReplyCallback(absl::AnyInvocable<void(const sdbus::Error *)> cb) {
auto device = device_.lock();
if (device != nullptr) device->SetPairReplyCallback(std::move(cb));
auto device = device_;
if (device) device->SetPairReplyCallback(std::move(cb));
}
bool ConnectToProfile(absl::string_view service_uuid);
@@ -126,7 +122,8 @@ class BluetoothDevice : public api::BluetoothDevice
mutable absl::Mutex properties_mutex_;
mutable std::string last_known_name_ ABSL_GUARDED_BY(properties_mutex_);
mutable MacAddress last_known_address_ ABSL_GUARDED_BY(properties_mutex_);
mutable std::weak_ptr<bluez::Device> device_;
std::shared_ptr<bluez::Device> device_;
};
class MonitoredBluetoothDevice final
@@ -45,9 +45,9 @@ BluetoothClassicMedium::BluetoothClassicMedium(BluetoothAdapter &adapter)
bool BluetoothClassicMedium::StartDiscovery(
DiscoveryCallback discovery_callback) {
device_watcher_ = std::make_unique<DeviceWatcher>(
*system_bus_, adapter_.GetObjectPath(), devices_,
*system_bus_, adapter_.GetObjectPath(), devices_, // BUG: this is getting called with devices_ being a nullptr
std::make_unique<DiscoveryCallback>(std::move(discovery_callback)),
observers_);
observers_); // BUG: observers_ is a nullptr
std::map<std::string, sdbus::Variant> filter;
filter["Transport"] = "auto";
@@ -103,8 +103,9 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
}
}
auto address = remote_device.GetMacAddress();
auto device = devices_->get_device_by_address(address);
// who is passing this here?
auto address = remote_device.GetMacAddress(); //BUG: this returns the last known name instead of mac address
auto device = devices_->get_device_by_address(address); //BUG: this returns nullptr. WHy? who knows
if (device == nullptr) {
LOG(ERROR) << __func__ << ": Device " << address
<< " is no longer known";
@@ -159,6 +159,7 @@ void DeviceWatcher::onInterfacesRemoved(
}
void DeviceWatcher::notifyExistingDevices() {
// NOTE: Existing devices don't get identified as endpoints. They only
std::map<sdbus::ObjectPath,
std::map<std::string, std::map<std::string, sdbus::Variant>>>
objects;
@@ -177,6 +178,7 @@ void DeviceWatcher::notifyExistingDevices() {
interfaces.count(org::bluez::Device1_proxy::INTERFACE_NAME) == 1;
});
for (; device_it != objects.end(); device_it++) {
LOG(INFO) << __func__ << ": Adding existing device "
<< device_it->first;
@@ -65,6 +65,16 @@ class BluetoothDevices final {
ABSL_LOCKS_EXCLUDED(devices_by_path_lock_);
void cleanup_lost_peripherals() ABSL_LOCKS_EXCLUDED(devices_by_path_lock_);
// DEBUG
void dump_devices() ABSL_LOCKS_EXCLUDED(devices_by_path_lock_) {
absl::ReaderMutexLock lock(&devices_by_path_lock_);
LOG(INFO) << "Dumping BluetoothDevices:";
for (const auto& [path, device] : devices_by_path_) {
LOG(INFO) << " - Device path: " << path << " , Name: " << device->GetName();
}
}
private:
std::shared_ptr<sdbus::IConnection> system_bus_;
ObserverList<api::BluetoothClassicMedium::Observer> &observers_;
@@ -40,10 +40,10 @@
#include "internal/platform/implementation/linux/preferences_manager.h"
#include "internal/platform/implementation/linux/submittable_executor.h"
#include "internal/platform/implementation/linux/timer.h"
#include "internal/platform/implementation/linux/wifi_direct.h"
#include "internal/platform/implementation/linux/wifi_hotspot.h"
#include "internal/platform/implementation/linux/wifi_lan.h"
#include "internal/platform/implementation/linux/wifi_medium.h"
// #include "internal/platform/implementation/linux/wifi_direct.h"
// #include "internal/platform/implementation/linux/wifi_hotspot.h"
// #include "internal/platform/implementation/linux/wifi_lan.h"
// #include "internal/platform/implementation/linux/wifi_medium.h"
#include "internal/platform/implementation/platform.h"
#include "absl/strings/str_cat.h"
@@ -210,89 +210,94 @@ ImplementationPlatform::CreateBleV2Medium(api::BluetoothAdapter &adapter) {
}
namespace {
static std::unique_ptr<linux::NetworkManagerWifiMedium> createWifiMedium(
std::shared_ptr<linux::networkmanager::NetworkManager> nm) {
std::vector<sdbus::ObjectPath> device_paths;
try {
device_paths = nm->GetAllDevices();
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(nm, "GetAllDevices", e);
return nullptr;
}
auto manager = linux::networkmanager::ObjectManager(nm->GetConnection());
std::map<sdbus::ObjectPath,
std::map<std::string, std::map<std::string, sdbus::Variant>>>
objects;
try {
objects = manager.GetManagedObjects();
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(nm, "GetManagedObjects", e);
return nullptr;
}
for (auto &device_path : device_paths) {
if (objects.count(device_path) == 1) {
auto device = objects[device_path];
if (device.count(org::freedesktop::NetworkManager::Device::
Wireless_proxy::INTERFACE_NAME) == 1) {
LOG(INFO) << __func__
<< ": Found a wireless device at :" << device_path;
return std::make_unique<linux::NetworkManagerWifiMedium>(nm,
device_path);
}
}
}
LOG(ERROR) << __func__
<< ": couldn't find a wireless device on this system";
return nullptr;
}
// static std::unique_ptr<linux::NetworkManagerWifiMedium> createWifiMedium(
// std::shared_ptr<linux::networkmanager::NetworkManager> nm) {
// return nullptr;
// std::vector<sdbus::ObjectPath> device_paths;
//
// try {
// device_paths = nm->GetAllDevices();
// } catch (const sdbus::Error &e) {
// DBUS_LOG_METHOD_CALL_ERROR(nm, "GetAllDevices", e);
// return nullptr;
// }
//
// auto manager = linux::networkmanager::ObjectManager(nm->GetConnection());
//
// std::map<sdbus::ObjectPath,
// std::map<std::string, std::map<std::string, sdbus::Variant>>>
// objects;
// try {
// objects = manager.GetManagedObjects();
// } catch (const sdbus::Error &e) {
// DBUS_LOG_METHOD_CALL_ERROR(nm, "GetManagedObjects", e);
// return nullptr;
// }
//
// for (auto &device_path : device_paths) {
// if (objects.count(device_path) == 1) {
// auto device = objects[device_path];
// if (device.count(org::freedesktop::NetworkManager::Device::
// Wireless_proxy::INTERFACE_NAME) == 1) {
// LOG(INFO) << __func__
// << ": Found a wireless device at :" << device_path;
// return std::make_unique<linux::NetworkManagerWifiMedium>(nm,
// device_path);
// }
// }
// }
//
// LOG(ERROR) << __func__
// << ": couldn't find a wireless device on this system";
// return nullptr;
// }
} // namespace
std::unique_ptr<api::WifiMedium> ImplementationPlatform::CreateWifiMedium() {
auto nm =
std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
return createWifiMedium(nm);
return nullptr;
// auto nm =
// std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
// return createWifiMedium(nm);
}
std::unique_ptr<api::WifiLanMedium>
ImplementationPlatform::CreateWifiLanMedium() {
auto nm =
std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
return std::make_unique<linux::WifiLanMedium>(nm);
return nullptr;
// auto nm =
// std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
// return std::make_unique<linux::WifiLanMedium>(nm);
}
std::unique_ptr<api::WifiHotspotMedium>
ImplementationPlatform::CreateWifiHotspotMedium() {
auto nm =
std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
auto wifiMedium = createWifiMedium(nm);
if (wifiMedium == nullptr) {
LOG(ERROR) << __func__ << ": Could not create a WiFi medium";
return nullptr;
}
return std::make_unique<linux::NetworkManagerWifiHotspotMedium>(
nm, std::move(wifiMedium));
return nullptr;
// auto nm =
// std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
// auto wifiMedium = createWifiMedium(nm);
//
// if (wifiMedium == nullptr) {
// LOG(ERROR) << __func__ << ": Could not create a WiFi medium";
// return nullptr;
// }
//
// return std::make_unique<linux::NetworkManagerWifiHotspotMedium>(
// nm, std::move(wifiMedium));
}
std::unique_ptr<api::WifiDirectMedium>
ImplementationPlatform::CreateWifiDirectMedium() {
auto nm =
std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
auto wifiMedium = createWifiMedium(nm);
if (wifiMedium == nullptr) {
LOG(ERROR) << __func__ << ": Could not create a WiFi medium";
return nullptr;
}
return std::make_unique<linux::NetworkManagerWifiDirectMedium>(
nm, std::move(wifiMedium));
return nullptr;
// auto nm =
// std::make_shared<linux::networkmanager::NetworkManager>(linux::getSystemBusConnection());
// auto wifiMedium = createWifiMedium(nm);
//
// if (wifiMedium == nullptr) {
// LOG(ERROR) << __func__ << ": Could not create a WiFi medium";
// return nullptr;
// }
//
// return std::make_unique<linux::NetworkManagerWifiDirectMedium>(
// nm, std::move(wifiMedium));
}
std::unique_ptr<api::Timer> ImplementationPlatform::CreateTimer() {
@@ -303,6 +308,10 @@ std::unique_ptr<api::DeviceInfo> ImplementationPlatform::CreateDeviceInfo() {
return std::make_unique<linux::DeviceInfo>(linux::getSystemBusConnection());
}
std::unique_ptr<AwdlMedium> ImplementationPlatform::CreateAwdlMedium() {
return nullptr;
}
absl::StatusOr<api::WebResponse> ImplementationPlatform::SendRequest(
const WebRequest &request) {
if (request.body.size() >= (8 * 1024 * 1024)) {
@@ -21,8 +21,12 @@
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/linux/preferences_manager.h"
#include "absl/strings/str_cat.h"
#include "internal/platform/implementation/linux/preferences_repository.h"
#include "internal/platform/logging.h"
#include "internal/platform/implementation/platform.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
@@ -33,15 +37,15 @@ using json = ::nlohmann::json;
} // namespace
PreferencesManager::PreferencesManager(absl::string_view file_path)
: api::PreferencesManager(file_path) {
std::optional<std::filesystem::path> path =
: api::PreferencesManager() {
std::optional<FilePath> path =
nearby::api::ImplementationPlatform::CreateDeviceInfo()
->GetLocalAppDataPath();
if (!path.has_value()) {
path = std::filesystem::temp_directory_path();
path = FilePath("/tmp");
}
std::filesystem::path full_path = *path / std::string(file_path);
std::filesystem::path full_path = std::filesystem::path(path->ToString()) / std::string(file_path);
preferences_repository_ =
std::make_unique<PreferencesRepository>(full_path.string());
value_ = preferences_repository_->LoadPreferences();