mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-09 04:48:10 +02:00
core/devices: Automatically create P2P device for wifi devices
If a wifi device supports P2P mode, then create a further P2P device for it automatically.
This commit is contained in:
parent
00e64d1332
commit
959886892a
3 changed files with 109 additions and 1 deletions
|
|
@ -22,6 +22,7 @@
|
||||||
#include "nm-default.h"
|
#include "nm-default.h"
|
||||||
|
|
||||||
#include "nm-device-wifi.h"
|
#include "nm-device-wifi.h"
|
||||||
|
#include "nm-device-p2p-wifi.h"
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -79,6 +80,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWifi,
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SCANNING_PROHIBITED,
|
SCANNING_PROHIBITED,
|
||||||
|
P2P_DEVICE_CREATED,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
@ -124,6 +126,8 @@ typedef struct {
|
||||||
guint wps_timeout_id;
|
guint wps_timeout_id;
|
||||||
|
|
||||||
NMSettingWirelessWakeOnWLan wowlan_restore;
|
NMSettingWirelessWakeOnWLan wowlan_restore;
|
||||||
|
|
||||||
|
NMDeviceP2PWifi *p2p_device;
|
||||||
} NMDeviceWifiPrivate;
|
} NMDeviceWifiPrivate;
|
||||||
|
|
||||||
struct _NMDeviceWifi
|
struct _NMDeviceWifi
|
||||||
|
|
@ -186,6 +190,10 @@ static void supplicant_iface_notify_current_bss (NMSupplicantInterface *iface,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
NMDeviceWifi *self);
|
NMDeviceWifi *self);
|
||||||
|
|
||||||
|
static void supplicant_iface_notify_p2p_available (NMSupplicantInterface *iface,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
NMDeviceWifi *self);
|
||||||
|
|
||||||
static void request_wireless_scan (NMDeviceWifi *self,
|
static void request_wireless_scan (NMDeviceWifi *self,
|
||||||
gboolean periodic,
|
gboolean periodic,
|
||||||
gboolean force_if_scanning,
|
gboolean force_if_scanning,
|
||||||
|
|
@ -198,6 +206,8 @@ static void ap_add_remove (NMDeviceWifi *self,
|
||||||
|
|
||||||
static void _hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset);
|
static void _hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset);
|
||||||
|
|
||||||
|
static void recheck_p2p_availability (NMDeviceWifi *self);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -291,6 +301,10 @@ supplicant_interface_acquire (NMDeviceWifi *self)
|
||||||
"notify::" NM_SUPPLICANT_INTERFACE_CURRENT_BSS,
|
"notify::" NM_SUPPLICANT_INTERFACE_CURRENT_BSS,
|
||||||
G_CALLBACK (supplicant_iface_notify_current_bss),
|
G_CALLBACK (supplicant_iface_notify_current_bss),
|
||||||
self);
|
self);
|
||||||
|
g_signal_connect (priv->sup_iface,
|
||||||
|
"notify::" NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE,
|
||||||
|
G_CALLBACK (supplicant_iface_notify_p2p_available),
|
||||||
|
self);
|
||||||
|
|
||||||
_notify_scanning (self);
|
_notify_scanning (self);
|
||||||
|
|
||||||
|
|
@ -347,6 +361,11 @@ supplicant_interface_release (NMDeviceWifi *self)
|
||||||
g_clear_object (&priv->sup_iface);
|
g_clear_object (&priv->sup_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->p2p_device) {
|
||||||
|
/* Signal to P2P device to also release its reference */
|
||||||
|
nm_device_p2p_wifi_set_mgmt_iface (priv->p2p_device, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
_notify_scanning (self);
|
_notify_scanning (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2028,6 +2047,10 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
||||||
&& new_state <= NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)
|
&& new_state <= NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)
|
||||||
priv->ssid_found = TRUE;
|
priv->ssid_found = TRUE;
|
||||||
|
|
||||||
|
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY &&
|
||||||
|
new_state >= NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||||
|
recheck_p2p_availability (self);
|
||||||
|
|
||||||
switch (new_state) {
|
switch (new_state) {
|
||||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||||
_LOGD (LOGD_WIFI, "supplicant ready");
|
_LOGD (LOGD_WIFI, "supplicant ready");
|
||||||
|
|
@ -2204,6 +2227,61 @@ supplicant_iface_notify_current_bss (NMSupplicantInterface *iface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We bind the existance of the P2P device to a wifi device that is being
|
||||||
|
* managed by NetworkManager and is capable of P2P operation.
|
||||||
|
* Note that some care must be taken here, because we don't want to re-create
|
||||||
|
* the device every time the supplicant interface is destroyed (e.g. due to
|
||||||
|
* a suspend/resume cycle).
|
||||||
|
* Therefore, this function will be called when a change in the P2P capability
|
||||||
|
* is detected and the supplicant interface has been initialised.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
recheck_p2p_availability (NMDeviceWifi *self)
|
||||||
|
{
|
||||||
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||||
|
NMDeviceP2PWifi *p2p_device;
|
||||||
|
gboolean p2p_available;
|
||||||
|
|
||||||
|
g_object_get (priv->sup_iface,
|
||||||
|
NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE, &p2p_available,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (p2p_available && !priv->p2p_device) {
|
||||||
|
g_autofree char *iface_name = NULL;
|
||||||
|
/* Create a P2P device. "p2p-dev-" is the same prefix as chosen by
|
||||||
|
* wpa_supplicant internally.
|
||||||
|
*/
|
||||||
|
iface_name = g_strconcat ("p2p-dev-", nm_device_get_iface (NM_DEVICE (self)), NULL);
|
||||||
|
p2p_device = NM_DEVICE_P2P_WIFI (nm_device_p2p_wifi_new (priv->sup_iface, iface_name));
|
||||||
|
priv->p2p_device = p2p_device;
|
||||||
|
|
||||||
|
g_signal_emit (self, signals[P2P_DEVICE_CREATED], 0, priv->p2p_device);
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (p2p_device), (gpointer*) &priv->p2p_device);
|
||||||
|
g_object_unref (p2p_device);
|
||||||
|
|
||||||
|
} else if (p2p_available && priv->p2p_device) {
|
||||||
|
nm_device_p2p_wifi_set_mgmt_iface (priv->p2p_device, priv->sup_iface);
|
||||||
|
|
||||||
|
} else if (!p2p_available && priv->p2p_device) {
|
||||||
|
/* Destroy the P2P device. */
|
||||||
|
g_object_remove_weak_pointer (G_OBJECT (priv->p2p_device), (gpointer*) &priv->p2p_device);
|
||||||
|
nm_device_p2p_wifi_remove (priv->p2p_device);
|
||||||
|
priv->p2p_device = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
supplicant_iface_notify_p2p_available (NMSupplicantInterface *iface,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
NMDeviceWifi *self)
|
||||||
|
{
|
||||||
|
/* Do not update when the interface is still initializing. */
|
||||||
|
if (nm_supplicant_interface_get_state (iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
recheck_p2p_availability (self);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_auth_or_fail (NMDeviceWifi *self,
|
handle_auth_or_fail (NMDeviceWifi *self,
|
||||||
NMActRequest *req,
|
NMActRequest *req,
|
||||||
|
|
@ -3426,4 +3504,12 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
||||||
G_STRUCT_OFFSET (NMDeviceWifiClass, scanning_prohibited),
|
G_STRUCT_OFFSET (NMDeviceWifiClass, scanning_prohibited),
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN);
|
G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
|
signals[P2P_DEVICE_CREATED] =
|
||||||
|
g_signal_new (NM_DEVICE_WIFI_P2P_DEVICE_CREATED,
|
||||||
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 1, NM_TYPE_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#define NM_DEVICE_WIFI_LAST_SCAN "last-scan"
|
#define NM_DEVICE_WIFI_LAST_SCAN "last-scan"
|
||||||
|
|
||||||
#define NM_DEVICE_WIFI_SCANNING_PROHIBITED "scanning-prohibited"
|
#define NM_DEVICE_WIFI_SCANNING_PROHIBITED "scanning-prohibited"
|
||||||
|
#define NM_DEVICE_WIFI_P2P_DEVICE_CREATED "p2p-device-created"
|
||||||
|
|
||||||
typedef struct _NMDeviceWifi NMDeviceWifi;
|
typedef struct _NMDeviceWifi NMDeviceWifi;
|
||||||
typedef struct _NMDeviceWifiClass NMDeviceWifiClass;
|
typedef struct _NMDeviceWifiClass NMDeviceWifiClass;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "nm-setting-wireless.h"
|
#include "nm-setting-wireless.h"
|
||||||
#include "nm-setting-olpc-mesh.h"
|
#include "nm-setting-olpc-mesh.h"
|
||||||
#include "nm-device-wifi.h"
|
#include "nm-device-wifi.h"
|
||||||
|
#include "nm-device-p2p-wifi.h"
|
||||||
#include "nm-device-olpc-mesh.h"
|
#include "nm-device-olpc-mesh.h"
|
||||||
#include "nm-device-iwd.h"
|
#include "nm-device-iwd.h"
|
||||||
#include "settings/nm-settings-connection.h"
|
#include "settings/nm-settings-connection.h"
|
||||||
|
|
@ -68,6 +69,18 @@ nm_device_factory_create (GError **error)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
p2p_device_created (NMDeviceWifi *device,
|
||||||
|
NMDeviceP2PWifi *p2p_device,
|
||||||
|
NMDeviceFactory *self)
|
||||||
|
{
|
||||||
|
nm_log_info (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
|
"P2P Wifi device controlled by wifi interface %s created",
|
||||||
|
nm_device_get_iface (NM_DEVICE (device)));
|
||||||
|
|
||||||
|
g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, p2p_device);
|
||||||
|
}
|
||||||
|
|
||||||
static NMDevice *
|
static NMDevice *
|
||||||
create_device (NMDeviceFactory *factory,
|
create_device (NMDeviceFactory *factory,
|
||||||
const char *iface,
|
const char *iface,
|
||||||
|
|
@ -98,6 +111,7 @@ create_device (NMDeviceFactory *factory,
|
||||||
NM_PRINT_FMT_QUOTE_STRING (backend),
|
NM_PRINT_FMT_QUOTE_STRING (backend),
|
||||||
WITH_IWD ? " (iwd support enabled)" : "");
|
WITH_IWD ? " (iwd support enabled)" : "");
|
||||||
if (!backend || !strcasecmp (backend, "wpa_supplicant")) {
|
if (!backend || !strcasecmp (backend, "wpa_supplicant")) {
|
||||||
|
NMDevice *device;
|
||||||
NMDeviceWifiCapabilities capabilities;
|
NMDeviceWifiCapabilities capabilities;
|
||||||
NM80211Mode mode;
|
NM80211Mode mode;
|
||||||
|
|
||||||
|
|
@ -120,7 +134,14 @@ create_device (NMDeviceFactory *factory,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nm_device_wifi_new (iface, capabilities);
|
device = nm_device_wifi_new (iface, capabilities);
|
||||||
|
|
||||||
|
g_signal_connect_object (device, NM_DEVICE_WIFI_P2P_DEVICE_CREATED,
|
||||||
|
G_CALLBACK (p2p_device_created),
|
||||||
|
factory,
|
||||||
|
0);
|
||||||
|
|
||||||
|
return device;
|
||||||
}
|
}
|
||||||
#if WITH_IWD
|
#if WITH_IWD
|
||||||
else if (!strcasecmp (backend, "iwd"))
|
else if (!strcasecmp (backend, "iwd"))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue