mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 15:16:12 -04:00
Add Wifi Direct medium
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "internal/platform/implementation/linux/mutex.h"
|
||||
#include "internal/platform/implementation/linux/submittable_executor.h"
|
||||
#include "internal/platform/implementation/linux/timer.h"
|
||||
#include "internal/platform/implementation/linux/wifi_direct.h"
|
||||
#include "internal/platform/implementation/linux/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/linux/wifi_lan.h"
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
@@ -163,6 +164,7 @@ ImplementationPlatform::CreateBluetoothAdapter() {
|
||||
}
|
||||
} catch (const sdbus::Error &e) {
|
||||
DBUS_LOG_METHOD_CALL_ERROR(&manager, "GetManagedObjects", e);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
@@ -259,7 +261,17 @@ ImplementationPlatform::CreateWifiHotspotMedium() {
|
||||
|
||||
std::unique_ptr<api::WifiDirectMedium>
|
||||
ImplementationPlatform::CreateWifiDirectMedium() {
|
||||
return nullptr;
|
||||
auto nm =
|
||||
std::make_shared<linux::NetworkManager>(linux::getSystemBusConnection());
|
||||
auto wifiMedium = createWifiMedium(nm);
|
||||
|
||||
if (wifiMedium == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Could not create a WiFi medium";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<linux::NetworkManagerWifiDirectMedium>(
|
||||
linux::getSystemBusConnection(), nm, std::move(wifiMedium));
|
||||
}
|
||||
|
||||
std::unique_ptr<api::Timer> ImplementationPlatform::CreateTimer() {
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <memory>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#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::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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,48 @@
|
||||
#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_(network_manager),
|
||||
wireless_device_(std::move(wireless_device)) {}
|
||||
~NetworkManagerWifiDirectMedium() {}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
sdbus::IConnection &system_bus_;
|
||||
std::shared_ptr<NetworkManager> network_manager_;
|
||||
std::unique_ptr<NetworkManagerWifiMedium> wireless_device_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "internal/platform/implementation/linux/wifi_direct_server_socket.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/linux/wifi_direct_socket.h"
|
||||
#include <netinet/in.h>
|
||||
#include <sys/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
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef PLATFORM_IMPL_LINUX_WIFI_DIRECT_SERVER_SOCKET_H_
|
||||
#define PLATFORM_IMPL_LINUX_WIFI_DIRECT_SERVER_SOCKET_H_
|
||||
|
||||
#include "internal/platform/implementation/linux/wifi_medium.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
namespace nearby {
|
||||
namespace linux {
|
||||
class NetworkManagerWifiDirectServerSocket
|
||||
: public api::WifiDirectServerSocket {
|
||||
public:
|
||||
NetworkManagerWifiDirectServerSocket(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) {}
|
||||
~NetworkManagerWifiDirectServerSocket() {}
|
||||
|
||||
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_ ;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#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:
|
||||
WifiDirectSocket(int socket);
|
||||
~WifiDirectSocket() = default;
|
||||
|
||||
InputStream &GetInputStream() override;
|
||||
OutputStream &GetOutputStream() override;
|
||||
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
sdbus::UnixFd fd_;
|
||||
OutputStream output_stream_;
|
||||
InputStream input_stream_;
|
||||
};
|
||||
} // namespace linux
|
||||
} // namespace nearby
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user