mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-07 00:31:11 +00:00
iwd: Add basic P2P device class for IWD
Similarly as with wpa_supplicant, create NMDeviceIwdP2P objects for P2P devices based on data from IWD -- not in NMWifiFactory::create_device because that is only triggered for system netdevs and a P2P-Device virtual interface has no netdev. Unlike NMDeviceWifiP2P, NMDeviceIwdP2P's iface property is a unique string that likely doesn't match any system interface name -- in theory there doesn't need to be any related netdev on the system (such as an Infrastructure-mode interface) before a P2P-Device is added. [thaller@redhat.com: modified original patch]
This commit is contained in:
parent
6bf080a7bb
commit
51ef157096
|
@ -3935,6 +3935,8 @@ if WITH_IWD
|
|||
src_core_devices_wifi_libnm_wifi_base_la_SOURCES += \
|
||||
src/core/devices/wifi/nm-device-iwd.c \
|
||||
src/core/devices/wifi/nm-device-iwd.h \
|
||||
src/core/devices/wifi/nm-device-iwd-p2p.c \
|
||||
src/core/devices/wifi/nm-device-iwd-p2p.h \
|
||||
src/core/devices/wifi/nm-iwd-manager.c \
|
||||
src/core/devices/wifi/nm-iwd-manager.h \
|
||||
$(NULL)
|
||||
|
|
|
@ -4,6 +4,7 @@ iwd_sources = files()
|
|||
if enable_iwd
|
||||
iwd_sources += files(
|
||||
'nm-device-iwd.c',
|
||||
'nm-device-iwd-p2p.c',
|
||||
'nm-iwd-manager.c',
|
||||
)
|
||||
endif
|
||||
|
|
1152
src/core/devices/wifi/nm-device-iwd-p2p.c
Normal file
1152
src/core/devices/wifi/nm-device-iwd-p2p.c
Normal file
File diff suppressed because it is too large
Load diff
36
src/core/devices/wifi/nm-device-iwd-p2p.h
Normal file
36
src/core/devices/wifi/nm-device-iwd-p2p.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __NM_DEVICE_IWD_P2P_H__
|
||||
#define __NM_DEVICE_IWD_P2P_H__
|
||||
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-device-wifi-p2p.h"
|
||||
|
||||
#define NM_TYPE_DEVICE_IWD_P2P (nm_device_iwd_p2p_get_type())
|
||||
#define NM_DEVICE_IWD_P2P(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_IWD_P2P, NMDeviceIwdP2P))
|
||||
#define NM_DEVICE_IWD_P2P_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_IWD_P2P, NMDeviceIwdP2PClass))
|
||||
#define NM_IS_DEVICE_IWD_P2P(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_IWD_P2P))
|
||||
#define NM_IS_DEVICE_IWD_P2P_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_IWD_P2P))
|
||||
#define NM_DEVICE_IWD_P2P_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_IWD_P2P, NMDeviceIwdP2PClass))
|
||||
|
||||
#define NM_DEVICE_IWD_P2P_PEERS NM_DEVICE_WIFI_P2P_PEERS
|
||||
#define NM_DEVICE_IWD_P2P_GROUPS NM_DEVICE_WIFI_P2P_GROUPS
|
||||
|
||||
typedef struct _NMDeviceIwdP2P NMDeviceIwdP2P;
|
||||
typedef struct _NMDeviceIwdP2PClass NMDeviceIwdP2PClass;
|
||||
|
||||
GType nm_device_iwd_p2p_get_type(void);
|
||||
|
||||
NMDeviceIwdP2P *nm_device_iwd_p2p_new(GDBusObject *object);
|
||||
|
||||
void nm_device_iwd_p2p_remove(NMDeviceIwdP2P *p2p);
|
||||
|
||||
void nm_device_iwd_p2p_peer_add_remove(NMDeviceIwdP2P *p2p, GDBusObject *peer_obj, bool add);
|
||||
|
||||
#endif /* __NM_DEVICE_IWD_P2P_H__ */
|
|
@ -15,6 +15,7 @@
|
|||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-device-iwd.h"
|
||||
#include "nm-device-iwd-p2p.h"
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-glib-aux/nm-random-utils.h"
|
||||
|
@ -25,6 +26,14 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
P2P_DEVICE_ADDED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
NMIwdNetworkSecurity security;
|
||||
|
@ -50,6 +59,7 @@ typedef struct {
|
|||
char *last_state_dir;
|
||||
char *warned_state_dir;
|
||||
bool netconfig_enabled;
|
||||
GHashTable *p2p_devices;
|
||||
} NMIwdManagerPrivate;
|
||||
|
||||
struct _NMIwdManager {
|
||||
|
@ -420,6 +430,66 @@ set_device_dbus_object(NMIwdManager *self, GDBusProxy *proxy, GDBusObject *objec
|
|||
nm_device_iwd_set_dbus_object(NM_DEVICE_IWD(device), object);
|
||||
}
|
||||
|
||||
static void
|
||||
add_p2p_device(NMIwdManager *self, GDBusProxy *proxy, GDBusObject *object)
|
||||
{
|
||||
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
||||
const char *path = g_dbus_object_get_object_path(object);
|
||||
NMDeviceIwdP2P *p2p;
|
||||
gs_unref_object GDBusInterface *wiphy = NULL;
|
||||
const char *phy_name;
|
||||
|
||||
if (g_hash_table_contains(priv->p2p_devices, path))
|
||||
return;
|
||||
|
||||
wiphy = g_dbus_object_get_interface(object, NM_IWD_WIPHY_INTERFACE);
|
||||
if (!wiphy)
|
||||
return;
|
||||
|
||||
phy_name = get_property_string_or_null(G_DBUS_PROXY(wiphy), "Name");
|
||||
if (!phy_name) {
|
||||
_LOGE("Name not cached for phy at %s", path);
|
||||
return;
|
||||
}
|
||||
|
||||
p2p = nm_device_iwd_p2p_new(object);
|
||||
if (!p2p) {
|
||||
_LOGE("Can't create NMDeviceIwdP2P for phy at %s", path);
|
||||
return;
|
||||
}
|
||||
|
||||
g_hash_table_insert(priv->p2p_devices, g_strdup(path), p2p);
|
||||
g_signal_emit(self, signals[P2P_DEVICE_ADDED], 0, p2p, phy_name);
|
||||
|
||||
/* There should be no peer objects before the device object appeared so don't
|
||||
* try to look for them and notify the new device. */
|
||||
}
|
||||
|
||||
static void
|
||||
remove_p2p_device(NMIwdManager *self, GDBusProxy *proxy, GDBusObject *object)
|
||||
{
|
||||
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
||||
const char *path = g_dbus_object_get_object_path(object);
|
||||
NMDeviceIwdP2P *p2p = g_hash_table_lookup(priv->p2p_devices, path);
|
||||
|
||||
if (!p2p)
|
||||
return;
|
||||
|
||||
g_hash_table_remove(priv->p2p_devices, path);
|
||||
}
|
||||
|
||||
static NMDeviceIwdP2P *
|
||||
get_p2p_device_from_peer(NMIwdManager *self, GDBusProxy *proxy)
|
||||
{
|
||||
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
||||
const char *device_path = get_property_string_or_null(proxy, "Device");
|
||||
|
||||
if (!device_path)
|
||||
return NULL;
|
||||
|
||||
return g_hash_table_lookup(priv->p2p_devices, device_path);
|
||||
}
|
||||
|
||||
static void
|
||||
known_network_update_cb(GObject *source, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
|
@ -999,6 +1069,22 @@ interface_added(GDBusObjectManager *object_manager,
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_streq(iface_name, NM_IWD_P2P_INTERFACE)) {
|
||||
add_p2p_device(self, proxy, object);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_streq(iface_name, NM_IWD_P2P_PEER_INTERFACE)) {
|
||||
NMDeviceIwdP2P *p2p = get_p2p_device_from_peer(self, proxy);
|
||||
|
||||
/* This is more conveniently done with a direct call than a signal because
|
||||
* this way we only notify the interested NMDeviceIwdP2P. */
|
||||
if (p2p)
|
||||
nm_device_iwd_p2p_peer_add_remove(p2p, object, TRUE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1052,6 +1138,20 @@ interface_removed(GDBusObjectManager *object_manager,
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_streq(iface_name, NM_IWD_P2P_INTERFACE)) {
|
||||
remove_p2p_device(self, proxy, object);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_streq(iface_name, NM_IWD_P2P_PEER_INTERFACE)) {
|
||||
NMDeviceIwdP2P *p2p = get_p2p_device_from_peer(self, proxy);
|
||||
|
||||
if (p2p)
|
||||
nm_device_iwd_p2p_peer_add_remove(p2p, object, FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1705,6 +1805,8 @@ nm_iwd_manager_init(NMIwdManager *self)
|
|||
g_free,
|
||||
(GDestroyNotify) known_network_data_free);
|
||||
|
||||
priv->p2p_devices = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
|
||||
prepare_object_manager(self);
|
||||
}
|
||||
|
||||
|
@ -1738,6 +1840,8 @@ dispose(GObject *object)
|
|||
nm_clear_g_free(&priv->last_state_dir);
|
||||
nm_clear_g_free(&priv->warned_state_dir);
|
||||
|
||||
g_hash_table_unref(nm_steal_pointer(&priv->p2p_devices));
|
||||
|
||||
G_OBJECT_CLASS(nm_iwd_manager_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
|
@ -1747,4 +1851,16 @@ nm_iwd_manager_class_init(NMIwdManagerClass *klass)
|
|||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->dispose = dispose;
|
||||
|
||||
signals[P2P_DEVICE_ADDED] = g_signal_new(NM_IWD_MANAGER_P2P_DEVICE_ADDED,
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
NM_TYPE_DEVICE,
|
||||
G_TYPE_STRING);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
#define NM_IWD_AP_INTERFACE "net.connman.iwd.AccessPoint"
|
||||
#define NM_IWD_ADHOC_INTERFACE "net.connman.iwd.AdHoc"
|
||||
#define NM_IWD_STATION_INTERFACE "net.connman.iwd.Station"
|
||||
#define NM_IWD_P2P_INTERFACE "net.connman.iwd.p2p.Device"
|
||||
#define NM_IWD_P2P_PEER_INTERFACE "net.connman.iwd.p2p.Peer"
|
||||
#define NM_IWD_P2P_SERVICE_MANAGER_INTERFACE "net.connman.iwd.p2p.ServiceManager"
|
||||
#define NM_IWD_P2P_WFD_INTERFACE "net.connman.iwd.p2p.Display"
|
||||
|
||||
#define NM_TYPE_IWD_MANAGER (nm_iwd_manager_get_type())
|
||||
|
@ -37,6 +39,8 @@
|
|||
#define NM_IWD_MANAGER_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_IWD_MANAGER, NMIwdManagerClass))
|
||||
|
||||
#define NM_IWD_MANAGER_P2P_DEVICE_ADDED "p2p-device-added"
|
||||
|
||||
typedef struct _NMIwdManager NMIwdManager;
|
||||
typedef struct _NMIwdManagerClass NMIwdManagerClass;
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "nm-device-wifi-p2p.h"
|
||||
#include "nm-device-olpc-mesh.h"
|
||||
#include "nm-device-iwd.h"
|
||||
#include "nm-device-iwd-p2p.h"
|
||||
#include "nm-iwd-manager.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
#include "libnm-platform/nm-platform.h"
|
||||
#include "nm-config.h"
|
||||
|
@ -67,6 +69,19 @@ p2p_device_created(NMDeviceWifi *device, NMDeviceWifiP2P *p2p_device, NMDeviceFa
|
|||
g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, p2p_device);
|
||||
}
|
||||
|
||||
#if WITH_IWD
|
||||
static void
|
||||
iwd_p2p_device_added(NMIwdManager *iwd,
|
||||
NMDeviceIwdP2P *p2p_device,
|
||||
const char *phy_name,
|
||||
NMDeviceFactory *self)
|
||||
{
|
||||
nm_log_info(LOGD_PLATFORM | LOGD_WIFI, "Wi-Fi P2P device added on %s", phy_name);
|
||||
|
||||
g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, p2p_device);
|
||||
}
|
||||
#endif
|
||||
|
||||
static NMDevice *
|
||||
create_device(NMDeviceFactory *factory,
|
||||
const char *iface,
|
||||
|
@ -138,8 +153,23 @@ create_device(NMDeviceFactory *factory,
|
|||
return device;
|
||||
}
|
||||
#if WITH_IWD
|
||||
else if (!g_ascii_strcasecmp(backend, "iwd"))
|
||||
else if (!g_ascii_strcasecmp(backend, "iwd")) {
|
||||
NMIwdManager *iwd = nm_iwd_manager_get();
|
||||
|
||||
if (!g_signal_handler_find(iwd,
|
||||
G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
G_CALLBACK(iwd_p2p_device_added),
|
||||
factory))
|
||||
g_signal_connect(iwd,
|
||||
NM_IWD_MANAGER_P2P_DEVICE_ADDED,
|
||||
G_CALLBACK(iwd_p2p_device_added),
|
||||
factory);
|
||||
|
||||
return nm_device_iwd_new(iface);
|
||||
}
|
||||
#endif
|
||||
|
||||
nm_log_warn(LOGD_PLATFORM | LOGD_WIFI,
|
||||
|
|
Loading…
Reference in a new issue