mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Removed unnecessary files
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_API_BLE_MEDIUM_H_
|
||||
#define PLATFORM_IMPL_LINUX_API_BLE_MEDIUM_H_
|
||||
|
||||
#include "internal/platform/implementation/ble.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
// Container of operations that can be performed over the BLE medium.
|
||||
class BleMedium : public api::BleMedium {
|
||||
public:
|
||||
BleMedium() {}
|
||||
~BleMedium() = default;
|
||||
|
||||
bool StartAdvertising(
|
||||
const std::string &service_id, const ByteArray &advertisement_bytes,
|
||||
const std::string &fast_advertisement_service_uuid) override {
|
||||
return false;
|
||||
}
|
||||
bool StopAdvertising(const std::string &service_id) override { return false; }
|
||||
|
||||
// Returns true once the BLE scan has been initiated.
|
||||
bool StartScanning(const std::string &service_id,
|
||||
const std::string &fast_advertisement_service_uuid,
|
||||
DiscoveredPeripheralCallback callback) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true once BLE scanning for service_id is well and truly stopped;
|
||||
// after this returns, there must be no more invocations of the
|
||||
// DiscoveredPeripheralCallback passed in to StartScanning() for service_id.
|
||||
bool StopScanning(const std::string &service_id) override { return false; }
|
||||
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
using AcceptedConnectionCallback = absl::AnyInvocable<void(
|
||||
api::BleSocket &socket, const std::string &service_id)>;
|
||||
|
||||
// Returns true once BLE socket connection requests to service_id can be
|
||||
// accepted.
|
||||
bool StartAcceptingConnections(const std::string &service_id,
|
||||
AcceptedConnectionCallback callback) override {
|
||||
return false;
|
||||
}
|
||||
bool StopAcceptingConnections(const std::string &service_id) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Connects to a BLE peripheral.
|
||||
// On success, returns a new BleSocket.
|
||||
// On error, returns nullptr.
|
||||
std::unique_ptr<api::BleSocket> Connect(
|
||||
api::BlePeripheral &peripheral, const std::string &service_id,
|
||||
CancellationFlag *cancellation_flag) override {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,85 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_API_BLE_V2_MEDIUM_H_
|
||||
#define PLATFORM_IMPL_LINUX_API_BLE_V2_MEDIUM_H_
|
||||
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class BleV2Medium : public api::ble_v2::BleMedium {
|
||||
bool StartAdvertising(
|
||||
const api::ble_v2::BleAdvertisementData &advertising_data,
|
||||
api::ble_v2::AdvertiseParameters advertise_set_parameters) override {
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<AdvertisingSession> StartAdvertising(
|
||||
const api::ble_v2::BleAdvertisementData &advertising_data,
|
||||
api::ble_v2::AdvertiseParameters advertise_set_parameters,
|
||||
AdvertisingCallback callback) override {
|
||||
return nullptr;
|
||||
}
|
||||
bool StopAdvertising() override { return false; }
|
||||
|
||||
bool StartScanning(const Uuid &service_uuid,
|
||||
api::ble_v2::TxPowerLevel tx_power_level,
|
||||
ScanCallback callback) override {
|
||||
return false;
|
||||
}
|
||||
bool StopScanning() override { return false; }
|
||||
|
||||
std::unique_ptr<ScanningSession> StartScanning(
|
||||
const Uuid &service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
|
||||
ScanningCallback callback) override {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
std::unique_ptr<api::ble_v2::GattServer> StartGattServer(
|
||||
api::ble_v2::ServerGattConnectionCallback callback) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::GattClient> ConnectToGattServer(
|
||||
api::ble_v2::BlePeripheral &peripheral,
|
||||
api::ble_v2::TxPowerLevel tx_power_level,
|
||||
api::ble_v2::ClientGattConnectionCallback callback) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::BleServerSocket> OpenServerSocket(
|
||||
const std::string &service_id) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::BleSocket> Connect(
|
||||
const std::string &service_id, api::ble_v2::TxPowerLevel tx_power_level,
|
||||
api::ble_v2::BlePeripheral &peripheral,
|
||||
CancellationFlag *cancellation_flag) override {
|
||||
return nullptr;
|
||||
}
|
||||
bool IsExtendedAdvertisementsAvailable() override { return false; }
|
||||
bool GetRemotePeripheral(const std::string &mac_address,
|
||||
GetRemotePeripheralCallback callback) override {
|
||||
return false;
|
||||
}
|
||||
bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
|
||||
GetRemotePeripheralCallback callback) override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,288 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include <sdbus-c++/AdaptorInterfaces.h>
|
||||
#include <sdbus-c++/Error.h>
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/IObject.h>
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_bluez_profile.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/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
|
||||
bool ProfileManager::ProfileRegistered(absl::string_view service_uuid) {
|
||||
registered_service_uuids_mutex_.ReaderLock();
|
||||
bool registered = registered_services_.count(std::string(service_uuid)) == 1;
|
||||
registered_service_uuids_mutex_.ReaderUnlock();
|
||||
return registered;
|
||||
}
|
||||
|
||||
void Profile::Release() {
|
||||
released_ = true;
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Profile object " << getObjectPath()
|
||||
<< " has been released";
|
||||
}
|
||||
|
||||
void Profile::NewConnection(
|
||||
const sdbus::ObjectPath &device_object_path, const sdbus::UnixFd &fd,
|
||||
const std::map<std::string, sdbus::Variant> &fd_props) {
|
||||
if (released_) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": NewConnection called on released object "
|
||||
<< getObjectPath();
|
||||
throw sdbus::Error("org.bluez.Error.Rejected",
|
||||
"NewConnection called on released object");
|
||||
}
|
||||
|
||||
auto device = devices_.get_device_by_path(device_object_path);
|
||||
|
||||
if (device == nullptr) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": NewConection called with a device object we don't know about: "
|
||||
<< device_object_path;
|
||||
throw sdbus::Error("org.bluez.Error.Rejected", "Unknown object");
|
||||
}
|
||||
|
||||
auto alias = device->Alias();
|
||||
auto mac_addr = device->Address();
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
|
||||
<< ": Connected to " << device->getObjectPath();
|
||||
|
||||
FDProperties props(fd_props);
|
||||
|
||||
absl::MutexLock l(&connections_lock_);
|
||||
connections_[mac_addr].push_back(std::pair(fd, props));
|
||||
}
|
||||
|
||||
void Profile::RequestDisconnection(
|
||||
const sdbus::ObjectPath &device_object_path) {
|
||||
auto device = devices_.get_device_by_path(device_object_path);
|
||||
if (device == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": " << getObjectPath()
|
||||
<< ": RequestDisconnection called with a device object "
|
||||
"we don't know about: "
|
||||
<< device_object_path;
|
||||
throw sdbus::Error("org.bluez.Error.Rejected", "Unknown object");
|
||||
}
|
||||
|
||||
auto mac_addr = device->Address();
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Disconnection requested for device "
|
||||
<< device_object_path;
|
||||
|
||||
absl::MutexLock l(&connections_lock_);
|
||||
if (connections_.count(mac_addr) == 0) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Disconnection requested, but we are not connected to this device";
|
||||
return;
|
||||
}
|
||||
|
||||
connections_.erase(mac_addr);
|
||||
}
|
||||
|
||||
bool ProfileManager::Register(std::optional<absl::string_view> name,
|
||||
absl::string_view service_uuid) {
|
||||
absl::MutexLock l(®istered_service_uuids_mutex_);
|
||||
if (registered_services_.count(std::string(service_uuid)) == 1) {
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": Trying to register profile "
|
||||
<< service_uuid << " which was already registered.";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto profile = std::make_shared<Profile>(
|
||||
getProxy().getConnection(), bluez::profile_object_path(service_uuid),
|
||||
devices_);
|
||||
|
||||
try {
|
||||
std::map<std::string, sdbus::Variant> options;
|
||||
if (name.has_value()) {
|
||||
options["Name"] = std::string(*name);
|
||||
options["RequireAuthorization"] = false;
|
||||
options["RequireAuthentication"] = false;
|
||||
options["Channel"] = static_cast<uint16_t>(0);
|
||||
options["PSM"] = static_cast<uint16_t>(0);
|
||||
}
|
||||
RegisterProfile(profile->getObjectPath(), std::string(service_uuid),
|
||||
options);
|
||||
} catch (const sdbus::Error &e) {
|
||||
BLUEZ_LOG_METHOD_CALL_ERROR(&getProxy(), "RegisterProfile", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
registered_services_.emplace(service_uuid, profile);
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< ": Registered profile instancefor service uuid "
|
||||
<< service_uuid;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProfileManager::Unregister(absl::string_view service_uuid) {
|
||||
absl::MutexLock l(®istered_service_uuids_mutex_);
|
||||
if (registered_services_.count(std::string(service_uuid)) == 0) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< __func__
|
||||
<< ": attempted to unregister a profile that is not registered";
|
||||
return;
|
||||
}
|
||||
|
||||
auto profile_object_path = bluez::profile_object_path(service_uuid);
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Unregistering profile "
|
||||
<< profile_object_path;
|
||||
|
||||
try {
|
||||
UnregisterProfile(profile_object_path);
|
||||
} catch (const sdbus::Error &e) {
|
||||
BLUEZ_LOG_METHOD_CALL_ERROR(&getProxy(), "UnregisterProfile", e);
|
||||
}
|
||||
|
||||
registered_services_.erase(std::string(service_uuid));
|
||||
}
|
||||
|
||||
// Get a service record FD for a connected profile (identified by service_uuid)
|
||||
// to the given device.
|
||||
std::optional<sdbus::UnixFd> ProfileManager::GetServiceRecordFD(
|
||||
api::BluetoothDevice &remote_device, absl::string_view service_uuid,
|
||||
CancellationFlag *cancellation_flag) {
|
||||
std::shared_ptr<Profile> profile;
|
||||
{
|
||||
absl::ReaderMutexLock lock(®istered_service_uuids_mutex_);
|
||||
if (registered_services_.count(std::string(service_uuid)) == 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Service " << service_uuid
|
||||
<< " is not registered";
|
||||
return std::nullopt;
|
||||
}
|
||||
profile = registered_services_[std::string(service_uuid)];
|
||||
}
|
||||
auto mac_addr = remote_device.GetMacAddress();
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": " << profile->getObjectPath()
|
||||
<< ": Attempting to get a FD for service "
|
||||
<< service_uuid << " on device " << mac_addr;
|
||||
|
||||
auto cond = [mac_addr, profile, cancellation_flag]() {
|
||||
profile->connections_lock_.AssertReaderHeld();
|
||||
return profile->connections_.count(mac_addr) != 0 ||
|
||||
(cancellation_flag != nullptr && cancellation_flag->Cancelled());
|
||||
};
|
||||
|
||||
absl::MutexLock connections_lock(&profile->connections_lock_,
|
||||
absl::Condition(&cond));
|
||||
|
||||
if (cancellation_flag != nullptr && cancellation_flag->Cancelled()) {
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< __func__ << ": " << profile->getObjectPath() << ": "
|
||||
<< remote_device.GetMacAddress()
|
||||
<< ": Cancelled waiting for a new connection on profile "
|
||||
<< service_uuid;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Listen for a connected profile on any device, returning the connected device
|
||||
// with its FD.
|
||||
std::optional<std::pair<std::shared_ptr<BluetoothDevice>, sdbus::UnixFd>>
|
||||
ProfileManager::GetServiceRecordFD(absl::string_view service_uuid,
|
||||
CancellationFlag *cancellation_flag) {
|
||||
std::shared_ptr<Profile> profile;
|
||||
|
||||
{
|
||||
absl::ReaderMutexLock lock(®istered_service_uuids_mutex_);
|
||||
if (registered_services_.count(std::string(service_uuid)) == 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
profile = registered_services_[std::string(service_uuid)];
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": " << profile->getObjectPath()
|
||||
<< ": Attempting to get a FD for service "
|
||||
<< service_uuid;
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
profile->connections_lock_.Lock();
|
||||
auto cond = [profile, &cancellation_flag]() {
|
||||
profile->connections_lock_.AssertReaderHeld();
|
||||
return !profile->connections_.empty() ||
|
||||
(cancellation_flag != nullptr && cancellation_flag->Cancelled());
|
||||
};
|
||||
profile->connections_lock_.Await(absl::Condition(&cond));
|
||||
|
||||
if (cancellation_flag != nullptr && cancellation_flag->Cancelled()) {
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< __func__ << ": Cancelled waiting for new connections on profile "
|
||||
<< profile->getObjectPath();
|
||||
profile->connections_lock_.Unlock();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto it = profile->connections_.begin();
|
||||
auto mac_addr = it->first;
|
||||
auto [fd, properties] = it->second.back();
|
||||
it->second.pop_back();
|
||||
if (it->second.empty()) profile->connections_.erase(it);
|
||||
profile->connections_lock_.Unlock();
|
||||
|
||||
auto device = devices_.get_device_by_address(mac_addr);
|
||||
if (device == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Device " << mac_addr
|
||||
<< " is no longer available";
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::pair(device, std::move(fd));
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,147 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_BLUEZ_PROFILE_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUETOOTH_BLUEZ_PROFILE_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include <sdbus-c++/AdaptorInterfaces.h>
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/IObject.h>
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <sdbus-c++/ProxyInterfaces.h>
|
||||
#include <sdbus-c++/StandardInterfaces.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_devices.h"
|
||||
#include "internal/platform/implementation/linux/bluez.h"
|
||||
#include "internal/platform/implementation/linux/generated/dbus/bluez/profile_manager_client.h"
|
||||
#include "internal/platform/implementation/linux/generated/dbus/bluez/profile_server.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class ProfileManager;
|
||||
|
||||
class Profile final
|
||||
: public sdbus::AdaptorInterfaces<org::bluez::Profile1_adaptor,
|
||||
sdbus::ManagedObject_adaptor> {
|
||||
public:
|
||||
Profile(const Profile &) = delete;
|
||||
Profile(Profile &&) = delete;
|
||||
Profile &operator=(const Profile &) = delete;
|
||||
Profile &operator=(Profile &&) = delete;
|
||||
Profile(sdbus::IConnection &system_bus, sdbus::ObjectPath profile_object_path,
|
||||
BluetoothDevices &devices)
|
||||
: AdaptorInterfaces(system_bus, std::move(profile_object_path)),
|
||||
released_(false),
|
||||
devices_(devices) {
|
||||
registerAdaptor();
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Created a new BlueZ profile at :"
|
||||
<< getObjectPath();
|
||||
}
|
||||
~Profile() { unregisterAdaptor(); }
|
||||
|
||||
private:
|
||||
friend class ProfileManager;
|
||||
|
||||
struct FDProperties {
|
||||
explicit FDProperties(const std::map<std::string, sdbus::Variant> &fd_props)
|
||||
: version(std::nullopt), features(std::nullopt) {
|
||||
if (fd_props.count("Version") == 1) {
|
||||
version = fd_props.at("Version");
|
||||
}
|
||||
if (fd_props.count("Features") == 1) {
|
||||
features = fd_props.at("Features");
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<uint16_t> version;
|
||||
std::optional<uint16_t> features;
|
||||
};
|
||||
|
||||
void Release() override;
|
||||
void NewConnection(const sdbus::ObjectPath &, const sdbus::UnixFd &,
|
||||
const std::map<std::string, sdbus::Variant> &) override
|
||||
ABSL_LOCKS_EXCLUDED(connections_lock_);
|
||||
void RequestDisconnection(const sdbus::ObjectPath &) override
|
||||
ABSL_LOCKS_EXCLUDED(connections_lock_);
|
||||
|
||||
std::atomic_bool released_;
|
||||
|
||||
absl::Mutex connections_lock_;
|
||||
std::map<std::string, std::vector<std::pair<sdbus::UnixFd, FDProperties>>>
|
||||
connections_ ABSL_GUARDED_BY(connections_lock_);
|
||||
|
||||
BluetoothDevices &devices_;
|
||||
};
|
||||
|
||||
class ProfileManager final
|
||||
: private sdbus::ProxyInterfaces<org::bluez::ProfileManager1_proxy> {
|
||||
public:
|
||||
ProfileManager(const ProfileManager &) = delete;
|
||||
ProfileManager(ProfileManager &&) = delete;
|
||||
ProfileManager &operator=(const ProfileManager &) = delete;
|
||||
ProfileManager &operator=(ProfileManager &&) = delete;
|
||||
ProfileManager(sdbus::IConnection &system_bus, BluetoothDevices &devices)
|
||||
: ProxyInterfaces(system_bus, bluez::SERVICE_DEST, "/org/bluez"),
|
||||
devices_(devices) {
|
||||
registerProxy();
|
||||
}
|
||||
~ProfileManager() { unregisterProxy(); }
|
||||
|
||||
bool ProfileRegistered(absl::string_view service_uuid)
|
||||
ABSL_LOCKS_EXCLUDED(registered_service_uuids_mutex_);
|
||||
bool Register(std::optional<absl::string_view> service_name,
|
||||
absl::string_view service_uuid)
|
||||
ABSL_LOCKS_EXCLUDED(registered_service_uuids_mutex_);
|
||||
bool Register(absl::string_view service_uuid)
|
||||
ABSL_LOCKS_EXCLUDED(registered_service_uuids_mutex_) {
|
||||
return Register(std::nullopt, service_uuid);
|
||||
}
|
||||
void Unregister(absl::string_view service_uuid)
|
||||
ABSL_LOCKS_EXCLUDED(registered_service_uuids_mutex_);
|
||||
|
||||
std::optional<sdbus::UnixFd> GetServiceRecordFD(
|
||||
api::BluetoothDevice &remote_device, absl::string_view service_uuid,
|
||||
CancellationFlag *cancellation_flag)
|
||||
ABSL_LOCKS_EXCLUDED(registered_service_uuids_mutex_);
|
||||
std::optional<std::pair<std::shared_ptr<BluetoothDevice>, sdbus::UnixFd>>
|
||||
GetServiceRecordFD(absl::string_view service_uuid,
|
||||
CancellationFlag *cancellation_flag)
|
||||
ABSL_LOCKS_EXCLUDED(registered_service_uuids_mutex_);
|
||||
|
||||
private:
|
||||
BluetoothDevices &devices_;
|
||||
// Maps service UUIDs to RegisteredService
|
||||
absl::Mutex registered_service_uuids_mutex_;
|
||||
std::map<std::string, std::shared_ptr<Profile>> registered_services_
|
||||
ABSL_GUARDED_BY(registered_service_uuids_mutex_);
|
||||
};
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
#endif
|
||||
@@ -1,178 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <sdbus-c++/IObject.h>
|
||||
#include <sdbus-c++/ProxyInterfaces.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/bluetooth_utils.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_device.h"
|
||||
#include "internal/platform/implementation/linux/bluez.h"
|
||||
#include "internal/platform/implementation/linux/dbus.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
BluetoothDevice::BluetoothDevice(sdbus::IConnection &system_bus,
|
||||
sdbus::ObjectPath device_object_path)
|
||||
: ProxyInterfaces(system_bus, bluez::SERVICE_DEST,
|
||||
std::move(device_object_path)),
|
||||
lost_(false) {
|
||||
registerProxy();
|
||||
try {
|
||||
last_known_name_ = Alias();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(this, "Alias", e);
|
||||
}
|
||||
try {
|
||||
last_known_address_ = Address();
|
||||
unique_id_ = BluetoothUtils::ToNumber(last_known_address_);
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(this, "Address", e);
|
||||
}
|
||||
}
|
||||
|
||||
std::string BluetoothDevice::GetName() const {
|
||||
auto bluez_device =
|
||||
sdbus::createProxy(getProxy().getConnection(), bluez::SERVICE_DEST,
|
||||
getProxy().getObjectPath());
|
||||
|
||||
try {
|
||||
std::string alias =
|
||||
bluez_device->getProperty("Alias").onInterface(bluez::DEVICE_INTERFACE);
|
||||
{
|
||||
absl::MutexLock l(&properties_mutex_);
|
||||
last_known_name_ = alias;
|
||||
}
|
||||
return alias;
|
||||
} catch (const sdbus::Error &e) {
|
||||
if (e.getName() == "org.freedesktop.DBus.Error.UnknownObject") {
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< __func__ << ": " << getObjectPath()
|
||||
<< ": device is no longer known, returning last known name";
|
||||
absl::ReaderMutexLock l(&properties_mutex_);
|
||||
return last_known_name_;
|
||||
}
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while trying to get Alias for device "
|
||||
<< bluez_device->getObjectPath();
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string BluetoothDevice::GetMacAddress() const {
|
||||
auto bluez_device =
|
||||
sdbus::createProxy(getProxy().getConnection(), bluez::SERVICE_DEST,
|
||||
getProxy().getObjectPath());
|
||||
|
||||
try {
|
||||
std::string addr = bluez_device->getProperty("Address").onInterface(
|
||||
bluez::DEVICE_INTERFACE);
|
||||
{
|
||||
absl::MutexLock l(&properties_mutex_);
|
||||
last_known_address_ = addr;
|
||||
}
|
||||
return addr;
|
||||
} catch (const sdbus::Error &e) {
|
||||
if (e.getName() == "org.freedesktop.DBus.Error.UnknownObject") {
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< __func__ << ": " << getObjectPath()
|
||||
<< ": device is no longer known, returning last known address";
|
||||
absl::ReaderMutexLock l(&properties_mutex_);
|
||||
return last_known_address_;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(ERROR) << __func__ << "Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while trying to get Address for device "
|
||||
<< bluez_device->getObjectPath();
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothDevice::onConnectProfileReply(const sdbus::Error *error) {
|
||||
if (error != nullptr && error->getName() != "org.bluez.Error.InProgress") {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << error->getName()
|
||||
<< "' with message '" << error->getMessage()
|
||||
<< " while connecting to profile.";
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothDevice::ConnectToProfile(absl::string_view service_uuid) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
|
||||
<< ": Attempting to connect to profile " << service_uuid;
|
||||
try {
|
||||
ConnectProfile(std::string(service_uuid));
|
||||
return true;
|
||||
} catch (const sdbus::Error &e) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while trying to asynchronously connect to profile "
|
||||
<< service_uuid << " on device " << getObjectPath();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MonitoredBluetoothDevice::MonitoredBluetoothDevice(
|
||||
sdbus::IConnection &system_bus, const sdbus::ObjectPath &device_object_path,
|
||||
ObserverList<api::BluetoothClassicMedium::Observer> &observers)
|
||||
: BluetoothDevice(system_bus, device_object_path),
|
||||
ProxyInterfaces<sdbus::Properties_proxy>(system_bus, bluez::SERVICE_DEST,
|
||||
std::string(device_object_path)),
|
||||
observers_(observers) {
|
||||
registerProxy();
|
||||
}
|
||||
|
||||
void MonitoredBluetoothDevice::onPropertiesChanged(
|
||||
const std::string &interfaceName,
|
||||
const std::map<std::string, sdbus::Variant> &changedProperties,
|
||||
const std::vector<std::string> &invalidatedProperties) {
|
||||
if (interfaceName != bluez::DEVICE_INTERFACE) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = changedProperties.begin(); it != changedProperties.end();
|
||||
it++) {
|
||||
if (it->first == bluez::DEVICE_PROP_ADDRESS) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
|
||||
<< ": Notifying observers about address change";
|
||||
std::string address = it->second;
|
||||
for (auto &observer : observers_.GetObservers()) {
|
||||
observer->DeviceAddressChanged(*this, address);
|
||||
}
|
||||
} else if (it->first == bluez::DEVICE_PROP_PAIRED) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
|
||||
<< "Notifying observers about paired status change.";
|
||||
for (auto &observer : observers_.GetObservers()) {
|
||||
observer->DevicePairedChanged(*this, it->second);
|
||||
}
|
||||
} else if (it->first == bluez::DEVICE_PROP_CONNECTED) {
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< __func__ << ": " << getObjectPath()
|
||||
<< "Notifying observers about connected status change";
|
||||
for (auto &observer : observers_.GetObservers()) {
|
||||
observer->DeviceConnectedStateChanged(*this, it->second);
|
||||
}
|
||||
} else if (it->first == bluez::DEVICE_NAME) {
|
||||
auto callback = discovery_cb_.lock();
|
||||
if (callback != nullptr && callback->device_name_changed_cb != nullptr)
|
||||
callback->device_name_changed_cb(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,135 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_CLASSIC_DEVICE_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUETOOTH_CLASSIC_DEVICE_H_
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <sdbus-c++/ProxyInterfaces.h>
|
||||
#include <sdbus-c++/StandardInterfaces.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/base/observer_list.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/generated/dbus/bluez/device_client.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
|
||||
class BluetoothDevice
|
||||
: public api::BluetoothDevice,
|
||||
public sdbus::ProxyInterfaces<org::bluez::Device1_proxy>,
|
||||
public api::ble_v2::BlePeripheral {
|
||||
public:
|
||||
using UniqueId = std::uint64_t;
|
||||
|
||||
BluetoothDevice(const BluetoothDevice &) = delete;
|
||||
BluetoothDevice(BluetoothDevice &&) = delete;
|
||||
BluetoothDevice &operator=(const BluetoothDevice &) = delete;
|
||||
BluetoothDevice &operator=(BluetoothDevice &&) = delete;
|
||||
BluetoothDevice(sdbus::IConnection &system_bus,
|
||||
sdbus::ObjectPath device_object_path);
|
||||
~BluetoothDevice() override { unregisterProxy(); }
|
||||
|
||||
// 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;
|
||||
|
||||
// BlePeripheral methods
|
||||
std::string GetAddress() const override { return GetMacAddress(); }
|
||||
UniqueId GetUniqueId() const override { return unique_id_; };
|
||||
|
||||
bool ConnectToProfile(absl::string_view service_uuid);
|
||||
|
||||
void set_pair_reply_callback(
|
||||
absl::AnyInvocable<void(const sdbus::Error *)> cb) {
|
||||
absl::MutexLock l(&pair_callback_lock_);
|
||||
on_pair_reply_cb_ = std::move(cb);
|
||||
}
|
||||
|
||||
void reset_pair_reply_callback() {
|
||||
absl::MutexLock l(&pair_callback_lock_);
|
||||
on_pair_reply_cb_ = DefaultCallback<const sdbus::Error *>();
|
||||
}
|
||||
|
||||
void MarkLost() { lost_ = true; }
|
||||
void UnmarkLost() { lost_ = false; }
|
||||
bool Lost() const { return lost_; }
|
||||
|
||||
protected:
|
||||
void onConnectProfileReply(const sdbus::Error *error) override;
|
||||
void onPairReply(const sdbus::Error *error) override {
|
||||
absl::ReaderMutexLock l(&pair_callback_lock_);
|
||||
on_pair_reply_cb_(error);
|
||||
};
|
||||
|
||||
private:
|
||||
absl::Mutex pair_callback_lock_;
|
||||
absl::AnyInvocable<void(const sdbus::Error *)> on_pair_reply_cb_ =
|
||||
DefaultCallback<const sdbus::Error *>();
|
||||
UniqueId unique_id_;
|
||||
std::atomic_bool lost_;
|
||||
|
||||
mutable absl::Mutex properties_mutex_;
|
||||
mutable std::string last_known_name_ ABSL_GUARDED_BY(properties_mutex_);
|
||||
mutable std::string last_known_address_ ABSL_GUARDED_BY(properties_mutex_);
|
||||
};
|
||||
|
||||
class MonitoredBluetoothDevice final
|
||||
: public BluetoothDevice,
|
||||
public sdbus::ProxyInterfaces<sdbus::Properties_proxy> {
|
||||
public:
|
||||
using sdbus::ProxyInterfaces<sdbus::Properties_proxy>::registerProxy;
|
||||
using sdbus::ProxyInterfaces<sdbus::Properties_proxy>::unregisterProxy;
|
||||
using sdbus::ProxyInterfaces<sdbus::Properties_proxy>::getObjectPath;
|
||||
|
||||
MonitoredBluetoothDevice(const MonitoredBluetoothDevice &) = delete;
|
||||
MonitoredBluetoothDevice(MonitoredBluetoothDevice &&) = delete;
|
||||
MonitoredBluetoothDevice &operator=(const MonitoredBluetoothDevice &) =
|
||||
delete;
|
||||
MonitoredBluetoothDevice &operator=(MonitoredBluetoothDevice &&) = delete;
|
||||
MonitoredBluetoothDevice(
|
||||
sdbus::IConnection &system_bus, const sdbus::ObjectPath &,
|
||||
ObserverList<api::BluetoothClassicMedium::Observer> &observers);
|
||||
~MonitoredBluetoothDevice() override { unregisterProxy(); }
|
||||
|
||||
void SetDiscoveryCallback(
|
||||
std::shared_ptr<api::BluetoothClassicMedium::DiscoveryCallback>
|
||||
&callback) {
|
||||
discovery_cb_ = callback;
|
||||
};
|
||||
|
||||
protected:
|
||||
void onPropertiesChanged(
|
||||
const std::string &interfaceName,
|
||||
const std::map<std::string, sdbus::Variant> &changedProperties,
|
||||
const std::vector<std::string> &invalidatedProperties) override;
|
||||
|
||||
private:
|
||||
ObserverList<api::BluetoothClassicMedium::Observer> &observers_;
|
||||
std::weak_ptr<api::BluetoothClassicMedium::DiscoveryCallback> discovery_cb_;
|
||||
};
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,233 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/substitute.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_bluez_profile.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_device.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_medium.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_server_socket.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_socket.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_pairing.h"
|
||||
#include "internal/platform/implementation/linux/bluez.h"
|
||||
#include "internal/platform/implementation/linux/generated/dbus/bluez/device_client.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
BluetoothClassicMedium::BluetoothClassicMedium(sdbus::IConnection &system_bus,
|
||||
BluetoothAdapter &adapter)
|
||||
: ProxyInterfaces(system_bus, "org.bluez", "/"),
|
||||
adapter_(adapter),
|
||||
devices_(std::make_shared<BluetoothDevices>(
|
||||
system_bus, adapter.GetObjectPath(), observers_)),
|
||||
profile_manager_(
|
||||
std::make_unique<ProfileManager>(system_bus, *devices_)) {
|
||||
registerProxy();
|
||||
}
|
||||
|
||||
void BluetoothClassicMedium::onInterfacesAdded(
|
||||
const sdbus::ObjectPath &object,
|
||||
const std::map<std::string, std::map<std::string, sdbus::Variant>>
|
||||
&interfaces) {
|
||||
auto path_prefix = absl::Substitute(
|
||||
"$0/dev_", adapter_.GetBluezAdapterObject().getObjectPath());
|
||||
if (object.find(path_prefix) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (devices_->get_device_by_path(object) != nullptr) {
|
||||
// Device already exists.
|
||||
return;
|
||||
}
|
||||
|
||||
if (interfaces.count(org::bluez::Device1_proxy::INTERFACE_NAME) == 1) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Encountered new device at " << object;
|
||||
|
||||
auto device = devices_->add_new_device(object);
|
||||
if (discovery_cb_ != nullptr &&
|
||||
discovery_cb_->device_discovered_cb != nullptr) {
|
||||
device->SetDiscoveryCallback(discovery_cb_);
|
||||
discovery_cb_->device_discovered_cb(*device);
|
||||
}
|
||||
|
||||
for (const auto &observer : observers_.GetObservers()) {
|
||||
observer->DeviceAdded(*device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothClassicMedium::onInterfacesRemoved(
|
||||
const sdbus::ObjectPath &object,
|
||||
const std::vector<std::string> &interfaces) {
|
||||
auto path_prefix = absl::Substitute("$0/dev_", adapter_.GetObjectPath());
|
||||
if (object.find(path_prefix) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto &interface : interfaces) {
|
||||
if (interface == org::bluez::Device1_proxy::INTERFACE_NAME) {
|
||||
{
|
||||
auto device = devices_->get_device_by_path(object);
|
||||
if (device == nullptr) {
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< ": received InterfacesRemoved for a device "
|
||||
"we don't know about: "
|
||||
<< object;
|
||||
return;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Device " << object
|
||||
<< " has been removed";
|
||||
if (discovery_cb_ != nullptr &&
|
||||
discovery_cb_->device_lost_cb != nullptr) {
|
||||
discovery_cb_->device_lost_cb(*device);
|
||||
}
|
||||
|
||||
for (const auto &observer : observers_.GetObservers()) {
|
||||
observer->DeviceRemoved(*device);
|
||||
}
|
||||
}
|
||||
devices_->remove_device_by_path(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothClassicMedium::StartDiscovery(
|
||||
DiscoveryCallback discovery_callback) {
|
||||
discovery_cb_ =
|
||||
std::make_shared<DiscoveryCallback>(std::move(discovery_callback));
|
||||
|
||||
std::map<std::string, sdbus::Variant> filter;
|
||||
filter["Transport"] = "bredr";
|
||||
auto &adapter = adapter_.GetBluezAdapterObject();
|
||||
|
||||
try {
|
||||
adapter.SetDiscoveryFilter(filter);
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(&adapter, "SetDiscoveryFilter", e);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
adapter.StartDiscovery();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StartDiscovery", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Starting BR/EDR discovery on "
|
||||
<< adapter_.GetObjectPath();
|
||||
adapter.StartDiscovery();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StartDiscovery", e);
|
||||
discovery_cb_.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BluetoothClassicMedium::StopDiscovery() {
|
||||
auto &adapter = adapter_.GetBluezAdapterObject();
|
||||
|
||||
try {
|
||||
NEARBY_LOGS(INFO) << __func__ << "Stopping discovery on "
|
||||
<< adapter.getObjectPath();
|
||||
|
||||
adapter.StopDiscovery();
|
||||
this->discovery_cb_.reset();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(&adapter, "StopDiscovery", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
||||
api::BluetoothDevice &remote_device, const std::string &service_uuid,
|
||||
CancellationFlag *cancellation_flag) {
|
||||
auto device_object_path = bluez::device_object_path(
|
||||
adapter_.GetObjectPath(), remote_device.GetMacAddress());
|
||||
if (!profile_manager_->ProfileRegistered(service_uuid)) {
|
||||
if (!profile_manager_->Register("", service_uuid)) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Could not register profile "
|
||||
<< service_uuid << " with Bluez";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto device = devices_->get_device_by_path(device_object_path);
|
||||
if (device == nullptr) return nullptr;
|
||||
|
||||
device->ConnectToProfile(service_uuid);
|
||||
|
||||
auto fd = profile_manager_->GetServiceRecordFD(remote_device, service_uuid,
|
||||
cancellation_flag);
|
||||
if (!fd.has_value()) {
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< ": Failed to get a new connection for profile "
|
||||
<< service_uuid << " for device "
|
||||
<< device_object_path;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::unique_ptr<api::BluetoothSocket>(
|
||||
new BluetoothSocket(device, fd.value()));
|
||||
}
|
||||
|
||||
std::unique_ptr<api::BluetoothServerSocket>
|
||||
BluetoothClassicMedium::ListenForService(const std::string &service_name,
|
||||
const std::string &service_uuid) {
|
||||
if (!profile_manager_->ProfileRegistered(service_uuid)) {
|
||||
if (!profile_manager_->Register(service_name, service_uuid)) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Could not register profile "
|
||||
<< service_name << " " << service_uuid
|
||||
<< " with Bluez";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return std::unique_ptr<api::BluetoothServerSocket>(
|
||||
new BluetoothServerSocket(*profile_manager_, service_uuid));
|
||||
}
|
||||
|
||||
api::BluetoothDevice *BluetoothClassicMedium::GetRemoteDevice(
|
||||
const std::string &mac_address) {
|
||||
auto device = devices_->get_device_by_address(mac_address);
|
||||
if (device == nullptr) return nullptr;
|
||||
|
||||
return device.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<api::BluetoothPairing> BluetoothClassicMedium::CreatePairing(
|
||||
api::BluetoothDevice &remote_device) {
|
||||
auto device = devices_->get_device_by_address(remote_device.GetMacAddress());
|
||||
if (device == nullptr) return nullptr;
|
||||
|
||||
return std::unique_ptr<api::BluetoothPairing>(
|
||||
new BluetoothPairing(adapter_, device));
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,133 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_CLASSIC_MEDIUM_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUETOOTH_CLASSIC_MEDIUM_H_
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <sdbus-c++/ProxyInterfaces.h>
|
||||
#include <sdbus-c++/StandardInterfaces.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "internal/base/observer_list.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_bluez_profile.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_devices.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
// Container of operations that can be performed over the Bluetooth Classic
|
||||
// medium.
|
||||
class BluetoothClassicMedium
|
||||
: public api::BluetoothClassicMedium,
|
||||
protected sdbus::ProxyInterfaces<sdbus::ObjectManager_proxy> {
|
||||
public:
|
||||
BluetoothClassicMedium(const BluetoothClassicMedium &) = delete;
|
||||
BluetoothClassicMedium(BluetoothClassicMedium &&) = delete;
|
||||
BluetoothClassicMedium &operator=(const BluetoothClassicMedium &) = delete;
|
||||
BluetoothClassicMedium &operator=(BluetoothClassicMedium &&) = delete;
|
||||
BluetoothClassicMedium(sdbus::IConnection &system_bus,
|
||||
BluetoothAdapter &adapter);
|
||||
~BluetoothClassicMedium() override { unregisterProxy(); };
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery()
|
||||
//
|
||||
// Returns true once the process of discovery has been initiated.
|
||||
bool StartDiscovery(DiscoveryCallback discovery_callback) override;
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#cancelDiscovery()
|
||||
//
|
||||
// Returns true once discovery is well and truly stopped; after this returns,
|
||||
// there must be no more invocations of the DiscoveryCallback passed in to
|
||||
// StartDiscovery().
|
||||
bool StopDiscovery() override;
|
||||
|
||||
// A combination of
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord
|
||||
// followed by
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#connect().
|
||||
//
|
||||
// service_uuid is the canonical textual representation
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
|
||||
// type 3 name-based
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
|
||||
// UUID.
|
||||
//
|
||||
// On success, returns a new BluetoothSocket.
|
||||
// On error, returns nullptr.
|
||||
std::unique_ptr<api::BluetoothSocket> ConnectToService(
|
||||
api::BluetoothDevice &remote_device, const std::string &service_uuid,
|
||||
CancellationFlag *cancellation_flag) override;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
|
||||
//
|
||||
// service_uuid is the canonical textual representation
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
|
||||
// type 3 name-based
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
|
||||
// UUID.
|
||||
//
|
||||
// Returns nullptr error.
|
||||
std::unique_ptr<api::BluetoothServerSocket> ListenForService(
|
||||
const std::string &service_name,
|
||||
const std::string &service_uuid) override;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createBond()
|
||||
//
|
||||
// Start the bonding (pairing) process with the remote device.
|
||||
// Return a Bluetooth pairing instance to handle the pairing process with the
|
||||
// remote device.
|
||||
std::unique_ptr<api::BluetoothPairing> CreatePairing(
|
||||
api::BluetoothDevice &remote_device) override;
|
||||
|
||||
api::BluetoothDevice *GetRemoteDevice(
|
||||
const std::string &mac_address) override;
|
||||
|
||||
void AddObserver(Observer *observer) override {
|
||||
observers_.AddObserver(observer);
|
||||
};
|
||||
void RemoveObserver(Observer *observer) override {
|
||||
observers_.RemoveObserver(observer);
|
||||
};
|
||||
|
||||
protected:
|
||||
void onInterfacesAdded(
|
||||
const sdbus::ObjectPath &objectPath,
|
||||
const std::map<std::string, std::map<std::string, sdbus::Variant>>
|
||||
&interfacesAndProperties) override;
|
||||
void onInterfacesRemoved(const sdbus::ObjectPath &objectPath,
|
||||
const std::vector<std::string> &interfaces) override;
|
||||
|
||||
private:
|
||||
BluetoothAdapter adapter_;
|
||||
ObserverList<Observer> observers_;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<BluetoothDevices> devices_;
|
||||
|
||||
private:
|
||||
std::shared_ptr<BluetoothClassicMedium::DiscoveryCallback> discovery_cb_;
|
||||
std::unique_ptr<ProfileManager> profile_manager_;
|
||||
};
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_server_socket.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_device.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_socket.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
std::unique_ptr<api::BluetoothSocket> BluetoothServerSocket::Accept() {
|
||||
if (stopped_.Cancelled()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": server socket has been stopped";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__
|
||||
<< ": accepting new connections for service uuid "
|
||||
<< service_uuid_;
|
||||
|
||||
auto pair = profile_manager_.GetServiceRecordFD(service_uuid_, &stopped_);
|
||||
if (!pair.has_value()) {
|
||||
if (!stopped_.Cancelled())
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Failed to get a new connection for profile "
|
||||
<< service_uuid_;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto [device, fd] = *pair;
|
||||
return std::make_unique<BluetoothSocket>(device, std::move(fd));
|
||||
}
|
||||
|
||||
Exception BluetoothServerSocket::Close() {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": closing bluetooth server socket";
|
||||
stopped_.Cancel();
|
||||
profile_manager_.Unregister(service_uuid_);
|
||||
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_SERVER_SOCKET_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUETOOTH_SERVER_SOCKET_H_
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_bluez_profile.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class BluetoothServerSocket final : public api::BluetoothServerSocket {
|
||||
public:
|
||||
BluetoothServerSocket(ProfileManager &profile_manager,
|
||||
absl::string_view service_uuid)
|
||||
: profile_manager_(profile_manager), service_uuid_(service_uuid) {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept()
|
||||
//
|
||||
// Blocks until either:
|
||||
// - at least one incoming connection request is available, or
|
||||
// - ServerSocket is closed.
|
||||
// On success, returns connected socket, ready to exchange data.
|
||||
// Returns nullptr on error.
|
||||
// Once error is reported, it is permanent, and ServerSocket has to be
|
||||
// closed.
|
||||
std::unique_ptr<api::BluetoothSocket> Accept() override;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close()
|
||||
//
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
CancellationFlag stopped_;
|
||||
ProfileManager &profile_manager_;
|
||||
std::string service_uuid_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,123 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_socket.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
Exception Poller::Ready() {
|
||||
while (true) {
|
||||
auto ret = poll(fds_, 1, -1);
|
||||
if (ret < 0) {
|
||||
if (errno == EAGAIN) continue;
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": error polling socket for I/O: "
|
||||
<< std::strerror(errno);
|
||||
return {Exception::kIo};
|
||||
}
|
||||
if ((fds_[0].revents & poll_event_) != 0) {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
if ((fds_[0].revents & POLLHUP) != 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": socket disconnected";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
if ((fds_[0].revents & (POLLERR | POLLNVAL)) != 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": an error occured on the socket";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExceptionOr<ByteArray> BluetoothInputStream::Read(std::int64_t size) {
|
||||
if (!fd_.isValid()) return Exception{Exception::kIo};
|
||||
|
||||
auto poller = Poller::CreateInputPoller(fd_);
|
||||
|
||||
std::string buffer;
|
||||
buffer.resize(size);
|
||||
char *data = buffer.data();
|
||||
|
||||
size_t total_read = 0;
|
||||
|
||||
while (total_read < size) {
|
||||
auto result = poller.Ready();
|
||||
if (result.Raised()) return result;
|
||||
|
||||
auto bytes_read = read(fd_.get(), &data[total_read], (size - total_read));
|
||||
if (bytes_read < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) continue;
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": error reading data on bluetooth socket: "
|
||||
<< std::strerror(errno);
|
||||
return {Exception::kIo};
|
||||
}
|
||||
total_read += bytes_read;
|
||||
}
|
||||
|
||||
return ExceptionOr{ByteArray(std::move(buffer))};
|
||||
}
|
||||
|
||||
Exception BluetoothInputStream::Close() {
|
||||
if (!fd_.isValid()) return {Exception::kIo};
|
||||
fd_.reset();
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
Exception BluetoothOutputStream::Write(const ByteArray &data) {
|
||||
if (!fd_.isValid()) return Exception{Exception::kIo};
|
||||
|
||||
auto poller = Poller::CreateOutputPoller(fd_);
|
||||
|
||||
size_t total_wrote = 0;
|
||||
|
||||
while (total_wrote < data.size()) {
|
||||
auto result = poller.Ready();
|
||||
if (result.Raised()) return result;
|
||||
|
||||
const char *buf = data.data();
|
||||
auto wrote =
|
||||
write(fd_.get(), &buf[total_wrote], (data.size() - total_wrote));
|
||||
if (wrote < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) continue;
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": error writing data on bluetooth socket: "
|
||||
<< std::strerror(errno);
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
total_wrote += wrote;
|
||||
}
|
||||
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
Exception BluetoothOutputStream::Close() {
|
||||
if (!fd_.isValid()) return {Exception::kIo};
|
||||
fd_.reset();
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,103 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_SOCKET_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUETOOTH_SOCKET_H_
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include <sdbus-c++/Types.h>
|
||||
#include <sys/poll.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_device.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
// BlueZ's NewConnection gives us a non-blocking FD, so we need to poll
|
||||
// it to be able to write/read bytes.
|
||||
class Poller final {
|
||||
public:
|
||||
static Poller CreateInputPoller(const sdbus::UnixFd &fd) {
|
||||
return Poller(fd, POLLIN);
|
||||
}
|
||||
|
||||
static Poller CreateOutputPoller(const sdbus::UnixFd &fd) {
|
||||
return Poller(fd, POLLOUT);
|
||||
}
|
||||
|
||||
Exception Ready();
|
||||
|
||||
private:
|
||||
Poller(const sdbus::UnixFd &fd, short event) : poll_event_(event) {
|
||||
fds_[0].fd = fd.get();
|
||||
fds_[0].events = event;
|
||||
}
|
||||
|
||||
short poll_event_;
|
||||
struct pollfd fds_[1];
|
||||
};
|
||||
|
||||
class BluetoothInputStream final : public nearby::InputStream {
|
||||
public:
|
||||
explicit BluetoothInputStream(sdbus::UnixFd fd) : fd_(std::move(fd)){};
|
||||
|
||||
ExceptionOr<ByteArray> Read(std::int64_t size) override;
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
sdbus::UnixFd fd_;
|
||||
};
|
||||
|
||||
class BluetoothOutputStream : public nearby::OutputStream {
|
||||
public:
|
||||
explicit BluetoothOutputStream(sdbus::UnixFd fd) : fd_(std::move(fd)){};
|
||||
|
||||
Exception Write(const ByteArray &data) override;
|
||||
Exception Flush() override { return {Exception::kSuccess}; }
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
sdbus::UnixFd fd_;
|
||||
};
|
||||
|
||||
class BluetoothSocket final : public api::BluetoothSocket {
|
||||
public:
|
||||
BluetoothSocket(std::shared_ptr<BluetoothDevice> device,
|
||||
const sdbus::UnixFd &fd)
|
||||
: device_(std::move(device)), output_stream_(fd), input_stream_(fd) {}
|
||||
|
||||
nearby::InputStream &GetInputStream() override { return input_stream_; }
|
||||
nearby::OutputStream &GetOutputStream() override { return output_stream_; }
|
||||
Exception Close() override {
|
||||
input_stream_.Close();
|
||||
output_stream_.Close();
|
||||
|
||||
return Exception{Exception::kSuccess};
|
||||
}
|
||||
api::BluetoothDevice *GetRemoteDevice() override { return device_.get(); };
|
||||
|
||||
private:
|
||||
std::shared_ptr<BluetoothDevice> device_;
|
||||
BluetoothOutputStream output_stream_;
|
||||
BluetoothInputStream input_stream_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
#endif
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
#include <absl/time/clock.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/synchronization/mutex.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/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
static constexpr std::chrono::minutes kLostPeripheralsCleanupMinFreq(5);
|
||||
|
||||
std::shared_ptr<BluetoothDevice> BluetoothDevices::get_device_by_path(
|
||||
const sdbus::ObjectPath &device_object_path) {
|
||||
absl::ReaderMutexLock l(&devices_by_path_lock_);
|
||||
|
||||
if (devices_by_path_.count(device_object_path) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return devices_by_path_[device_object_path];
|
||||
}
|
||||
|
||||
std::shared_ptr<BluetoothDevice> BluetoothDevices::get_device_by_address(
|
||||
const std::string &addr) {
|
||||
auto device_object_path =
|
||||
bluez::device_object_path(adapter_object_path_, addr);
|
||||
return get_device_by_path(device_object_path);
|
||||
}
|
||||
|
||||
void BluetoothDevices::remove_device_by_path(
|
||||
const sdbus::ObjectPath &device_object_path) {
|
||||
absl::MutexLock l(&devices_by_path_lock_);
|
||||
|
||||
devices_by_path_.erase(device_object_path);
|
||||
}
|
||||
|
||||
void BluetoothDevices::mark_peripheral_lost(
|
||||
const sdbus::ObjectPath &device_object_path) {
|
||||
absl::ReaderMutexLock lock(&devices_by_path_lock_);
|
||||
if (devices_by_path_.count(device_object_path) == 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Device " << device_object_path
|
||||
<< " doesn't exist";
|
||||
}
|
||||
devices_by_path_[device_object_path]->MarkLost();
|
||||
}
|
||||
|
||||
void BluetoothDevices::cleanup_lost_peripherals() {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
absl::MutexLock lock(&devices_by_path_lock_);
|
||||
if ((now - last_cleanup_) < kLostPeripheralsCleanupMinFreq) {
|
||||
return;
|
||||
}
|
||||
last_cleanup_ = now;
|
||||
|
||||
for (auto it = devices_by_path_.begin(), end = devices_by_path_.end();
|
||||
it != end;) {
|
||||
auto copy = it++;
|
||||
if (copy->second->Lost()) devices_by_path_.erase(copy);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<MonitoredBluetoothDevice> BluetoothDevices::add_new_device(
|
||||
sdbus::ObjectPath device_object_path) {
|
||||
absl::MutexLock l(&devices_by_path_lock_);
|
||||
auto [device_it, inserted] = devices_by_path_.emplace(
|
||||
std::string(device_object_path),
|
||||
std::make_shared<MonitoredBluetoothDevice>(
|
||||
system_bus_, std::move(device_object_path), observers_));
|
||||
if (!inserted) device_it->second->UnmarkLost();
|
||||
return device_it->second;
|
||||
}
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_DEVICES_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUETOOTH_DEVICES_H_
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/base/observer_list.h"
|
||||
#include "internal/platform/bluetooth_utils.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_device.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class BluetoothDevices final {
|
||||
public:
|
||||
BluetoothDevices(
|
||||
sdbus::IConnection &system_bus, sdbus::ObjectPath adapter_object_path,
|
||||
ObserverList<api::BluetoothClassicMedium::Observer> &observers)
|
||||
: system_bus_(system_bus),
|
||||
observers_(observers),
|
||||
adapter_object_path_(std::move(adapter_object_path)) {}
|
||||
|
||||
std::shared_ptr<BluetoothDevice> get_device_by_path(const sdbus::ObjectPath &)
|
||||
ABSL_LOCKS_EXCLUDED(devices_by_path_lock_);
|
||||
std::shared_ptr<BluetoothDevice> get_device_by_address(const std::string &);
|
||||
std::shared_ptr<BluetoothDevice> get_device_by_unique_id(
|
||||
api::ble_v2::BlePeripheral::UniqueId id) {
|
||||
auto addr = BluetoothUtils::FromNumber(id);
|
||||
return get_device_by_address(addr);
|
||||
}
|
||||
|
||||
std::shared_ptr<MonitoredBluetoothDevice> add_new_device(sdbus::ObjectPath)
|
||||
ABSL_LOCKS_EXCLUDED(devices_by_path_lock_);
|
||||
|
||||
void remove_device_by_path(const sdbus::ObjectPath &)
|
||||
ABSL_LOCKS_EXCLUDED(devices_by_path_lock_);
|
||||
void mark_peripheral_lost(const sdbus::ObjectPath &)
|
||||
ABSL_LOCKS_EXCLUDED(devices_by_path_lock_);
|
||||
void cleanup_lost_peripherals() ABSL_LOCKS_EXCLUDED(devices_by_path_lock_);
|
||||
|
||||
private:
|
||||
sdbus::IConnection &system_bus_;
|
||||
ObserverList<api::BluetoothClassicMedium::Observer> &observers_;
|
||||
sdbus::ObjectPath adapter_object_path_;
|
||||
|
||||
absl::Mutex devices_by_path_lock_;
|
||||
absl::flat_hash_map<std::string, std::shared_ptr<MonitoredBluetoothDevice>>
|
||||
devices_by_path_ ABSL_GUARDED_BY(devices_by_path_lock_);
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_cleanup_
|
||||
ABSL_GUARDED_BY(devices_by_path_lock_);
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,141 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <sdbus-c++/Error.h>
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_pairing.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
|
||||
void BluetoothPairing::pairing_reply_handler(const sdbus::Error *error) {
|
||||
if (error != nullptr && error->isValid()) {
|
||||
const auto &name = error->getName();
|
||||
api::BluetoothPairingCallback::PairingError err =
|
||||
api::BluetoothPairingCallback::PairingError::kAuthFailed;
|
||||
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": "
|
||||
<< "Got error '" << error->getName()
|
||||
<< "' with message '" << error->getMessage()
|
||||
<< "' while pairing with device "
|
||||
<< device_->getObjectPath();
|
||||
|
||||
if (name == "org.bluez.Error.AuthenticationCanceled") {
|
||||
err = api::BluetoothPairingCallback::PairingError::kAuthCanceled;
|
||||
} else if (name == "org.bluez.Error.AuthenticationFailed") {
|
||||
err = api::BluetoothPairingCallback::PairingError::kAuthFailed;
|
||||
} else if (name == "org.bluez.Error.AuthenticationRejected") {
|
||||
err = api::BluetoothPairingCallback::PairingError::kAuthRejected;
|
||||
} else if (name == "org.bluez.Error.AuthenticationTimeout") {
|
||||
err = api::BluetoothPairingCallback::PairingError::kAuthTimeout;
|
||||
}
|
||||
|
||||
if (pairing_cb_.on_pairing_error_cb != nullptr) {
|
||||
pairing_cb_.on_pairing_error_cb(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if (pairing_cb_.on_paired_cb != nullptr) {
|
||||
pairing_cb_.on_paired_cb();
|
||||
}
|
||||
}
|
||||
|
||||
BluetoothPairing::BluetoothPairing(
|
||||
BluetoothAdapter &adapter, std::shared_ptr<BluetoothDevice> remote_device)
|
||||
: device_(std::move(remote_device)), adapter_(adapter) {}
|
||||
|
||||
bool BluetoothPairing::InitiatePairing(
|
||||
api::BluetoothPairingCallback pairing_cb) {
|
||||
pairing_cb_ = std::move(pairing_cb);
|
||||
if (pairing_cb_.on_pairing_initiated_cb != nullptr)
|
||||
pairing_cb_.on_pairing_initiated_cb(api::PairingParams{
|
||||
api::PairingParams::PairingType::kConsent, std::string()});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BluetoothPairing::FinishPairing(
|
||||
std::optional<absl::string_view> pin_code) {
|
||||
device_->set_pair_reply_callback([this](const sdbus::Error *error) {
|
||||
this->pairing_reply_handler(error);
|
||||
});
|
||||
|
||||
try {
|
||||
pair_async_call_ = device_->Pair();
|
||||
} catch (const sdbus::Error &e) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while trying to initiate pairing for device "
|
||||
<< device_->getObjectPath();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BluetoothPairing::CancelPairing() {
|
||||
try {
|
||||
if (pair_async_call_.isPending()) {
|
||||
pair_async_call_.cancel();
|
||||
}
|
||||
|
||||
device_->CancelPairing();
|
||||
} catch (const sdbus::Error &e) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while trying to cancel pairing for device "
|
||||
<< device_->getObjectPath();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BluetoothPairing::Unpair() {
|
||||
try {
|
||||
adapter_.RemoveDeviceByObjectPath(device_->getObjectPath());
|
||||
return true;
|
||||
} catch (const sdbus::Error &e) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while trying to unpair device "
|
||||
<< device_->getObjectPath() << " on adapter "
|
||||
<< adapter_.GetObjectPath();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothPairing::IsPaired() {
|
||||
try {
|
||||
bool bonded = device_->Bonded();
|
||||
return bonded;
|
||||
} catch (const sdbus::Error &e) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while trying to get Bonded state for device "
|
||||
<< device_->getObjectPath();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_PAIRING_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUETOOTH_PAIRING_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <sdbus-c++/Error.h>
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/IProxy.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/linux/bluetooth_classic_device.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class BluetoothPairing final : public api::BluetoothPairing {
|
||||
public:
|
||||
BluetoothPairing(BluetoothAdapter &adapter, std::shared_ptr<BluetoothDevice> remote_device);
|
||||
|
||||
bool InitiatePairing(api::BluetoothPairingCallback pairing_cb) override;
|
||||
bool FinishPairing(std::optional<absl::string_view> pin_code) override;
|
||||
bool CancelPairing() override;
|
||||
bool Unpair() override;
|
||||
bool IsPaired() override;
|
||||
|
||||
private:
|
||||
void pairing_reply_handler(const sdbus::Error *e);
|
||||
|
||||
sdbus::PendingAsyncCall pair_async_call_;
|
||||
|
||||
std::shared_ptr<BluetoothDevice> device_;
|
||||
linux::BluetoothAdapter &adapter_;
|
||||
|
||||
api::BluetoothPairingCallback pairing_cb_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,79 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/strings/str_replace.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/substitute.h"
|
||||
#include "internal/platform/implementation/linux/bluez.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
namespace bluez {
|
||||
std::string device_object_path(const sdbus::ObjectPath &adapter_object_path,
|
||||
absl::string_view mac_address) {
|
||||
return absl::Substitute(
|
||||
"$0/dev_$1", adapter_object_path,
|
||||
absl::StrReplaceAll(absl::AsciiStrToUpper(mac_address), {{":", "_"}}));
|
||||
}
|
||||
|
||||
sdbus::ObjectPath profile_object_path(absl::string_view service_uuid) {
|
||||
return absl::Substitute(
|
||||
"/com/google/nearby/medium/bluetooth_classic/profiles/$0",
|
||||
absl::StrReplaceAll(service_uuid, {{"-", "_"}}));
|
||||
}
|
||||
|
||||
sdbus::ObjectPath adapter_object_path(absl::string_view name) {
|
||||
return absl::Substitute("/org/bluez/$0", name);
|
||||
}
|
||||
|
||||
sdbus::ObjectPath gatt_service_path(size_t num) {
|
||||
return absl::Substitute("$0/service$1", NEARBY_BLE_GATT_PATH_ROOT, num);
|
||||
}
|
||||
|
||||
sdbus::ObjectPath gatt_characteristic_path(
|
||||
const sdbus::ObjectPath &service_path, size_t num) {
|
||||
return absl::Substitute("$0/char$1", service_path, num);
|
||||
}
|
||||
|
||||
sdbus::ObjectPath ble_advertisement_path(size_t num) {
|
||||
return absl::Substitute("/com/google/nearby/medium/ble/advertisement/$0",
|
||||
num);
|
||||
}
|
||||
|
||||
sdbus::ObjectPath advertisement_monitor_path(absl::string_view uuid) {
|
||||
return absl::Substitute(
|
||||
"/com/google/nearby/medium/ble/advertisement/monitor/$0",
|
||||
absl::StrReplaceAll(uuid, {{"-", "_"}}));
|
||||
}
|
||||
|
||||
int16_t TxPowerLevelDbm(api::ble_v2::TxPowerLevel level) {
|
||||
switch (level) {
|
||||
case api::ble_v2::TxPowerLevel::kUnknown:
|
||||
return 0;
|
||||
case api::ble_v2::TxPowerLevel::kUltraLow:
|
||||
return -3;
|
||||
case api::ble_v2::TxPowerLevel::kLow:
|
||||
return 0;
|
||||
case api::ble_v2::TxPowerLevel::kMedium:
|
||||
return 3;
|
||||
case api::ble_v2::TxPowerLevel::kHigh:
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace bluez
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,86 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_BLUEZ_H_
|
||||
#define PLATFORM_IMPL_LINUX_BLUEZ_H_
|
||||
|
||||
#include <sdbus-c++/ProxyInterfaces.h>
|
||||
#include <sdbus-c++/StandardInterfaces.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#define BLUEZ_LOG_METHOD_CALL_ERROR(proxy, method, err) \
|
||||
do { \
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << (err).getName() \
|
||||
<< "' with message '" << (err).getMessage() \
|
||||
<< "' while calling " << method << " on object " \
|
||||
<< (proxy)->getObjectPath(); \
|
||||
} while (false)
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
namespace bluez {
|
||||
static constexpr const char *SERVICE_DEST = "org.bluez";
|
||||
|
||||
static constexpr const char *ADAPTER_INTERFACE = "org.bluez.Adapter1";
|
||||
|
||||
static constexpr const char *DEVICE_INTERFACE = "org.bluez.Device1";
|
||||
static constexpr const char *DEVICE_PROP_ADDRESS = "Address";
|
||||
static constexpr const char *DEVICE_PROP_ALIAS = "Alias";
|
||||
static constexpr const char *DEVICE_PROP_PAIRED = "Paired";
|
||||
static constexpr const char *DEVICE_PROP_CONNECTED = "Connected";
|
||||
static constexpr const char *DEVICE_NAME = "Name";
|
||||
|
||||
static constexpr const char *NEARBY_BLE_GATT_PATH_ROOT =
|
||||
"/com/google/nearby/medium/ble/gatt";
|
||||
|
||||
std::string device_object_path(const sdbus::ObjectPath &adapter_object_path,
|
||||
absl::string_view mac_address);
|
||||
sdbus::ObjectPath profile_object_path(absl::string_view service_uuid);
|
||||
sdbus::ObjectPath adapter_object_path(absl::string_view name);
|
||||
sdbus::ObjectPath gatt_service_path(size_t num);
|
||||
sdbus::ObjectPath gatt_characteristic_path(
|
||||
const sdbus::ObjectPath &service_path, size_t num);
|
||||
sdbus::ObjectPath ble_advertisement_path(size_t num);
|
||||
sdbus::ObjectPath advertisement_monitor_path(absl::string_view uuid);
|
||||
int16_t TxPowerLevelDbm(api::ble_v2::TxPowerLevel level);
|
||||
|
||||
class BluezObjectManager
|
||||
: public sdbus::ProxyInterfaces<sdbus::ObjectManager_proxy> {
|
||||
public:
|
||||
BluezObjectManager(sdbus::IConnection &system_bus)
|
||||
: ProxyInterfaces(system_bus, "org.bluez", "/") {
|
||||
registerProxy();
|
||||
}
|
||||
~BluezObjectManager() { unregisterProxy(); }
|
||||
|
||||
protected:
|
||||
void onInterfacesAdded(
|
||||
const sdbus::ObjectPath &objectPath,
|
||||
const std::map<std::string, std::map<std::string, sdbus::Variant>>
|
||||
&interfacesAndProperties) override {}
|
||||
void onInterfacesRemoved(
|
||||
const sdbus::ObjectPath &objectPath,
|
||||
const std::vector<std::string> &interfaces) override {}
|
||||
};
|
||||
|
||||
} // namespace bluez
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,185 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <memory>
|
||||
|
||||
#include "internal/platform/implementation/linux/wifi_direct.h"
|
||||
#include "internal/platform/implementation/linux/wifi_direct_server_socket.h"
|
||||
#include "internal/platform/implementation/linux/wifi_direct_socket.h"
|
||||
#include "internal/platform/implementation/linux/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
std::unique_ptr<api::WifiDirectSocket>
|
||||
NetworkManagerWifiDirectMedium::ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag *cancellation_flag) {
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error opening socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Connecting to " << ip_address << ":"
|
||||
<< port;
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_addr.s_addr = inet_addr(std::string(ip_address).c_str());
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
auto ret =
|
||||
connect(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr));
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error connecting to socket: "
|
||||
<< std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<WifiDirectSocket>(sock);
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiDirectServerSocket>
|
||||
NetworkManagerWifiDirectMedium::ListenForService(int port) {
|
||||
auto active_connection = wireless_device_->GetActiveConnection();
|
||||
if (active_connection == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ip4addresses = active_connection->GetIP4Addresses();
|
||||
if (ip4addresses.empty()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< "Could not find any IPv4 addresses for active connection "
|
||||
<< active_connection->getObjectPath();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error opening socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr(ip4addresses[0].c_str());
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
auto ret =
|
||||
bind(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr));
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error binding to socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Listening for services on "
|
||||
<< ip4addresses[0] << ":" << port << " on device "
|
||||
<< wireless_device_->getObjectPath();
|
||||
|
||||
ret = listen(sock, 0);
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error listening on socket: "
|
||||
<< std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<NetworkManagerWifiDirectServerSocket>(
|
||||
sock, system_bus_, active_connection->getObjectPath(), network_manager_);
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiDirectMedium::ConnectWifiDirect(
|
||||
WifiDirectCredentials *wifi_direct_credentials) {
|
||||
if (wifi_direct_credentials == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": hotspot_credentials cannot be null";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ssid = wifi_direct_credentials->GetSSID();
|
||||
auto password = wifi_direct_credentials->GetPassword();
|
||||
|
||||
return wireless_device_->ConnectToNetwork(ssid, password,
|
||||
api::WifiAuthType::kWpaPsk) ==
|
||||
api::WifiConnectionStatus::kConnected;
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiDirectMedium::DisconnectWifiDirect() {
|
||||
if (!ConnectedToWifi()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Not connected to a WiFi hotspot";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto active_connection = wireless_device_->GetActiveConnection();
|
||||
if (active_connection == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
network_manager_->DeactivateConnection(active_connection->getObjectPath());
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(network_manager_, "DeactivateConnection", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiDirectMedium::ConnectedToWifi() {
|
||||
try {
|
||||
auto mode = wireless_device_->Mode();
|
||||
return mode == 2; // NM_802_11_MODE_INFRA
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(wireless_device_, "Mode", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiDirectMedium::StartWifiDirect(
|
||||
WifiDirectCredentials *wifi_direct_credentials) {
|
||||
// According to the comments in the windows implementation, the wifi direct
|
||||
// medium is currently just a regular wifi hotspot.
|
||||
// auto wireless_device = std::make_unique<NetworkManagerWifiMedium>(
|
||||
// network_manager_, system_bus_, wireless_device_->getObjectPath());
|
||||
// auto hotspot = NetworkManagerWifiHotspotMedium(system_bus_, network_manager_,
|
||||
// std::move(wireless_device));
|
||||
|
||||
// HotspotCredentials hotspot_creds;
|
||||
// if (!hotspot.StartWifiHotspot(&hotspot_creds)) return false;
|
||||
|
||||
// wifi_direct_credentials->SetSSID(hotspot_creds.GetSSID());
|
||||
// wifi_direct_credentials->SetPassword(hotspot_creds.GetPassword());
|
||||
// return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiDirectMedium::StopWifiDirect() {
|
||||
// auto wireless_device = std::make_unique<NetworkManagerWifiMedium>(
|
||||
// network_manager_, system_bus_, wireless_device_->getObjectPath());
|
||||
// auto hotspot = NetworkManagerWifiHotspotMedium(system_bus_, network_manager_,
|
||||
// std::move(wireless_device));
|
||||
|
||||
// return hotspot.DisconnectWifiHotspot();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_WIFI_DIRECT_H_
|
||||
#define PLATFORM_IMPL_LINUX_WIFI_DIRECT_H_
|
||||
#include <memory>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class NetworkManagerWifiDirectMedium : public api::WifiDirectMedium {
|
||||
public:
|
||||
NetworkManagerWifiDirectMedium(
|
||||
sdbus::IConnection &system_bus,
|
||||
std::shared_ptr<NetworkManager> network_manager,
|
||||
std::unique_ptr<NetworkManagerWifiMedium> wireless_device)
|
||||
: system_bus_(system_bus),
|
||||
network_manager_(std::move(network_manager)),
|
||||
wireless_device_(std::move(wireless_device)) {}
|
||||
|
||||
bool IsInterfaceValid() const override { return true; }
|
||||
std::unique_ptr<api::WifiDirectSocket> ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag *cancellation_flag) override;
|
||||
std::unique_ptr<api::WifiDirectServerSocket> ListenForService(
|
||||
int port) override;
|
||||
bool ConnectWifiDirect(
|
||||
WifiDirectCredentials *wifi_direct_credentials) override;
|
||||
bool DisconnectWifiDirect() override;
|
||||
|
||||
bool StartWifiDirect(WifiDirectCredentials *wifi_direct_credentials) override;
|
||||
bool StopWifiDirect() override;
|
||||
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange()
|
||||
override {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
bool ConnectedToWifi();
|
||||
|
||||
sdbus::IConnection &system_bus_;
|
||||
std::shared_ptr<NetworkManager> network_manager_;
|
||||
std::unique_ptr<NetworkManagerWifiMedium> wireless_device_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,81 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/linux/wifi_direct_server_socket.h"
|
||||
#include "internal/platform/implementation/linux/wifi_direct_socket.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
std::string NetworkManagerWifiDirectServerSocket::GetIPAddress() const {
|
||||
NetworkManagerActiveConnection active_conn(system_bus_,
|
||||
active_connection_path_);
|
||||
auto ip4addresses = active_conn.GetIP4Addresses();
|
||||
if (ip4addresses.empty()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Could not find any IPv4 addresses for active connection "
|
||||
<< active_connection_path_;
|
||||
return std::string();
|
||||
}
|
||||
return ip4addresses[0];
|
||||
}
|
||||
|
||||
int NetworkManagerWifiDirectServerSocket::GetPort() const {
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
auto ret =
|
||||
getsockname(fd_.get(), reinterpret_cast<struct sockaddr *>(&sin), &len);
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error getting information for socket "
|
||||
<< fd_.get() << ": " << std::strerror(errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ntohs(sin.sin_port);
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiDirectSocket>
|
||||
NetworkManagerWifiDirectServerSocket::Accept() {
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
|
||||
auto conn =
|
||||
accept(fd_.get(), reinterpret_cast<struct sockaddr *>(&addr), &len);
|
||||
if (conn < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error accepting incoming connections on socket "
|
||||
<< fd_.get() << ": " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<WifiDirectSocket>(conn);
|
||||
}
|
||||
|
||||
Exception NetworkManagerWifiDirectServerSocket::Close() {
|
||||
int fd = fd_.release();
|
||||
auto ret = close(fd);
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error closing socket " << fd << ": "
|
||||
<< std::strerror(errno);
|
||||
return {Exception::kFailed};
|
||||
}
|
||||
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_WIFI_DIRECT_SERVER_SOCKET_H_
|
||||
#define PLATFORM_IMPL_LINUX_WIFI_DIRECT_SERVER_SOCKET_H_
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class NetworkManagerWifiDirectServerSocket
|
||||
: public api::WifiDirectServerSocket {
|
||||
public:
|
||||
NetworkManagerWifiDirectServerSocket(
|
||||
int socket, sdbus::IConnection &system_bus,
|
||||
sdbus::ObjectPath active_connection_path,
|
||||
std::shared_ptr<NetworkManager> network_manager)
|
||||
: fd_(socket),
|
||||
system_bus_(system_bus),
|
||||
active_connection_path_(std::move(active_connection_path)),
|
||||
network_manager_(std::move(network_manager)) {}
|
||||
|
||||
std::string GetIPAddress() const override;
|
||||
int GetPort() const override;
|
||||
std::unique_ptr<api::WifiDirectSocket> Accept() override;
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
sdbus::UnixFd fd_;
|
||||
sdbus::IConnection &system_bus_;
|
||||
sdbus::ObjectPath active_connection_path_;
|
||||
std::shared_ptr<NetworkManager> network_manager_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_WIFI_DIRECT_SOCKET_H_
|
||||
#define PLATFORM_IMPL_LINUX_WIFI_DIRECT_SOCKET_H_
|
||||
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/linux/stream.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class WifiDirectSocket : public api::WifiDirectSocket {
|
||||
public:
|
||||
explicit WifiDirectSocket(int socket)
|
||||
: fd_(sdbus::UnixFd(socket)), output_stream_(fd_), input_stream_(fd_) {}
|
||||
|
||||
InputStream &GetInputStream() override { return input_stream_; };
|
||||
OutputStream &GetOutputStream() override { return output_stream_; };
|
||||
|
||||
Exception Close() override {
|
||||
input_stream_.Close();
|
||||
output_stream_.Close();
|
||||
|
||||
return Exception{Exception::kSuccess};
|
||||
};
|
||||
|
||||
private:
|
||||
sdbus::UnixFd fd_;
|
||||
OutputStream output_stream_;
|
||||
InputStream input_stream_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,336 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include <systemd/sd-id128.h>
|
||||
|
||||
#include "internal/platform/implementation/linux/dbus.h"
|
||||
#include "internal/platform/implementation/linux/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/linux/wifi_hotspot_server_socket.h"
|
||||
#include "internal/platform/implementation/linux/wifi_hotspot_socket.h"
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
#include "internal/platform/implementation/wifi.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
std::unique_ptr<api::WifiHotspotSocket>
|
||||
NetworkManagerWifiHotspotMedium::ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag *cancellation_flag) {
|
||||
if (!WifiHotspotActive()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Cannot connect to service without an active WiFi hotspot";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error opening socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Connecting to " << ip_address << ":"
|
||||
<< port;
|
||||
struct sockaddr_in addr {};
|
||||
addr.sin_addr.s_addr = inet_addr(std::string(ip_address).c_str());
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
auto ret =
|
||||
connect(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr));
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error connecting to socket: "
|
||||
<< std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<WifiHotspotSocket>(sock);
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotServerSocket>
|
||||
NetworkManagerWifiHotspotMedium::ListenForService(int port) {
|
||||
if (!WifiHotspotActive()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Cannot connect to service without an active WiFi hotspot";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto active_connection = wireless_device_->GetActiveConnection();
|
||||
if (active_connection == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ip4addresses = active_connection->GetIP4Addresses();
|
||||
if (ip4addresses.empty()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< "Could not find any IPv4 addresses for active connection "
|
||||
<< active_connection->getObjectPath();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error opening socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr(ip4addresses[0].c_str());
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
auto ret =
|
||||
bind(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr));
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error binding to socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Listening for services on "
|
||||
<< ip4addresses[0] << ":" << port << " on device "
|
||||
<< wireless_device_->getObjectPath();
|
||||
|
||||
ret = listen(sock, 0);
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error listening on socket: "
|
||||
<< std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<NetworkManagerWifiHotspotServerSocket>(
|
||||
sock, system_bus_, active_connection->getObjectPath(), network_manager_);
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::StartWifiHotspot(
|
||||
HotspotCredentials *hotspot_credentials) {
|
||||
if (WifiHotspotActive()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": " << wireless_device_->getObjectPath()
|
||||
<< ": cannot start WiFi hotspot, a hotspot is already "
|
||||
"active on this device";
|
||||
return false;
|
||||
}
|
||||
|
||||
sd_id128_t id;
|
||||
if (auto ret = sd_id128_randomize(&id); ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": error generating a 128-bit ID: "
|
||||
<< std::strerror(ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
char id_cstr[SD_ID128_UUID_STRING_MAX];
|
||||
sd_id128_to_string(id, id_cstr);
|
||||
|
||||
std::string ssid = absl::StrCat("DIRECT-", id_cstr);
|
||||
ssid.resize(32);
|
||||
hotspot_credentials->SetSSID(ssid);
|
||||
|
||||
if (auto ret = sd_id128_randomize(&id); ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": error generating a 128-bit ID: "
|
||||
<< std::strerror(ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
sd_id128_to_string(id, id_cstr);
|
||||
std::string password = std::string(id_cstr, 15);
|
||||
hotspot_credentials->SetPassword(password);
|
||||
|
||||
if (auto ret = sd_id128_randomize(&id); ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": error generating a 128-bit ID: "
|
||||
<< std::strerror(ret);
|
||||
return false;
|
||||
}
|
||||
sd_id128_to_uuid_string(id, id_cstr);
|
||||
|
||||
std::vector<uint8_t> ssid_bytes(ssid.begin(), ssid.end());
|
||||
std::map<std::string, std::map<std::string, sdbus::Variant>>
|
||||
connection_settings{
|
||||
{
|
||||
"connection",
|
||||
std::map<std::string, sdbus::Variant>{
|
||||
{"uuid", std::string(id_cstr)},
|
||||
{"id", "Google Nearby Hotspot"},
|
||||
{"type", "802-11-wireless"},
|
||||
{"zone", "Public"}},
|
||||
},
|
||||
{"802-11-wireless",
|
||||
std::map<std::string, sdbus::Variant>{
|
||||
{"assigned-mac-address", "random"},
|
||||
{"ap-isolation",
|
||||
static_cast<std::int32_t>(0)}, // NM_TERNARY_FALSE
|
||||
{"mode", "ap"},
|
||||
{"ssid", ssid_bytes},
|
||||
{"security", "802-11-wireless-security"}}},
|
||||
{"802-11-wireless-security",
|
||||
std::map<std::string, sdbus::Variant>{
|
||||
{"group", std::vector<std::string>{"ccmp"}},
|
||||
{"key-mgmt", "wpa-psk"},
|
||||
{
|
||||
"pairwise",
|
||||
std::vector<std::string>{"ccmp"},
|
||||
},
|
||||
{"proto", std::vector<std::string>{"rsn"}},
|
||||
{"psk", password}}},
|
||||
{"ipv4", std::map<std::string, sdbus::Variant>{{"method", "shared"}}},
|
||||
{"ipv6", std::map<std::string, sdbus::Variant>{
|
||||
{"addr-gen-mode", static_cast<std::int32_t>(1)},
|
||||
{"method", "shared"},
|
||||
}}};
|
||||
std::unique_ptr<NetworkManagerActiveConnection> active_conn;
|
||||
try {
|
||||
auto [path, active_path, result] =
|
||||
network_manager_->AddAndActivateConnection2(
|
||||
connection_settings, wireless_device_->getObjectPath(), "/",
|
||||
{{"persist", "volatile"}, {"bind-activation", "dbus-client"}});
|
||||
active_conn = std::make_unique<NetworkManagerActiveConnection>(system_bus_,
|
||||
active_path);
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(network_manager_, "AddAndActivateConnection2",
|
||||
e);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto [reason, timeout] = active_conn->WaitForConnection();
|
||||
if (timeout) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << ": "
|
||||
<< ": timed out while waiting for connection "
|
||||
<< active_conn->getObjectPath()
|
||||
<< " to be activated, last NMActiveConnectionStateReason: "
|
||||
<< reason.value();
|
||||
DisconnectWifiHotspot();
|
||||
return false;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Started a WiFi hotspot on device "
|
||||
<< wireless_device_->getObjectPath() << " at "
|
||||
<< active_conn->getObjectPath();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::StopWifiHotspot() {
|
||||
if (!WifiHotspotActive()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << ": " << wireless_device_->getObjectPath()
|
||||
<< ": Cannot stop WiFi hotspot as a WiFi hotspot is not active";
|
||||
}
|
||||
|
||||
// Get the active connection object for the hotspot AP.
|
||||
sdbus::ObjectPath active_ap_path;
|
||||
|
||||
try {
|
||||
active_ap_path = wireless_device_->ActiveAccessPoint();
|
||||
if (active_ap_path.empty()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": No active access points on "
|
||||
<< wireless_device_->getObjectPath();
|
||||
return false;
|
||||
}
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(wireless_device_, "ActiveAccessPoint", e);
|
||||
}
|
||||
|
||||
auto object_manager = NetworkManagerObjectManager(system_bus_);
|
||||
auto active_connection = wireless_device_->GetActiveConnection();
|
||||
if (active_connection == nullptr) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Could not find an active connection using the access point "
|
||||
<< active_ap_path;
|
||||
return false;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__ << ": " << wireless_device_->getObjectPath()
|
||||
<< ": Deactivating active connection "
|
||||
<< active_connection->getObjectPath();
|
||||
|
||||
try {
|
||||
network_manager_->DeactivateConnection(active_connection->getObjectPath());
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(network_manager_, "DeactivateConnection", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::ConnectWifiHotspot(
|
||||
HotspotCredentials *hotspot_credentials) {
|
||||
if (hotspot_credentials == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": hotspot_credentials cannot be null";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ssid = hotspot_credentials->GetSSID();
|
||||
auto password = hotspot_credentials->GetPassword();
|
||||
|
||||
return wireless_device_->ConnectToNetwork(ssid, password,
|
||||
api::WifiAuthType::kWpaPsk) ==
|
||||
api::WifiConnectionStatus::kConnected;
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::DisconnectWifiHotspot() {
|
||||
if (!ConnectedToWifi()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Not connected to a WiFi hotspot";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto active_connection = wireless_device_->GetActiveConnection();
|
||||
if (active_connection == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
network_manager_->DeactivateConnection(active_connection->getObjectPath());
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(network_manager_, "DeactivateConnection", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::WifiHotspotActive() {
|
||||
try {
|
||||
auto mode = wireless_device_->Mode();
|
||||
return mode == 3; // NM_802_11_MODE_AP
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(wireless_device_, "Mode", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::ConnectedToWifi() {
|
||||
try {
|
||||
auto mode = wireless_device_->Mode();
|
||||
return mode == 2; // NM_802_11_MODE_INFRA
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(wireless_device_, "Mode", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,74 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_WIFI_HOTSPOT_H_
|
||||
#define PLATFORM_IMPL_LINUX_WIFI_HOTSPOT_H_
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/Types.h>
|
||||
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class NetworkManagerWifiHotspotMedium : public api::WifiHotspotMedium {
|
||||
public:
|
||||
NetworkManagerWifiHotspotMedium(
|
||||
sdbus::IConnection &system_bus,
|
||||
std::shared_ptr<NetworkManager> network_manager,
|
||||
sdbus::ObjectPath wireless_device_object_path)
|
||||
: system_bus_(system_bus),
|
||||
wireless_device_(std::make_unique<NetworkManagerWifiMedium>(
|
||||
network_manager, system_bus,
|
||||
std::move(wireless_device_object_path))),
|
||||
network_manager_(std::move(network_manager)) {}
|
||||
NetworkManagerWifiHotspotMedium(
|
||||
sdbus::IConnection &system_bus,
|
||||
std::shared_ptr<NetworkManager> network_manager,
|
||||
std::unique_ptr<NetworkManagerWifiMedium> wireless_device)
|
||||
: system_bus_(system_bus),
|
||||
wireless_device_(std::move(wireless_device)),
|
||||
network_manager_(std::move(network_manager)) {}
|
||||
|
||||
bool IsInterfaceValid() const override { return true; }
|
||||
std::unique_ptr<api::WifiHotspotSocket> ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag *cancellation_flag) override;
|
||||
std::unique_ptr<api::WifiHotspotServerSocket> ListenForService(
|
||||
int port) override;
|
||||
|
||||
bool StartWifiHotspot(HotspotCredentials *hotspot_credentials) override;
|
||||
bool StopWifiHotspot() override;
|
||||
|
||||
bool ConnectWifiHotspot(HotspotCredentials *hotspot_credentials) override;
|
||||
bool DisconnectWifiHotspot() override;
|
||||
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange()
|
||||
override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
bool WifiHotspotActive();
|
||||
bool ConnectedToWifi();
|
||||
|
||||
sdbus::IConnection &system_bus_;
|
||||
std::unique_ptr<NetworkManagerWifiMedium> wireless_device_;
|
||||
std::shared_ptr<NetworkManager> network_manager_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,80 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "internal/platform/implementation/linux/wifi_hotspot_server_socket.h"
|
||||
#include "internal/platform/implementation/linux/wifi_hotspot_socket.h"
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
std::string NetworkManagerWifiHotspotServerSocket::GetIPAddress() const {
|
||||
NetworkManagerActiveConnection active_conn(system_bus_,
|
||||
active_connection_path_);
|
||||
auto ip4addresses = active_conn.GetIP4Addresses();
|
||||
if (ip4addresses.empty()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Could not find any IPv4 addresses for active connection "
|
||||
<< active_connection_path_;
|
||||
return {};
|
||||
}
|
||||
return ip4addresses[0];
|
||||
}
|
||||
|
||||
int NetworkManagerWifiHotspotServerSocket::GetPort() const {
|
||||
struct sockaddr_in sin{};
|
||||
socklen_t len = sizeof(sin);
|
||||
auto ret =
|
||||
getsockname(fd_.get(), reinterpret_cast<struct sockaddr *>(&sin), &len);
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error getting information for socket "
|
||||
<< fd_.get() << ": " << std::strerror(errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ntohs(sin.sin_port);
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotSocket>
|
||||
NetworkManagerWifiHotspotServerSocket::Accept() {
|
||||
struct sockaddr_in addr{};
|
||||
socklen_t len = sizeof(addr);
|
||||
|
||||
auto conn =
|
||||
accept(fd_.get(), reinterpret_cast<struct sockaddr *>(&addr), &len);
|
||||
if (conn < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error accepting incoming connections on socket "
|
||||
<< fd_.get() << ": " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<WifiHotspotSocket>(conn);
|
||||
}
|
||||
|
||||
Exception NetworkManagerWifiHotspotServerSocket::Close() {
|
||||
auto ret = close(fd_.release());
|
||||
if (ret < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Error closing socket: "
|
||||
<< std::strerror(errno);
|
||||
return {Exception::kFailed};
|
||||
}
|
||||
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_WIFI_SERVER_SOCKET_H_
|
||||
#define PLATFORM_IMPL_LINUX_WIFI_SERVER_SOCKET_H_
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class NetworkManagerWifiHotspotServerSocket
|
||||
: public api::WifiHotspotServerSocket {
|
||||
public:
|
||||
NetworkManagerWifiHotspotServerSocket(
|
||||
int socket, sdbus::IConnection &system_bus,
|
||||
sdbus::ObjectPath active_connection_path,
|
||||
std::shared_ptr<NetworkManager> network_manager)
|
||||
: fd_(socket),
|
||||
system_bus_(system_bus),
|
||||
active_connection_path_(std::move(active_connection_path)),
|
||||
network_manager_(std::move(network_manager)) {}
|
||||
|
||||
std::string GetIPAddress() const override;
|
||||
int GetPort() const override;
|
||||
std::unique_ptr<api::WifiHotspotSocket> Accept() override;
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
sdbus::UnixFd fd_;
|
||||
sdbus::IConnection &system_bus_;
|
||||
sdbus::ObjectPath active_connection_path_;
|
||||
std::shared_ptr<NetworkManager> network_manager_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_LINUX_WIFI_HOTSPOT_SOCKET_H_
|
||||
#define PLATFORM_IMPL_LINUX_WIFI_HOTSPOT_SOCKET_H_
|
||||
|
||||
#include "internal/platform/implementation/linux/stream.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
public:
|
||||
explicit WifiHotspotSocket(int connection_fd)
|
||||
: fd_(sdbus::UnixFd(connection_fd)),
|
||||
output_stream_(fd_),
|
||||
input_stream_(fd_) {}
|
||||
|
||||
nearby::InputStream &GetInputStream() override { return input_stream_; };
|
||||
nearby::OutputStream &GetOutputStream() override { return output_stream_; };
|
||||
Exception Close() override {
|
||||
input_stream_.Close();
|
||||
output_stream_.Close();
|
||||
|
||||
return Exception{Exception::kSuccess};
|
||||
};
|
||||
|
||||
private:
|
||||
sdbus::UnixFd fd_;
|
||||
OutputStream output_stream_;
|
||||
InputStream input_stream_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -157,7 +157,7 @@ bool WifiLanMedium::StartDiscovery(
|
||||
avahi_->ServiceBrowserPrepare(-1, // AVAHI_IF_UNSPEC
|
||||
-1, // AVAHI_PROTO_UNSPED
|
||||
service_type, std::string(), 0);
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
NEARBY_VLOG(1)
|
||||
<< __func__
|
||||
<< ": Created a new org.freedesktop.Avahi.ServiceBrowser object at "
|
||||
<< browser_object_path;
|
||||
@@ -177,7 +177,7 @@ bool WifiLanMedium::StartDiscovery(
|
||||
service_browsers_mutex_.ReaderUnlock();
|
||||
|
||||
try {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Starting service discovery for "
|
||||
NEARBY_VLOG(1) << __func__ << ": Starting service discovery for "
|
||||
<< browser->getObjectPath();
|
||||
browser->Start();
|
||||
} catch (const sdbus::Error &e) {
|
||||
@@ -211,7 +211,7 @@ std::unique_ptr<api::WifiLanSocket> WifiLanMedium::ConnectToService(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Connecting to " << ip_address << ":"
|
||||
NEARBY_VLOG(1) << __func__ << ": Connecting to " << ip_address << ":"
|
||||
<< port;
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_addr.s_addr = inet_addr(ip_address.c_str());
|
||||
@@ -259,7 +259,7 @@ std::unique_ptr<api::WifiLanServerSocket> WifiLanMedium::ListenForService(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << "Listening for services on port " << port;
|
||||
NEARBY_VLOG(1) << __func__ << "Listening for services on port " << port;
|
||||
|
||||
return std::make_unique<WifiLanServerSocket>(sock, network_manager_,
|
||||
system_bus_);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/ProxyInterfaces.h>
|
||||
|
||||
Reference in New Issue
Block a user