mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 07:06:11 -04:00
Add more wifi code.
This commit is contained in:
@@ -1,86 +1,114 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <random>
|
||||
#include <sys/socket.h>
|
||||
#include <systemd/sd-id128.h>
|
||||
|
||||
#include "internal/platform/implementation/linux/dbus.h"
|
||||
#include "internal/platform/implementation/linux/networkmanager_connection_active_client_glue.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 {
|
||||
bool NetworkManagerWifiHotspotMedium::ConnectWifiHotspot(
|
||||
HotspotCredentials *hotspot_credentials) {
|
||||
if (hotspot_credentials == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": hotspot_credentials cannot be null";
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
auto ssid = hotspot_credentials->GetSSID();
|
||||
auto password = hotspot_credentials->GetPassword();
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Error opening socket: " << std::strerror(errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return wireless_device_->ConnectToNetwork(ssid, password,
|
||||
api::WifiAuthType::kWpaPsk) ==
|
||||
api::WifiConnectionStatus::kConnected;
|
||||
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);
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::DisconnectWifiHotspot() {
|
||||
std::unique_ptr<api::WifiHotspotServerSocket>
|
||||
NetworkManagerWifiHotspotMedium::ListenForService(int port) {
|
||||
if (!WifiHotspotActive()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": WiFi hotspot is not active";
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
sdbus::ObjectPath active_ap_path;
|
||||
|
||||
try {
|
||||
active_ap_path = wireless_device_->ActiveAccessPoint();
|
||||
if (active_ap_path.empty()) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Not connected to any 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 objects = object_manager.GetManagedObjects();
|
||||
|
||||
for (auto &[path, interfaces] : objects) {
|
||||
if (path.find("/org/freedesktop/NetworkManager/ActiveConnection/") == 0) {
|
||||
if (interfaces.count(org::freedesktop::NetworkManager::Connection::
|
||||
Active_proxy::INTERFACE_NAME) == 1) {
|
||||
sdbus::ObjectPath specific_object =
|
||||
interfaces[org::freedesktop::NetworkManager::Connection::
|
||||
Active_proxy::INTERFACE_NAME]["SpecificObject"];
|
||||
if (specific_object == active_ap_path) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Deactivating active connection "
|
||||
<< active_ap_path;
|
||||
|
||||
try {
|
||||
network_manager_->DeactivateConnection(path);
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(network_manager_, "DeactiveConnection",
|
||||
e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Could not find an active connection with the access point "
|
||||
<< active_ap_path;
|
||||
return false;
|
||||
return std::make_unique<NetworkManagerWifiHotspotServerSocket>(sock,
|
||||
system_bus_, active_connection->getObjectPath(), network_manager_);
|
||||
}
|
||||
|
||||
bool NetworkManagerWifiHotspotMedium::StartWifiHotspot(
|
||||
@@ -150,11 +178,12 @@ bool NetworkManagerWifiHotspotMedium::StartWifiHotspot(
|
||||
}}};
|
||||
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"}});
|
||||
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);
|
||||
active_path);
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(network_manager_, "AddAndActivateConnection2",
|
||||
e);
|
||||
@@ -163,13 +192,14 @@ bool NetworkManagerWifiHotspotMedium::StartWifiHotspot(
|
||||
|
||||
auto [reason, timeout] = active_conn->WaitForConnection();
|
||||
if (timeout) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": "
|
||||
<< ": timed out while waiting for connection "
|
||||
<< active_conn->getObjectPath()
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << ": "
|
||||
<< ": timed out while waiting for connection "
|
||||
<< active_conn->getObjectPath()
|
||||
<< " to be activated, last NMActiveConnectionStateReason: "
|
||||
<< reason.value();
|
||||
DisconnectWifiHotspot();
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Started a WiFi hotspot on device "
|
||||
@@ -178,6 +208,87 @@ bool NetworkManagerWifiHotspotMedium::StartWifiHotspot(
|
||||
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 (!WifiHotspotActive()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": WiFi hotspot is not active";
|
||||
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();
|
||||
@@ -187,5 +298,6 @@ bool NetworkManagerWifiHotspotMedium::WifiHotspotActive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
@@ -8,43 +8,51 @@
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class NetworkManagerWifiHotspotMedium : api::WifiHotspotMedium {
|
||||
public:
|
||||
NetworkManagerWifiHotspotMedium(
|
||||
sdbus::IConnection &system_bus,
|
||||
std::shared_ptr<NetworkManager> network_manager,
|
||||
const sdbus::ObjectPath &wireless_device_object_path)
|
||||
: system_bus_(system_bus),
|
||||
wireless_device_(std::make_unique<NetworkManagerWifiMedium>(
|
||||
network_manager, system_bus, wireless_device_object_path)),
|
||||
network_manager_(network_manager) {}
|
||||
~NetworkManagerWifiHotspotMedium() {}
|
||||
namespace linux {
|
||||
class NetworkManagerWifiHotspotMedium : public api::WifiHotspotMedium {
|
||||
public:
|
||||
NetworkManagerWifiHotspotMedium(
|
||||
sdbus::IConnection &system_bus,
|
||||
std::shared_ptr<NetworkManager> network_manager,
|
||||
const sdbus::ObjectPath &wireless_device_object_path)
|
||||
: system_bus_(system_bus),
|
||||
wireless_device_(std::make_unique<NetworkManagerWifiMedium>(
|
||||
network_manager, system_bus, wireless_device_object_path)),
|
||||
network_manager_(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_(network_manager) {}
|
||||
~NetworkManagerWifiHotspotMedium() {}
|
||||
|
||||
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 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 StartWifiHotspot(HotspotCredentials *hotspot_credentials) override;
|
||||
bool StopWifiHotspot() override;
|
||||
|
||||
bool ConnectWifiHotspot(HotspotCredentials *hotspot_credentials) override;
|
||||
bool DisconnectWifiHotspot() 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();
|
||||
|
||||
sdbus::IConnection &system_bus_;
|
||||
std::unique_ptr<NetworkManagerWifiMedium> wireless_device_;
|
||||
std::shared_ptr<NetworkManager> network_manager_;
|
||||
};
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>>
|
||||
GetDynamicPortRange() override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool WifiHotspotActive();
|
||||
|
||||
sdbus::IConnection &system_bus_;
|
||||
std::unique_ptr<NetworkManagerWifiMedium> wireless_device_;
|
||||
std::shared_ptr<NetworkManager> network_manager_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#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 std::string();
|
||||
}
|
||||
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() {
|
||||
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
|
||||
@@ -0,0 +1,37 @@
|
||||
#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,
|
||||
const sdbus::ObjectPath &active_connection_path,
|
||||
std::shared_ptr<NetworkManager> network_manager)
|
||||
: fd_(socket), system_bus_(system_bus),
|
||||
active_connection_path_(active_connection_path),
|
||||
network_manager_(network_manager) {}
|
||||
~NetworkManagerWifiHotspotServerSocket() {}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,33 @@
|
||||
#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:
|
||||
WifiHotspotSocket(int connection_fd)
|
||||
: fd_(sdbus::UnixFd(connection_fd)), output_stream_(fd_),
|
||||
input_stream_(fd_) {}
|
||||
~WifiHotspotSocket() {}
|
||||
|
||||
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
|
||||
@@ -79,6 +79,7 @@ bool WifiLanMedium::StartAdvertising(const NsdServiceInfo &nsd_service_info) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while adding service";
|
||||
return false;
|
||||
}
|
||||
|
||||
advertising_ = true;
|
||||
@@ -107,6 +108,7 @@ bool WifiLanMedium::StopAdvertising(const NsdServiceInfo &nsd_service_info) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
|
||||
<< "' with message '" << e.getMessage()
|
||||
<< "' while removing service";
|
||||
return false;
|
||||
}
|
||||
|
||||
advertising_ = false;
|
||||
@@ -137,6 +139,7 @@ bool WifiLanMedium::StartDiscovery(
|
||||
std::move(callback));
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(avahi_, "ServiceBrowserPrepare", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &browser = service_browsers_[service_type];
|
||||
@@ -146,6 +149,7 @@ bool WifiLanMedium::StartDiscovery(
|
||||
browser->Start();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(browser, "Start", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -163,6 +167,7 @@ bool WifiLanMedium::StopDiscovery(const std::string &service_type) {
|
||||
browser->Free();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(browser, "Free", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
service_browsers_.erase(service_type);
|
||||
@@ -199,7 +204,8 @@ WifiLanMedium::ConnectToService(const std::string &ip_address, int port,
|
||||
return std::make_unique<WifiLanSocket>(std::move(fd));
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiLanServerSocket> WifiLanMedium::ListenForService(int port) {
|
||||
std::unique_ptr<api::WifiLanServerSocket>
|
||||
WifiLanMedium::ListenForService(int port) {
|
||||
auto sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
@@ -229,7 +235,8 @@ std::unique_ptr<api::WifiLanServerSocket> WifiLanMedium::ListenForService(int po
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<WifiLanServerSocket>(sock, network_manager_);
|
||||
return std::make_unique<WifiLanServerSocket>(sock, network_manager_,
|
||||
system_bus_);
|
||||
}
|
||||
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange() {
|
||||
|
||||
@@ -46,9 +46,12 @@ std::string WifiLanServerSocket::GetIPAddress() const {
|
||||
address_data = ip4config.AddressData();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(&ip4config, "IP4Config", e);
|
||||
continue;
|
||||
}
|
||||
|
||||
return address_data[0]["address"];
|
||||
if (address_data.size() > 0) {
|
||||
return address_data[0]["address"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,16 @@ std::ostream &operator<<(std::ostream &s,
|
||||
std::unique_ptr<NetworkManagerIP4Config>
|
||||
NetworkManagerObjectManager::GetIp4Config(
|
||||
const sdbus::ObjectPath &active_connection) {
|
||||
auto objects = GetManagedObjects();
|
||||
std::map<sdbus::ObjectPath,
|
||||
std::map<std::string, std::map<std::string, sdbus::Variant>>>
|
||||
objects;
|
||||
try {
|
||||
objects = GetManagedObjects();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(this, "GetManagedObjects", e);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto &[object_path, interfaces] : objects) {
|
||||
if (object_path.find("/org/freedesktop/NetworkManager/ActiveConnection/",
|
||||
0) == 0) {
|
||||
@@ -82,6 +91,44 @@ NetworkManagerObjectManager::GetIp4Config(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<NetworkManagerActiveConnection>
|
||||
NetworkManagerObjectManager::GetActiveConnectionForAccessPoint(
|
||||
const sdbus::ObjectPath &access_point,
|
||||
const sdbus::ObjectPath &device_path) {
|
||||
std::map<sdbus::ObjectPath,
|
||||
std::map<std::string, std::map<std::string, sdbus::Variant>>>
|
||||
objects;
|
||||
try {
|
||||
objects = GetManagedObjects();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(this, "GetManagedObjects", e);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto &[object_path, interfaces] : objects) {
|
||||
if (object_path.find("/org/freedesktop/NetworkManager/ActiveConnection/") ==
|
||||
0) {
|
||||
if (interfaces.count(org::freedesktop::NetworkManager::Connection::
|
||||
Active_proxy::INTERFACE_NAME) == 1) {
|
||||
auto props = interfaces[org::freedesktop::NetworkManager::Connection::
|
||||
Active_proxy::INTERFACE_NAME];
|
||||
sdbus::ObjectPath specific_object = props["SpecificObject"];
|
||||
if (specific_object == access_point) {
|
||||
std::vector<sdbus::ObjectPath> devices = props["Devices"];
|
||||
for (auto &path : devices) {
|
||||
if (path == device_path) {
|
||||
return std::make_unique<NetworkManagerActiveConnection>(
|
||||
getProxy().getConnection(), object_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
api::WifiCapability &NetworkManagerWifiMedium::GetCapability() {
|
||||
try {
|
||||
auto cap_mask = WirelessCapabilities();
|
||||
@@ -331,7 +378,7 @@ NetworkManagerWifiMedium::ConnectToNetwork(absl::string_view ssid,
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__ << ": " << getObjectPath()
|
||||
<< ": Added a new connection at " << connection_path;
|
||||
<< ": Added a new connection at " << connection_path;
|
||||
auto active_connection = NetworkManagerActiveConnection(
|
||||
getProxy().getConnection(), active_conn_path);
|
||||
auto [reason, timeout] = active_connection.WaitForConnection();
|
||||
@@ -372,5 +419,34 @@ std::string NetworkManagerWifiMedium::GetIpAddress() {
|
||||
return information_.ip_address_dot_decimal;
|
||||
}
|
||||
|
||||
std::unique_ptr<NetworkManagerActiveConnection>
|
||||
NetworkManagerWifiMedium::GetActiveConnection() {
|
||||
sdbus::ObjectPath active_ap_path;
|
||||
|
||||
try {
|
||||
active_ap_path = ActiveAccessPoint();
|
||||
if (active_ap_path.empty()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": No active access points on "
|
||||
<< getObjectPath();
|
||||
return nullptr;
|
||||
}
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(this, "ActiveAccessPoint", e);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto object_manager = NetworkManagerObjectManager(getProxy().getConnection());
|
||||
auto conn = object_manager.GetActiveConnectionForAccessPoint(active_ap_path,
|
||||
getObjectPath());
|
||||
|
||||
if (conn == nullptr) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Could not find an active connection using the access point "
|
||||
<< active_ap_path << " and device " << getObjectPath();
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
@@ -65,29 +65,6 @@ public:
|
||||
~NetworkManagerIP4Config() { unregisterProxy(); }
|
||||
};
|
||||
|
||||
class NetworkManagerObjectManager
|
||||
: public sdbus::ProxyInterfaces<sdbus::ObjectManager_proxy> {
|
||||
public:
|
||||
NetworkManagerObjectManager(sdbus::IConnection &system_bus)
|
||||
: ProxyInterfaces(system_bus, "org.freedesktop.NetworkManager",
|
||||
"/org/freedesktop") {
|
||||
registerProxy();
|
||||
}
|
||||
~NetworkManagerObjectManager() { unregisterProxy(); }
|
||||
|
||||
std::unique_ptr<NetworkManagerIP4Config>
|
||||
GetIp4Config(const sdbus::ObjectPath &access_point);
|
||||
|
||||
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 {}
|
||||
};
|
||||
|
||||
class NetworkManagerAccessPoint
|
||||
: public sdbus::ProxyInterfaces<
|
||||
org::freedesktop::NetworkManager::AccessPoint_proxy> {
|
||||
@@ -187,7 +164,35 @@ public:
|
||||
|
||||
return state == kStateActivated ? std::pair{std::nullopt, false}
|
||||
: std::pair{std::optional(reason), false};
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<std::string> GetIP4Addresses() {
|
||||
sdbus::ObjectPath ip4config_path;
|
||||
try {
|
||||
ip4config_path = Ip4Config();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(this, "Ip4Config", e);
|
||||
return {};
|
||||
}
|
||||
|
||||
NetworkManagerIP4Config ip4config(getProxy().getConnection(),
|
||||
ip4config_path);
|
||||
std::vector<std::map<std::string, sdbus::Variant>> address_data;
|
||||
try {
|
||||
address_data = ip4config.AddressData();
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_PROPERTY_GET_ERROR(&ip4config, "AddressData", e);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> ip4addresses;
|
||||
for (auto &data : address_data) {
|
||||
if (data.count("address") == 1) {
|
||||
ip4addresses.push_back(data["address"]);
|
||||
}
|
||||
}
|
||||
return ip4addresses;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::Mutex state_mutex_;
|
||||
@@ -195,11 +200,37 @@ private:
|
||||
ActiveConnectionStateReason reason_ ABSL_GUARDED_BY(state_mutex_);
|
||||
};
|
||||
|
||||
class NetworkManagerObjectManager
|
||||
: public sdbus::ProxyInterfaces<sdbus::ObjectManager_proxy> {
|
||||
public:
|
||||
NetworkManagerObjectManager(sdbus::IConnection &system_bus)
|
||||
: ProxyInterfaces(system_bus, "org.freedesktop.NetworkManager",
|
||||
"/org/freedesktop") {
|
||||
registerProxy();
|
||||
}
|
||||
~NetworkManagerObjectManager() { unregisterProxy(); }
|
||||
|
||||
std::unique_ptr<NetworkManagerIP4Config>
|
||||
GetIp4Config(const sdbus::ObjectPath &access_point);
|
||||
std::unique_ptr<NetworkManagerActiveConnection>
|
||||
GetActiveConnectionForAccessPoint(const sdbus::ObjectPath &access_point_path,
|
||||
const sdbus::ObjectPath &device_path);
|
||||
|
||||
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 {}
|
||||
};
|
||||
|
||||
class NetworkManagerWifiMedium
|
||||
: public api::WifiMedium,
|
||||
public sdbus::ProxyInterfaces<
|
||||
org::freedesktop::NetworkManager::Device::Wireless_proxy,
|
||||
sdbus::Properties_proxy> {
|
||||
org::freedesktop::NetworkManager::Device::Wireless_proxy,
|
||||
sdbus::Properties_proxy> {
|
||||
public:
|
||||
NetworkManagerWifiMedium(std::shared_ptr<NetworkManager> network_manager,
|
||||
sdbus::IConnection &system_bus,
|
||||
@@ -239,6 +270,8 @@ public:
|
||||
bool VerifyInternetConnectivity() override;
|
||||
std::string GetIpAddress() override;
|
||||
|
||||
std::unique_ptr<NetworkManagerActiveConnection> GetActiveConnection();
|
||||
|
||||
protected:
|
||||
void onPropertiesChanged(
|
||||
const std::string &interfaceName,
|
||||
|
||||
Reference in New Issue
Block a user