supplicant: merge branch 'th/supplicant'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/426
This commit is contained in:
Thomas Haller 2020-03-12 10:32:31 +01:00
commit f714ae7626
15 changed files with 4257 additions and 2977 deletions

View file

@ -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, &timestamp))
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

View file

@ -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, &timestamp))
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

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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 *

View file

@ -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__ */

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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__ */

View file

@ -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 */