mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-15 04:24:32 +00:00
supplicant: merge branch 'th/supplicant'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/426
This commit is contained in:
commit
f714ae7626
|
@ -43,6 +43,8 @@ _LOG_DECLARE_SELF(NMDeviceEthernet);
|
|||
#define PPPOE_RECONNECT_DELAY 7
|
||||
#define PPPOE_ENCAP_OVERHEAD 8 /* 2 bytes for PPP, 6 for PPPoE */
|
||||
|
||||
#define SUPPLICANT_LNK_TIMEOUT_SEC 15
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
|
@ -74,16 +76,17 @@ typedef struct _NMDeviceEthernetPrivate {
|
|||
|
||||
struct {
|
||||
NMSupplicantManager *mgr;
|
||||
NMSupplMgrCreateIfaceHandle *create_handle;
|
||||
NMSupplicantInterface *iface;
|
||||
|
||||
/* signal handler ids */
|
||||
gulong iface_state_id;
|
||||
gulong auth_state_id;
|
||||
|
||||
/* Timeouts and idles */
|
||||
guint con_timeout_id;
|
||||
|
||||
guint timeout_id;
|
||||
guint lnk_timeout_id;
|
||||
|
||||
bool is_associated:1;
|
||||
} supplicant;
|
||||
|
||||
NMActRequestGetSecretsCallId *wired_secrets_id;
|
||||
|
@ -399,7 +402,9 @@ supplicant_interface_release (NMDeviceEthernet *self)
|
|||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
nm_clear_g_source (&priv->supplicant.timeout_id);
|
||||
nm_clear_pointer (&priv->supplicant.create_handle, nm_supplicant_manager_create_interface_cancel);
|
||||
|
||||
nm_clear_g_source (&priv->supplicant.lnk_timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.con_timeout_id);
|
||||
nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.iface_state_id);
|
||||
nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.auth_state_id);
|
||||
|
@ -537,7 +542,7 @@ wired_secrets_get_secrets (NMDeviceEthernet *self,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
link_timeout_cb (gpointer user_data)
|
||||
supplicant_lnk_timeout_cb (gpointer user_data)
|
||||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
@ -546,13 +551,13 @@ link_timeout_cb (gpointer user_data)
|
|||
NMConnection *applied_connection;
|
||||
const char *setting_name;
|
||||
|
||||
priv->supplicant.timeout_id = 0;
|
||||
priv->supplicant.lnk_timeout_id = 0;
|
||||
|
||||
req = nm_device_get_act_request (device);
|
||||
|
||||
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
|
||||
wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT);
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* Disconnect event during initial authentication and credentials
|
||||
|
@ -577,13 +582,13 @@ link_timeout_cb (gpointer user_data)
|
|||
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
wired_secrets_get_secrets (self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
time_out:
|
||||
_LOGW (LOGD_DEVICE | LOGD_ETHER, "link timed out.");
|
||||
wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static NMSupplicantConfig *
|
||||
|
@ -615,19 +620,87 @@ build_supplicant_config (NMDeviceEthernet *self,
|
|||
return config;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_state_is_completed (NMDeviceEthernet *self,
|
||||
NMSupplicantInterfaceState state)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
if (state == NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
|
||||
nm_clear_g_source (&priv->supplicant.lnk_timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.con_timeout_id);
|
||||
|
||||
/* If this is the initial association during device activation,
|
||||
* schedule the next activation stage.
|
||||
*/
|
||||
if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_CONFIG) {
|
||||
_LOGI (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: (ethernet) Stage 2 of 5 (Device Configure) successful.");
|
||||
nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !priv->supplicant.lnk_timeout_id
|
||||
&& !priv->supplicant.con_timeout_id)
|
||||
priv->supplicant.lnk_timeout_id = g_timeout_add_seconds (SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_assoc_cb (NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
|
||||
NMDeviceEthernet *self;
|
||||
NMDeviceEthernetPrivate *priv;
|
||||
|
||||
if (error && !nm_utils_error_is_cancelled_or_disposing (error)) {
|
||||
if (nm_utils_error_is_cancelled_or_disposing (error))
|
||||
return;
|
||||
|
||||
self = NM_DEVICE_ETHERNET (user_data);
|
||||
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
if (error) {
|
||||
supplicant_interface_release (self);
|
||||
nm_device_queue_state (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
nm_assert (!priv->supplicant.lnk_timeout_id);
|
||||
nm_assert (!priv->supplicant.is_associated);
|
||||
|
||||
priv->supplicant.is_associated = TRUE;
|
||||
supplicant_iface_state_is_completed (self,
|
||||
nm_supplicant_interface_get_state (priv->supplicant.iface));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_iface_start (NMDeviceEthernet *self)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
gs_unref_object NMSupplicantConfig *config = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
config = build_supplicant_config (self, &error);
|
||||
if (!config) {
|
||||
_LOGE (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: (ethernet) couldn't build security configuration: %s",
|
||||
error->message);
|
||||
supplicant_interface_release (self);
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_supplicant_interface_disconnect (priv->supplicant.iface);
|
||||
nm_supplicant_interface_assoc (priv->supplicant.iface,
|
||||
config,
|
||||
supplicant_iface_assoc_cb,
|
||||
self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -639,69 +712,26 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
NMSupplicantConfig *config;
|
||||
NMDeviceState devstate;
|
||||
GError *error = NULL;
|
||||
NMSupplicantInterfaceState new_state = new_state_i;
|
||||
NMSupplicantInterfaceState old_state = old_state_i;
|
||||
|
||||
if (new_state == old_state)
|
||||
return;
|
||||
|
||||
_LOGI (LOGD_DEVICE | LOGD_ETHER, "supplicant interface state: %s -> %s",
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
|
||||
devstate = nm_device_get_state (device);
|
||||
|
||||
switch (new_state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||
config = build_supplicant_config (self, &error);
|
||||
if (config) {
|
||||
nm_supplicant_interface_assoc (priv->supplicant.iface, config,
|
||||
supplicant_iface_assoc_cb, self);
|
||||
g_object_unref (config);
|
||||
} else {
|
||||
_LOGE (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: (ethernet) couldn't build security configuration: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
|
||||
nm_clear_g_source (&priv->supplicant.timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.con_timeout_id);
|
||||
|
||||
/* If this is the initial association during device activation,
|
||||
* schedule the next activation stage.
|
||||
*/
|
||||
if (devstate == NM_DEVICE_STATE_CONFIG) {
|
||||
_LOGI (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: (ethernet) Stage 2 of 5 (Device Configure) successful.");
|
||||
nm_device_activate_schedule_stage3_ip_config_start (device);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
/* Start the link timeout so we allow some time for reauthentication */
|
||||
if (!priv->supplicant.timeout_id)
|
||||
priv->supplicant.timeout_id = g_timeout_add_seconds (15, link_timeout_cb, device);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
||||
supplicant_interface_release (self);
|
||||
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device))
|
||||
wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
||||
if (!supplicant_iface_start (self))
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->supplicant.is_associated)
|
||||
supplicant_iface_state_is_completed (self, new_state);
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
|
@ -770,43 +800,70 @@ supplicant_connection_timeout_cb (gpointer user_data)
|
|||
if (nm_settings_connection_get_timestamp (connection, ×tamp))
|
||||
new_secrets = !timestamp;
|
||||
|
||||
if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_FAILURE)
|
||||
if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_NO_SECRETS);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_interface_init (NMDeviceEthernet *self)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
guint timeout;
|
||||
|
||||
supplicant_interface_release (self);
|
||||
|
||||
priv->supplicant.iface = nm_supplicant_manager_create_interface (priv->supplicant.mgr,
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
NM_SUPPLICANT_DRIVER_WIRED);
|
||||
|
||||
if (!priv->supplicant.iface) {
|
||||
_LOGE (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Couldn't initialize supplicant interface");
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* Listen for its state signals */
|
||||
if ( !priv->supplicant.lnk_timeout_id
|
||||
&& priv->supplicant.iface) {
|
||||
NMSupplicantInterfaceState state;
|
||||
|
||||
state = nm_supplicant_interface_get_state (priv->supplicant.iface);
|
||||
if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
|
||||
&& NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (state))
|
||||
priv->supplicant.lnk_timeout_id = g_timeout_add_seconds (SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_interface_create_cb (NMSupplicantManager *supplicant_manager,
|
||||
NMSupplMgrCreateIfaceHandle *handle,
|
||||
NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceEthernet *self;
|
||||
NMDeviceEthernetPrivate *priv;
|
||||
guint timeout;
|
||||
|
||||
if (nm_utils_error_is_cancelled (error))
|
||||
return;
|
||||
|
||||
self = user_data;
|
||||
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (priv->supplicant.create_handle == handle);
|
||||
priv->supplicant.create_handle = NULL;
|
||||
|
||||
if (error) {
|
||||
_LOGE (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Couldn't initialize supplicant interface: %s",
|
||||
error->message);
|
||||
supplicant_interface_release (self);
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->supplicant.iface = g_object_ref (iface);
|
||||
priv->supplicant.is_associated = FALSE;
|
||||
|
||||
priv->supplicant.iface_state_id = g_signal_connect (priv->supplicant.iface,
|
||||
NM_SUPPLICANT_INTERFACE_STATE,
|
||||
G_CALLBACK (supplicant_iface_state_cb),
|
||||
self);
|
||||
|
||||
/* Set up a timeout on the connection attempt */
|
||||
timeout = nm_device_get_supplicant_timeout (NM_DEVICE (self));
|
||||
priv->supplicant.con_timeout_id = g_timeout_add_seconds (timeout,
|
||||
supplicant_connection_timeout_cb,
|
||||
self);
|
||||
|
||||
return TRUE;
|
||||
if (NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (iface)))
|
||||
supplicant_iface_start (self);
|
||||
}
|
||||
|
||||
static NMPlatformLinkDuplexType
|
||||
|
@ -973,18 +1030,21 @@ supplicant_check_secrets_needed (NMDeviceEthernet *self, NMDeviceStateReason *ou
|
|||
ret = handle_auth_or_fail (self, req, FALSE);
|
||||
if (ret != NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS);
|
||||
} else {
|
||||
_LOGI (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: (ethernet) connection '%s' requires no security. No secrets needed.",
|
||||
nm_connection_get_id (connection));
|
||||
|
||||
if (supplicant_interface_init (self))
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
else
|
||||
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
_LOGI (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: (ethernet) connection '%s' requires no security. No secrets needed.",
|
||||
nm_connection_get_id (connection));
|
||||
|
||||
supplicant_interface_release (self);
|
||||
|
||||
priv->supplicant.create_handle = nm_supplicant_manager_create_interface (priv->supplicant.mgr,
|
||||
nm_device_get_ifindex (NM_DEVICE (self)),
|
||||
NM_SUPPLICANT_DRIVER_WIRED,
|
||||
supplicant_interface_create_cb,
|
||||
self);
|
||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -23,6 +23,10 @@ _LOG_DECLARE_SELF(NMDeviceMacsec);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define SUPPLICANT_LNK_TIMEOUT_SEC 15
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceMacsec,
|
||||
PROP_SCI,
|
||||
PROP_CIPHER_SUITE,
|
||||
|
@ -45,16 +49,17 @@ typedef struct {
|
|||
|
||||
struct {
|
||||
NMSupplicantManager *mgr;
|
||||
NMSupplMgrCreateIfaceHandle *create_handle;
|
||||
NMSupplicantInterface *iface;
|
||||
|
||||
/* signal handler ids */
|
||||
gulong iface_state_id;
|
||||
|
||||
/* Timeouts and idles */
|
||||
guint con_timeout_id;
|
||||
guint lnk_timeout_id;
|
||||
|
||||
bool is_associated:1;
|
||||
} supplicant;
|
||||
|
||||
guint supplicant_timeout_id;
|
||||
NMActRequestGetSecretsCallId *macsec_secrets_id;
|
||||
} NMDeviceMacsecPrivate;
|
||||
|
||||
|
@ -254,7 +259,9 @@ supplicant_interface_release (NMDeviceMacsec *self)
|
|||
{
|
||||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
|
||||
nm_clear_g_source (&priv->supplicant_timeout_id);
|
||||
nm_clear_pointer (&priv->supplicant.create_handle, nm_supplicant_manager_create_interface_cancel);
|
||||
|
||||
nm_clear_g_source (&priv->supplicant.lnk_timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.con_timeout_id);
|
||||
nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.iface_state_id);
|
||||
|
||||
|
@ -264,21 +271,6 @@ supplicant_interface_release (NMDeviceMacsec *self)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_assoc_cb (NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data);
|
||||
|
||||
if (error && !nm_utils_error_is_cancelled_or_disposing (error)) {
|
||||
supplicant_interface_release (self);
|
||||
nm_device_queue_state (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
macsec_secrets_cb (NMActRequest *req,
|
||||
NMActRequestGetSecretsCallId *call_id,
|
||||
|
@ -351,7 +343,7 @@ macsec_secrets_get_secrets (NMDeviceMacsec *self,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
link_timeout_cb (gpointer user_data)
|
||||
supplicant_lnk_timeout_cb (gpointer user_data)
|
||||
{
|
||||
NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data);
|
||||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
|
@ -360,7 +352,7 @@ link_timeout_cb (gpointer user_data)
|
|||
NMConnection *applied_connection;
|
||||
const char *setting_name;
|
||||
|
||||
priv->supplicant_timeout_id = 0;
|
||||
priv->supplicant.lnk_timeout_id = 0;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
|
||||
|
@ -368,7 +360,7 @@ link_timeout_cb (gpointer user_data)
|
|||
nm_device_state_changed (dev,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT);
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* Disconnect event during initial authentication and credentials
|
||||
|
@ -392,13 +384,98 @@ link_timeout_cb (gpointer user_data)
|
|||
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
macsec_secrets_get_secrets (self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
time_out:
|
||||
_LOGW (LOGD_DEVICE | LOGD_ETHER, "link timed out.");
|
||||
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_state_is_completed (NMDeviceMacsec *self,
|
||||
NMSupplicantInterfaceState state)
|
||||
{
|
||||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
|
||||
if (state == NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
|
||||
nm_clear_g_source (&priv->supplicant.lnk_timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.con_timeout_id);
|
||||
|
||||
nm_device_bring_up (NM_DEVICE (self), TRUE, NULL);
|
||||
|
||||
/* If this is the initial association during device activation,
|
||||
* schedule the next activation stage.
|
||||
*/
|
||||
if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_CONFIG) {
|
||||
_LOGI (LOGD_DEVICE,
|
||||
"Activation: Stage 2 of 5 (Device Configure) successful.");
|
||||
nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !priv->supplicant.lnk_timeout_id
|
||||
&& !priv->supplicant.con_timeout_id)
|
||||
priv->supplicant.lnk_timeout_id = g_timeout_add_seconds (SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_assoc_cb (NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceMacsec *self;
|
||||
NMDeviceMacsecPrivate *priv;
|
||||
|
||||
if (nm_utils_error_is_cancelled_or_disposing (error))
|
||||
return;
|
||||
|
||||
self = user_data;
|
||||
priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
|
||||
if (error) {
|
||||
supplicant_interface_release (self);
|
||||
nm_device_queue_state (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
nm_assert (!priv->supplicant.lnk_timeout_id);
|
||||
nm_assert (!priv->supplicant.is_associated);
|
||||
|
||||
priv->supplicant.is_associated = TRUE;
|
||||
supplicant_iface_state_is_completed (self,
|
||||
nm_supplicant_interface_get_state (priv->supplicant.iface));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_iface_start (NMDeviceMacsec *self)
|
||||
{
|
||||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
gs_unref_object NMSupplicantConfig *config = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
config = build_supplicant_config (self, &error);
|
||||
if (!config) {
|
||||
_LOGE (LOGD_DEVICE,
|
||||
"Activation: couldn't build security configuration: %s",
|
||||
error->message);
|
||||
supplicant_interface_release (self);
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_supplicant_interface_disconnect (priv->supplicant.iface);
|
||||
nm_supplicant_interface_assoc (priv->supplicant.iface,
|
||||
config,
|
||||
supplicant_iface_assoc_cb,
|
||||
self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -410,73 +487,28 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
{
|
||||
NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data);
|
||||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
NMSupplicantConfig *config;
|
||||
NMDeviceState devstate;
|
||||
GError *error = NULL;
|
||||
NMSupplicantInterfaceState new_state = new_state_i;
|
||||
NMSupplicantInterfaceState old_state = old_state_i;
|
||||
|
||||
if (new_state == old_state)
|
||||
return;
|
||||
|
||||
_LOGI (LOGD_DEVICE, "supplicant interface state: %s -> %s",
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
|
||||
devstate = nm_device_get_state (device);
|
||||
|
||||
switch (new_state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||
config = build_supplicant_config (self, &error);
|
||||
if (config) {
|
||||
nm_supplicant_interface_assoc (priv->supplicant.iface, config,
|
||||
supplicant_iface_assoc_cb, self);
|
||||
g_object_unref (config);
|
||||
} else {
|
||||
_LOGE (LOGD_DEVICE,
|
||||
"Activation: couldn't build security configuration: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
|
||||
nm_clear_g_source (&priv->supplicant_timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.con_timeout_id);
|
||||
nm_device_bring_up (device, TRUE, NULL);
|
||||
|
||||
/* If this is the initial association during device activation,
|
||||
* schedule the next activation stage.
|
||||
*/
|
||||
if (devstate == NM_DEVICE_STATE_CONFIG) {
|
||||
_LOGI (LOGD_DEVICE,
|
||||
"Activation: Stage 2 of 5 (Device Configure) successful.");
|
||||
nm_device_activate_schedule_stage3_ip_config_start (device);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
/* Start the link timeout so we allow some time for reauthentication */
|
||||
if (!priv->supplicant_timeout_id)
|
||||
priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, device);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
||||
supplicant_interface_release (self);
|
||||
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
||||
if (!supplicant_iface_start (self))
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->supplicant.is_associated)
|
||||
supplicant_iface_state_is_completed (self, new_state);
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
|
@ -527,11 +559,10 @@ supplicant_connection_timeout_cb (gpointer user_data)
|
|||
"Activation: (macsec) association took too long.");
|
||||
|
||||
supplicant_interface_release (self);
|
||||
req = nm_device_get_act_request (device);
|
||||
g_assert (req);
|
||||
|
||||
req = nm_device_get_act_request (device);
|
||||
connection = nm_act_request_get_settings_connection (req);
|
||||
g_assert (connection);
|
||||
g_return_val_if_fail (connection, G_SOURCE_REMOVE);
|
||||
|
||||
/* Ask for new secrets only if we've never activated this connection
|
||||
* before. If we've connected before, don't bother the user with dialogs,
|
||||
|
@ -540,48 +571,73 @@ supplicant_connection_timeout_cb (gpointer user_data)
|
|||
if (nm_settings_connection_get_timestamp (connection, ×tamp))
|
||||
new_secrets = !timestamp;
|
||||
|
||||
if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
_LOGW (LOGD_DEVICE, "Activation: (macsec) asking for new secrets");
|
||||
else
|
||||
if (handle_auth_or_fail (self, req, new_secrets) != NM_ACT_STAGE_RETURN_POSTPONE) {
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_interface_init (NMDeviceMacsec *self)
|
||||
{
|
||||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
NMDevice *parent;
|
||||
guint timeout;
|
||||
|
||||
parent = nm_device_parent_get_device (NM_DEVICE (self));
|
||||
g_return_val_if_fail (parent, FALSE);
|
||||
|
||||
supplicant_interface_release (self);
|
||||
|
||||
priv->supplicant.iface = nm_supplicant_manager_create_interface (priv->supplicant.mgr,
|
||||
nm_device_get_iface (parent),
|
||||
NM_SUPPLICANT_DRIVER_MACSEC);
|
||||
|
||||
if (!priv->supplicant.iface) {
|
||||
_LOGE (LOGD_DEVICE,
|
||||
"Couldn't initialize supplicant interface");
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* Listen for its state signals */
|
||||
_LOGW (LOGD_DEVICE, "Activation: (macsec) asking for new secrets");
|
||||
|
||||
if ( !priv->supplicant.lnk_timeout_id
|
||||
&& priv->supplicant.iface) {
|
||||
NMSupplicantInterfaceState state;
|
||||
|
||||
state = nm_supplicant_interface_get_state (priv->supplicant.iface);
|
||||
if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
|
||||
&& NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (state))
|
||||
priv->supplicant.lnk_timeout_id = g_timeout_add_seconds (SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_interface_create_cb (NMSupplicantManager *supplicant_manager,
|
||||
NMSupplMgrCreateIfaceHandle *handle,
|
||||
NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceMacsec *self;
|
||||
NMDeviceMacsecPrivate *priv;
|
||||
guint timeout;
|
||||
|
||||
if (nm_utils_error_is_cancelled (error))
|
||||
return;
|
||||
|
||||
self = user_data;
|
||||
priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (priv->supplicant.create_handle == handle);
|
||||
|
||||
priv->supplicant.create_handle = NULL;
|
||||
|
||||
if (error) {
|
||||
_LOGE (LOGD_DEVICE,
|
||||
"Couldn't initialize supplicant interface: %s",
|
||||
error->message);
|
||||
supplicant_interface_release (self);
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->supplicant.iface = g_object_ref (iface);
|
||||
priv->supplicant.is_associated = FALSE;
|
||||
|
||||
priv->supplicant.iface_state_id = g_signal_connect (priv->supplicant.iface,
|
||||
NM_SUPPLICANT_INTERFACE_STATE,
|
||||
G_CALLBACK (supplicant_iface_state_cb),
|
||||
self);
|
||||
|
||||
/* Set up a timeout on the connection attempt */
|
||||
timeout = nm_device_get_supplicant_timeout (NM_DEVICE (self));
|
||||
priv->supplicant.con_timeout_id = g_timeout_add_seconds (timeout,
|
||||
supplicant_connection_timeout_cb,
|
||||
self);
|
||||
return TRUE;
|
||||
|
||||
if (NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (iface)))
|
||||
supplicant_iface_start (self);
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
|
@ -591,7 +647,9 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
|
||||
NMConnection *connection;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMDevice *parent;
|
||||
const char *setting_name;
|
||||
int ifindex;
|
||||
|
||||
connection = nm_device_get_applied_connection (NM_DEVICE (self));
|
||||
|
||||
|
@ -612,18 +670,26 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
ret = handle_auth_or_fail (self, req, FALSE);
|
||||
if (ret != NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS);
|
||||
} else {
|
||||
_LOGI (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: connection '%s' requires no security. No secrets needed.",
|
||||
nm_connection_get_id (connection));
|
||||
|
||||
if (supplicant_interface_init (self))
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
else
|
||||
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
_LOGI (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation: connection '%s' requires no security. No secrets needed.",
|
||||
nm_connection_get_id (connection));
|
||||
|
||||
supplicant_interface_release (self);
|
||||
|
||||
parent = nm_device_parent_get_device (NM_DEVICE (self));
|
||||
g_return_val_if_fail (parent, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
ifindex = nm_device_get_ifindex (parent);
|
||||
g_return_val_if_fail (ifindex > 0, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
priv->supplicant.create_handle = nm_supplicant_manager_create_interface (priv->supplicant.mgr,
|
||||
ifindex,
|
||||
NM_SUPPLICANT_DRIVER_MACSEC,
|
||||
supplicant_interface_create_cb,
|
||||
self);
|
||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -7,24 +7,26 @@
|
|||
|
||||
#include "nm-device-iwd.h"
|
||||
|
||||
#include "nm-libnm-core-intern/nm-common-macros.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "devices/nm-device-private.h"
|
||||
#include "nm-utils.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-act-request.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
#include "nm-config.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-glib-aux/nm-ref-string.h"
|
||||
#include "nm-iwd-manager.h"
|
||||
#include "nm-libnm-core-intern/nm-common-macros.h"
|
||||
#include "nm-setting-8021x.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-std-aux/nm-dbus-compat.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-wifi-common.h"
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
#include "settings/nm-settings.h"
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "nm-wifi-common.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-config.h"
|
||||
#include "nm-iwd-manager.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-std-aux/nm-dbus-compat.h"
|
||||
#include "supplicant/nm-supplicant-types.h"
|
||||
|
||||
#include "devices/nm-device-logging.h"
|
||||
_LOG_DECLARE_SELF(NMDeviceIwd);
|
||||
|
@ -191,45 +193,43 @@ remove_all_aps (NMDeviceIwd *self)
|
|||
nm_device_recheck_available_connections (NM_DEVICE (self));
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
vardict_from_network_type (const char *type)
|
||||
static NM80211ApSecurityFlags
|
||||
ap_security_flags_from_network_type (const char *type)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
const char *key_mgmt = "";
|
||||
const char *pairwise = "ccmp";
|
||||
NM80211ApSecurityFlags flags;
|
||||
|
||||
if (!strcmp (type, "psk"))
|
||||
key_mgmt = "wpa-psk";
|
||||
else if (!strcmp (type, "8021x"))
|
||||
key_mgmt = "wpa-eap";
|
||||
if (nm_streq (type, "psk"))
|
||||
flags = NM_802_11_AP_SEC_KEY_MGMT_PSK;
|
||||
else if (nm_streq (type, "8021x"))
|
||||
flags = NM_802_11_AP_SEC_KEY_MGMT_802_1X;
|
||||
else
|
||||
return NULL;
|
||||
return NM_802_11_AP_SEC_NONE;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add (&builder, "{sv}", "KeyMgmt",
|
||||
g_variant_new_strv (&key_mgmt, 1));
|
||||
g_variant_builder_add (&builder, "{sv}", "Pairwise",
|
||||
g_variant_new_strv (&pairwise, 1));
|
||||
g_variant_builder_add (&builder, "{sv}", "Group",
|
||||
g_variant_new_string ("ccmp"));
|
||||
return g_variant_new ("a{sv}", &builder);
|
||||
flags |= NM_802_11_AP_SEC_PAIR_CCMP;
|
||||
flags |= NM_802_11_AP_SEC_GROUP_CCMP;
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void
|
||||
insert_ap_from_network (NMDeviceIwd *self,
|
||||
GHashTable *aps,
|
||||
const char *path,
|
||||
gint64 last_seen_msec,
|
||||
int16_t signal,
|
||||
uint32_t ap_id)
|
||||
{
|
||||
gs_unref_object GDBusProxy *network_proxy = NULL;
|
||||
gs_unref_variant GVariant *name_value = NULL, *type_value = NULL;
|
||||
const char *name, *type;
|
||||
GVariantBuilder builder;
|
||||
gs_unref_variant GVariant *props = NULL;
|
||||
GVariant *rsn;
|
||||
gs_unref_variant GVariant *name_value = NULL;
|
||||
gs_unref_variant GVariant *type_value = NULL;
|
||||
nm_auto_ref_string NMRefString *bss_path = NULL;
|
||||
const char *name;
|
||||
const char *type;
|
||||
NMSupplicantBssInfo bss_info;
|
||||
uint8_t bssid[6];
|
||||
NMWifiAP *ap;
|
||||
gs_unref_bytes GBytes *ssid = NULL;
|
||||
|
||||
bss_path = nm_ref_string_new (path);
|
||||
|
||||
if (g_hash_table_lookup (aps, path)) {
|
||||
_LOGD (LOGD_WIFI, "Duplicate network at %s", path);
|
||||
|
@ -253,6 +253,11 @@ insert_ap_from_network (NMDeviceIwd *self,
|
|||
name = g_variant_get_string (name_value, NULL);
|
||||
type = g_variant_get_string (type_value, NULL);
|
||||
|
||||
if (nm_streq (type, "wep")) {
|
||||
/* WEP not supported */
|
||||
return;
|
||||
}
|
||||
|
||||
/* What we get from IWD are networks, or ESSs, that may contain
|
||||
* multiple APs, or BSSs, each. We don't get information about any
|
||||
* specific BSSs within an ESS but we can safely present each ESS
|
||||
|
@ -268,32 +273,26 @@ insert_ap_from_network (NMDeviceIwd *self,
|
|||
bssid[4] = ap_id >> 8;
|
||||
bssid[5] = ap_id;
|
||||
|
||||
/* WEP not supported */
|
||||
if (nm_streq (type, "wep"))
|
||||
return;
|
||||
ssid = g_bytes_new (name, NM_MIN (32u, strlen (name)));
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add (&builder, "{sv}", "BSSID",
|
||||
g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, bssid, 6, 1));
|
||||
g_variant_builder_add (&builder, "{sv}", "Mode",
|
||||
g_variant_new_string ("infrastructure"));
|
||||
bss_info = (NMSupplicantBssInfo) {
|
||||
.bss_path = bss_path,
|
||||
.last_seen_msec = last_seen_msec,
|
||||
.bssid_valid = TRUE,
|
||||
.mode = NM_802_11_MODE_INFRA,
|
||||
.rsn_flags = ap_security_flags_from_network_type (type),
|
||||
.ssid = ssid,
|
||||
.signal_percent = nm_wifi_utils_level_to_quality (signal / 100),
|
||||
.frequency = 2417,
|
||||
.max_rate = 65000,
|
||||
};
|
||||
memcpy (bss_info.bssid, bssid, sizeof (bssid));
|
||||
|
||||
rsn = vardict_from_network_type (type);
|
||||
if (rsn)
|
||||
g_variant_builder_add (&builder, "{sv}", "RSN", rsn);
|
||||
ap = nm_wifi_ap_new_from_properties (&bss_info);
|
||||
|
||||
props = g_variant_new ("a{sv}", &builder);
|
||||
nm_assert (bss_path == nm_wifi_ap_get_supplicant_path (ap));
|
||||
|
||||
ap = nm_wifi_ap_new_from_properties (path, props);
|
||||
|
||||
nm_wifi_ap_set_ssid_arr (ap,
|
||||
(const guint8 *) name,
|
||||
NM_MIN (32, strlen (name)));
|
||||
|
||||
nm_wifi_ap_set_strength (ap, nm_wifi_utils_level_to_quality (signal / 100));
|
||||
nm_wifi_ap_set_freq (ap, 2417);
|
||||
nm_wifi_ap_set_max_bitrate (ap, 65000);
|
||||
g_hash_table_insert (aps, (gpointer) nm_wifi_ap_get_supplicant_path (ap), ap);
|
||||
g_hash_table_insert (aps, bss_path, ap);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -313,6 +312,7 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|||
gboolean compat;
|
||||
const char *return_sig;
|
||||
static uint32_t ap_id = 0;
|
||||
gint64 last_seen_msec;
|
||||
|
||||
variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error);
|
||||
if (!variant) {
|
||||
|
@ -336,16 +336,17 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
|||
return;
|
||||
}
|
||||
|
||||
new_aps = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref);
|
||||
new_aps = g_hash_table_new_full (nm_direct_hash, NULL, NULL, g_object_unref);
|
||||
|
||||
g_variant_get (variant, return_sig, &networks);
|
||||
|
||||
last_seen_msec = nm_utils_get_monotonic_timestamp_msec ();
|
||||
if (compat) {
|
||||
while (g_variant_iter_next (networks, "(&o&sn&s)", &path, &name, &signal, &type))
|
||||
insert_ap_from_network (self, new_aps, path, signal, ap_id++);
|
||||
insert_ap_from_network (self, new_aps, path, last_seen_msec, signal, ap_id++);
|
||||
} else {
|
||||
while (g_variant_iter_next (networks, "(&on)", &path, &signal))
|
||||
insert_ap_from_network (self, new_aps, path, signal, ap_id++);
|
||||
insert_ap_from_network (self, new_aps, path, last_seen_msec, signal, ap_id++);
|
||||
}
|
||||
|
||||
g_variant_iter_free (networks);
|
||||
|
@ -570,7 +571,7 @@ is_ap_known_network (NMWifiAP *ap)
|
|||
gs_unref_variant GVariant *known_network = NULL;
|
||||
|
||||
network_proxy = nm_iwd_manager_get_dbus_interface (nm_iwd_manager_get (),
|
||||
nm_wifi_ap_get_supplicant_path (ap),
|
||||
nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap)),
|
||||
NM_IWD_NETWORK_INTERFACE);
|
||||
if (!network_proxy)
|
||||
return FALSE;
|
||||
|
@ -1148,7 +1149,7 @@ try_reply_agent_request (NMDeviceIwd *self,
|
|||
|
||||
*replied = FALSE;
|
||||
|
||||
if (!strcmp (method_name, "RequestPassphrase")) {
|
||||
if (nm_streq (method_name, "RequestPassphrase")) {
|
||||
const char *psk;
|
||||
|
||||
if (!s_wireless_sec)
|
||||
|
@ -1168,7 +1169,7 @@ try_reply_agent_request (NMDeviceIwd *self,
|
|||
*setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
|
||||
*setting_key = NM_SETTING_WIRELESS_SECURITY_PSK;
|
||||
return TRUE;
|
||||
} else if (!strcmp (method_name, "RequestPrivateKeyPassphrase")) {
|
||||
} else if (nm_streq (method_name, "RequestPrivateKeyPassphrase")) {
|
||||
const char *password;
|
||||
|
||||
if (!s_8021x)
|
||||
|
@ -1188,7 +1189,7 @@ try_reply_agent_request (NMDeviceIwd *self,
|
|||
*setting_name = NM_SETTING_802_1X_SETTING_NAME;
|
||||
*setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD;
|
||||
return TRUE;
|
||||
} else if (!strcmp (method_name, "RequestUserNameAndPassword")) {
|
||||
} else if (nm_streq (method_name, "RequestUserNameAndPassword")) {
|
||||
const char *identity, *password;
|
||||
|
||||
if (!s_8021x)
|
||||
|
@ -1212,7 +1213,7 @@ try_reply_agent_request (NMDeviceIwd *self,
|
|||
else
|
||||
*setting_key = NM_SETTING_802_1X_PASSWORD;
|
||||
return TRUE;
|
||||
} else if (!strcmp (method_name, "RequestUserPassword")) {
|
||||
} else if (nm_streq (method_name, "RequestUserPassword")) {
|
||||
const char *password;
|
||||
|
||||
if (!s_8021x)
|
||||
|
@ -1812,12 +1813,12 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
}
|
||||
|
||||
network_proxy = nm_iwd_manager_get_dbus_interface (nm_iwd_manager_get (),
|
||||
nm_wifi_ap_get_supplicant_path (ap),
|
||||
nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap)),
|
||||
NM_IWD_NETWORK_INTERFACE);
|
||||
if (!network_proxy) {
|
||||
_LOGE (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) could not get Network interface proxy for %s",
|
||||
nm_wifi_ap_get_supplicant_path (ap));
|
||||
nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap)));
|
||||
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -12,19 +12,20 @@
|
|||
#include "supplicant/nm-supplicant-manager.h"
|
||||
#include "supplicant/nm-supplicant-interface.h"
|
||||
|
||||
#include "nm-manager.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-wifi-p2p-peer.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "devices/nm-device-private.h"
|
||||
#include "settings/nm-settings.h"
|
||||
#include "nm-setting-wifi-p2p.h"
|
||||
#include "nm-act-request.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-glib-aux/nm-ref-string.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-setting-wifi-p2p.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-wifi-p2p-peer.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "platform/nmp-object.h"
|
||||
#include "settings/nm-settings.h"
|
||||
|
||||
#include "devices/nm-device-logging.h"
|
||||
_LOG_DECLARE_SELF(NMDeviceWifiP2P);
|
||||
|
@ -227,11 +228,7 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
|
|||
return FALSE;
|
||||
|
||||
supplicant_state = nm_supplicant_interface_get_state (priv->mgmt_iface);
|
||||
if ( supplicant_state < NM_SUPPLICANT_INTERFACE_STATE_READY
|
||||
|| supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (supplicant_state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -649,52 +646,49 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
NMSupplicantInterfaceState new_state = new_state_i;
|
||||
NMSupplicantInterfaceState old_state = old_state_i;
|
||||
|
||||
if (new_state == old_state)
|
||||
return;
|
||||
|
||||
_LOGI (LOGD_DEVICE | LOGD_WIFI,
|
||||
"supplicant management interface state: %s -> %s",
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
|
||||
switch (new_state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||
_LOGD (LOGD_WIFI, "supplicant ready");
|
||||
nm_device_queue_recheck_available (device,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
|
||||
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
_set_is_waiting_for_supplicant (self, FALSE);
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
||||
supplicant_interfaces_release (self, TRUE);
|
||||
nm_device_queue_recheck_available (device,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
||||
_LOGD (LOGD_WIFI, "supplicant ready");
|
||||
nm_device_queue_recheck_available (device,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
_set_is_waiting_for_supplicant (self, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_peer_updated_cb (NMSupplicantInterface *iface,
|
||||
const char *object_path,
|
||||
GVariant *properties,
|
||||
supplicant_iface_peer_changed_cb (NMSupplicantInterface *iface,
|
||||
NMSupplicantPeerInfo *peer_info,
|
||||
gboolean is_present,
|
||||
NMDeviceWifiP2P *self)
|
||||
{
|
||||
NMDeviceWifiP2PPrivate *priv;
|
||||
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
|
||||
NMWifiP2PPeer *found_peer;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (object_path != NULL);
|
||||
found_peer = nm_wifi_p2p_peers_find_by_supplicant_path (&priv->peers_lst_head, peer_info->peer_path->str);
|
||||
|
||||
priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
|
||||
if (!is_present) {
|
||||
if (!found_peer)
|
||||
return;
|
||||
|
||||
peer_add_remove (self, FALSE, found_peer, TRUE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
found_peer = nm_wifi_p2p_peers_find_by_supplicant_path (&priv->peers_lst_head, object_path);
|
||||
if (found_peer) {
|
||||
if (!nm_wifi_p2p_peer_update_from_properties (found_peer, object_path, properties))
|
||||
if (!nm_wifi_p2p_peer_update_from_properties (found_peer, peer_info))
|
||||
return;
|
||||
|
||||
update_disconnect_on_connection_peer_missing (self);
|
||||
|
@ -702,35 +696,11 @@ supplicant_iface_peer_updated_cb (NMSupplicantInterface *iface,
|
|||
} else {
|
||||
gs_unref_object NMWifiP2PPeer *peer = NULL;
|
||||
|
||||
peer = nm_wifi_p2p_peer_new_from_properties (object_path, properties);
|
||||
if (!peer) {
|
||||
_LOGD (LOGD_WIFI, "invalid P2P peer properties received for %s", object_path);
|
||||
return;
|
||||
}
|
||||
|
||||
peer = nm_wifi_p2p_peer_new_from_properties (peer_info);
|
||||
peer_add_remove (self, TRUE, peer, TRUE);
|
||||
}
|
||||
|
||||
schedule_peer_list_dump (self);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_peer_removed_cb (NMSupplicantInterface *iface,
|
||||
const char *object_path,
|
||||
NMDeviceWifiP2P *self)
|
||||
{
|
||||
NMDeviceWifiP2PPrivate *priv;
|
||||
NMWifiP2PPeer *peer;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (object_path != NULL);
|
||||
|
||||
priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
|
||||
peer = nm_wifi_p2p_peers_find_by_supplicant_path (&priv->peers_lst_head, object_path);
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
peer_add_remove (self, FALSE, peer, TRUE);
|
||||
out:
|
||||
schedule_peer_list_dump (self);
|
||||
}
|
||||
|
||||
|
@ -742,7 +712,7 @@ check_group_iface_ready (NMDeviceWifiP2P *self)
|
|||
if (!priv->group_iface)
|
||||
return;
|
||||
|
||||
if (nm_supplicant_interface_get_state (priv->group_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
if (!NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (priv->group_iface)))
|
||||
return;
|
||||
|
||||
if (!nm_supplicant_interface_get_p2p_group_joined (priv->group_iface))
|
||||
|
@ -754,6 +724,24 @@ check_group_iface_ready (NMDeviceWifiP2P *self)
|
|||
nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self));
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_group_iface_is_ready (NMDeviceWifiP2P *self)
|
||||
{
|
||||
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
|
||||
|
||||
_LOGD (LOGD_WIFI, "P2P Group supplicant ready");
|
||||
|
||||
if (!nm_device_set_ip_iface (NM_DEVICE (self), nm_supplicant_interface_get_ifname (priv->group_iface))) {
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
_set_is_waiting_for_supplicant (self, FALSE);
|
||||
check_group_iface_ready (self);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_group_iface_state_cb (NMSupplicantInterface *iface,
|
||||
int new_state_i,
|
||||
|
@ -762,44 +750,26 @@ supplicant_group_iface_state_cb (NMSupplicantInterface *iface,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data);
|
||||
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
NMSupplicantInterfaceState new_state = new_state_i;
|
||||
NMSupplicantInterfaceState old_state = old_state_i;
|
||||
|
||||
if (new_state == old_state)
|
||||
return;
|
||||
|
||||
_LOGI (LOGD_DEVICE | LOGD_WIFI,
|
||||
"P2P Group supplicant interface state: %s -> %s",
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
|
||||
switch (new_state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||
_LOGD (LOGD_WIFI, "P2P Group supplicant ready");
|
||||
|
||||
if (!nm_device_set_ip_iface (device, nm_supplicant_interface_get_ifname (priv->group_iface))) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
_set_is_waiting_for_supplicant (self, FALSE);
|
||||
|
||||
check_group_iface_ready (self);
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
||||
supplicant_group_interface_release (self);
|
||||
|
||||
nm_device_state_changed (device,
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
||||
supplicant_group_iface_is_ready (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -833,8 +803,9 @@ supplicant_iface_group_started_cb (NMSupplicantInterface *iface,
|
|||
NMDeviceWifiP2P *self)
|
||||
{
|
||||
NMDeviceWifiP2PPrivate *priv;
|
||||
NMSupplicantInterfaceState state;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (self);
|
||||
|
||||
if (!nm_device_is_activating (NM_DEVICE (self))) {
|
||||
_LOGW (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant notified a group start but we are not trying to connect! Ignoring the event.");
|
||||
|
@ -844,6 +815,7 @@ supplicant_iface_group_started_cb (NMSupplicantInterface *iface,
|
|||
priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
|
||||
|
||||
supplicant_group_interface_release (self);
|
||||
|
||||
priv->group_iface = g_object_ref (group_iface);
|
||||
|
||||
/* We need to wait for the interface to be ready and the group
|
||||
|
@ -862,10 +834,13 @@ supplicant_iface_group_started_cb (NMSupplicantInterface *iface,
|
|||
G_CALLBACK (supplicant_group_iface_group_finished_cb),
|
||||
self);
|
||||
|
||||
if (nm_supplicant_interface_get_state (priv->group_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
state = nm_supplicant_interface_get_state (priv->group_iface);
|
||||
if (state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
||||
_set_is_waiting_for_supplicant (self, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
check_group_iface_ready (self);
|
||||
supplicant_group_iface_is_ready (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -935,9 +910,8 @@ device_state_changed (NMDevice *device,
|
|||
break;
|
||||
case NM_DEVICE_STATE_UNAVAILABLE:
|
||||
if ( !priv->mgmt_iface
|
||||
|| nm_supplicant_interface_get_state (priv->mgmt_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
|| !NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (priv->mgmt_iface)))
|
||||
_set_is_waiting_for_supplicant (self, TRUE);
|
||||
|
||||
break;
|
||||
case NM_DEVICE_STATE_NEED_AUTH:
|
||||
/* Disconnect? */
|
||||
|
@ -1084,20 +1058,20 @@ nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self,
|
|||
goto done;
|
||||
|
||||
_LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant management interface changed to %s.",
|
||||
nm_supplicant_interface_get_object_path (iface));
|
||||
nm_ref_string_get_str (nm_supplicant_interface_get_object_path (iface)));
|
||||
|
||||
priv->mgmt_iface = g_object_ref (iface);
|
||||
|
||||
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_STATE,
|
||||
g_signal_connect (priv->mgmt_iface,
|
||||
NM_SUPPLICANT_INTERFACE_STATE,
|
||||
G_CALLBACK (supplicant_iface_state_cb),
|
||||
self);
|
||||
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_PEER_UPDATED,
|
||||
G_CALLBACK (supplicant_iface_peer_updated_cb),
|
||||
g_signal_connect (priv->mgmt_iface,
|
||||
NM_SUPPLICANT_INTERFACE_PEER_CHANGED,
|
||||
G_CALLBACK (supplicant_iface_peer_changed_cb),
|
||||
self);
|
||||
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_PEER_REMOVED,
|
||||
G_CALLBACK (supplicant_iface_peer_removed_cb),
|
||||
self);
|
||||
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_GROUP_STARTED,
|
||||
g_signal_connect (priv->mgmt_iface,
|
||||
NM_SUPPLICANT_INTERFACE_GROUP_STARTED,
|
||||
G_CALLBACK (supplicant_iface_group_started_cb),
|
||||
self);
|
||||
done:
|
||||
|
@ -1106,8 +1080,7 @@ done:
|
|||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
_set_is_waiting_for_supplicant (self,
|
||||
!priv->mgmt_iface
|
||||
|| ( nm_supplicant_interface_get_state (priv->mgmt_iface)
|
||||
< NM_SUPPLICANT_INTERFACE_STATE_READY));
|
||||
|| !NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (priv->mgmt_iface)));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nm-glib-aux/nm-ref-string.h"
|
||||
#include "nm-device-wifi-p2p.h"
|
||||
#include "nm-wifi-ap.h"
|
||||
#include "nm-libnm-core-intern/nm-common-macros.h"
|
||||
|
@ -74,6 +75,7 @@ typedef struct {
|
|||
gint8 invalid_strength_counter;
|
||||
|
||||
CList aps_lst_head;
|
||||
GHashTable *aps_idx_by_supplicant_path;
|
||||
|
||||
NMWifiAP * current_ap;
|
||||
guint32 rate;
|
||||
|
@ -90,6 +92,7 @@ typedef struct {
|
|||
guint ap_dump_id;
|
||||
|
||||
NMSupplicantManager *sup_mgr;
|
||||
NMSupplMgrCreateIfaceHandle *sup_create_handle;
|
||||
NMSupplicantInterface *sup_iface;
|
||||
guint sup_timeout_id; /* supplicant association timeout */
|
||||
|
||||
|
@ -137,28 +140,31 @@ G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
|
|||
|
||||
static gboolean check_scanning_prohibited (NMDeviceWifi *self, gboolean periodic);
|
||||
|
||||
static void supplicant_iface_state_down (NMDeviceWifi *self);
|
||||
|
||||
static void schedule_scan (NMDeviceWifi *self, gboolean backoff);
|
||||
|
||||
static void cleanup_association_attempt (NMDeviceWifi * self,
|
||||
gboolean disconnect);
|
||||
|
||||
static void supplicant_iface_state (NMDeviceWifi *self,
|
||||
NMSupplicantInterfaceState new_state,
|
||||
NMSupplicantInterfaceState old_state,
|
||||
int disconnect_reason,
|
||||
gboolean is_real_signal);
|
||||
|
||||
static void supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
||||
int new_state_i,
|
||||
int old_state_i,
|
||||
int disconnect_reason,
|
||||
gpointer user_data);
|
||||
|
||||
static void supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface,
|
||||
const char *object_path,
|
||||
GVariant *properties,
|
||||
NMDeviceWifi *self);
|
||||
|
||||
static void supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface,
|
||||
const char *object_path,
|
||||
static void supplicant_iface_bss_changed_cb (NMSupplicantInterface *iface,
|
||||
NMSupplicantBssInfo *bss_info,
|
||||
gboolean is_present,
|
||||
NMDeviceWifi *self);
|
||||
|
||||
static void supplicant_iface_scan_done_cb (NMSupplicantInterface * iface,
|
||||
gboolean success,
|
||||
NMDeviceWifi * self);
|
||||
|
||||
static void supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface,
|
||||
|
@ -237,36 +243,40 @@ unmanaged_on_quit (NMDevice *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_interface_acquire (NMDeviceWifi *self)
|
||||
static void
|
||||
supplicant_interface_acquire_cb (NMSupplicantManager *supplicant_manager,
|
||||
NMSupplMgrCreateIfaceHandle *handle,
|
||||
NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceWifi *self = user_data;
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (!priv->sup_iface, TRUE);
|
||||
if (nm_utils_error_is_cancelled (error))
|
||||
return;
|
||||
|
||||
priv->sup_iface = nm_supplicant_manager_create_interface (priv->sup_mgr,
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
NM_SUPPLICANT_DRIVER_WIRELESS);
|
||||
if (!priv->sup_iface) {
|
||||
_LOGE (LOGD_WIFI, "Couldn't initialize supplicant interface");
|
||||
return FALSE;
|
||||
nm_assert (priv->sup_create_handle == handle);
|
||||
|
||||
priv->sup_create_handle = NULL;
|
||||
|
||||
if (error) {
|
||||
_LOGE (LOGD_WIFI, "Couldn't initialize supplicant interface: %s",
|
||||
error->message);
|
||||
supplicant_iface_state_down (self);
|
||||
nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_supplicant_interface_get_state (priv->sup_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, FALSE);
|
||||
priv->sup_iface = g_object_ref (iface);
|
||||
|
||||
g_signal_connect (priv->sup_iface,
|
||||
NM_SUPPLICANT_INTERFACE_STATE,
|
||||
G_CALLBACK (supplicant_iface_state_cb),
|
||||
self);
|
||||
g_signal_connect (priv->sup_iface,
|
||||
NM_SUPPLICANT_INTERFACE_BSS_UPDATED,
|
||||
G_CALLBACK (supplicant_iface_bss_updated_cb),
|
||||
self);
|
||||
g_signal_connect (priv->sup_iface,
|
||||
NM_SUPPLICANT_INTERFACE_BSS_REMOVED,
|
||||
G_CALLBACK (supplicant_iface_bss_removed_cb),
|
||||
NM_SUPPLICANT_INTERFACE_BSS_CHANGED,
|
||||
G_CALLBACK (supplicant_iface_bss_changed_cb),
|
||||
self);
|
||||
g_signal_connect (priv->sup_iface,
|
||||
NM_SUPPLICANT_INTERFACE_SCAN_DONE,
|
||||
|
@ -291,7 +301,30 @@ supplicant_interface_acquire (NMDeviceWifi *self)
|
|||
|
||||
_notify_scanning (self);
|
||||
|
||||
return TRUE;
|
||||
if (nm_supplicant_interface_get_state (priv->sup_iface) != NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
||||
/* fake an initial state change. */
|
||||
supplicant_iface_state (user_data,
|
||||
NM_SUPPLICANT_INTERFACE_STATE_STARTING,
|
||||
nm_supplicant_interface_get_state (priv->sup_iface),
|
||||
0,
|
||||
FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_interface_acquire (NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (!priv->sup_iface);
|
||||
nm_assert (!priv->sup_create_handle);
|
||||
|
||||
priv->sup_create_handle = nm_supplicant_manager_create_interface (priv->sup_mgr,
|
||||
nm_device_get_ifindex (NM_DEVICE (self)),
|
||||
NM_SUPPLICANT_DRIVER_WIRELESS,
|
||||
supplicant_interface_acquire_cb,
|
||||
self);
|
||||
nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -310,18 +343,17 @@ _requested_scan_set (NMDeviceWifi *self, gboolean value)
|
|||
nm_device_add_pending_action ((NMDevice *) self, NM_PENDING_ACTION_WIFI_SCAN, TRUE);
|
||||
else {
|
||||
nm_device_emit_recheck_auto_activate (NM_DEVICE (self));
|
||||
nm_device_remove_pending_action ((NMDevice *) self, NM_PENDING_ACTION_WIFI_SCAN, TRUE);
|
||||
nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WIFI_SCAN, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_interface_release (NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv;
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
if (nm_clear_pointer (&priv->sup_create_handle, nm_supplicant_manager_create_interface_cancel))
|
||||
nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
|
||||
|
||||
_requested_scan_set (self, FALSE);
|
||||
|
||||
|
@ -477,12 +509,16 @@ ap_add_remove (NMDeviceWifi *self,
|
|||
g_object_ref (ap);
|
||||
ap->wifi_device = NM_DEVICE (self);
|
||||
c_list_link_tail (&priv->aps_lst_head, &ap->aps_lst);
|
||||
if (!g_hash_table_insert (priv->aps_idx_by_supplicant_path, nm_wifi_ap_get_supplicant_path (ap), ap))
|
||||
nm_assert_not_reached ();
|
||||
nm_dbus_object_export (NM_DBUS_OBJECT (ap));
|
||||
_ap_dump (self, LOGL_DEBUG, ap, "added", 0);
|
||||
nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, TRUE);
|
||||
} else {
|
||||
ap->wifi_device = NULL;
|
||||
c_list_unlink (&ap->aps_lst);
|
||||
if (!g_hash_table_remove (priv->aps_idx_by_supplicant_path, nm_wifi_ap_get_supplicant_path (ap)))
|
||||
nm_assert_not_reached ();
|
||||
_ap_dump (self, LOGL_DEBUG, ap, "removed", 0);
|
||||
}
|
||||
|
||||
|
@ -936,7 +972,7 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
|
|||
return FALSE;
|
||||
|
||||
supplicant_state = nm_supplicant_interface_get_state (priv->sup_iface);
|
||||
if ( supplicant_state < NM_SUPPLICANT_INTERFACE_STATE_READY
|
||||
if ( supplicant_state <= NM_SUPPLICANT_INTERFACE_STATE_STARTING
|
||||
|| supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)
|
||||
return FALSE;
|
||||
|
||||
|
@ -1198,7 +1234,8 @@ _nm_device_wifi_request_scan (NMDeviceWifi *self,
|
|||
}
|
||||
|
||||
last_scan = nm_supplicant_interface_get_last_scan (priv->sup_iface);
|
||||
if (last_scan && (nm_utils_get_monotonic_timestamp_msec () - last_scan) < 10 * NM_UTILS_MSEC_PER_SEC) {
|
||||
if ( last_scan > 0
|
||||
&& (nm_utils_get_monotonic_timestamp_msec () - last_scan) < 10 * NM_UTILS_MSEC_PER_SEC) {
|
||||
g_dbus_method_invocation_return_error_literal (invocation,
|
||||
NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_NOT_ALLOWED,
|
||||
|
@ -1469,16 +1506,15 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff)
|
|||
|
||||
static void
|
||||
supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
|
||||
gboolean success,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
_LOGD (LOGD_WIFI, "wifi-scan: scan-done callback: %s", success ? "successful" : "failed");
|
||||
_LOGD (LOGD_WIFI, "wifi-scan: scan-done callback");
|
||||
|
||||
priv->last_scan = nm_utils_get_monotonic_timestamp_msec ();
|
||||
_notify (self, PROP_LAST_SCAN);
|
||||
schedule_scan (self, success);
|
||||
schedule_scan (self, TRUE);
|
||||
|
||||
_requested_scan_set (self, FALSE);
|
||||
}
|
||||
|
@ -1552,40 +1588,43 @@ try_fill_ssid_for_hidden_ap (NMDeviceWifi *self,
|
|||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface,
|
||||
const char *object_path,
|
||||
GVariant *properties,
|
||||
supplicant_iface_bss_changed_cb (NMSupplicantInterface *iface,
|
||||
NMSupplicantBssInfo *bss_info,
|
||||
gboolean is_present,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMDeviceState state;
|
||||
NMWifiAP *found_ap = NULL;
|
||||
NMWifiAP *found_ap;
|
||||
GBytes *ssid;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (properties != NULL);
|
||||
g_return_if_fail (iface != NULL);
|
||||
found_ap = g_hash_table_lookup (priv->aps_idx_by_supplicant_path, bss_info->bss_path);
|
||||
|
||||
/* Ignore new APs when unavailable, unmanaged, or in AP mode */
|
||||
state = nm_device_get_state (NM_DEVICE (self));
|
||||
if (state <= NM_DEVICE_STATE_UNAVAILABLE)
|
||||
return;
|
||||
if (NM_DEVICE_WIFI_GET_PRIVATE (self)->mode == NM_802_11_MODE_AP)
|
||||
if (!is_present) {
|
||||
if (!found_ap)
|
||||
return;
|
||||
if (found_ap == priv->current_ap) {
|
||||
/* The current AP cannot be removed (to prevent NM indicating that
|
||||
* it is connected, but to nothing), but it must be removed later
|
||||
* when the current AP is changed or cleared. Set 'fake' to
|
||||
* indicate that this AP is now unknown to the supplicant.
|
||||
*/
|
||||
if (nm_wifi_ap_set_fake (found_ap, TRUE))
|
||||
_ap_dump (self, LOGL_DEBUG, found_ap, "updated", 0);
|
||||
} else {
|
||||
ap_add_remove (self, FALSE, found_ap, TRUE);
|
||||
schedule_ap_list_dump (self);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
found_ap = nm_wifi_aps_find_by_supplicant_path (&priv->aps_lst_head, object_path);
|
||||
if (found_ap) {
|
||||
if (!nm_wifi_ap_update_from_properties (found_ap, object_path, properties))
|
||||
if (!nm_wifi_ap_update_from_properties (found_ap, bss_info))
|
||||
return;
|
||||
_ap_dump (self, LOGL_DEBUG, found_ap, "updated", 0);
|
||||
} else {
|
||||
gs_unref_object NMWifiAP *ap = NULL;
|
||||
|
||||
ap = nm_wifi_ap_new_from_properties (object_path, properties);
|
||||
if (!ap) {
|
||||
_LOGD (LOGD_WIFI, "invalid AP properties received for %s", object_path);
|
||||
return;
|
||||
}
|
||||
ap = nm_wifi_ap_new_from_properties (bss_info);
|
||||
|
||||
/* Let the manager try to fill in the SSID from seen-bssids lists */
|
||||
ssid = nm_wifi_ap_get_ssid (ap);
|
||||
|
@ -1615,42 +1654,12 @@ supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface,
|
|||
/* Update the current AP if the supplicant notified a current BSS change
|
||||
* before it sent the current BSS's scan result.
|
||||
*/
|
||||
if (g_strcmp0 (nm_supplicant_interface_get_current_bss (iface), object_path) == 0)
|
||||
if (nm_supplicant_interface_get_current_bss (iface) == bss_info->bss_path)
|
||||
supplicant_iface_notify_current_bss (priv->sup_iface, NULL, self);
|
||||
|
||||
schedule_ap_list_dump (self);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface,
|
||||
const char *object_path,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv;
|
||||
NMWifiAP *ap;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (object_path != NULL);
|
||||
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
ap = nm_wifi_aps_find_by_supplicant_path (&priv->aps_lst_head, object_path);
|
||||
if (!ap)
|
||||
return;
|
||||
|
||||
if (ap == priv->current_ap) {
|
||||
/* The current AP cannot be removed (to prevent NM indicating that
|
||||
* it is connected, but to nothing), but it must be removed later
|
||||
* when the current AP is changed or cleared. Set 'fake' to
|
||||
* indicate that this AP is now unknown to the supplicant.
|
||||
*/
|
||||
if (nm_wifi_ap_set_fake (ap, TRUE))
|
||||
_ap_dump (self, LOGL_DEBUG, ap, "updated", 0);
|
||||
} else {
|
||||
ap_add_remove (self, FALSE, ap, TRUE);
|
||||
schedule_ap_list_dump (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect)
|
||||
{
|
||||
|
@ -2029,50 +2038,71 @@ reacquire_interface_cb (gpointer user_data)
|
|||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
||||
int new_state_i,
|
||||
int old_state_i,
|
||||
int disconnect_reason,
|
||||
gpointer user_data)
|
||||
supplicant_iface_state_down (NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
|
||||
nm_device_queue_recheck_available (device,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
cleanup_association_attempt (self, FALSE);
|
||||
|
||||
/* If the device is already in UNAVAILABLE state then the state change
|
||||
* is a NOP and the interface won't be re-acquired in the device state
|
||||
* change handler. So ensure we have a new one here so that we're
|
||||
* ready if the supplicant comes back.
|
||||
*/
|
||||
supplicant_interface_release (self);
|
||||
if (priv->failed_iface_count < 5)
|
||||
priv->reacquire_iface_id = g_timeout_add_seconds (10, reacquire_interface_cb, self);
|
||||
else
|
||||
_LOGI (LOGD_DEVICE | LOGD_WIFI, "supplicant interface keeps failing, giving up");
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_state (NMDeviceWifi *self,
|
||||
NMSupplicantInterfaceState new_state,
|
||||
NMSupplicantInterfaceState old_state,
|
||||
int disconnect_reason,
|
||||
gboolean is_real_signal)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
NMDeviceState devstate;
|
||||
gboolean scanning;
|
||||
NMSupplicantInterfaceState new_state = new_state_i;
|
||||
NMSupplicantInterfaceState old_state = old_state_i;
|
||||
|
||||
if (new_state == old_state)
|
||||
return;
|
||||
|
||||
_LOGI (LOGD_DEVICE | LOGD_WIFI,
|
||||
"supplicant interface state: %s -> %s",
|
||||
"supplicant interface state: %s -> %s%s",
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
nm_supplicant_interface_state_to_string (new_state),
|
||||
is_real_signal ? "" : " (simulated signal)");
|
||||
|
||||
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
||||
supplicant_iface_state_down (self);
|
||||
goto out;
|
||||
}
|
||||
|
||||
devstate = nm_device_get_state (device);
|
||||
scanning = nm_supplicant_interface_get_scanning (iface);
|
||||
scanning = nm_supplicant_interface_get_scanning (priv->sup_iface);
|
||||
|
||||
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
||||
_LOGD (LOGD_WIFI, "supplicant ready");
|
||||
nm_device_queue_recheck_available (NM_DEVICE (device),
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
priv->scan_interval = SCAN_INTERVAL_MIN;
|
||||
}
|
||||
|
||||
/* In these states we know the supplicant is actually talking to something */
|
||||
if ( new_state >= NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING
|
||||
&& new_state <= NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)
|
||||
priv->ssid_found = TRUE;
|
||||
|
||||
if ( old_state < NM_SUPPLICANT_INTERFACE_STATE_READY
|
||||
&& new_state >= NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING)
|
||||
recheck_p2p_availability (self);
|
||||
|
||||
switch (new_state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||
_LOGD (LOGD_WIFI, "supplicant ready");
|
||||
nm_device_queue_recheck_available (NM_DEVICE (device),
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
priv->scan_interval = SCAN_INTERVAL_MIN;
|
||||
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
|
||||
nm_clear_g_source (&priv->sup_timeout_id);
|
||||
nm_clear_g_source (&priv->link_timeout_id);
|
||||
|
@ -2127,26 +2157,6 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
nm_device_queue_recheck_available (NM_DEVICE (device),
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
cleanup_association_attempt (self, FALSE);
|
||||
|
||||
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
|
||||
|
||||
/* If the device is already in UNAVAILABLE state then the state change
|
||||
* is a NOP and the interface won't be re-acquired in the device state
|
||||
* change handler. So ensure we have a new one here so that we're
|
||||
* ready if the supplicant comes back.
|
||||
*/
|
||||
supplicant_interface_release (self);
|
||||
if (priv->failed_iface_count < 5)
|
||||
priv->reacquire_iface_id = g_timeout_add_seconds (10, reacquire_interface_cb, self);
|
||||
else
|
||||
_LOGI (LOGD_DEVICE | LOGD_WIFI, "supplicant interface keeps failing, giving up");
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_INACTIVE:
|
||||
/* we would clear _requested_scan_set() and trigger a new scan.
|
||||
* However, we don't want to cancel the current pending action, so force
|
||||
|
@ -2157,10 +2167,25 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Signal scanning state changes */
|
||||
if ( new_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING
|
||||
|| old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
|
||||
_notify_scanning (self);
|
||||
out:
|
||||
_notify_scanning (self);
|
||||
|
||||
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING)
|
||||
nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
||||
int new_state_i,
|
||||
int old_state_i,
|
||||
int disconnect_reason,
|
||||
gpointer user_data)
|
||||
{
|
||||
supplicant_iface_state (user_data,
|
||||
new_state_i,
|
||||
old_state_i,
|
||||
disconnect_reason,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2197,12 +2222,12 @@ supplicant_iface_notify_current_bss (NMSupplicantInterface *iface,
|
|||
NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
const char *current_bss;
|
||||
NMRefString *current_bss;
|
||||
NMWifiAP *new_ap = NULL;
|
||||
|
||||
current_bss = nm_supplicant_interface_get_current_bss (iface);
|
||||
if (current_bss)
|
||||
new_ap = nm_wifi_aps_find_by_supplicant_path (&priv->aps_lst_head, current_bss);
|
||||
new_ap = g_hash_table_lookup (priv->aps_idx_by_supplicant_path, current_bss);
|
||||
|
||||
if (new_ap != priv->current_ap) {
|
||||
const char *new_bssid = NULL;
|
||||
|
@ -2293,11 +2318,8 @@ 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);
|
||||
if (nm_supplicant_interface_get_state (iface) > NM_SUPPLICANT_INTERFACE_STATE_STARTING)
|
||||
recheck_p2p_availability (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -3058,8 +3080,7 @@ device_state_changed (NMDevice *device,
|
|||
/* Clean up the supplicant interface because in these states the
|
||||
* device cannot be used.
|
||||
*/
|
||||
if (priv->sup_iface)
|
||||
supplicant_interface_release (self);
|
||||
supplicant_interface_release (self);
|
||||
|
||||
nm_clear_g_source (&priv->periodic_source_id);
|
||||
|
||||
|
@ -3160,8 +3181,7 @@ set_enabled (NMDevice *device, gboolean enabled)
|
|||
|
||||
/* Re-initialize the supplicant interface and wait for it to be ready */
|
||||
cleanup_supplicant_failures (self);
|
||||
if (priv->sup_iface)
|
||||
supplicant_interface_release (self);
|
||||
supplicant_interface_release (self);
|
||||
supplicant_interface_acquire (self);
|
||||
|
||||
_LOGD (LOGD_WIFI, "enable waiting on supplicant state");
|
||||
|
@ -3296,6 +3316,7 @@ nm_device_wifi_init (NMDeviceWifi *self)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
c_list_init (&priv->aps_lst_head);
|
||||
priv->aps_idx_by_supplicant_path = g_hash_table_new (nm_direct_hash, NULL);
|
||||
|
||||
priv->hidden_probe_scan_warn = TRUE;
|
||||
priv->mode = NM_802_11_MODE_INFRA;
|
||||
|
@ -3364,6 +3385,9 @@ finalize (GObject *object)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (c_list_is_empty (&priv->aps_lst_head));
|
||||
nm_assert (g_hash_table_size (priv->aps_idx_by_supplicant_path) == 0);
|
||||
|
||||
g_hash_table_unref (priv->aps_idx_by_supplicant_path);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
|
||||
}
|
||||
|
|
|
@ -874,7 +874,8 @@ nm_iwd_manager_is_known_network (NMIwdManager *self, const char *name,
|
|||
}
|
||||
|
||||
GDBusProxy *
|
||||
nm_iwd_manager_get_dbus_interface (NMIwdManager *self, const char *path,
|
||||
nm_iwd_manager_get_dbus_interface (NMIwdManager *self,
|
||||
const char *path,
|
||||
const char *name)
|
||||
{
|
||||
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self);
|
||||
|
|
|
@ -10,15 +10,16 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nm-setting-wireless.h"
|
||||
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-glib-aux/nm-ref-string.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "supplicant/nm-supplicant-interface.h"
|
||||
|
||||
#define PROTO_WPA "wpa"
|
||||
#define PROTO_RSN "rsn"
|
||||
|
@ -39,8 +40,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMWifiAP,
|
|||
);
|
||||
|
||||
struct _NMWifiAPPrivate {
|
||||
char *supplicant_path; /* D-Bus object path of this AP from wpa_supplicant */
|
||||
|
||||
/* Scanned or cached values */
|
||||
GBytes * ssid;
|
||||
char * address;
|
||||
|
@ -49,6 +48,9 @@ struct _NMWifiAPPrivate {
|
|||
guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */
|
||||
guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */
|
||||
|
||||
gint64 last_seen_msec; /* Timestamp when the AP was seen lastly (in nm_utils_get_monotonic_timestamp_*() scale).
|
||||
* Note that this value might be negative! */
|
||||
|
||||
NM80211ApFlags flags; /* General flags */
|
||||
NM80211ApSecurityFlags wpa_flags; /* WPA-related flags */
|
||||
NM80211ApSecurityFlags rsn_flags; /* RSN (WPA2) -related flags */
|
||||
|
@ -58,7 +60,6 @@ struct _NMWifiAPPrivate {
|
|||
/* Non-scanned attributes */
|
||||
bool fake:1; /* Whether or not the AP is from a scan */
|
||||
bool hotspot:1; /* Whether the AP is a local device's hotspot network */
|
||||
gint32 last_seen; /* Timestamp when the AP was seen lastly (obtained via nm_utils_get_monotonic_timestamp_sec()) */
|
||||
};
|
||||
|
||||
typedef struct _NMWifiAPPrivate NMWifiAPPrivate;
|
||||
|
@ -73,14 +74,6 @@ G_DEFINE_TYPE (NMWifiAP, nm_wifi_ap, NM_TYPE_DBUS_OBJECT)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *
|
||||
nm_wifi_ap_get_supplicant_path (NMWifiAP *ap)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), NULL);
|
||||
|
||||
return NM_WIFI_AP_GET_PRIVATE (ap)->supplicant_path;
|
||||
}
|
||||
|
||||
GBytes *
|
||||
nm_wifi_ap_get_ssid (const NMWifiAP *ap)
|
||||
{
|
||||
|
@ -148,11 +141,7 @@ nm_wifi_ap_set_ssid (NMWifiAP *ap, GBytes *ssid)
|
|||
static gboolean
|
||||
nm_wifi_ap_set_flags (NMWifiAP *ap, NM80211ApFlags flags)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
if (priv->flags != flags) {
|
||||
priv->flags = flags;
|
||||
|
@ -165,11 +154,8 @@ nm_wifi_ap_set_flags (NMWifiAP *ap, NM80211ApFlags flags)
|
|||
static gboolean
|
||||
nm_wifi_ap_set_wpa_flags (NMWifiAP *ap, NM80211ApSecurityFlags flags)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
if (priv->wpa_flags != flags) {
|
||||
priv->wpa_flags = flags;
|
||||
_notify (ap, PROP_WPA_FLAGS);
|
||||
|
@ -181,11 +167,8 @@ nm_wifi_ap_set_wpa_flags (NMWifiAP *ap, NM80211ApSecurityFlags flags)
|
|||
static gboolean
|
||||
nm_wifi_ap_set_rsn_flags (NMWifiAP *ap, NM80211ApSecurityFlags flags)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
if (priv->rsn_flags != flags) {
|
||||
priv->rsn_flags = flags;
|
||||
_notify (ap, PROP_RSN_FLAGS);
|
||||
|
@ -203,11 +186,9 @@ nm_wifi_ap_get_address (const NMWifiAP *ap)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
nm_wifi_ap_set_address_bin (NMWifiAP *ap, const guint8 *addr /* ETH_ALEN bytes */)
|
||||
nm_wifi_ap_set_address_bin (NMWifiAP *ap, const guint8 addr[static 6 /* ETH_ALEN */])
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
if ( !priv->address
|
||||
|| !nm_utils_hwaddr_matches (addr, ETH_ALEN, priv->address, -1)) {
|
||||
|
@ -241,16 +222,14 @@ nm_wifi_ap_get_mode (NMWifiAP *ap)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
nm_wifi_ap_set_mode (NMWifiAP *ap, const NM80211Mode mode)
|
||||
nm_wifi_ap_set_mode (NMWifiAP *ap, NM80211Mode mode)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
g_return_val_if_fail ( mode == NM_802_11_MODE_ADHOC
|
||||
|| mode == NM_802_11_MODE_INFRA
|
||||
|| mode == NM_802_11_MODE_MESH, FALSE);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
nm_assert (NM_IN_SET (mode, NM_802_11_MODE_UNKNOWN,
|
||||
NM_802_11_MODE_ADHOC,
|
||||
NM_802_11_MODE_INFRA,
|
||||
NM_802_11_MODE_MESH));
|
||||
|
||||
if (priv->mode != mode) {
|
||||
priv->mode = mode;
|
||||
|
@ -277,13 +256,9 @@ nm_wifi_ap_get_strength (NMWifiAP *ap)
|
|||
}
|
||||
|
||||
gboolean
|
||||
nm_wifi_ap_set_strength (NMWifiAP *ap, const gint8 strength)
|
||||
nm_wifi_ap_set_strength (NMWifiAP *ap, gint8 strength)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
if (priv->strength != strength) {
|
||||
priv->strength = strength;
|
||||
|
@ -303,13 +278,9 @@ nm_wifi_ap_get_freq (NMWifiAP *ap)
|
|||
|
||||
gboolean
|
||||
nm_wifi_ap_set_freq (NMWifiAP *ap,
|
||||
const guint32 freq)
|
||||
guint32 freq)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
if (priv->freq != freq) {
|
||||
priv->freq = freq;
|
||||
|
@ -378,16 +349,12 @@ nm_wifi_ap_get_flags (const NMWifiAP *ap)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
nm_wifi_ap_set_last_seen (NMWifiAP *ap, gint32 last_seen)
|
||||
nm_wifi_ap_set_last_seen (NMWifiAP *ap, gint32 last_seen_msec)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
if (priv->last_seen != last_seen) {
|
||||
priv->last_seen = last_seen;
|
||||
if (priv->last_seen_msec != last_seen_msec) {
|
||||
priv->last_seen_msec = last_seen_msec;
|
||||
_notify (ap, PROP_LAST_SEEN);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -402,180 +369,53 @@ nm_wifi_ap_get_metered (const NMWifiAP *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NM80211ApSecurityFlags
|
||||
security_from_vardict (GVariant *security)
|
||||
{
|
||||
NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE;
|
||||
const char **array, *tmp;
|
||||
|
||||
g_return_val_if_fail (g_variant_is_of_type (security, G_VARIANT_TYPE_VARDICT), NM_802_11_AP_SEC_NONE);
|
||||
|
||||
if ( g_variant_lookup (security, "KeyMgmt", "^a&s", &array)
|
||||
&& array) {
|
||||
if (g_strv_contains (array, "wpa-psk") ||
|
||||
g_strv_contains (array, "wpa-ft-psk"))
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
|
||||
if (g_strv_contains (array, "wpa-eap") ||
|
||||
g_strv_contains (array, "wpa-ft-eap") ||
|
||||
g_strv_contains (array, "wpa-fils-sha256") ||
|
||||
g_strv_contains (array, "wpa-fils-sha384"))
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
|
||||
if (g_strv_contains (array, "sae"))
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_SAE;
|
||||
if (g_strv_contains (array, "owe"))
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_OWE;
|
||||
g_free (array);
|
||||
}
|
||||
|
||||
if ( g_variant_lookup (security, "Pairwise", "^a&s", &array)
|
||||
&& array) {
|
||||
if (g_strv_contains (array, "tkip"))
|
||||
flags |= NM_802_11_AP_SEC_PAIR_TKIP;
|
||||
if (g_strv_contains (array, "ccmp"))
|
||||
flags |= NM_802_11_AP_SEC_PAIR_CCMP;
|
||||
g_free (array);
|
||||
}
|
||||
|
||||
if (g_variant_lookup (security, "Group", "&s", &tmp)) {
|
||||
if (strcmp (tmp, "wep40") == 0)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_WEP40;
|
||||
if (strcmp (tmp, "wep104") == 0)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_WEP104;
|
||||
if (strcmp (tmp, "tkip") == 0)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_TKIP;
|
||||
if (strcmp (tmp, "ccmp") == 0)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_CCMP;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_wifi_ap_update_from_properties (NMWifiAP *ap,
|
||||
const char *supplicant_path,
|
||||
GVariant *properties)
|
||||
const NMSupplicantBssInfo *bss_info)
|
||||
{
|
||||
NMWifiAPPrivate *priv;
|
||||
const guint8 *bytes;
|
||||
GVariant *v;
|
||||
gsize len;
|
||||
gsize i;
|
||||
gboolean b = FALSE;
|
||||
const char *s;
|
||||
gint16 i16;
|
||||
guint16 u16;
|
||||
gboolean changed = FALSE;
|
||||
gboolean metered;
|
||||
guint32 max_rate, rate;
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE);
|
||||
g_return_val_if_fail (properties, FALSE);
|
||||
g_return_val_if_fail (bss_info, FALSE);
|
||||
nm_assert (NM_IS_REF_STRING (bss_info->bss_path));
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (ap);
|
||||
|
||||
nm_assert ( !ap->_supplicant_path
|
||||
|| ap->_supplicant_path == bss_info->bss_path);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (ap));
|
||||
|
||||
if (g_variant_lookup (properties, "Privacy", "b", &b) && b)
|
||||
changed |= nm_wifi_ap_set_flags (ap, priv->flags | NM_802_11_AP_FLAGS_PRIVACY);
|
||||
|
||||
v = g_variant_lookup_value (properties, "WPS", G_VARIANT_TYPE_VARDICT);
|
||||
if (v) {
|
||||
if (g_variant_lookup (v, "Type", "&s", &s)) {
|
||||
changed |= nm_wifi_ap_set_flags (ap, priv->flags | NM_802_11_AP_FLAGS_WPS);
|
||||
if (strcmp (s, "pbc") == 0)
|
||||
changed |= nm_wifi_ap_set_flags (ap, priv->flags | NM_802_11_AP_FLAGS_WPS_PBC);
|
||||
else if (strcmp (s, "pin") == 0)
|
||||
changed |= nm_wifi_ap_set_flags (ap, priv->flags | NM_802_11_AP_FLAGS_WPS_PIN);
|
||||
}
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
if (g_variant_lookup (properties, "Mode", "&s", &s)) {
|
||||
if (!g_strcmp0 (s, "infrastructure"))
|
||||
changed |= nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA);
|
||||
else if (!g_strcmp0 (s, "ad-hoc"))
|
||||
changed |= nm_wifi_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
|
||||
else if (!g_strcmp0 (s, "mesh"))
|
||||
changed |= nm_wifi_ap_set_mode (ap, NM_802_11_MODE_MESH);
|
||||
}
|
||||
|
||||
if (g_variant_lookup (properties, "Signal", "n", &i16))
|
||||
changed |= nm_wifi_ap_set_strength (ap, nm_wifi_utils_level_to_quality (i16));
|
||||
|
||||
if (g_variant_lookup (properties, "Frequency", "q", &u16))
|
||||
changed |= nm_wifi_ap_set_freq (ap, u16);
|
||||
|
||||
v = g_variant_lookup_value (properties, "SSID", G_VARIANT_TYPE_BYTESTRING);
|
||||
if (v) {
|
||||
bytes = g_variant_get_fixed_array (v, &len, 1);
|
||||
len = MIN (32, len);
|
||||
|
||||
/* Stupid ieee80211 layer uses <hidden> */
|
||||
if ( bytes
|
||||
&& len
|
||||
&& !( NM_IN_SET (len, 8, 9)
|
||||
&& memcmp (bytes, "<hidden>", len) == 0)
|
||||
&& !nm_utils_is_empty_ssid (bytes, len)) {
|
||||
/* good */
|
||||
} else
|
||||
len = 0;
|
||||
|
||||
changed |= nm_wifi_ap_set_ssid_arr (ap, bytes, len);
|
||||
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
v = g_variant_lookup_value (properties, "BSSID", G_VARIANT_TYPE_BYTESTRING);
|
||||
if (v) {
|
||||
bytes = g_variant_get_fixed_array (v, &len, 1);
|
||||
if ( len == ETH_ALEN
|
||||
&& memcmp (bytes, nm_ip_addr_zero.addr_eth, ETH_ALEN) != 0
|
||||
&& memcmp (bytes, (char[ETH_ALEN]) { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, ETH_ALEN) != 0)
|
||||
changed |= nm_wifi_ap_set_address_bin (ap, bytes);
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
max_rate = 0;
|
||||
v = g_variant_lookup_value (properties, "Rates", G_VARIANT_TYPE ("au"));
|
||||
if (v) {
|
||||
const guint32 *rates = g_variant_get_fixed_array (v, &len, sizeof (guint32));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
max_rate = NM_MAX (max_rate, rates[i]);
|
||||
g_variant_unref (v);
|
||||
}
|
||||
v = g_variant_lookup_value (properties, "IEs", G_VARIANT_TYPE_BYTESTRING);
|
||||
if (v) {
|
||||
bytes = g_variant_get_fixed_array (v, &len, 1);
|
||||
nm_wifi_utils_parse_ies (bytes, len, &rate, &metered);
|
||||
max_rate = NM_MAX (max_rate, rate);
|
||||
g_variant_unref (v);
|
||||
priv->metered = metered;
|
||||
}
|
||||
|
||||
if (max_rate)
|
||||
changed |= nm_wifi_ap_set_max_bitrate (ap, max_rate / 1000);
|
||||
|
||||
v = g_variant_lookup_value (properties, "WPA", G_VARIANT_TYPE_VARDICT);
|
||||
if (v) {
|
||||
changed |= nm_wifi_ap_set_wpa_flags (ap, priv->wpa_flags | security_from_vardict (v));
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
v = g_variant_lookup_value (properties, "RSN", G_VARIANT_TYPE_VARDICT);
|
||||
if (v) {
|
||||
changed |= nm_wifi_ap_set_rsn_flags (ap, priv->rsn_flags | security_from_vardict (v));
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
if (!priv->supplicant_path) {
|
||||
priv->supplicant_path = g_strdup (supplicant_path);
|
||||
if (!ap->_supplicant_path) {
|
||||
ap->_supplicant_path = nm_ref_string_ref (bss_info->bss_path);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
changed |= nm_wifi_ap_set_last_seen (ap, nm_utils_get_monotonic_timestamp_sec ());
|
||||
changed |= nm_wifi_ap_set_flags (ap, bss_info->ap_flags);
|
||||
changed |= nm_wifi_ap_set_mode (ap, bss_info->mode);
|
||||
changed |= nm_wifi_ap_set_strength (ap, bss_info->signal_percent);
|
||||
changed |= nm_wifi_ap_set_freq (ap, bss_info->frequency);
|
||||
changed |= nm_wifi_ap_set_ssid (ap, bss_info->ssid);
|
||||
|
||||
if (bss_info->bssid_valid)
|
||||
changed |= nm_wifi_ap_set_address_bin (ap, bss_info->bssid);
|
||||
else {
|
||||
/* we don't actually clear the value. */
|
||||
}
|
||||
|
||||
changed |= nm_wifi_ap_set_max_bitrate (ap, bss_info->max_rate);
|
||||
|
||||
if (priv->metered != bss_info->metered) {
|
||||
priv->metered = bss_info->metered;
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
changed |= nm_wifi_ap_set_wpa_flags (ap, bss_info->wpa_flags);
|
||||
changed |= nm_wifi_ap_set_rsn_flags (ap, bss_info->rsn_flags);
|
||||
|
||||
changed |= nm_wifi_ap_set_last_seen (ap, bss_info->last_seen_msec);
|
||||
|
||||
changed |= nm_wifi_ap_set_fake (ap, FALSE);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (ap));
|
||||
|
@ -674,9 +514,10 @@ nm_wifi_ap_to_string (const NMWifiAP *self,
|
|||
g_return_val_if_fail (NM_IS_WIFI_AP (self), NULL);
|
||||
|
||||
priv = NM_WIFI_AP_GET_PRIVATE (self);
|
||||
|
||||
chan = nm_utils_wifi_freq_to_channel (priv->freq);
|
||||
if (priv->supplicant_path)
|
||||
supplicant_id = strrchr (priv->supplicant_path, '/') ?: supplicant_id;
|
||||
if (self->_supplicant_path)
|
||||
supplicant_id = strrchr (self->_supplicant_path->str, '/') ?: supplicant_id;
|
||||
|
||||
export_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self));
|
||||
if (export_path)
|
||||
|
@ -703,7 +544,9 @@ nm_wifi_ap_to_string (const NMWifiAP *self,
|
|||
priv->metered ? 'M' : '_',
|
||||
priv->wpa_flags & 0xFFFF,
|
||||
priv->rsn_flags & 0xFFFF,
|
||||
priv->last_seen > 0 ? ((now_s > 0 ? now_s : nm_utils_get_monotonic_timestamp_sec ()) - priv->last_seen) : -1,
|
||||
priv->last_seen_msec != G_MININT64
|
||||
? (int) ((now_s > 0 ? now_s : nm_utils_get_monotonic_timestamp_sec ()) - (priv->last_seen_msec / 1000))
|
||||
: -1,
|
||||
supplicant_id,
|
||||
export_path);
|
||||
return str_buf;
|
||||
|
@ -856,9 +699,9 @@ get_property (GObject *object, guint prop_id,
|
|||
break;
|
||||
case PROP_LAST_SEEN:
|
||||
g_value_set_int (value,
|
||||
priv->last_seen > 0
|
||||
? (int) nm_utils_monotonic_timestamp_as_boottime (priv->last_seen, NM_UTILS_NSEC_PER_SEC)
|
||||
: -1);
|
||||
priv->last_seen_msec != G_MININT64
|
||||
? (int) NM_MAX (nm_utils_monotonic_timestamp_as_boottime (priv->last_seen_msec, NM_UTILS_NSEC_PER_MSEC) / 1000, 1)
|
||||
: -1);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
@ -883,26 +726,16 @@ nm_wifi_ap_init (NMWifiAP *self)
|
|||
priv->flags = NM_802_11_AP_FLAGS_NONE;
|
||||
priv->wpa_flags = NM_802_11_AP_SEC_NONE;
|
||||
priv->rsn_flags = NM_802_11_AP_SEC_NONE;
|
||||
priv->last_seen = -1;
|
||||
priv->last_seen_msec = G_MININT64;
|
||||
}
|
||||
|
||||
NMWifiAP *
|
||||
nm_wifi_ap_new_from_properties (const char *supplicant_path, GVariant *properties)
|
||||
nm_wifi_ap_new_from_properties (const NMSupplicantBssInfo *bss_info)
|
||||
{
|
||||
NMWifiAP *ap;
|
||||
|
||||
g_return_val_if_fail (supplicant_path != NULL, NULL);
|
||||
g_return_val_if_fail (properties != NULL, NULL);
|
||||
|
||||
ap = (NMWifiAP *) g_object_new (NM_TYPE_WIFI_AP, NULL);
|
||||
nm_wifi_ap_update_from_properties (ap, supplicant_path, properties);
|
||||
|
||||
/* ignore APs with invalid or missing BSSIDs */
|
||||
if (!nm_wifi_ap_get_address (ap)) {
|
||||
g_object_unref (ap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ap = g_object_new (NM_TYPE_WIFI_AP, NULL);
|
||||
nm_wifi_ap_update_from_properties (ap, bss_info);
|
||||
return ap;
|
||||
}
|
||||
|
||||
|
@ -1028,7 +861,7 @@ finalize (GObject *object)
|
|||
nm_assert (!self->wifi_device);
|
||||
nm_assert (c_list_is_empty (&self->aps_lst));
|
||||
|
||||
g_free (priv->supplicant_path);
|
||||
nm_ref_string_unref (self->_supplicant_path);
|
||||
if (priv->ssid)
|
||||
g_bytes_unref (priv->ssid);
|
||||
g_free (priv->address);
|
||||
|
@ -1195,20 +1028,6 @@ nm_wifi_aps_find_first_compatible (const CList *aps_lst_head,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
NMWifiAP *
|
||||
nm_wifi_aps_find_by_supplicant_path (const CList *aps_lst_head, const char *path)
|
||||
{
|
||||
NMWifiAP *ap;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
|
||||
c_list_for_each_entry (ap, aps_lst_head, aps_lst) {
|
||||
if (nm_streq0 (path, nm_wifi_ap_get_supplicant_path (ap)))
|
||||
return ap;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMWifiAP *
|
||||
|
|
|
@ -33,20 +33,21 @@ typedef struct {
|
|||
NMDBusObject parent;
|
||||
NMDevice *wifi_device;
|
||||
CList aps_lst;
|
||||
NMRefString *_supplicant_path;
|
||||
struct _NMWifiAPPrivate *_priv;
|
||||
} NMWifiAP;
|
||||
|
||||
struct _NMSupplicantBssInfo;
|
||||
|
||||
typedef struct _NMWifiAPClass NMWifiAPClass;
|
||||
|
||||
GType nm_wifi_ap_get_type (void);
|
||||
|
||||
NMWifiAP * nm_wifi_ap_new_from_properties (const char *supplicant_path,
|
||||
GVariant *properties);
|
||||
NMWifiAP * nm_wifi_ap_new_fake_from_connection (NMConnection *connection);
|
||||
NMWifiAP *nm_wifi_ap_new_from_properties (const struct _NMSupplicantBssInfo *bss_info);
|
||||
NMWifiAP *nm_wifi_ap_new_fake_from_connection (NMConnection *connection);
|
||||
|
||||
gboolean nm_wifi_ap_update_from_properties (NMWifiAP *ap,
|
||||
const char *supplicant_path,
|
||||
GVariant *properties);
|
||||
gboolean nm_wifi_ap_update_from_properties (NMWifiAP *ap,
|
||||
const struct _NMSupplicantBssInfo *bss_info);
|
||||
|
||||
gboolean nm_wifi_ap_check_compatible (NMWifiAP *self,
|
||||
NMConnection *connection);
|
||||
|
@ -56,7 +57,14 @@ gboolean nm_wifi_ap_complete_connection (NMWifiAP *self,
|
|||
gboolean lock_bssid,
|
||||
GError **error);
|
||||
|
||||
const char * nm_wifi_ap_get_supplicant_path (NMWifiAP *ap);
|
||||
static inline NMRefString *
|
||||
nm_wifi_ap_get_supplicant_path (NMWifiAP *ap)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_WIFI_AP (ap), NULL);
|
||||
|
||||
return ap->_supplicant_path;
|
||||
}
|
||||
|
||||
GBytes *nm_wifi_ap_get_ssid (const NMWifiAP *ap);
|
||||
gboolean nm_wifi_ap_set_ssid_arr (NMWifiAP *ap,
|
||||
const guint8 *ssid,
|
||||
|
@ -94,8 +102,6 @@ const char **nm_wifi_aps_get_paths (const CList *aps_lst_head,
|
|||
NMWifiAP *nm_wifi_aps_find_first_compatible (const CList *aps_lst_head,
|
||||
NMConnection *connection);
|
||||
|
||||
NMWifiAP *nm_wifi_aps_find_by_supplicant_path (const CList *aps_lst_head, const char *path);
|
||||
|
||||
NMWifiAP *nm_wifi_ap_lookup_for_device (NMDevice *device, const char *exported_path);
|
||||
|
||||
#endif /* __NM_WIFI_AP_H__ */
|
||||
|
|
|
@ -9,15 +9,16 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nm-setting-wireless.h"
|
||||
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-glib-aux/nm-ref-string.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "supplicant/nm-supplicant-types.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -35,7 +36,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMWifiP2PPeer,
|
|||
);
|
||||
|
||||
struct _NMWifiP2PPeerPrivate {
|
||||
char *supplicant_path; /* D-Bus object path of this Peer from wpa_supplicant */
|
||||
NMRefString *supplicant_path; /* D-Bus object path of this Peer from wpa_supplicant */
|
||||
|
||||
/* Scanned or cached values */
|
||||
char * name;
|
||||
|
@ -150,7 +151,7 @@ nm_wifi_p2p_peer_get_supplicant_path (NMWifiP2PPeer *peer)
|
|||
{
|
||||
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
|
||||
|
||||
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->supplicant_path;
|
||||
return nm_ref_string_get_str (NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->supplicant_path);
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -260,6 +261,7 @@ gboolean
|
|||
nm_wifi_p2p_peer_set_wfd_ies (NMWifiP2PPeer *peer, GBytes *wfd_ies)
|
||||
{
|
||||
NMWifiP2PPeerPrivate *priv;
|
||||
gs_unref_bytes GBytes *wfd_ies_old = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE);
|
||||
|
||||
|
@ -268,7 +270,7 @@ nm_wifi_p2p_peer_set_wfd_ies (NMWifiP2PPeer *peer, GBytes *wfd_ies)
|
|||
if (nm_gbytes_equal0 (priv->wfd_ies, wfd_ies))
|
||||
return FALSE;
|
||||
|
||||
g_bytes_unref (priv->wfd_ies);
|
||||
wfd_ies_old = g_steal_pointer (&priv->wfd_ies);
|
||||
priv->wfd_ies = wfd_ies ? g_bytes_ref (wfd_ies) : NULL;
|
||||
|
||||
_notify (peer, PROP_WFD_IES);
|
||||
|
@ -371,69 +373,42 @@ nm_wifi_p2p_peer_set_last_seen (NMWifiP2PPeer *peer, gint32 last_seen)
|
|||
|
||||
gboolean
|
||||
nm_wifi_p2p_peer_update_from_properties (NMWifiP2PPeer *peer,
|
||||
const char *supplicant_path,
|
||||
GVariant *properties)
|
||||
const NMSupplicantPeerInfo *peer_info)
|
||||
{
|
||||
NMWifiP2PPeerPrivate *priv;
|
||||
const guint8 *bytes;
|
||||
GVariant *v;
|
||||
gsize len;
|
||||
const char *s;
|
||||
gint32 i32;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE);
|
||||
g_return_val_if_fail (properties, FALSE);
|
||||
g_return_val_if_fail (peer_info, FALSE);
|
||||
nm_assert (NM_IS_REF_STRING (peer_info->peer_path));
|
||||
|
||||
priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer);
|
||||
|
||||
nm_assert ( !priv->supplicant_path
|
||||
|| priv->supplicant_path == peer_info->peer_path);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (peer));
|
||||
|
||||
if (g_variant_lookup (properties, "level", "i", &i32))
|
||||
changed |= nm_wifi_p2p_peer_set_strength (peer, nm_wifi_utils_level_to_quality (i32));
|
||||
|
||||
if (g_variant_lookup (properties, "DeviceName", "&s", &s))
|
||||
changed |= nm_wifi_p2p_peer_set_name (peer, s);
|
||||
|
||||
if (g_variant_lookup (properties, "Manufacturer", "&s", &s))
|
||||
changed |= nm_wifi_p2p_peer_set_manufacturer (peer, s);
|
||||
|
||||
if (g_variant_lookup (properties, "Model", "&s", &s))
|
||||
changed |= nm_wifi_p2p_peer_set_model (peer, s);
|
||||
|
||||
if (g_variant_lookup (properties, "ModelNumber", "&s", &s))
|
||||
changed |= nm_wifi_p2p_peer_set_model_number (peer, s);
|
||||
|
||||
if (g_variant_lookup (properties, "Serial", "&s", &s))
|
||||
changed |= nm_wifi_p2p_peer_set_serial (peer, s);
|
||||
|
||||
v = g_variant_lookup_value (properties, "DeviceAddress", G_VARIANT_TYPE_BYTESTRING);
|
||||
if (v) {
|
||||
bytes = g_variant_get_fixed_array (v, &len, 1);
|
||||
if ( len == ETH_ALEN
|
||||
&& memcmp (bytes, nm_ip_addr_zero.addr_eth, ETH_ALEN) != 0
|
||||
&& memcmp (bytes, (char[ETH_ALEN]) { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, ETH_ALEN) != 0)
|
||||
changed |= nm_wifi_p2p_peer_set_address_bin (peer, bytes);
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
/* The IEs property contains the WFD R1 subelements */
|
||||
v = g_variant_lookup_value (properties, "IEs", G_VARIANT_TYPE_BYTESTRING);
|
||||
if (v) {
|
||||
gs_unref_bytes GBytes *b = NULL;
|
||||
|
||||
bytes = g_variant_get_fixed_array (v, &len, 1);
|
||||
b = g_bytes_new (bytes, len);
|
||||
changed |= nm_wifi_p2p_peer_set_wfd_ies (peer, b);
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
if (!priv->supplicant_path) {
|
||||
priv->supplicant_path = g_strdup (supplicant_path);
|
||||
priv->supplicant_path = nm_ref_string_ref (peer_info->peer_path);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
changed |= nm_wifi_p2p_peer_set_last_seen (peer, nm_utils_get_monotonic_timestamp_sec ());
|
||||
changed |= nm_wifi_p2p_peer_set_strength (peer, peer_info->signal_percent);
|
||||
changed |= nm_wifi_p2p_peer_set_name (peer, peer_info->device_name);
|
||||
changed |= nm_wifi_p2p_peer_set_manufacturer (peer, peer_info->manufacturer);
|
||||
changed |= nm_wifi_p2p_peer_set_model (peer, peer_info->model);
|
||||
changed |= nm_wifi_p2p_peer_set_model_number (peer, peer_info->model_number);
|
||||
changed |= nm_wifi_p2p_peer_set_serial (peer, peer_info->serial);
|
||||
|
||||
if (peer_info->address_valid)
|
||||
changed |= nm_wifi_p2p_peer_set_address_bin (peer, peer_info->address);
|
||||
else {
|
||||
/* we don't reset the address. */
|
||||
}
|
||||
|
||||
changed |= nm_wifi_p2p_peer_set_wfd_ies (peer, peer_info->ies);
|
||||
changed |= nm_wifi_p2p_peer_set_last_seen (peer, peer_info->last_seen_msec / 1000u);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (peer));
|
||||
|
||||
|
@ -455,7 +430,7 @@ nm_wifi_p2p_peer_to_string (const NMWifiP2PPeer *self,
|
|||
priv = NM_WIFI_P2P_PEER_GET_PRIVATE (self);
|
||||
|
||||
if (priv->supplicant_path)
|
||||
supplicant_id = strrchr (priv->supplicant_path, '/') ?: supplicant_id;
|
||||
supplicant_id = strrchr (priv->supplicant_path->str, '/') ?: supplicant_id;
|
||||
|
||||
export_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self));
|
||||
if (export_path)
|
||||
|
@ -571,22 +546,14 @@ nm_wifi_p2p_peer_init (NMWifiP2PPeer *self)
|
|||
}
|
||||
|
||||
NMWifiP2PPeer *
|
||||
nm_wifi_p2p_peer_new_from_properties (const char *supplicant_path, GVariant *properties)
|
||||
nm_wifi_p2p_peer_new_from_properties (const NMSupplicantPeerInfo *peer_info)
|
||||
{
|
||||
NMWifiP2PPeer *peer;
|
||||
|
||||
g_return_val_if_fail (supplicant_path != NULL, NULL);
|
||||
g_return_val_if_fail (properties != NULL, NULL);
|
||||
|
||||
peer = (NMWifiP2PPeer *) g_object_new (NM_TYPE_WIFI_P2P_PEER, NULL);
|
||||
nm_wifi_p2p_peer_update_from_properties (peer, supplicant_path, properties);
|
||||
|
||||
/* ignore peers with invalid or missing address */
|
||||
if (!nm_wifi_p2p_peer_get_address (peer)) {
|
||||
g_object_unref (peer);
|
||||
return NULL;
|
||||
}
|
||||
g_return_val_if_fail (peer_info, NULL);
|
||||
|
||||
peer = g_object_new (NM_TYPE_WIFI_P2P_PEER, NULL);
|
||||
nm_wifi_p2p_peer_update_from_properties (peer, peer_info);
|
||||
return peer;
|
||||
}
|
||||
|
||||
|
@ -599,7 +566,7 @@ finalize (GObject *object)
|
|||
nm_assert (!self->wifi_device);
|
||||
nm_assert (c_list_is_empty (&self->peers_lst));
|
||||
|
||||
g_free (priv->supplicant_path);
|
||||
nm_ref_string_unref (priv->supplicant_path);
|
||||
g_free (priv->name);
|
||||
g_free (priv->manufacturer);
|
||||
g_free (priv->model);
|
||||
|
|
|
@ -37,14 +37,14 @@ typedef struct {
|
|||
|
||||
typedef struct _NMWifiP2PPeerClass NMWifiP2PPeerClass;
|
||||
|
||||
struct _NMSupplicantPeerInfo;
|
||||
|
||||
GType nm_wifi_p2p_peer_get_type (void);
|
||||
|
||||
NMWifiP2PPeer * nm_wifi_p2p_peer_new_from_properties (const char *supplicant_path,
|
||||
GVariant *properties);
|
||||
NMWifiP2PPeer *nm_wifi_p2p_peer_new_from_properties (const struct _NMSupplicantPeerInfo *peer_info);
|
||||
|
||||
gboolean nm_wifi_p2p_peer_update_from_properties (NMWifiP2PPeer *peer,
|
||||
const char *supplicant_path,
|
||||
GVariant *properties);
|
||||
gboolean nm_wifi_p2p_peer_update_from_properties (NMWifiP2PPeer *peer,
|
||||
const struct _NMSupplicantPeerInfo *peer_info);
|
||||
|
||||
gboolean nm_wifi_p2p_peer_check_compatible (NMWifiP2PPeer *self,
|
||||
NMConnection *connection);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,10 +16,9 @@
|
|||
* A mix of wpa_supplicant interface states and internal states.
|
||||
*/
|
||||
typedef enum {
|
||||
NM_SUPPLICANT_INTERFACE_STATE_INVALID = -1,
|
||||
NM_SUPPLICANT_INTERFACE_STATE_INIT = 0,
|
||||
NM_SUPPLICANT_INTERFACE_STATE_STARTING,
|
||||
NM_SUPPLICANT_INTERFACE_STATE_READY,
|
||||
NM_SUPPLICANT_INTERFACE_STATE_INVALID = 0,
|
||||
|
||||
NM_SUPPLICANT_INTERFACE_STATE_STARTING = 1,
|
||||
|
||||
NM_SUPPLICANT_INTERFACE_STATE_DISABLED,
|
||||
NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED,
|
||||
|
@ -35,6 +34,13 @@ typedef enum {
|
|||
NM_SUPPLICANT_INTERFACE_STATE_DOWN,
|
||||
} NMSupplicantInterfaceState;
|
||||
|
||||
static inline gboolean
|
||||
NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (NMSupplicantInterfaceState state)
|
||||
{
|
||||
return state > NM_SUPPLICANT_INTERFACE_STATE_STARTING
|
||||
&& state < NM_SUPPLICANT_INTERFACE_STATE_DOWN;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
NM_SUPPLICANT_AUTH_STATE_UNKNOWN,
|
||||
NM_SUPPLICANT_AUTH_STATE_STARTED,
|
||||
|
@ -50,8 +56,9 @@ typedef enum {
|
|||
#define NM_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_INTERFACE))
|
||||
#define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass))
|
||||
|
||||
#define NM_SUPPLICANT_INTERFACE_IFACE "iface"
|
||||
#define NM_SUPPLICANT_INTERFACE_OBJECT_PATH "object-path"
|
||||
#define NM_SUPPLICANT_INTERFACE_SUPPLICANT_MANAGER "supplicant-manager"
|
||||
#define NM_SUPPLICANT_INTERFACE_DBUS_OBJECT_PATH "dbus-object-path"
|
||||
#define NM_SUPPLICANT_INTERFACE_IFINDEX "ifindex"
|
||||
#define NM_SUPPLICANT_INTERFACE_SCANNING "scanning"
|
||||
#define NM_SUPPLICANT_INTERFACE_CURRENT_BSS "current-bss"
|
||||
#define NM_SUPPLICANT_INTERFACE_P2P_GROUP_JOINED "p2p-group-joined"
|
||||
|
@ -59,15 +66,11 @@ typedef enum {
|
|||
#define NM_SUPPLICANT_INTERFACE_P2P_GROUP_OWNER "p2p-group-owner"
|
||||
#define NM_SUPPLICANT_INTERFACE_DRIVER "driver"
|
||||
#define NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE "p2p-available"
|
||||
#define NM_SUPPLICANT_INTERFACE_GLOBAL_CAPABILITIES "global-capabilities"
|
||||
#define NM_SUPPLICANT_INTERFACE_AUTH_STATE "auth-state"
|
||||
|
||||
#define NM_SUPPLICANT_INTERFACE_STATE "state"
|
||||
#define NM_SUPPLICANT_INTERFACE_REMOVED "removed"
|
||||
#define NM_SUPPLICANT_INTERFACE_BSS_UPDATED "bss-updated"
|
||||
#define NM_SUPPLICANT_INTERFACE_BSS_REMOVED "bss-removed"
|
||||
#define NM_SUPPLICANT_INTERFACE_PEER_UPDATED "peer-updated"
|
||||
#define NM_SUPPLICANT_INTERFACE_PEER_REMOVED "peer-removed"
|
||||
#define NM_SUPPLICANT_INTERFACE_BSS_CHANGED "bss-changed"
|
||||
#define NM_SUPPLICANT_INTERFACE_PEER_CHANGED "peer-changed"
|
||||
#define NM_SUPPLICANT_INTERFACE_SCAN_DONE "scan-done"
|
||||
#define NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS "wps-credentials"
|
||||
#define NM_SUPPLICANT_INTERFACE_GROUP_STARTED "group-started"
|
||||
|
@ -85,13 +88,17 @@ struct _NMSupplicantInterface {
|
|||
|
||||
GType nm_supplicant_interface_get_type (void);
|
||||
|
||||
NMSupplicantInterface *nm_supplicant_interface_new (const char *ifname,
|
||||
const char *object_path,
|
||||
NMSupplicantDriver driver,
|
||||
NMSupplCapMask global_capabilities);
|
||||
NMSupplicantInterface *nm_supplicant_interface_new (NMSupplicantManager *supplicant_manager,
|
||||
NMRefString *object_path,
|
||||
int ifindex,
|
||||
NMSupplicantDriver driver);
|
||||
|
||||
void nm_supplicant_interface_set_supplicant_available (NMSupplicantInterface *self,
|
||||
gboolean available);
|
||||
NMRefString *nm_supplicant_interface_get_name_owner (NMSupplicantInterface *self);
|
||||
NMRefString *nm_supplicant_interface_get_object_path (NMSupplicantInterface * iface);
|
||||
|
||||
void _nm_supplicant_interface_set_state_down (NMSupplicantInterface * self,
|
||||
gboolean force_remove_from_supplicant,
|
||||
const char *reason);
|
||||
|
||||
typedef void (*NMSupplicantInterfaceAssocCb) (NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
|
@ -115,8 +122,6 @@ nm_supplicant_interface_disconnect_async (NMSupplicantInterface * self,
|
|||
NMSupplicantInterfaceDisconnectCb callback,
|
||||
gpointer user_data);
|
||||
|
||||
const char *nm_supplicant_interface_get_object_path (NMSupplicantInterface * iface);
|
||||
|
||||
void nm_supplicant_interface_request_scan (NMSupplicantInterface *self,
|
||||
GBytes *const*ssids,
|
||||
guint ssids_len);
|
||||
|
@ -127,7 +132,7 @@ const char *nm_supplicant_interface_state_to_string (NMSupplicantInterfaceState
|
|||
|
||||
gboolean nm_supplicant_interface_get_scanning (NMSupplicantInterface *self);
|
||||
|
||||
const char *nm_supplicant_interface_get_current_bss (NMSupplicantInterface *self);
|
||||
NMRefString *nm_supplicant_interface_get_current_bss (NMSupplicantInterface *self);
|
||||
|
||||
gint64 nm_supplicant_interface_get_last_scan (NMSupplicantInterface *self);
|
||||
|
||||
|
@ -135,6 +140,8 @@ const char *nm_supplicant_interface_get_ifname (NMSupplicantInterface *self);
|
|||
|
||||
guint nm_supplicant_interface_get_max_scan_ssids (NMSupplicantInterface *self);
|
||||
|
||||
gboolean nm_supplicant_interface_get_p2p_available (NMSupplicantInterface *self);
|
||||
|
||||
gboolean nm_supplicant_interface_get_p2p_group_joined (NMSupplicantInterface *self);
|
||||
|
||||
const char* nm_supplicant_interface_get_p2p_group_path (NMSupplicantInterface *self);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,19 +17,49 @@
|
|||
#define NM_IS_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_MANAGER))
|
||||
#define NM_SUPPLICANT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass))
|
||||
|
||||
#define NM_SUPPLICANT_MANAGER_AVAILABLE_CHANGED "available-changed"
|
||||
|
||||
typedef struct _NMSupplicantManagerClass NMSupplicantManagerClass;
|
||||
|
||||
GType nm_supplicant_manager_get_type (void);
|
||||
|
||||
NMSupplicantManager *nm_supplicant_manager_get (void);
|
||||
|
||||
NMTernary nm_supplicant_manager_is_available (NMSupplicantManager *self);
|
||||
|
||||
GDBusConnection *nm_supplicant_manager_get_dbus_connection (NMSupplicantManager *self);
|
||||
NMRefString *nm_supplicant_manager_get_dbus_name_owner (NMSupplicantManager *self);
|
||||
NMSupplCapMask nm_supplicant_manager_get_global_capabilities (NMSupplicantManager *self);
|
||||
|
||||
void nm_supplicant_manager_set_wfd_ies (NMSupplicantManager *self,
|
||||
GBytes *wfd_ies);
|
||||
|
||||
NMSupplicantInterface *nm_supplicant_manager_create_interface (NMSupplicantManager *mgr,
|
||||
const char *ifname,
|
||||
NMSupplicantDriver driver);
|
||||
typedef struct _NMSupplMgrCreateIfaceHandle NMSupplMgrCreateIfaceHandle;
|
||||
|
||||
typedef void (*NMSupplicantManagerCreateInterfaceCb) (NMSupplicantManager *self,
|
||||
NMSupplMgrCreateIfaceHandle *handle,
|
||||
NMSupplicantInterface *iface,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
NMSupplMgrCreateIfaceHandle *nm_supplicant_manager_create_interface (NMSupplicantManager *self,
|
||||
int ifindex,
|
||||
NMSupplicantDriver driver,
|
||||
NMSupplicantManagerCreateInterfaceCb callback,
|
||||
gpointer user_data);
|
||||
|
||||
void nm_supplicant_manager_create_interface_cancel (NMSupplMgrCreateIfaceHandle *handle);
|
||||
|
||||
NMSupplicantInterface *nm_supplicant_manager_create_interface_from_path (NMSupplicantManager *self,
|
||||
const char *object_path);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void _nm_supplicant_manager_unregister_interface (NMSupplicantManager *self,
|
||||
NMSupplicantInterface *supp_iface);
|
||||
|
||||
void _nm_supplicant_manager_dbus_call_remove_interface (NMSupplicantManager *self,
|
||||
const char *name_owner,
|
||||
const char *iface_path);
|
||||
|
||||
#endif /* __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ */
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef __NETWORKMANAGER_SUPPLICANT_TYPES_H__
|
||||
#define __NETWORKMANAGER_SUPPLICANT_TYPES_H__
|
||||
|
||||
#include "c-list/src/c-list.h"
|
||||
|
||||
#define NM_WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1"
|
||||
#define NM_WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1"
|
||||
#define NM_WPAS_DBUS_INTERFACE "fi.w1.wpa_supplicant1"
|
||||
|
@ -138,4 +140,65 @@ const char *nm_supplicant_driver_to_string (NMSupplicantDriver driver);
|
|||
#define NM_SUPPLICANT_ERROR (nm_supplicant_error_quark ())
|
||||
GQuark nm_supplicant_error_quark (void);
|
||||
|
||||
typedef struct _NMSupplicantBssInfo {
|
||||
NMRefString *bss_path;
|
||||
|
||||
NMSupplicantInterface *_self;
|
||||
CList _bss_lst;
|
||||
GCancellable *_init_cancellable;
|
||||
|
||||
GBytes *ssid;
|
||||
|
||||
gint64 last_seen_msec;
|
||||
|
||||
NM80211ApSecurityFlags wpa_flags; /* WPA-related flags */
|
||||
NM80211ApSecurityFlags rsn_flags; /* RSN (WPA2) -related flags */
|
||||
|
||||
guint32 frequency;
|
||||
|
||||
guint32 max_rate;
|
||||
|
||||
guint8 signal_percent;
|
||||
|
||||
guint8 bssid[6 /* ETH_ALEN */];
|
||||
|
||||
NM80211ApFlags ap_flags:5;
|
||||
|
||||
NM80211Mode mode:4;
|
||||
|
||||
bool bssid_valid:1;
|
||||
|
||||
bool metered:1;
|
||||
|
||||
bool _bss_dirty:1;
|
||||
|
||||
} NMSupplicantBssInfo;
|
||||
|
||||
typedef struct _NMSupplicantPeerInfo{
|
||||
NMRefString *peer_path;
|
||||
|
||||
CList _peer_lst;
|
||||
NMSupplicantInterface *_self;
|
||||
GCancellable *_init_cancellable;
|
||||
|
||||
char *device_name;
|
||||
char *manufacturer;
|
||||
char *model;
|
||||
char *model_number;
|
||||
char *serial;
|
||||
|
||||
GBytes *ies;
|
||||
|
||||
gint64 last_seen_msec;
|
||||
|
||||
guint8 address[6 /* ETH_ALEN */];
|
||||
|
||||
gint8 signal_percent;
|
||||
|
||||
bool address_valid:1;
|
||||
|
||||
bool _peer_dirty:1;
|
||||
|
||||
} NMSupplicantPeerInfo;
|
||||
|
||||
#endif /* NM_SUPPLICANT_TYPES_H */
|
||||
|
|
Loading…
Reference in a new issue