From 9b742d920aeaecbc285580a69f5a095ecfcfdef6 Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Wed, 16 Aug 2023 02:00:09 +0530 Subject: [PATCH] Add initial wifi medium code. --- internal/platform/implementation/linux/dbus.h | 29 + .../networkmanager_accesspoint_client_glue.h | 87 +++ .../linux/networkmanager_client_glue.h | 320 ++++++++++ ...etworkmanager_device_wifip2p_client_glue.h | 64 ++ ...tworkmanager_device_wireless_client_glue.h | 103 +++ .../networkmanager_ip4config_client_glue.h | 102 +++ ...freedesktop.NetworkManager.AccessPoint.xml | 99 +++ ...edesktop.NetworkManager.Device.WifiP2P.xml | 76 +++ ...desktop.NetworkManager.Device.Wireless.xml | 131 ++++ ...g.freedesktop.NetworkManager.IP4Config.xml | 117 ++++ .../linux/org.freedesktop.NetworkManager.xml | 598 ++++++++++++++++++ .../implementation/linux/wifi_medium.cc | 171 +++++ .../implementation/linux/wifi_medium.h | 130 ++++ 13 files changed, 2027 insertions(+) create mode 100644 internal/platform/implementation/linux/dbus.h create mode 100644 internal/platform/implementation/linux/networkmanager_accesspoint_client_glue.h create mode 100644 internal/platform/implementation/linux/networkmanager_client_glue.h create mode 100644 internal/platform/implementation/linux/networkmanager_device_wifip2p_client_glue.h create mode 100644 internal/platform/implementation/linux/networkmanager_device_wireless_client_glue.h create mode 100644 internal/platform/implementation/linux/networkmanager_ip4config_client_glue.h create mode 100644 internal/platform/implementation/linux/org.freedesktop.NetworkManager.AccessPoint.xml create mode 100644 internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.WifiP2P.xml create mode 100644 internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.Wireless.xml create mode 100644 internal/platform/implementation/linux/org.freedesktop.NetworkManager.IP4Config.xml create mode 100644 internal/platform/implementation/linux/org.freedesktop.NetworkManager.xml create mode 100644 internal/platform/implementation/linux/wifi_medium.cc create mode 100644 internal/platform/implementation/linux/wifi_medium.h diff --git a/internal/platform/implementation/linux/dbus.h b/internal/platform/implementation/linux/dbus.h new file mode 100644 index 00000000..53e57212 --- /dev/null +++ b/internal/platform/implementation/linux/dbus.h @@ -0,0 +1,29 @@ +#ifndef PLATFORM_IMPL_LINUX_DBUS_H_ +#define PLATFORM_IMPL_LINUX_DBUS_H_ +#include "internal/platform/logging.h" + +#define DBUS_LOG_METHOD_CALL_ERROR(p, m, e) \ + do { \ + NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << (e).getName() \ + << "' with message '" << (e).getMessage() \ + << "' while calling " << (m) << " on object " \ + << (p)->getObjectPath(); \ + } while (false) + +#define DBUS_LOG_PROPERTY_GET_ERROR(p, prop, e) \ + do { \ + NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << (e).getName() \ + << "' with message '" << (e).getMessage() \ + << "' while getting property " << (prop) \ + << " on object " << (p)->getObjectPath(); \ + } while (false) + +#define DBUS_LOG_PROPERTY_SET_ERROR(p, prop, e) \ + do { \ + NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << (e).getName() \ + << "' with message '" << (e).getMessage() \ + << "' while setting property " << (prop) \ + << " on object " << (p)->getObjectPath(); \ + } while (false) + +#endif diff --git a/internal/platform/implementation/linux/networkmanager_accesspoint_client_glue.h b/internal/platform/implementation/linux/networkmanager_accesspoint_client_glue.h new file mode 100644 index 00000000..0408af2c --- /dev/null +++ b/internal/platform/implementation/linux/networkmanager_accesspoint_client_glue.h @@ -0,0 +1,87 @@ + +/* + * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! + */ + +#ifndef __sdbuscpp__networkmanager_accesspoint_client_glue_h__proxy__H__ +#define __sdbuscpp__networkmanager_accesspoint_client_glue_h__proxy__H__ + +#include +#include +#include + +namespace org { +namespace freedesktop { +namespace NetworkManager { + +class AccessPoint_proxy +{ +public: + static constexpr const char* INTERFACE_NAME = "org.freedesktop.NetworkManager.AccessPoint"; + +protected: + AccessPoint_proxy(sdbus::IProxy& proxy) + : proxy_(proxy) + { + } + + ~AccessPoint_proxy() = default; + +public: + uint32_t Flags() + { + return proxy_.getProperty("Flags").onInterface(INTERFACE_NAME); + } + + uint32_t WpaFlags() + { + return proxy_.getProperty("WpaFlags").onInterface(INTERFACE_NAME); + } + + uint32_t RsnFlags() + { + return proxy_.getProperty("RsnFlags").onInterface(INTERFACE_NAME); + } + + std::vector Ssid() + { + return proxy_.getProperty("Ssid").onInterface(INTERFACE_NAME); + } + + uint32_t Frequency() + { + return proxy_.getProperty("Frequency").onInterface(INTERFACE_NAME); + } + + std::string HwAddress() + { + return proxy_.getProperty("HwAddress").onInterface(INTERFACE_NAME); + } + + uint32_t Mode() + { + return proxy_.getProperty("Mode").onInterface(INTERFACE_NAME); + } + + uint32_t MaxBitrate() + { + return proxy_.getProperty("MaxBitrate").onInterface(INTERFACE_NAME); + } + + uint8_t Strength() + { + return proxy_.getProperty("Strength").onInterface(INTERFACE_NAME); + } + + int32_t LastSeen() + { + return proxy_.getProperty("LastSeen").onInterface(INTERFACE_NAME); + } + +private: + sdbus::IProxy& proxy_; +}; + +}}} // namespaces + +#endif diff --git a/internal/platform/implementation/linux/networkmanager_client_glue.h b/internal/platform/implementation/linux/networkmanager_client_glue.h new file mode 100644 index 00000000..f13b9544 --- /dev/null +++ b/internal/platform/implementation/linux/networkmanager_client_glue.h @@ -0,0 +1,320 @@ + +/* + * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! + */ + +#ifndef __sdbuscpp__networkmanager_client_glue_h__proxy__H__ +#define __sdbuscpp__networkmanager_client_glue_h__proxy__H__ + +#include +#include +#include + +namespace org { +namespace freedesktop { + +class NetworkManager_proxy +{ +public: + static constexpr const char* INTERFACE_NAME = "org.freedesktop.NetworkManager"; + +protected: + NetworkManager_proxy(sdbus::IProxy& proxy) + : proxy_(proxy) + { + proxy_.uponSignal("CheckPermissions").onInterface(INTERFACE_NAME).call([this](){ this->onCheckPermissions(); }); + proxy_.uponSignal("StateChanged").onInterface(INTERFACE_NAME).call([this](const uint32_t& state){ this->onStateChanged(state); }); + proxy_.uponSignal("DeviceAdded").onInterface(INTERFACE_NAME).call([this](const sdbus::ObjectPath& device_path){ this->onDeviceAdded(device_path); }); + proxy_.uponSignal("DeviceRemoved").onInterface(INTERFACE_NAME).call([this](const sdbus::ObjectPath& device_path){ this->onDeviceRemoved(device_path); }); + } + + ~NetworkManager_proxy() = default; + + virtual void onCheckPermissions() = 0; + virtual void onStateChanged(const uint32_t& state) = 0; + virtual void onDeviceAdded(const sdbus::ObjectPath& device_path) = 0; + virtual void onDeviceRemoved(const sdbus::ObjectPath& device_path) = 0; + +public: + void Reload(const uint32_t& flags) + { + proxy_.callMethod("Reload").onInterface(INTERFACE_NAME).withArguments(flags); + } + + std::vector GetDevices() + { + std::vector result; + proxy_.callMethod("GetDevices").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + std::vector GetAllDevices() + { + std::vector result; + proxy_.callMethod("GetAllDevices").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + sdbus::ObjectPath GetDeviceByIpIface(const std::string& iface) + { + sdbus::ObjectPath result; + proxy_.callMethod("GetDeviceByIpIface").onInterface(INTERFACE_NAME).withArguments(iface).storeResultsTo(result); + return result; + } + + sdbus::ObjectPath ActivateConnection(const sdbus::ObjectPath& connection, const sdbus::ObjectPath& device, const sdbus::ObjectPath& specific_object) + { + sdbus::ObjectPath result; + proxy_.callMethod("ActivateConnection").onInterface(INTERFACE_NAME).withArguments(connection, device, specific_object).storeResultsTo(result); + return result; + } + + std::tuple AddAndActivateConnection(const std::map>& connection, const sdbus::ObjectPath& device, const sdbus::ObjectPath& specific_object) + { + std::tuple result; + proxy_.callMethod("AddAndActivateConnection").onInterface(INTERFACE_NAME).withArguments(connection, device, specific_object).storeResultsTo(result); + return result; + } + + std::tuple> AddAndActivateConnection2(const std::map>& connection, const sdbus::ObjectPath& device, const sdbus::ObjectPath& specific_object, const std::map& options) + { + std::tuple> result; + proxy_.callMethod("AddAndActivateConnection2").onInterface(INTERFACE_NAME).withArguments(connection, device, specific_object, options).storeResultsTo(result); + return result; + } + + void DeactivateConnection(const sdbus::ObjectPath& active_connection) + { + proxy_.callMethod("DeactivateConnection").onInterface(INTERFACE_NAME).withArguments(active_connection); + } + + void Sleep(const bool& sleep) + { + proxy_.callMethod("Sleep").onInterface(INTERFACE_NAME).withArguments(sleep); + } + + void Enable(const bool& enable) + { + proxy_.callMethod("Enable").onInterface(INTERFACE_NAME).withArguments(enable); + } + + std::map GetPermissions() + { + std::map result; + proxy_.callMethod("GetPermissions").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + void SetLogging(const std::string& level, const std::string& domains) + { + proxy_.callMethod("SetLogging").onInterface(INTERFACE_NAME).withArguments(level, domains); + } + + std::tuple GetLogging() + { + std::tuple result; + proxy_.callMethod("GetLogging").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + uint32_t CheckConnectivity() + { + uint32_t result; + proxy_.callMethod("CheckConnectivity").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + uint32_t state() + { + uint32_t result; + proxy_.callMethod("state").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + sdbus::ObjectPath CheckpointCreate(const std::vector& devices, const uint32_t& rollback_timeout, const uint32_t& flags) + { + sdbus::ObjectPath result; + proxy_.callMethod("CheckpointCreate").onInterface(INTERFACE_NAME).withArguments(devices, rollback_timeout, flags).storeResultsTo(result); + return result; + } + + void CheckpointDestroy(const sdbus::ObjectPath& checkpoint) + { + proxy_.callMethod("CheckpointDestroy").onInterface(INTERFACE_NAME).withArguments(checkpoint); + } + + std::map CheckpointRollback(const sdbus::ObjectPath& checkpoint) + { + std::map result; + proxy_.callMethod("CheckpointRollback").onInterface(INTERFACE_NAME).withArguments(checkpoint).storeResultsTo(result); + return result; + } + + void CheckpointAdjustRollbackTimeout(const sdbus::ObjectPath& checkpoint, const uint32_t& add_timeout) + { + proxy_.callMethod("CheckpointAdjustRollbackTimeout").onInterface(INTERFACE_NAME).withArguments(checkpoint, add_timeout); + } + +public: + std::vector Devices() + { + return proxy_.getProperty("Devices").onInterface(INTERFACE_NAME); + } + + std::vector AllDevices() + { + return proxy_.getProperty("AllDevices").onInterface(INTERFACE_NAME); + } + + std::vector Checkpoints() + { + return proxy_.getProperty("Checkpoints").onInterface(INTERFACE_NAME); + } + + bool NetworkingEnabled() + { + return proxy_.getProperty("NetworkingEnabled").onInterface(INTERFACE_NAME); + } + + bool WirelessEnabled() + { + return proxy_.getProperty("WirelessEnabled").onInterface(INTERFACE_NAME); + } + + void WirelessEnabled(const bool& value) + { + proxy_.setProperty("WirelessEnabled").onInterface(INTERFACE_NAME).toValue(value); + } + + bool WirelessHardwareEnabled() + { + return proxy_.getProperty("WirelessHardwareEnabled").onInterface(INTERFACE_NAME); + } + + bool WwanEnabled() + { + return proxy_.getProperty("WwanEnabled").onInterface(INTERFACE_NAME); + } + + void WwanEnabled(const bool& value) + { + proxy_.setProperty("WwanEnabled").onInterface(INTERFACE_NAME).toValue(value); + } + + bool WwanHardwareEnabled() + { + return proxy_.getProperty("WwanHardwareEnabled").onInterface(INTERFACE_NAME); + } + + bool WimaxEnabled() + { + return proxy_.getProperty("WimaxEnabled").onInterface(INTERFACE_NAME); + } + + void WimaxEnabled(const bool& value) + { + proxy_.setProperty("WimaxEnabled").onInterface(INTERFACE_NAME).toValue(value); + } + + bool WimaxHardwareEnabled() + { + return proxy_.getProperty("WimaxHardwareEnabled").onInterface(INTERFACE_NAME); + } + + uint32_t RadioFlags() + { + return proxy_.getProperty("RadioFlags").onInterface(INTERFACE_NAME); + } + + std::vector ActiveConnections() + { + return proxy_.getProperty("ActiveConnections").onInterface(INTERFACE_NAME); + } + + sdbus::ObjectPath PrimaryConnection() + { + return proxy_.getProperty("PrimaryConnection").onInterface(INTERFACE_NAME); + } + + std::string PrimaryConnectionType() + { + return proxy_.getProperty("PrimaryConnectionType").onInterface(INTERFACE_NAME); + } + + uint32_t Metered() + { + return proxy_.getProperty("Metered").onInterface(INTERFACE_NAME); + } + + sdbus::ObjectPath ActivatingConnection() + { + return proxy_.getProperty("ActivatingConnection").onInterface(INTERFACE_NAME); + } + + bool Startup() + { + return proxy_.getProperty("Startup").onInterface(INTERFACE_NAME); + } + + std::string Version() + { + return proxy_.getProperty("Version").onInterface(INTERFACE_NAME); + } + + std::vector VersionInfo() + { + return proxy_.getProperty("VersionInfo").onInterface(INTERFACE_NAME); + } + + std::vector Capabilities() + { + return proxy_.getProperty("Capabilities").onInterface(INTERFACE_NAME); + } + + uint32_t State() + { + return proxy_.getProperty("State").onInterface(INTERFACE_NAME); + } + + uint32_t Connectivity() + { + return proxy_.getProperty("Connectivity").onInterface(INTERFACE_NAME); + } + + bool ConnectivityCheckAvailable() + { + return proxy_.getProperty("ConnectivityCheckAvailable").onInterface(INTERFACE_NAME); + } + + bool ConnectivityCheckEnabled() + { + return proxy_.getProperty("ConnectivityCheckEnabled").onInterface(INTERFACE_NAME); + } + + void ConnectivityCheckEnabled(const bool& value) + { + proxy_.setProperty("ConnectivityCheckEnabled").onInterface(INTERFACE_NAME).toValue(value); + } + + std::string ConnectivityCheckUri() + { + return proxy_.getProperty("ConnectivityCheckUri").onInterface(INTERFACE_NAME); + } + + std::map GlobalDnsConfiguration() + { + return proxy_.getProperty("GlobalDnsConfiguration").onInterface(INTERFACE_NAME); + } + + void GlobalDnsConfiguration(const std::map& value) + { + proxy_.setProperty("GlobalDnsConfiguration").onInterface(INTERFACE_NAME).toValue(value); + } + +private: + sdbus::IProxy& proxy_; +}; + +}} // namespaces + +#endif diff --git a/internal/platform/implementation/linux/networkmanager_device_wifip2p_client_glue.h b/internal/platform/implementation/linux/networkmanager_device_wifip2p_client_glue.h new file mode 100644 index 00000000..df968c97 --- /dev/null +++ b/internal/platform/implementation/linux/networkmanager_device_wifip2p_client_glue.h @@ -0,0 +1,64 @@ + +/* + * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! + */ + +#ifndef __sdbuscpp__networkmanager_device_wifip2p_client_glue_h__proxy__H__ +#define __sdbuscpp__networkmanager_device_wifip2p_client_glue_h__proxy__H__ + +#include +#include +#include + +namespace org { +namespace freedesktop { +namespace NetworkManager { +namespace Device { + +class WifiP2P_proxy +{ +public: + static constexpr const char* INTERFACE_NAME = "org.freedesktop.NetworkManager.Device.WifiP2P"; + +protected: + WifiP2P_proxy(sdbus::IProxy& proxy) + : proxy_(proxy) + { + proxy_.uponSignal("PeerAdded").onInterface(INTERFACE_NAME).call([this](const sdbus::ObjectPath& peer){ this->onPeerAdded(peer); }); + proxy_.uponSignal("PeerRemoved").onInterface(INTERFACE_NAME).call([this](const sdbus::ObjectPath& peer){ this->onPeerRemoved(peer); }); + } + + ~WifiP2P_proxy() = default; + + virtual void onPeerAdded(const sdbus::ObjectPath& peer) = 0; + virtual void onPeerRemoved(const sdbus::ObjectPath& peer) = 0; + +public: + void StartFind(const std::map& options) + { + proxy_.callMethod("StartFind").onInterface(INTERFACE_NAME).withArguments(options); + } + + void StopFind() + { + proxy_.callMethod("StopFind").onInterface(INTERFACE_NAME); + } + +public: + std::string HwAddress() + { + return proxy_.getProperty("HwAddress").onInterface(INTERFACE_NAME); + } + + std::vector Peers() + { + return proxy_.getProperty("Peers").onInterface(INTERFACE_NAME); + } + +private: + sdbus::IProxy& proxy_; +}; + +}}}} // namespaces + +#endif diff --git a/internal/platform/implementation/linux/networkmanager_device_wireless_client_glue.h b/internal/platform/implementation/linux/networkmanager_device_wireless_client_glue.h new file mode 100644 index 00000000..b8a85787 --- /dev/null +++ b/internal/platform/implementation/linux/networkmanager_device_wireless_client_glue.h @@ -0,0 +1,103 @@ + +/* + * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! + */ + +#ifndef __sdbuscpp__networkmanager_device_wireless_client_glue_h__proxy__H__ +#define __sdbuscpp__networkmanager_device_wireless_client_glue_h__proxy__H__ + +#include +#include +#include + +namespace org { +namespace freedesktop { +namespace NetworkManager { +namespace Device { + +class Wireless_proxy +{ +public: + static constexpr const char* INTERFACE_NAME = "org.freedesktop.NetworkManager.Device.Wireless"; + +protected: + Wireless_proxy(sdbus::IProxy& proxy) + : proxy_(proxy) + { + proxy_.uponSignal("AccessPointAdded").onInterface(INTERFACE_NAME).call([this](const sdbus::ObjectPath& access_point){ this->onAccessPointAdded(access_point); }); + proxy_.uponSignal("AccessPointRemoved").onInterface(INTERFACE_NAME).call([this](const sdbus::ObjectPath& access_point){ this->onAccessPointRemoved(access_point); }); + } + + ~Wireless_proxy() = default; + + virtual void onAccessPointAdded(const sdbus::ObjectPath& access_point) = 0; + virtual void onAccessPointRemoved(const sdbus::ObjectPath& access_point) = 0; + +public: + std::vector GetAccessPoints() + { + std::vector result; + proxy_.callMethod("GetAccessPoints").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + std::vector GetAllAccessPoints() + { + std::vector result; + proxy_.callMethod("GetAllAccessPoints").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + void RequestScan(const std::map& options) + { + proxy_.callMethod("RequestScan").onInterface(INTERFACE_NAME).withArguments(options); + } + +public: + std::string HwAddress() + { + return proxy_.getProperty("HwAddress").onInterface(INTERFACE_NAME); + } + + std::string PermHwAddress() + { + return proxy_.getProperty("PermHwAddress").onInterface(INTERFACE_NAME); + } + + uint32_t Mode() + { + return proxy_.getProperty("Mode").onInterface(INTERFACE_NAME); + } + + uint32_t Bitrate() + { + return proxy_.getProperty("Bitrate").onInterface(INTERFACE_NAME); + } + + std::vector AccessPoints() + { + return proxy_.getProperty("AccessPoints").onInterface(INTERFACE_NAME); + } + + sdbus::ObjectPath ActiveAccessPoint() + { + return proxy_.getProperty("ActiveAccessPoint").onInterface(INTERFACE_NAME); + } + + uint32_t WirelessCapabilities() + { + return proxy_.getProperty("WirelessCapabilities").onInterface(INTERFACE_NAME); + } + + int64_t LastScan() + { + return proxy_.getProperty("LastScan").onInterface(INTERFACE_NAME); + } + +private: + sdbus::IProxy& proxy_; +}; + +}}}} // namespaces + +#endif diff --git a/internal/platform/implementation/linux/networkmanager_ip4config_client_glue.h b/internal/platform/implementation/linux/networkmanager_ip4config_client_glue.h new file mode 100644 index 00000000..442180ff --- /dev/null +++ b/internal/platform/implementation/linux/networkmanager_ip4config_client_glue.h @@ -0,0 +1,102 @@ + +/* + * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! + */ + +#ifndef __sdbuscpp__networkmanager_ip4config_client_glue_h__proxy__H__ +#define __sdbuscpp__networkmanager_ip4config_client_glue_h__proxy__H__ + +#include +#include +#include + +namespace org { +namespace freedesktop { +namespace NetworkManager { + +class IP4Config_proxy +{ +public: + static constexpr const char* INTERFACE_NAME = "org.freedesktop.NetworkManager.IP4Config"; + +protected: + IP4Config_proxy(sdbus::IProxy& proxy) + : proxy_(proxy) + { + } + + ~IP4Config_proxy() = default; + +public: + std::vector> Addresses() + { + return proxy_.getProperty("Addresses").onInterface(INTERFACE_NAME); + } + + std::vector> AddressData() + { + return proxy_.getProperty("AddressData").onInterface(INTERFACE_NAME); + } + + std::string Gateway() + { + return proxy_.getProperty("Gateway").onInterface(INTERFACE_NAME); + } + + std::vector> Routes() + { + return proxy_.getProperty("Routes").onInterface(INTERFACE_NAME); + } + + std::vector> RouteData() + { + return proxy_.getProperty("RouteData").onInterface(INTERFACE_NAME); + } + + std::vector Nameservers() + { + return proxy_.getProperty("Nameservers").onInterface(INTERFACE_NAME); + } + + std::vector> NameserverData() + { + return proxy_.getProperty("NameserverData").onInterface(INTERFACE_NAME); + } + + std::vector Domains() + { + return proxy_.getProperty("Domains").onInterface(INTERFACE_NAME); + } + + std::vector Searches() + { + return proxy_.getProperty("Searches").onInterface(INTERFACE_NAME); + } + + std::vector DnsOptions() + { + return proxy_.getProperty("DnsOptions").onInterface(INTERFACE_NAME); + } + + int32_t DnsPriority() + { + return proxy_.getProperty("DnsPriority").onInterface(INTERFACE_NAME); + } + + std::vector WinsServers() + { + return proxy_.getProperty("WinsServers").onInterface(INTERFACE_NAME); + } + + std::vector WinsServerData() + { + return proxy_.getProperty("WinsServerData").onInterface(INTERFACE_NAME); + } + +private: + sdbus::IProxy& proxy_; +}; + +}}} // namespaces + +#endif diff --git a/internal/platform/implementation/linux/org.freedesktop.NetworkManager.AccessPoint.xml b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.AccessPoint.xml new file mode 100644 index 00000000..7340bda3 --- /dev/null +++ b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.AccessPoint.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.WifiP2P.xml b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.WifiP2P.xml new file mode 100644 index 00000000..73b8cc0c --- /dev/null +++ b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.WifiP2P.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.Wireless.xml b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.Wireless.xml new file mode 100644 index 00000000..c428e998 --- /dev/null +++ b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.Device.Wireless.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/platform/implementation/linux/org.freedesktop.NetworkManager.IP4Config.xml b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.IP4Config.xml new file mode 100644 index 00000000..f6e18b76 --- /dev/null +++ b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.IP4Config.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/platform/implementation/linux/org.freedesktop.NetworkManager.xml b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.xml new file mode 100644 index 00000000..c92c8017 --- /dev/null +++ b/internal/platform/implementation/linux/org.freedesktop.NetworkManager.xml @@ -0,0 +1,598 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/platform/implementation/linux/wifi_medium.cc b/internal/platform/implementation/linux/wifi_medium.cc new file mode 100644 index 00000000..beba67c4 --- /dev/null +++ b/internal/platform/implementation/linux/wifi_medium.cc @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "absl/synchronization/mutex.h" +#include "internal/platform/implementation/linux/dbus.h" +#include "internal/platform/implementation/linux/networkmanager_device_wireless_client_glue.h" +#include "internal/platform/implementation/linux/wifi_medium.h" +#include "internal/platform/implementation/wifi.h" + +namespace nearby { +namespace linux { + +std::unique_ptr +NetworkManagerObjectManager::GetIp4Config( + const sdbus::ObjectPath &access_point) { + auto objects = GetManagedObjects(); + for (auto &[object_path, interfaces] : objects) { + if (object_path.find("/org/freedesktop/NetworkManager/ActiveConnection/", + 0) == 0) { + if (interfaces.count( + "org.freedesktop.NetworkManager.Connection.Active") == 1) { + auto props = + interfaces["org.freedesktop.NetworkManager.Connection.Active"]; + sdbus::ObjectPath specific_object = props["SpecificObject"]; + sdbus::ObjectPath ip4config = props["Ip4Config"]; + + if (specific_object == access_point) + return std::make_unique( + getProxy().getConnection(), ip4config); + } + } + } + + return nullptr; +} + +api::WifiCapability &NetworkManagerWifiMedium::GetCapability() { + try { + auto cap_mask = WirelessCapabilities(); + // https://networkmanager.dev/docs/api/latest/nm-dbus-types.html#NMDeviceWifiCapabilities + capability_.supports_5_ghz = (cap_mask & 0x00000400); + capability_.supports_6_ghz = false; + capability_.support_wifi_direct = true; + } catch (const sdbus::Error &e) { + DBUS_LOG_PROPERTY_GET_ERROR(&getProxy(), "WirelessCapabilities", e); + } + + return capability_; +} + +api::WifiInformation &NetworkManagerWifiMedium::GetInformation() { + { + absl::ReaderMutexLock l(&active_access_point_lock_); + if (!active_access_point_.has_value()) { + information_ = api::WifiInformation{false}; + return information_; + } + } + try { + absl::MutexLock l(&active_access_point_lock_); + + auto ssid_vec = active_access_point_->Ssid(); + std::string ssid{ssid_vec.begin(), ssid_vec.end()}; + + information_ = + api::WifiInformation{true, ssid, active_access_point_->HwAddress(), + (int32_t)(active_access_point_->Frequency())}; + NetworkManagerObjectManager manager(getProxy().getConnection()); + auto ip4config = + manager.GetIp4Config(active_access_point_->getObjectPath()); + + if (ip4config != nullptr) { + auto address_data = ip4config->AddressData(); + if (address_data.size() > 0) { + std::string address = address_data[0]["address"]; + information_.ip_address_dot_decimal = address; + + struct in_addr addr; + inet_aton(address.c_str(), &addr); + + char addr_bytes[4]; + memcpy(addr_bytes, &addr.s_addr, sizeof(addr_bytes)); + information_.ip_address_4_bytes = std::string(addr_bytes, 4); + } + } else { + NEARBY_LOGS(ERROR) << __func__ + << ": Could not find the Ip4Config object for " + << active_access_point_->getObjectPath(); + } + } catch (const sdbus::Error &e) { + absl::ReaderMutexLock l(&active_access_point_lock_); + NEARBY_LOGS(ERROR) + << __func__ << ": Got error '" << e.getName() << "' with message '" + << e.getMessage() + << "' while populating network information for access point " + << active_access_point_->getObjectPath(); + } + + return information_; +} + +void NetworkManagerWifiMedium::onPropertiesChanged( + const std::string &interfaceName, + const std::map &changedProperties, + const std::vector &invalidatedProperties) { + if (interfaceName != org::freedesktop::NetworkManager::Device:: + Wireless_proxy::INTERFACE_NAME) { + return; + } + + for (auto &[property, _val] : changedProperties) { + if (property == "LastScan") { + absl::ReaderMutexLock l(&scan_result_callback_lock_); + if (scan_result_callback_.has_value()) { + // scan_result_callback_->get().OnScanResults() + } + } + } +} + +bool NetworkManagerWifiMedium::Scan( + const api::WifiMedium::ScanResultCallback &scan_result_callback) { + absl::MutexLock l(&scan_result_callback_lock_); + scan_result_callback_ = scan_result_callback; + + try { + RequestScan(std::map()); + } catch (const sdbus::Error &e) { + scan_result_callback_ = std::nullopt; + DBUS_LOG_METHOD_CALL_ERROR(&getProxy(), "RequestScan", e); + return false; + } + return true; +} + +api::WifiConnectionStatus +NetworkManagerWifiMedium::ConnectToNetwork(absl::string_view ssid, + absl::string_view password, + api::WifiAuthType auth_type) {} + +bool NetworkManagerWifiMedium::VerifyInternetConnectivity() { + auto network_manager_proxy_ = sdbus::createProxy( + "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager"); + network_manager_proxy_->finishRegistration(); + + try { + std::uint32_t connectivity; + network_manager_proxy_->callMethod("CheckConnectivity") + .onInterface("org.freedesktop.NetworkManager") + .storeResultsTo(connectivity); + return connectivity == 4; // NM_CONNECTIVITY_FULL + } catch (const sdbus::Error &e) { + DBUS_LOG_METHOD_CALL_ERROR(network_manager_proxy_, "CheckConnectivity", e); + return false; + } +} + +std::string NetworkManagerWifiMedium::GetIpAddress() { + GetInformation(); + return information_.ip_address_dot_decimal; +} + +} // namespace linux +} // namespace nearby diff --git a/internal/platform/implementation/linux/wifi_medium.h b/internal/platform/implementation/linux/wifi_medium.h new file mode 100644 index 00000000..116063df --- /dev/null +++ b/internal/platform/implementation/linux/wifi_medium.h @@ -0,0 +1,130 @@ +#ifndef PLATFORM_IMPL_LINUX_WIFI_MEDIUM_H_ +#define PLATFORM_IMPL_LINUX_WIFI_MEDIUM_H_ + +#include +#include +#include + +#include +#include +#include +#include + +#include "absl/synchronization/mutex.h" +#include "internal/platform/implementation/linux/networkmanager_accesspoint_client_glue.h" +#include "internal/platform/implementation/linux/networkmanager_device_wireless_client_glue.h" +#include "internal/platform/implementation/linux/networkmanager_ip4config_client_glue.h" +#include "internal/platform/implementation/wifi.h" + +namespace nearby { +namespace linux { +class NetworkManagerIP4Config + : public sdbus::ProxyInterfaces< + org::freedesktop::NetworkManager::IP4Config_proxy> { +public: + NetworkManagerIP4Config(sdbus::IConnection &system_bus, + const sdbus::ObjectPath &config_object_path) + : ProxyInterfaces(system_bus, "org.freedesktop.NetworkManager", + config_object_path) { + registerProxy(); + } + ~NetworkManagerIP4Config() { unregisterProxy(); } +}; + +class NetworkManagerObjectManager + : public sdbus::ProxyInterfaces { +public: + NetworkManagerObjectManager(sdbus::IConnection &system_bus) + : ProxyInterfaces(system_bus, "org.freedesktop.NetworkManager", + "/org/freedesktop") { + registerProxy(); + } + ~NetworkManagerObjectManager() { unregisterProxy(); } + + std::unique_ptr + GetIp4Config(const sdbus::ObjectPath &access_point); + +protected: + void onInterfacesAdded( + const sdbus::ObjectPath &objectPath, + const std::map> + &interfacesAndProperties) override {} + void + onInterfacesRemoved(const sdbus::ObjectPath &objectPath, + const std::vector &interfaces) override {} +}; + +class NetworkManagerAccessPoint + : public sdbus::ProxyInterfaces< + org::freedesktop::NetworkManager::AccessPoint_proxy> { +public: + NetworkManagerAccessPoint(sdbus::IConnection &system_bus, + const sdbus::ObjectPath &access_point_object_path) + : ProxyInterfaces(system_bus, "org.freedesktop.NetworkManager", + access_point_object_path) { + registerProxy(); + } + ~NetworkManagerAccessPoint() { unregisterProxy(); } +}; + +class NetworkManagerWifiMedium + : public api::WifiMedium, + sdbus::ProxyInterfaces< + org::freedesktop::NetworkManager::Device::Wireless_proxy, + sdbus::Properties_proxy> { +public: + NetworkManagerWifiMedium(sdbus::IConnection &system_bus, + const sdbus::ObjectPath &wireless_device_object_path) + : ProxyInterfaces(system_bus, "org.freedesktop.NetworkManager", + wireless_device_object_path) { + active_access_point_ = std::nullopt; + registerProxy(); + } + + ~NetworkManagerWifiMedium() override { unregisterProxy(); } + + class ScanResultCallback : public api::WifiMedium::ScanResultCallback { + public: + ~ScanResultCallback() override = default; + void OnScanResults( + const std::vector &scan_results) override { + // TODO: Add implementation at some point + } + }; + + bool IsInterfaceValid() const override { return true; }; + api::WifiCapability &GetCapability() override; + api::WifiInformation &GetInformation() override; + + bool Scan(const api::WifiMedium::ScanResultCallback &scan_result_callback) override; + + api::WifiConnectionStatus + ConnectToNetwork(absl::string_view ssid, absl::string_view password, + api::WifiAuthType auth_type) override; + + bool VerifyInternetConnectivity() override; + std::string GetIpAddress() override; + +protected: + void onPropertiesChanged( + const std::string &interfaceName, + const std::map &changedProperties, + const std::vector &invalidatedProperties) override; + +private: + api::WifiCapability capability_; + api::WifiInformation information_{false}; + + absl::Mutex active_access_point_lock_; + std::optional active_access_point_; + + absl::Mutex scan_result_callback_lock_; + std::optional< + std::reference_wrapper> + scan_result_callback_; +}; + +} // namespace linux +} // namespace nearby + +#endif