summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-04-03 11:27:16 +0200
committerThomas Haller <thaller@redhat.com>2020-04-03 11:27:16 +0200
commit9a54111cc040ebd868d7a6695d12c4204e7092ea (patch)
treedd38588cc67f2a5f648cbe57ddfd3178e3d5b544
parent2da092b5922b823b51ec5ff5ad6e8d6d41c82a69 (diff)
parentfa86fe4ee23067870e2daa6966e8b59817cbd18d (diff)
downloadNetworkManager-9a54111cc040ebd868d7a6695d12c4204e7092ea.tar.gz
wifi: merge branch 'th/fix-wifi-scan-1'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/445
-rw-r--r--clients/cli/devices.c3
-rw-r--r--shared/nm-glib-aux/nm-hash-utils.c112
-rw-r--r--shared/nm-glib-aux/nm-hash-utils.h23
-rw-r--r--src/devices/nm-device-ethernet.c4
-rw-r--r--src/devices/nm-device-macsec.c4
-rw-r--r--src/devices/wifi/nm-device-iwd.c45
-rw-r--r--src/devices/wifi/nm-device-iwd.h2
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.c47
-rw-r--r--src/devices/wifi/nm-device-wifi-p2p.c8
-rw-r--r--src/devices/wifi/nm-device-wifi.c371
-rw-r--r--src/devices/wifi/nm-device-wifi.h7
-rw-r--r--src/devices/wifi/nm-wifi-ap.c14
-rw-r--r--src/devices/wifi/nm-wifi-ap.h2
-rw-r--r--src/supplicant/nm-supplicant-interface.c228
-rw-r--r--src/supplicant/nm-supplicant-interface.h10
15 files changed, 481 insertions, 399 deletions
diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index a4b7ec18af..d829368304 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -2922,7 +2922,6 @@ wifi_list_finish (WifiListData *wifi_list_data,
guint i;
if ( !force_finished
- && scan_info->rescan_cutoff_msec != G_MAXINT64
&& scan_info->rescan_cutoff_msec > _device_wifi_get_last_scan (wifi_list_data->wifi)) {
/* wait longer... */
return;
@@ -3115,7 +3114,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
else if (nm_streq (rescan, "no"))
rescan_cutoff_msec = G_MININT64;
else if (nm_streq (rescan, "yes"))
- rescan_cutoff_msec = G_MAXINT64;
+ rescan_cutoff_msec = nm_utils_get_timestamp_msec ();
else {
g_string_printf (nmc->return_text, _("Error: invalid rescan argument: '%s' not among [auto, no, yes]"), rescan);
return NMC_RESULT_ERROR_USER_INPUT;
diff --git a/shared/nm-glib-aux/nm-hash-utils.c b/shared/nm-glib-aux/nm-hash-utils.c
index cd51bbaf63..0a701d06e1 100644
--- a/shared/nm-glib-aux/nm-hash-utils.c
+++ b/shared/nm-glib-aux/nm-hash-utils.c
@@ -24,7 +24,6 @@ static const guint8 *volatile global_seed = NULL;
static const guint8 *
_get_hash_key_init (void)
{
- static gsize g_lock;
/* the returned hash is aligned to guin64, hence, it is safe
* to use it as guint* or guint64* pointer. */
static union {
@@ -34,50 +33,49 @@ _get_hash_key_init (void)
guint64 _align_as_uint64;
} g_arr;
const guint8 *g;
- union {
- guint8 v8[HASH_KEY_SIZE];
- guint vuint;
- } t_arr;
again:
g = g_atomic_pointer_get (&global_seed);
- if (G_LIKELY (g != NULL)) {
- nm_assert (g == g_arr.v8);
- return g;
- }
-
- {
- CSipHash siph_state;
+ if (!G_UNLIKELY (g)) {
+ static gsize g_lock;
uint64_t h;
-
- /* initialize a random key in t_arr. */
+ union {
+ guint vuint;
+ guint8 v8[HASH_KEY_SIZE];
+ guint8 _extra_entropy[3 * HASH_KEY_SIZE];
+ } t_arr;
nm_utils_random_bytes (&t_arr, sizeof (t_arr));
- /* use siphash() of the key-size, to mangle the first guint. Otherwise,
- * the first guint has only the entropy that nm_utils_random_bytes()
- * generated for the first 4 bytes and relies on a good random generator.
+ /* We only initialize one random hash key. So we can spend some effort
+ * of getting this right. For one, we collect more random bytes than
+ * necessary.
*
- * The first int is especially interesting for nm_hash_static() below, and we
- * want to have it all the entropy of t_arr. */
- c_siphash_init (&siph_state, t_arr.v8);
- c_siphash_append (&siph_state, (const guint8 *) &t_arr, sizeof (t_arr));
- h = c_siphash_finalize (&siph_state);
- if (sizeof (guint) < sizeof (h))
- t_arr.vuint = t_arr.vuint ^ ((guint) (h & 0xFFFFFFFFu)) ^ ((guint) (h >> 32));
+ * Then, the first guint of the seed should have all the entropy that we could
+ * obtain in sizeof(t_arr). For that, siphash(t_arr) and xor the first guint
+ * with hash.
+ * The first guint is especially interesting for nm_hash_static() below that
+ * doesn't use siphash itself. */
+ h = c_siphash_hash (t_arr.v8,
+ (const guint8 *) &t_arr,
+ sizeof (t_arr));
+ if (sizeof (h) > sizeof (guint))
+ t_arr.vuint = t_arr.vuint ^ ((guint) (h & G_MAXUINT)) ^ ((guint) (h >> 32));
else
- t_arr.vuint = t_arr.vuint ^ ((guint) (h & 0xFFFFFFFFu));
- }
+ t_arr.vuint = t_arr.vuint ^ ((guint) (h & G_MAXUINT));
- if (!g_once_init_enter (&g_lock)) {
- /* lost a race. The random key is already initialized. */
- goto again;
+ if (!g_once_init_enter (&g_lock)) {
+ /* lost a race. The random key is already initialized. */
+ goto again;
+ }
+
+ memcpy (g_arr.v8, t_arr.v8, HASH_KEY_SIZE);
+ g = g_arr.v8;
+ g_atomic_pointer_set (&global_seed, g);
+ g_once_init_leave (&g_lock, 1);
}
- memcpy (g_arr.v8, t_arr.v8, HASH_KEY_SIZE);
- g = g_arr.v8;
- g_atomic_pointer_set (&global_seed, g);
- g_once_init_leave (&g_lock, 1);
+ nm_assert (g == g_arr.v8);
return g;
}
@@ -94,18 +92,24 @@ again:
guint
nm_hash_static (guint static_seed)
{
- /* note that we only xor the static_seed with the key.
- * We don't use siphash, which would mix the bits better.
- * Note that this doesn't matter, because static_seed is not
- * supposed to be a value that you are hashing (for that, use
- * full siphash).
- * Instead, different callers may set a different static_seed
- * so that nm_hash_str(NULL) != nm_hash_ptr(NULL).
+ /* Note that we only xor the static_seed with the first guint of the key.
+ *
+ * We don't use siphash, which would mix the bits better with _get_hash_key().
+ * Note that nm_hash_static() isn't used to hash the static_seed. Instead, it
+ * is used to get a unique hash value in a static context. That means, every
+ * caller is responsible to choose a static_seed that is sufficiently
+ * distinct from all other callers. In other words, static_seed should be a
+ * unique constant with good entropy.
+ *
+ * Note that _get_hash_key_init() already xored the first guint of the
+ * key with the siphash of the entire static key. That means, even if
+ * we got bad randomness for the first guint, the first guint is also
+ * mixed with the randomness of the entire random key.
*
- * Also, ensure that we don't return zero.
+ * Also, ensure that we don't return zero (like for nm_hash_complete()).
*/
- return ((*((const guint *) _get_hash_key ())) ^ static_seed)
- ?: static_seed ?: 3679500967u;
+ return ((*((const guint *) _get_hash_key ())) ^ static_seed)
+ ?: 3679500967u;
}
void
@@ -257,3 +261,25 @@ nm_ppdirect_equal (gconstpointer a, gconstpointer b)
return **s1 == **s2;
}
+
+/*****************************************************************************/
+
+guint
+nm_pgbytes_hash (gconstpointer p)
+{
+ GBytes *const*ptr = p;
+ gconstpointer arr;
+ gsize len;
+
+ arr = g_bytes_get_data (*ptr, &len);
+ return nm_hash_mem (1470631313u, arr, len);
+}
+
+gboolean
+nm_pgbytes_equal (gconstpointer a, gconstpointer b)
+{
+ GBytes *const*ptr_a = a;
+ GBytes *const*ptr_b = b;
+
+ return g_bytes_equal (*ptr_a, *ptr_b);
+}
diff --git a/shared/nm-glib-aux/nm-hash-utils.h b/shared/nm-glib-aux/nm-hash-utils.h
index 21c5e58416..9f2e976678 100644
--- a/shared/nm-glib-aux/nm-hash-utils.h
+++ b/shared/nm-glib-aux/nm-hash-utils.h
@@ -88,15 +88,15 @@ nm_hash_complete (NMHashState *state)
/* we don't ever want to return a zero hash.
*
* NMPObject requires that in _idx_obj_part(), and it's just a good idea. */
- return (((guint) (h >> 32)) ^ ((guint) h)) ?: 1396707757u;
+ return (((guint) (h >> 32)) ^ ((guint) h))
+ ?: 1396707757u;
}
static inline void
nm_hash_update (NMHashState *state, const void *ptr, gsize n)
{
nm_assert (state);
- nm_assert (ptr);
- nm_assert (n > 0);
+ nm_assert (n == 0 || ptr);
/* Note: the data passed in here might be sensitive data (secrets),
* that we should nm_explicty_zero() afterwards. However, since
@@ -267,6 +267,18 @@ guint nm_str_hash (gconstpointer str);
nm_hash_complete (&_h); \
})
+static inline guint
+nm_hash_mem (guint static_seed, const void *ptr, gsize n)
+{
+ NMHashState h;
+
+ if (n == 0)
+ return nm_hash_static (static_seed);
+ nm_hash_init (&h, static_seed);
+ nm_hash_update (&h, ptr, n);
+ return nm_hash_complete (&h);
+}
+
/*****************************************************************************/
/* nm_pstr_*() are for hashing keys that are pointers to strings,
@@ -303,6 +315,11 @@ gboolean nm_ppdirect_equal (gconstpointer a, gconstpointer b);
/*****************************************************************************/
+guint nm_pgbytes_hash (gconstpointer p);
+gboolean nm_pgbytes_equal (gconstpointer a, gconstpointer b);
+
+/*****************************************************************************/
+
#define NM_HASH_OBFUSCATE_PTR_FMT "%016" G_GINT64_MODIFIER "x"
/* sometimes we want to log a pointer directly, for providing context/information about
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index dc44c084bd..7556bb27ba 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -811,7 +811,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
state = nm_supplicant_interface_get_state (priv->supplicant.iface);
if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
- && NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (state))
+ && 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);
}
@@ -862,7 +862,7 @@ supplicant_interface_create_cb (NMSupplicantManager *supplicant_manager,
supplicant_connection_timeout_cb,
self);
- if (NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (iface)))
+ if (nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (iface)))
supplicant_iface_start (self);
}
diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c
index 4d620831ac..f1878078b2 100644
--- a/src/devices/nm-device-macsec.c
+++ b/src/devices/nm-device-macsec.c
@@ -584,7 +584,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
state = nm_supplicant_interface_get_state (priv->supplicant.iface);
if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
- && NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (state))
+ && 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);
}
@@ -636,7 +636,7 @@ supplicant_interface_create_cb (NMSupplicantManager *supplicant_manager,
supplicant_connection_timeout_cb,
self);
- if (NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (iface)))
+ if (nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (iface)))
supplicant_iface_start (self);
}
diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c
index 49fe07fb08..3c1d5b2298 100644
--- a/src/devices/wifi/nm-device-iwd.c
+++ b/src/devices/wifi/nm-device-iwd.c
@@ -43,14 +43,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceIwd,
PROP_LAST_SCAN,
);
-enum {
- SCANNING_PROHIBITED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
typedef struct {
GDBusObject * dbus_obj;
GDBusProxy * dbus_device_proxy;
@@ -79,9 +71,6 @@ struct _NMDeviceIwd {
struct _NMDeviceIwdClass {
NMDeviceClass parent;
-
- /* Signals */
- gboolean (*scanning_prohibited) (NMDeviceIwd *device, gboolean periodic);
};
/*****************************************************************************/
@@ -95,21 +84,22 @@ G_DEFINE_TYPE (NMDeviceIwd, nm_device_iwd, NM_TYPE_DEVICE)
static void schedule_periodic_scan (NMDeviceIwd *self,
gboolean initial_scan);
+static gboolean check_scanning_prohibited (NMDeviceIwd *self, gboolean periodic);
+
/*****************************************************************************/
static void
_ap_dump (NMDeviceIwd *self,
NMLogLevel log_level,
const NMWifiAP *ap,
- const char *prefix,
- gint32 now_s)
+ const char *prefix)
{
char buf[1024];
buf[0] = '\0';
_NMLOG (log_level, LOGD_WIFI_SCAN, "wifi-ap: %-7s %s",
prefix,
- nm_wifi_ap_to_string (ap, buf, sizeof (buf), now_s));
+ nm_wifi_ap_to_string (ap, buf, sizeof (buf), 0));
}
/* Callers ensure we're not removing current_ap */
@@ -126,12 +116,12 @@ ap_add_remove (NMDeviceIwd *self,
ap->wifi_device = NM_DEVICE (self);
c_list_link_tail (&priv->aps_lst_head, &ap->aps_lst);
nm_dbus_object_export (NM_DBUS_OBJECT (ap));
- _ap_dump (self, LOGL_DEBUG, ap, "added", 0);
+ _ap_dump (self, LOGL_DEBUG, ap, "added");
nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, TRUE);
} else {
ap->wifi_device = NULL;
c_list_unlink (&ap->aps_lst);
- _ap_dump (self, LOGL_DEBUG, ap, "removed", 0);
+ _ap_dump (self, LOGL_DEBUG, ap, "removed");
}
_notify (self, PROP_ACCESS_POINTS);
@@ -357,7 +347,7 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
nm_wifi_ap_get_supplicant_path (ap));
if (new_ap) {
if (nm_wifi_ap_set_strength (ap, nm_wifi_ap_get_strength (new_ap))) {
- _ap_dump (self, LOGL_TRACE, ap, "updated", 0);
+ _ap_dump (self, LOGL_TRACE, ap, "updated");
changed = TRUE;
}
g_hash_table_remove (new_aps,
@@ -973,15 +963,6 @@ _nm_device_iwd_get_aps (NMDeviceIwd *self)
return &NM_DEVICE_IWD_GET_PRIVATE (self)->aps_lst_head;
}
-static gboolean
-check_scanning_prohibited (NMDeviceIwd *self, gboolean periodic)
-{
- gboolean prohibited = FALSE;
-
- g_signal_emit (self, signals[SCANNING_PROHIBITED], 0, periodic, &prohibited);
- return prohibited;
-}
-
static void
scan_cb (GObject *source, GAsyncResult *res, gpointer user_data)
{
@@ -1091,7 +1072,7 @@ _nm_device_iwd_request_scan (NMDeviceIwd *self,
}
static gboolean
-scanning_prohibited (NMDeviceIwd *self, gboolean periodic)
+check_scanning_prohibited (NMDeviceIwd *self, gboolean periodic)
{
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
@@ -2581,8 +2562,6 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass)
device_class->state_changed = device_state_changed;
- klass->scanning_prohibited = scanning_prohibited;
-
obj_properties[PROP_MODE] =
g_param_spec_uint (NM_DEVICE_IWD_MODE, "", "",
NM_802_11_MODE_UNKNOWN,
@@ -2627,12 +2606,4 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-
- signals[SCANNING_PROHIBITED] =
- g_signal_new (NM_DEVICE_IWD_SCANNING_PROHIBITED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMDeviceIwdClass, scanning_prohibited),
- NULL, NULL, NULL,
- G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN);
}
diff --git a/src/devices/wifi/nm-device-iwd.h b/src/devices/wifi/nm-device-iwd.h
index 586e02f4b3..1f15d3f4bb 100644
--- a/src/devices/wifi/nm-device-iwd.h
+++ b/src/devices/wifi/nm-device-iwd.h
@@ -25,8 +25,6 @@
#define NM_DEVICE_IWD_SCANNING NM_DEVICE_WIFI_SCANNING
#define NM_DEVICE_IWD_LAST_SCAN NM_DEVICE_WIFI_LAST_SCAN
-#define NM_DEVICE_IWD_SCANNING_PROHIBITED NM_DEVICE_WIFI_SCANNING_PROHIBITED
-
typedef struct _NMDeviceIwd NMDeviceIwd;
typedef struct _NMDeviceIwdClass NMDeviceIwdClass;
diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c
index 2850682b00..770b53f60c 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.c
+++ b/src/devices/wifi/nm-device-olpc-mesh.c
@@ -130,7 +130,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device);
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
- gboolean scanning;
/* disconnect companion device, if it is connected */
if (nm_device_get_act_request (NM_DEVICE (priv->companion))) {
@@ -145,8 +144,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
}
/* wait with continuing configuration until the companion device is done scanning */
- g_object_get (priv->companion, NM_DEVICE_WIFI_SCANNING, &scanning, NULL);
- if (scanning) {
+ if (nm_device_wifi_get_scanning (NM_DEVICE_WIFI (priv->companion))) {
priv->stage1_waiting = TRUE;
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -237,6 +235,9 @@ companion_cleanup (NMDeviceOlpcMesh *self)
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
if (priv->companion) {
+ nm_device_wifi_scanning_prohibited_track (NM_DEVICE_WIFI (priv->companion),
+ self,
+ FALSE);
g_signal_handlers_disconnect_by_data (priv->companion, self);
g_clear_object (&priv->companion);
}
@@ -248,13 +249,14 @@ companion_notify_cb (NMDeviceWifi *companion, GParamSpec *pspec, gpointer user_d
{
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data);
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
- gboolean scanning;
+
+ nm_assert (NM_IS_DEVICE_WIFI (companion));
+ nm_assert (priv->companion == (gpointer) companion);
if (!priv->stage1_waiting)
return;
- g_object_get (companion, NM_DEVICE_WIFI_SCANNING, &scanning, NULL);
- if (!scanning) {
+ if (!nm_device_wifi_get_scanning (NM_DEVICE_WIFI (companion))) {
priv->stage1_waiting = FALSE;
nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self), FALSE);
}
@@ -290,16 +292,6 @@ companion_state_changed_cb (NMDeviceWifi *companion,
}
static gboolean
-companion_scan_prohibited_cb (NMDeviceWifi *companion, gboolean periodic, gpointer user_data)
-{
- NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data);
- NMDeviceState state = nm_device_get_state (NM_DEVICE (self));
-
- /* Don't allow the companion to scan while configuring the mesh interface */
- return (state >= NM_DEVICE_STATE_PREPARE) && (state <= NM_DEVICE_STATE_IP_CONFIG);
-}
-
-static gboolean
companion_autoconnect_allowed_cb (NMDeviceWifi *companion, gpointer user_data)
{
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data);
@@ -324,7 +316,7 @@ check_companion (NMDeviceOlpcMesh *self, NMDevice *other)
if (!nm_utils_hwaddr_matches (my_addr, -1, their_addr, -1))
return FALSE;
- g_assert (priv->companion == NULL);
+ nm_assert (priv->companion == NULL);
priv->companion = g_object_ref (other);
_LOGI (LOGD_OLPC, "found companion Wi-Fi device %s",
@@ -336,9 +328,6 @@ check_companion (NMDeviceOlpcMesh *self, NMDevice *other)
g_signal_connect (G_OBJECT (other), "notify::" NM_DEVICE_WIFI_SCANNING,
G_CALLBACK (companion_notify_cb), self);
- g_signal_connect (G_OBJECT (other), NM_DEVICE_WIFI_SCANNING_PROHIBITED,
- G_CALLBACK (companion_scan_prohibited_cb), self);
-
g_signal_connect (G_OBJECT (other), NM_DEVICE_AUTOCONNECT_ALLOWED,
G_CALLBACK (companion_autoconnect_allowed_cb), self);
@@ -400,8 +389,24 @@ state_changed (NMDevice *device,
NMDeviceState old_state,
NMDeviceStateReason reason)
{
+ NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device);
+ NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
+
if (new_state == NM_DEVICE_STATE_UNAVAILABLE)
- find_companion (NM_DEVICE_OLPC_MESH (device));
+ find_companion (self);
+
+ if (priv->companion) {
+ gboolean temporarily_prohibited = FALSE;
+
+ if ( new_state >= NM_DEVICE_STATE_PREPARE
+ && new_state <= NM_DEVICE_STATE_IP_CONFIG) {
+ /* Don't allow the companion to scan while configuring the mesh interface */
+ temporarily_prohibited = TRUE;
+ }
+ nm_device_wifi_scanning_prohibited_track (NM_DEVICE_WIFI (priv->companion),
+ self,
+ temporarily_prohibited);
+ }
}
static guint32
diff --git a/src/devices/wifi/nm-device-wifi-p2p.c b/src/devices/wifi/nm-device-wifi-p2p.c
index a655c95025..497bc43603 100644
--- a/src/devices/wifi/nm-device-wifi-p2p.c
+++ b/src/devices/wifi/nm-device-wifi-p2p.c
@@ -228,7 +228,7 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
return FALSE;
supplicant_state = nm_supplicant_interface_get_state (priv->mgmt_iface);
- return NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (supplicant_state);
+ return nm_supplicant_interface_state_is_operational (supplicant_state);
}
static gboolean
@@ -712,7 +712,7 @@ check_group_iface_ready (NMDeviceWifiP2P *self)
if (!priv->group_iface)
return;
- if (!NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (priv->group_iface)))
+ 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))
@@ -910,7 +910,7 @@ device_state_changed (NMDevice *device,
break;
case NM_DEVICE_STATE_UNAVAILABLE:
if ( !priv->mgmt_iface
- || !NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (priv->mgmt_iface)))
+ || !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:
@@ -1080,7 +1080,7 @@ done:
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
_set_is_waiting_for_supplicant (self,
!priv->mgmt_iface
- || !NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (nm_supplicant_interface_get_state (priv->mgmt_iface)));
+ || !nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (priv->mgmt_iface)));
}
void
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index ce5cf1a466..266a842514 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -12,6 +12,7 @@
#include <unistd.h>
#include "nm-glib-aux/nm-ref-string.h"
+#include "nm-glib-aux/nm-c-list.h"
#include "nm-device-wifi-p2p.h"
#include "nm-wifi-ap.h"
#include "nm-libnm-core-intern/nm-common-macros.h"
@@ -43,10 +44,9 @@
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceWifi);
-/* All of these are in seconds */
-#define SCAN_INTERVAL_MIN 3
-#define SCAN_INTERVAL_STEP 20
-#define SCAN_INTERVAL_MAX 120
+#define SCAN_INTERVAL_SEC_MIN 3
+#define SCAN_INTERVAL_SEC_STEP 20
+#define SCAN_INTERVAL_SEC_MAX 120
#define SCAN_RAND_MAC_ADDRESS_EXPIRE_MIN 5
@@ -63,7 +63,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWifi,
);
enum {
- SCANNING_PROHIBITED,
P2P_DEVICE_CREATED,
LAST_SIGNAL
@@ -72,11 +71,11 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
- gint8 invalid_strength_counter;
-
CList aps_lst_head;
GHashTable *aps_idx_by_supplicant_path;
+ CList scanning_prohibited_lst_head;
+
NMWifiAP * current_ap;
guint32 rate;
bool enabled:1; /* rfkilled or not */
@@ -85,9 +84,10 @@ typedef struct {
bool is_scanning:1;
bool hidden_probe_scan_warn:1;
- gint64 last_scan; /* milliseconds */
+ gint64 last_scan_msec;
+
gint32 scheduled_scan_time; /* seconds */
- guint8 scan_interval; /* seconds */
+ guint8 scan_interval_sec;
guint pending_scan_id;
guint ap_dump_id;
@@ -100,7 +100,7 @@ typedef struct {
NMActRequestGetSecretsCallId *wifi_secrets_id;
- guint periodic_source_id;
+ guint periodic_update_id;
guint link_timeout_id;
guint32 failed_iface_count;
guint reacquire_iface_id;
@@ -125,9 +125,6 @@ struct _NMDeviceWifi
struct _NMDeviceWifiClass
{
NMDeviceClass parent;
-
- /* Signals */
- gboolean (*scanning_prohibited) (NMDeviceWifi *device, gboolean periodic);
};
/*****************************************************************************/
@@ -164,17 +161,10 @@ static void supplicant_iface_bss_changed_cb (NMSupplicantInterface *iface,
gboolean is_present,
NMDeviceWifi *self);
-static void supplicant_iface_scan_done_cb (NMSupplicantInterface * iface,
- NMDeviceWifi * self);
-
static void supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface,
GVariant *credentials,
NMDeviceWifi *self);
-static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface,
- GParamSpec * pspec,
- NMDeviceWifi * self);
-
static void supplicant_iface_notify_current_bss (NMSupplicantInterface *iface,
GParamSpec *pspec,
NMDeviceWifi *self);
@@ -183,6 +173,10 @@ static void supplicant_iface_notify_p2p_available (NMSupplicantInterface *iface,
GParamSpec *pspec,
NMDeviceWifi *self);
+static void _requested_scan_set (NMDeviceWifi *self, gboolean value);
+
+static void periodic_update (NMDeviceWifi *self);
+
static void request_wireless_scan (NMDeviceWifi *self,
gboolean periodic,
gboolean force_if_scanning,
@@ -199,19 +193,66 @@ static void recheck_p2p_availability (NMDeviceWifi *self);
/*****************************************************************************/
+void
+nm_device_wifi_scanning_prohibited_track (NMDeviceWifi *self,
+ gpointer tag,
+ gboolean temporarily_prohibited)
+{
+ NMDeviceWifiPrivate *priv;
+ NMCListElem *elem;
+
+ g_return_if_fail (NM_IS_DEVICE_WIFI (self));
+ nm_assert (tag);
+
+ priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+
+ /* We track these with a simple CList. This would be not efficient, if
+ * there would be many users that need to be tracked at the same time (there
+ * aren't). In fact, most of the time there is no NMDeviceOlpcMesh and
+ * nobody tracks itself here. Optimize for that and simplicity. */
+
+ elem = nm_c_list_elem_find_first (&priv->scanning_prohibited_lst_head,
+ iter,
+ iter == tag);
+
+ if (!temporarily_prohibited) {
+ if (!elem)
+ return;
+
+ nm_c_list_elem_free (elem);
+ return;
+ }
+
+ if (elem)
+ return;
+
+ c_list_link_tail (&priv->scanning_prohibited_lst_head,
+ &nm_c_list_elem_new_stale (tag)->lst);
+}
+
+/*****************************************************************************/
+
static void
_ap_dump (NMDeviceWifi *self,
NMLogLevel log_level,
const NMWifiAP *ap,
const char *prefix,
- gint32 now_s)
+ gint64 now_msec)
{
char buf[1024];
buf[0] = '\0';
_NMLOG (log_level, LOGD_WIFI_SCAN, "wifi-ap: %-7s %s",
prefix,
- nm_wifi_ap_to_string (ap, buf, sizeof (buf), now_s));
+ nm_wifi_ap_to_string (ap, buf, sizeof (buf), now_msec));
+}
+
+gboolean
+nm_device_wifi_get_scanning (NMDeviceWifi *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), FALSE);
+
+ return NM_DEVICE_WIFI_GET_PRIVATE (self)->is_scanning;
}
static void
@@ -219,6 +260,7 @@ _notify_scanning (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
gboolean scanning;
+ gboolean last_scan_changed = FALSE;
scanning = priv->sup_iface
&& nm_supplicant_interface_get_scanning (priv->sup_iface);
@@ -226,9 +268,42 @@ _notify_scanning (NMDeviceWifi *self)
if (scanning == priv->is_scanning)
return;
- _LOGD (LOGD_WIFI, "wifi-scan: scanning-state: %s", scanning ? "scanning" : "idle");
priv->is_scanning = scanning;
- _notify (self, PROP_SCANNING);
+
+ if ( !scanning
+ || priv->last_scan_msec == 0) {
+ last_scan_changed = TRUE;
+ priv->last_scan_msec = nm_utils_get_monotonic_timestamp_msec ();
+ }
+
+ _LOGD (LOGD_WIFI,
+ "wifi-scan: scanning-state: %s%s",
+ scanning ? "scanning" : "idle",
+ last_scan_changed ? " (notify last-scan)" : "");
+
+ schedule_scan (self, TRUE);
+
+ nm_gobject_notify_together (self,
+ PROP_SCANNING,
+ last_scan_changed
+ ? PROP_LAST_SCAN
+ : PROP_0);
+
+ if (!priv->is_scanning) {
+ _requested_scan_set (self, FALSE);
+ if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED) {
+ /* Run a quick update of current AP when coming out of a scan */
+ periodic_update (self);
+ }
+ }
+}
+
+static void
+supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface,
+ GParamSpec *pspec,
+ NMDeviceWifi *self)
+{
+ _notify_scanning (self);
}
static gboolean
@@ -279,10 +354,6 @@ supplicant_interface_acquire_cb (NMSupplicantManager *supplicant_manager,
G_CALLBACK (supplicant_iface_bss_changed_cb),
self);
g_signal_connect (priv->sup_iface,
- NM_SUPPLICANT_INTERFACE_SCAN_DONE,
- G_CALLBACK (supplicant_iface_scan_done_cb),
- self);
- g_signal_connect (priv->sup_iface,
NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS,
G_CALLBACK (supplicant_iface_wps_credentials_cb),
self);
@@ -360,9 +431,9 @@ supplicant_interface_release (NMDeviceWifi *self)
nm_clear_g_source (&priv->pending_scan_id);
/* Reset the scan interval to be pretty frequent when disconnected */
- priv->scan_interval = SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP;
+ priv->scan_interval_sec = SCAN_INTERVAL_SEC_MIN + SCAN_INTERVAL_SEC_STEP;
_LOGD (LOGD_WIFI, "wifi-scan: reset interval to %u seconds",
- (unsigned) priv->scan_interval);
+ (unsigned) priv->scan_interval_sec);
nm_clear_g_source (&priv->ap_dump_id);
@@ -442,44 +513,48 @@ set_current_ap (NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available
static void
periodic_update (NMDeviceWifi *self)
{
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- int ifindex = nm_device_get_ifindex (NM_DEVICE (self));
+ NMDeviceWifiPrivate *priv;
+ int ifindex;
guint32 new_rate;
- int percent;
- NMDeviceState state;
- NMSupplicantInterfaceState supplicant_state;
- /* BSSID and signal strength have meaningful values only if the device
- * is activated and not scanning.
- */
- state = nm_device_get_state (NM_DEVICE (self));
- if (state != NM_DEVICE_STATE_ACTIVATED)
+ if (nm_device_get_state (NM_DEVICE (self)) != NM_DEVICE_STATE_ACTIVATED) {
+ /* BSSID and signal strength have meaningful values only if the device
+ * is activated and not scanning.
+ */
return;
+ }
- /* Only update current AP if we're actually talking to something, otherwise
- * assume the old one (if any) is still valid until we're told otherwise or
- * the connection fails.
- */
- supplicant_state = nm_supplicant_interface_get_state (priv->sup_iface);
- if ( supplicant_state < NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING
- || supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
- || nm_supplicant_interface_get_scanning (priv->sup_iface))
+ priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+
+ if ( !nm_supplicant_interface_state_is_associated (nm_supplicant_interface_get_state (priv->sup_iface))
+ || nm_supplicant_interface_get_scanning (priv->sup_iface)) {
+ /* Only update current AP if we're actually talking to something, otherwise
+ * assume the old one (if any) is still valid until we're told otherwise or
+ * the connection fails.
+ */
return;
+ }
- /* In AP mode we currently have nothing to do. */
- if (priv->mode == NM_802_11_MODE_AP)
+ if (priv->mode == NM_802_11_MODE_AP) {
+ /* In AP mode we currently have nothing to do. */
return;
+ }
+
+ ifindex = nm_device_get_ifindex (NM_DEVICE (self));
+ if (ifindex <= 0)
+ g_return_if_reached ();
if (priv->current_ap) {
- /* Smooth out the strength to work around crappy drivers */
+ int percent;
+
percent = nm_platform_wifi_get_quality (nm_device_get_platform (NM_DEVICE (self)), ifindex);
- if (percent >= 0 || ++priv->invalid_strength_counter > 3) {
+ if ( percent >= 0
+ && percent <= 100) {
if (nm_wifi_ap_set_strength (priv->current_ap, (gint8) percent)) {
#if NM_MORE_LOGGING
_ap_dump (self, LOGL_TRACE, priv->current_ap, "updated", 0);
#endif
}
- priv->invalid_strength_counter = 0;
}
}
@@ -493,7 +568,7 @@ periodic_update (NMDeviceWifi *self)
static gboolean
periodic_update_cb (gpointer user_data)
{
- periodic_update (NM_DEVICE_WIFI (user_data));
+ periodic_update (user_data);
return TRUE;
}
@@ -629,7 +704,7 @@ deactivate (NMDevice *device)
int ifindex = nm_device_get_ifindex (device);
NM80211Mode old_mode = priv->mode;
- nm_clear_g_source (&priv->periodic_source_id);
+ nm_clear_g_source (&priv->periodic_update_id);
cleanup_association_attempt (self, TRUE);
@@ -1120,7 +1195,7 @@ ssids_options_to_ptrarray (GVariant *value, GError **error)
if (num_ssids > 32) {
g_set_error_literal (error,
NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_NOT_ALLOWED,
+ NM_DEVICE_ERROR_INVALID_ARGUMENT,
"too many SSIDs requested to scan");
return NULL;
}
@@ -1137,7 +1212,7 @@ ssids_options_to_ptrarray (GVariant *value, GError **error)
if (len > 32) {
g_set_error (error,
NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_NOT_ALLOWED,
+ NM_DEVICE_ERROR_INVALID_ARGUMENT,
"SSID at index %d more than 32 bytes", (int) i);
return NULL;
}
@@ -1163,8 +1238,7 @@ dbus_request_scan_cb (NMDevice *device,
gpointer user_data)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
- gs_unref_variant GVariant *scan_options = user_data;
- gs_unref_ptrarray GPtrArray *ssids = NULL;
+ gs_unref_ptrarray GPtrArray *ssids = user_data;
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
@@ -1179,41 +1253,42 @@ dbus_request_scan_cb (NMDevice *device,
return;
}
- if (scan_options) {
- gs_unref_variant GVariant *val = g_variant_lookup_value (scan_options, "ssids", NULL);
+ request_wireless_scan (self, FALSE, FALSE, ssids);
+ g_dbus_method_invocation_return_value (context, NULL);
+}
+
+void
+_nm_device_wifi_request_scan (NMDeviceWifi *self,
+ GVariant *options,
+ GDBusMethodInvocation *invocation)
+{
+ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ NMDevice *device = NM_DEVICE (self);
+ gint64 last_scan;
+ gs_unref_ptrarray GPtrArray *ssids = NULL;
+
+ if (options) {
+ gs_unref_variant GVariant *val = g_variant_lookup_value (options, "ssids", NULL);
if (val) {
gs_free_error GError *ssid_error = NULL;
if (!g_variant_is_of_type (val, G_VARIANT_TYPE ("aay"))) {
- g_dbus_method_invocation_return_error_literal (context,
+ g_dbus_method_invocation_return_error_literal (invocation,
NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_NOT_ALLOWED,
+ NM_DEVICE_ERROR_INVALID_ARGUMENT,
"Invalid 'ssid' scan option");
return;
}
ssids = ssids_options_to_ptrarray (val, &ssid_error);
if (ssid_error) {
- g_dbus_method_invocation_return_gerror (context, ssid_error);
+ g_dbus_method_invocation_return_gerror (invocation, ssid_error);
return;
}
}
}
- request_wireless_scan (self, FALSE, FALSE, ssids);
- g_dbus_method_invocation_return_value (context, NULL);
-}
-
-void
-_nm_device_wifi_request_scan (NMDeviceWifi *self,
- GVariant *options,
- GDBusMethodInvocation *invocation)
-{
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- NMDevice *device = NM_DEVICE (self);
- gint64 last_scan;
-
if ( !priv->enabled
|| !priv->sup_iface
|| nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED
@@ -1235,7 +1310,12 @@ _nm_device_wifi_request_scan (NMDeviceWifi *self,
last_scan = nm_supplicant_interface_get_last_scan (priv->sup_iface);
if ( last_scan > 0
- && (nm_utils_get_monotonic_timestamp_msec () - last_scan) < 10 * NM_UTILS_MSEC_PER_SEC) {
+ && nm_utils_get_monotonic_timestamp_msec () < last_scan + (10 * NM_UTILS_MSEC_PER_SEC)) {
+ /* FIXME: we really should not outright reject a scan request in this case. We should
+ * ensure to start a scan request soon, possibly with rate limiting. And there is no
+ * need to tell the caller that we aren't going to scan...
+ *
+ * Same above, if we are currently scanning... */
g_dbus_method_invocation_return_error_literal (invocation,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ALLOWED,
@@ -1250,16 +1330,19 @@ _nm_device_wifi_request_scan (NMDeviceWifi *self,
NM_AUTH_PERMISSION_WIFI_SCAN,
TRUE,
dbus_request_scan_cb,
- options ? g_variant_ref (options) : NULL);
+ g_steal_pointer (&ssids));
}
static gboolean
-scanning_prohibited (NMDeviceWifi *self, gboolean periodic)
+check_scanning_prohibited (NMDeviceWifi *self,
+ gboolean periodic)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- NMSupplicantInterfaceState supplicant_state;
- g_return_val_if_fail (priv->sup_iface != NULL, TRUE);
+ nm_assert (NM_IS_SUPPLICANT_INTERFACE (priv->sup_iface));
+
+ if (!c_list_is_empty (&priv->scanning_prohibited_lst_head))
+ return TRUE;
/* Don't scan when a an AP or Ad-Hoc connection is active as it will
* disrupt connected clients or peers.
@@ -1296,11 +1379,11 @@ scanning_prohibited (NMDeviceWifi *self, gboolean periodic)
}
/* Prohibit scans if the supplicant is busy */
- supplicant_state = nm_supplicant_interface_get_state (priv->sup_iface);
- if ( supplicant_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING
- || supplicant_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED
- || supplicant_state == NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE
- || supplicant_state == NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE
+ if ( NM_IN_SET (nm_supplicant_interface_get_state (priv->sup_iface),
+ NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING,
+ NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED,
+ NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE,
+ NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE)
|| nm_supplicant_interface_get_scanning (priv->sup_iface))
return TRUE;
@@ -1309,15 +1392,6 @@ scanning_prohibited (NMDeviceWifi *self, gboolean periodic)
}
static gboolean
-check_scanning_prohibited (NMDeviceWifi *self, gboolean periodic)
-{
- gboolean prohibited = FALSE;
-
- g_signal_emit (self, signals[SCANNING_PROHIBITED], 0, periodic, &prohibited);
- return prohibited;
-}
-
-static gboolean
hidden_filter_func (NMSettings *settings,
NMSettingsConnection *set_con,
gpointer user_data)
@@ -1468,14 +1542,15 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff)
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
gint32 now = nm_utils_get_monotonic_timestamp_sec ();
- /* Cancel the pending scan if it would happen later than (now + the scan_interval) */
+ /* Cancel the pending scan if it would happen later than (now + the scan_interval_sec) */
if (priv->pending_scan_id) {
- if (now + priv->scan_interval < priv->scheduled_scan_time)
+ if (now + priv->scan_interval_sec < priv->scheduled_scan_time)
nm_clear_g_source (&priv->pending_scan_id);
}
if (!priv->pending_scan_id) {
- guint factor = 2, next_scan = priv->scan_interval;
+ guint factor = 2;
+ guint next_scan = priv->scan_interval_sec;
if ( nm_device_is_activating (NM_DEVICE (self))
|| (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED))
@@ -1485,40 +1560,25 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff)
request_wireless_scan_periodic,
self);
- priv->scheduled_scan_time = now + priv->scan_interval;
- if (backoff && (priv->scan_interval < (SCAN_INTERVAL_MAX / factor))) {
- priv->scan_interval += (SCAN_INTERVAL_STEP / factor);
+ priv->scheduled_scan_time = now + priv->scan_interval_sec;
+ if (backoff && (priv->scan_interval_sec < (SCAN_INTERVAL_SEC_MAX / factor))) {
+ priv->scan_interval_sec += (SCAN_INTERVAL_SEC_STEP / factor);
/* Ensure the scan interval will never be less than 20s... */
- priv->scan_interval = MAX(priv->scan_interval, SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP);
+ priv->scan_interval_sec = MAX(priv->scan_interval_sec, SCAN_INTERVAL_SEC_MIN + SCAN_INTERVAL_SEC_STEP);
/* ... or more than 120s */
- priv->scan_interval = MIN(priv->scan_interval, SCAN_INTERVAL_MAX);
- } else if (!backoff && (priv->scan_interval == 0)) {
+ priv->scan_interval_sec = MIN(priv->scan_interval_sec, SCAN_INTERVAL_SEC_MAX);
+ } else if (!backoff && (priv->scan_interval_sec == 0)) {
/* Invalid combination; would cause continual rescheduling of
* the scan and hog CPU. Reset to something minimally sane.
*/
- priv->scan_interval = 5;
+ priv->scan_interval_sec = 5;
}
_LOGD (LOGD_WIFI, "wifi-scan: scheduled in %d seconds (interval now %d seconds)",
- next_scan, priv->scan_interval);
+ next_scan, priv->scan_interval_sec);
}
}
-static void
-supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
- NMDeviceWifi *self)
-{
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- _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, TRUE);
-
- _requested_scan_set (self, FALSE);
-}
-
/****************************************************************************
* WPA Supplicant control stuff
*
@@ -1534,14 +1594,21 @@ ap_list_dump (gpointer user_data)
if (_LOGD_ENABLED (LOGD_WIFI_SCAN)) {
NMWifiAP *ap;
- gint32 now_s = nm_utils_get_monotonic_timestamp_sec ();
-
- _LOGD (LOGD_WIFI_SCAN, "APs: [now:%u last:%" G_GINT64_FORMAT " next:%u]",
- now_s,
- priv->last_scan / NM_UTILS_MSEC_PER_SEC,
+ gint64 now_msec = nm_utils_get_monotonic_timestamp_msec ();
+ char str_buf[100];
+
+ _LOGD (LOGD_WIFI_SCAN, "APs: [now:%u.%03u, last:%s, next:%u]",
+ (guint) (now_msec / NM_UTILS_MSEC_PER_SEC),
+ (guint) (now_msec % NM_UTILS_MSEC_PER_SEC),
+ priv->last_scan_msec > 0
+ ? nm_sprintf_buf (str_buf,
+ "%u.%03u",
+ (guint) (priv->last_scan_msec / NM_UTILS_MSEC_PER_SEC),
+ (guint) (priv->last_scan_msec % NM_UTILS_MSEC_PER_SEC))
+ : "-1",
priv->scheduled_scan_time);
c_list_for_each_entry (ap, &priv->aps_lst_head, aps_lst)
- _ap_dump (self, LOGL_DEBUG, ap, "dump", now_s);
+ _ap_dump (self, LOGL_DEBUG, ap, "dump", now_msec);
}
return G_SOURCE_REMOVE;
}
@@ -2091,7 +2158,7 @@ supplicant_iface_state (NMDeviceWifi *self,
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;
+ priv->scan_interval_sec = SCAN_INTERVAL_SEC_MIN;
}
/* In these states we know the supplicant is actually talking to something */
@@ -2204,19 +2271,6 @@ supplicant_iface_assoc_cb (NMSupplicantInterface *iface,
}
static void
-supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface,
- GParamSpec *pspec,
- NMDeviceWifi *self)
-{
- _notify_scanning (self);
-
- /* Run a quick update of current AP when coming out of a scan */
- if ( !NM_DEVICE_WIFI_GET_PRIVATE (self)->is_scanning
- && nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED)
- periodic_update (self);
-}
-
-static void
supplicant_iface_notify_current_bss (NMSupplicantInterface *iface,
GParamSpec *pspec,
NMDeviceWifi *self)
@@ -2874,8 +2928,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
supplicant_connection_timeout_cb,
self);
- if (!priv->periodic_source_id)
- priv->periodic_source_id = g_timeout_add_seconds (6, periodic_update_cb, self);
+ if (!priv->periodic_update_id)
+ priv->periodic_update_id = g_timeout_add_seconds (6, periodic_update_cb, self);
/* We'll get stage3 started when the supplicant connects */
return NM_ACT_STAGE_RETURN_POSTPONE;
@@ -3050,7 +3104,7 @@ activation_success_handler (NMDevice *device)
update_seen_bssids_cache (self, priv->current_ap);
/* Reset scan interval to something reasonable */
- priv->scan_interval = SCAN_INTERVAL_MIN + (SCAN_INTERVAL_STEP * 2);
+ priv->scan_interval_sec = SCAN_INTERVAL_SEC_MIN + (SCAN_INTERVAL_SEC_STEP * 2);
}
static void
@@ -3072,7 +3126,7 @@ device_state_changed (NMDevice *device,
*/
supplicant_interface_release (self);
- nm_clear_g_source (&priv->periodic_source_id);
+ nm_clear_g_source (&priv->periodic_update_id);
cleanup_association_attempt (self, TRUE);
cleanup_supplicant_failures (self);
@@ -3111,7 +3165,7 @@ device_state_changed (NMDevice *device,
break;
case NM_DEVICE_STATE_DISCONNECTED:
/* Kick off a scan to get latest results */
- priv->scan_interval = SCAN_INTERVAL_MIN;
+ priv->scan_interval_sec = SCAN_INTERVAL_SEC_MIN;
request_wireless_scan (self, FALSE, FALSE, NULL);
break;
default:
@@ -3266,13 +3320,13 @@ get_property (GObject *object, guint prop_id,
nm_dbus_utils_g_value_set_object_path (value, priv->current_ap);
break;
case PROP_SCANNING:
- g_value_set_boolean (value, priv->is_scanning);
+ g_value_set_boolean (value, nm_device_wifi_get_scanning (self));
break;
case PROP_LAST_SCAN:
g_value_set_int64 (value,
- priv->last_scan > 0
- ? nm_utils_monotonic_timestamp_as_boottime (priv->last_scan, NM_UTILS_NSEC_PER_MSEC)
- : (gint64) -1);
+ priv->last_scan_msec > 0
+ ? nm_utils_monotonic_timestamp_as_boottime (priv->last_scan_msec, NM_UTILS_NSEC_PER_MSEC)
+ : (gint64) -1);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -3306,6 +3360,7 @@ nm_device_wifi_init (NMDeviceWifi *self)
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
c_list_init (&priv->aps_lst_head);
+ c_list_init (&priv->scanning_prohibited_lst_head);
priv->aps_idx_by_supplicant_path = g_hash_table_new (nm_direct_hash, NULL);
priv->hidden_probe_scan_warn = TRUE;
@@ -3347,7 +3402,9 @@ dispose (GObject *object)
NMDeviceWifi *self = NM_DEVICE_WIFI (object);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- nm_clear_g_source (&priv->periodic_source_id);
+ nm_assert (c_list_is_empty (&priv->scanning_prohibited_lst_head));
+
+ nm_clear_g_source (&priv->periodic_update_id);
wifi_secrets_cancel (self);
@@ -3425,8 +3482,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
device_class->state_changed = device_state_changed;
- klass->scanning_prohibited = scanning_prohibited;
-
obj_properties[PROP_MODE] =
g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "",
NM_802_11_MODE_UNKNOWN,
@@ -3473,14 +3528,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
- signals[SCANNING_PROHIBITED] =
- g_signal_new (NM_DEVICE_WIFI_SCANNING_PROHIBITED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMDeviceWifiClass, scanning_prohibited),
- NULL, NULL, NULL,
- G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN);
-
signals[P2P_DEVICE_CREATED] =
g_signal_new (NM_DEVICE_WIFI_P2P_DEVICE_CREATED,
G_OBJECT_CLASS_TYPE (object_class),
diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h
index d861d24712..c9fce4e267 100644
--- a/src/devices/wifi/nm-device-wifi.h
+++ b/src/devices/wifi/nm-device-wifi.h
@@ -24,7 +24,6 @@
#define NM_DEVICE_WIFI_SCANNING "scanning"
#define NM_DEVICE_WIFI_LAST_SCAN "last-scan"
-#define NM_DEVICE_WIFI_SCANNING_PROHIBITED "scanning-prohibited"
#define NM_DEVICE_WIFI_P2P_DEVICE_CREATED "p2p-device-created"
typedef struct _NMDeviceWifi NMDeviceWifi;
@@ -42,4 +41,10 @@ void _nm_device_wifi_request_scan (NMDeviceWifi *self,
GPtrArray *nmtst_ssids_options_to_ptrarray (GVariant *value, GError **error);
+gboolean nm_device_wifi_get_scanning (NMDeviceWifi *self);
+
+void nm_device_wifi_scanning_prohibited_track (NMDeviceWifi *self,
+ gpointer tag,
+ gboolean temporarily_prohibited);
+
#endif /* __NETWORKMANAGER_DEVICE_WIFI_H__ */
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index 038d847807..e427c86fbd 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -503,13 +503,14 @@ const char *
nm_wifi_ap_to_string (const NMWifiAP *self,
char *str_buf,
gulong buf_len,
- gint32 now_s)
+ gint64 now_msec)
{
const NMWifiAPPrivate *priv;
const char *supplicant_id = "-";
const char *export_path;
guint32 chan;
gs_free char *ssid_to_free = NULL;
+ char str_buf_ts[100];
g_return_val_if_fail (NM_IS_WIFI_AP (self), NULL);
@@ -525,8 +526,10 @@ nm_wifi_ap_to_string (const NMWifiAP *self,
else
export_path = "/";
+ nm_utils_get_monotonic_timestamp_msec_cached (&now_msec);
+
g_snprintf (str_buf, buf_len,
- "%17s %-35s [ %c %3u %3u%% %c%c W:%04X R:%04X ] %3us sup:%s [nm:%s]",
+ "%17s %-35s [ %c %3u %3u%% %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]",
priv->address ?: "(none)",
(ssid_to_free = _nm_utils_ssid_to_string (priv->ssid)),
(priv->mode == NM_802_11_MODE_ADHOC
@@ -545,8 +548,11 @@ nm_wifi_ap_to_string (const NMWifiAP *self,
priv->wpa_flags & 0xFFFF,
priv->rsn_flags & 0xFFFF,
priv->last_seen_msec != G_MININT64
- ? (int) ((now_s > 0 ? now_s : nm_utils_get_monotonic_timestamp_sec ()) - (priv->last_seen_msec / 1000))
- : -1,
+ ? nm_sprintf_buf (str_buf_ts,
+ "%3u.%03us",
+ (guint) ((now_msec - priv->last_seen_msec) / 1000),
+ (guint) ((now_msec - priv->last_seen_msec) % 1000))
+ : " ",
supplicant_id,
export_path);
return str_buf;
diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h
index 2b3864a767..1bf4e604fd 100644
--- a/src/devices/wifi/nm-wifi-ap.h
+++ b/src/devices/wifi/nm-wifi-ap.h
@@ -94,7 +94,7 @@ gboolean nm_wifi_ap_get_metered (const NMWifiAP *self);
const char *nm_wifi_ap_to_string (const NMWifiAP *self,
char *str_buf,
gulong buf_len,
- gint32 now_s);
+ gint64 now_msec);
const char **nm_wifi_aps_get_paths (const CList *aps_lst_head,
gboolean include_without_ssid);
diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c
index 9725b983dd..cc3d109e35 100644
--- a/src/supplicant/nm-supplicant-interface.c
+++ b/src/supplicant/nm-supplicant-interface.c
@@ -59,7 +59,6 @@ enum {
STATE, /* change in the interface's state */
BSS_CHANGED, /* a new BSS appeared, was updated, or was removed. */
PEER_CHANGED, /* a new Peer appeared, was updated, or was removed */
- SCAN_DONE, /* wifi scan is complete */
WPS_CREDENTIALS, /* WPS credentials received */
GROUP_STARTED, /* a new Group (interface) was created */
GROUP_FINISHED, /* a Group (interface) has been finished */
@@ -141,11 +140,16 @@ typedef struct _NMSupplicantInterfacePrivate {
NMSupplicantInterfaceState state;
NMSupplicantInterfaceState supp_state;
- bool scanning:1;
+ bool scanning_property:1;
+ bool scanning_cached:1;
- bool p2p_capable:1;
+ bool p2p_capable_property:1;
+ bool p2p_capable_cached:1;
- bool p2p_group_is_owner:1;
+ bool p2p_group_owner_property:1;
+ bool p2p_group_owner_cached:1;
+
+ bool p2p_group_joined_cached:1;
bool is_ready_main:1;
bool is_ready_p2p_device:1;
@@ -433,11 +437,79 @@ _remove_network (NMSupplicantInterface *self)
/*****************************************************************************/
-static gboolean
-_prop_p2p_available_get (NMSupplicantInterfacePrivate *priv)
+static void
+_notify_maybe_scanning (NMSupplicantInterface *self)
{
- return priv->is_ready_p2p_device
- && priv->p2p_capable;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ gboolean scanning;
+
+ scanning = nm_supplicant_interface_state_is_operational (priv->state)
+ && ( priv->scanning_property
+ || priv->supp_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING);
+
+ if (priv->scanning_cached == scanning)
+ return;
+
+ if ( !scanning
+ && !c_list_is_empty (&priv->bss_initializing_lst_head)) {
+ /* we would change state to indicate we no longer scan. However,
+ * we still have BSS instances to be initialized. Delay the
+ * state change further. */
+ return;
+ }
+
+ _LOGT ("scanning: %s", scanning ? "yes" : "no");
+
+ if (!scanning)
+ priv->last_scan_msec = nm_utils_get_monotonic_timestamp_msec ();
+ else {
+ /* while we are scanning, we set the timestamp to -1. */
+ priv->last_scan_msec = -1;
+ }
+ priv->scanning_cached = scanning;
+ _notify (self, PROP_SCANNING);
+}
+
+static void
+_notify_maybe_p2p_available (NMSupplicantInterface *self)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ gboolean value;
+
+ value = priv->is_ready_p2p_device
+ && priv->p2p_capable_property;
+
+ if (priv->p2p_capable_cached == value)
+ return;
+
+ priv->p2p_capable_cached = value;
+ _notify (self, PROP_P2P_AVAILABLE);
+}
+
+static void
+_notify_maybe_p2p_group (NMSupplicantInterface *self)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ gboolean value_joined;
+ gboolean value_owner;
+ gboolean joined_changed;
+ gboolean owner_changed;
+
+ value_joined = priv->p2p_group_path
+ && !priv->p2p_group_properties_cancellable;
+ value_owner = value_joined
+ && priv->p2p_group_owner_property;
+
+ if ((joined_changed = (priv->p2p_group_joined_cached != value_joined)))
+ priv->p2p_group_joined_cached = value_joined;
+
+ if ((owner_changed = (priv->p2p_group_owner_cached != value_owner)))
+ priv->p2p_group_owner_cached = value_owner;
+
+ if (joined_changed)
+ _notify (self, PROP_P2P_GROUP_JOINED);
+ if (owner_changed)
+ _notify (self, PROP_P2P_GROUP_OWNER);
}
/*****************************************************************************/
@@ -457,6 +529,9 @@ _bss_info_changed_emit (NMSupplicantInterface *self,
NMSupplicantBssInfo *bss_info,
gboolean is_present)
{
+ _LOGT ("BSS %s %s",
+ bss_info->bss_path->str,
+ is_present ? "updated" : "deleted");
g_signal_emit (self,
signals[BSS_CHANGED],
0,
@@ -687,6 +762,8 @@ _bss_info_get_all_cb (GVariant *result,
_bss_info_properties_changed (self, bss_info, properties, TRUE);
_starting_check_ready (self);
+
+ _notify_maybe_scanning (self);
}
static void
@@ -1026,6 +1103,8 @@ set_state_down (NMSupplicantInterface *self,
_remove_network (self);
nm_clear_pointer (&priv->current_bss, nm_ref_string_unref);
+
+ _notify_maybe_scanning (self);
}
static void
@@ -1036,7 +1115,7 @@ set_state (NMSupplicantInterface *self, NMSupplicantInterfaceState new_state)
nm_assert (new_state > NM_SUPPLICANT_INTERFACE_STATE_STARTING);
nm_assert (new_state < NM_SUPPLICANT_INTERFACE_STATE_DOWN);
- nm_assert (NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (new_state));
+ nm_assert (nm_supplicant_interface_state_is_operational (new_state));
nm_assert (priv->state >= NM_SUPPLICANT_INTERFACE_STATE_STARTING);
nm_assert (priv->state < NM_SUPPLICANT_INTERFACE_STATE_DOWN);
@@ -1048,9 +1127,6 @@ set_state (NMSupplicantInterface *self, NMSupplicantInterfaceState new_state)
nm_supplicant_interface_state_to_string (new_state),
nm_supplicant_interface_state_to_string (priv->state));
- if (old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
- priv->last_scan_msec = nm_utils_get_monotonic_timestamp_msec ();
-
priv->state = new_state;
_emit_signal_state (self,
@@ -1069,35 +1145,20 @@ nm_supplicant_interface_get_current_bss (NMSupplicantInterface *self)
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->current_bss;
}
-static inline gboolean
-_prop_scanning_get (NMSupplicantInterfacePrivate *priv)
-{
- return ( priv->scanning
- || priv->supp_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
- && NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (priv->state);
-}
-
gboolean
nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
{
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
- return _prop_scanning_get (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self));
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->scanning_cached;
}
gint64
nm_supplicant_interface_get_last_scan (NMSupplicantInterface *self)
{
- NMSupplicantInterfacePrivate *priv;
-
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
- priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
- /* returns -1 if we are currently scanning. */
- return _prop_scanning_get (priv)
- ? -1
- : priv->last_scan_msec;
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->last_scan_msec;
}
#define MATCH_PROPERTY(p, n, v, t) (!strcmp (p, n) && g_variant_is_of_type (v, t))
@@ -1129,7 +1190,7 @@ parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities)
/* Setting p2p_capable might toggle _prop_p2p_available_get(). However,
* we don't need to check for a property changed notification, because
* the caller did g_object_freeze_notify() and will perform the check. */
- priv->p2p_capable = g_strv_contains (array, "p2p");
+ priv->p2p_capable_property = g_strv_contains (array, "p2p");
g_free (array);
}
@@ -1176,7 +1237,7 @@ _starting_check_ready (NMSupplicantInterface *self)
nm_assert (priv->state == NM_SUPPLICANT_INTERFACE_STATE_STARTING);
- if (!NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (priv->supp_state)) {
+ if (!nm_supplicant_interface_state_is_operational (priv->supp_state)) {
_LOGW ("Supplicant state is unknown during initialization. Destroy the interface");
set_state_down (self, TRUE, "failure to get valid interface state");
return;
@@ -1264,37 +1325,19 @@ nm_supplicant_interface_get_auth_state (NMSupplicantInterface *self)
/*****************************************************************************/
-static gboolean
-_prop_p2p_group_joined_get (NMSupplicantInterfacePrivate *priv)
-{
- return priv->p2p_group_path
- && !priv->p2p_group_properties_cancellable;
-}
-
-static gboolean
-_prop_p2p_group_is_owner_get (NMSupplicantInterfacePrivate *priv)
-{
- return _prop_p2p_group_joined_get (priv)
- && priv->p2p_group_is_owner;
-}
-
static void
_p2p_group_properties_changed (NMSupplicantInterface *self,
GVariant *properties)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- gboolean old_val_p2p_group_is_owner;
const char *s;
- old_val_p2p_group_is_owner = _prop_p2p_group_is_owner_get (priv);
-
if (!properties)
- priv->p2p_group_is_owner = FALSE;
+ priv->p2p_group_owner_property = FALSE;
else if (g_variant_lookup (properties, "Role", "&s", &s))
- priv->p2p_group_is_owner = nm_streq (s, "GO");
+ priv->p2p_group_owner_property = nm_streq (s, "GO");
- if (old_val_p2p_group_is_owner != _prop_p2p_group_is_owner_get (priv))
- _notify (self, PROP_P2P_GROUP_OWNER);
+ _notify_maybe_p2p_group (self);
}
static void
@@ -1331,8 +1374,6 @@ _p2p_group_properties_get_all_cb (GVariant *result,
{
NMSupplicantInterface *self;
NMSupplicantInterfacePrivate *priv;
- gboolean old_val_p2p_group_joined;
- gboolean old_val_p2p_group_is_owner;
gs_unref_variant GVariant *properties = NULL;
if (nm_utils_error_is_cancelled (error))
@@ -1343,9 +1384,6 @@ _p2p_group_properties_get_all_cb (GVariant *result,
g_object_freeze_notify (G_OBJECT (self));
- old_val_p2p_group_joined = _prop_p2p_group_joined_get (priv);
- old_val_p2p_group_is_owner = _prop_p2p_group_is_owner_get (priv);
-
nm_clear_g_cancellable (&priv->p2p_group_properties_cancellable);
if (result)
@@ -1355,10 +1393,7 @@ _p2p_group_properties_get_all_cb (GVariant *result,
_starting_check_ready (self);
- if (old_val_p2p_group_joined != _prop_p2p_group_joined_get (priv))
- _notify (self, PROP_P2P_GROUP_JOINED);
- if (old_val_p2p_group_is_owner != _prop_p2p_group_is_owner_get (priv))
- _notify (self, PROP_P2P_GROUP_OWNER);
+ _notify_maybe_p2p_group (self);
g_object_thaw_notify (G_OBJECT (self));
}
@@ -1369,17 +1404,12 @@ _p2p_group_set_path (NMSupplicantInterface *self,
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
nm_auto_ref_string NMRefString *group_path = NULL;
- gboolean old_val_p2p_group_joined;
- gboolean old_val_p2p_group_is_owner;
group_path = nm_ref_string_new (nm_dbus_path_not_empty (path));
if (priv->p2p_group_path == group_path)
return;
- old_val_p2p_group_joined = _prop_p2p_group_joined_get (priv);
- old_val_p2p_group_is_owner = _prop_p2p_group_is_owner_get (priv);
-
nm_clear_g_dbus_connection_signal (priv->dbus_connection,
&priv->p2p_group_properties_changed_id);
nm_clear_g_cancellable (&priv->p2p_group_properties_cancellable);
@@ -1407,10 +1437,7 @@ _p2p_group_set_path (NMSupplicantInterface *self,
}
_notify (self, PROP_P2P_GROUP_PATH);
- if (old_val_p2p_group_joined != _prop_p2p_group_joined_get (priv))
- _notify (self, PROP_P2P_GROUP_JOINED);
- if (old_val_p2p_group_is_owner != _prop_p2p_group_is_owner_get (priv))
- _notify (self, PROP_P2P_GROUP_OWNER);
+ _notify_maybe_p2p_group (self);
nm_assert_starting_has_pending_count (priv->starting_pending_count);
}
@@ -1762,13 +1789,8 @@ _properties_changed_main (NMSupplicantInterface *self,
g_variant_unref (v_v);
}
- if (nm_g_variant_lookup (properties, "Scanning", "b", &v_b)) {
- if (priv->scanning != (!!v_b)) {
- if (priv->scanning)
- priv->last_scan_msec = nm_utils_get_monotonic_timestamp_msec ();
- priv->scanning = v_b;
- }
- }
+ if (nm_g_variant_lookup (properties, "Scanning", "b", &v_b))
+ priv->scanning_property = v_b;
if (nm_g_variant_lookup (properties, "Ifname", "&s", &v_s)) {
if (nm_utils_strdup_reset (&priv->ifname, v_s))
@@ -1855,6 +1877,8 @@ _properties_changed_main (NMSupplicantInterface *self,
if (do_set_state)
set_state (self, priv->supp_state);
+
+ _notify_maybe_scanning (self);
}
static void
@@ -2318,12 +2342,13 @@ scan_request_cb (GObject *source, GAsyncResult *result, gpointer user_data)
self = NM_SUPPLICANT_INTERFACE (user_data);
if (error) {
if (_nm_dbus_error_has_name (error, "fi.w1.wpa_supplicant1.Interface.ScanError"))
- _LOGD ("could not get scan request result: %s", error->message);
+ _LOGD ("request-scan: could not get scan request result: %s", error->message);
else {
g_dbus_error_strip_remote_error (error);
- _LOGW ("could not get scan request result: %s", error->message);
+ _LOGW ("request-scan: could not get scan request result: %s", error->message);
}
- }
+ } else
+ _LOGT ("request-scan: request scanning success");
}
void
@@ -2339,7 +2364,8 @@ nm_supplicant_interface_request_scan (NMSupplicantInterface *self,
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- /* Scan parameters */
+ _LOGT ("request-scan: request scanning (%u ssids)...", ssids_len);
+
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&builder, "{sv}", "Type", g_variant_new_string ("active"));
g_variant_builder_add (&builder, "{sv}", "AllowRoam", g_variant_new_boolean (FALSE));
@@ -2518,8 +2544,6 @@ _properties_changed (NMSupplicantInterface *self,
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
gboolean is_main;
- gboolean old_val_scanning;
- gboolean old_val_p2p_available;
nm_assert (!properties || g_variant_is_of_type (properties, G_VARIANT_TYPE ("a{sv}")));
@@ -2540,9 +2564,6 @@ _properties_changed (NMSupplicantInterface *self,
priv->starting_pending_count++;
- old_val_scanning = _prop_scanning_get (priv);
- old_val_p2p_available = _prop_p2p_available_get (priv);
-
if (is_main) {
priv->is_ready_main = TRUE;
_properties_changed_main (self, properties);
@@ -2554,10 +2575,8 @@ _properties_changed (NMSupplicantInterface *self,
priv->starting_pending_count--;
_starting_check_ready (self);
- if (old_val_scanning != _prop_scanning_get (priv))
- _notify (self, PROP_SCANNING);
- if (old_val_p2p_available != _prop_p2p_available_get (priv))
- _notify (self, PROP_P2P_AVAILABLE);
+ _notify_maybe_scanning (self);
+ _notify_maybe_p2p_available (self);
g_object_thaw_notify (G_OBJECT (self));
}
@@ -2707,16 +2726,6 @@ _signal_handle (NMSupplicantInterface *self,
if (!priv->is_ready_main)
return;
- if (nm_streq (signal_name, "ScanDone")) {
- priv->last_scan_msec = nm_utils_get_monotonic_timestamp_msec ();
- _LOGT ("ScanDone signal received");
- if (priv->state > NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
- nm_assert (priv->state < NM_SUPPLICANT_INTERFACE_STATE_DOWN);
- g_signal_emit (self, signals[SCAN_DONE], 0);
- }
- return;
- }
-
if (nm_streq (signal_name, "BSSAdded")) {
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oa{sv})")))
return;
@@ -2864,11 +2873,11 @@ _signal_cb (GDBusConnection *connection,
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
priv->starting_pending_count++;
-
_signal_handle (self, signal_interface_name, signal_name, parameters);
-
priv->starting_pending_count--;
_starting_check_ready (self);
+
+ _notify_maybe_scanning (self);
}
/*****************************************************************************/
@@ -2876,13 +2885,13 @@ _signal_cb (GDBusConnection *connection,
gboolean
nm_supplicant_interface_get_p2p_available (NMSupplicantInterface *self)
{
- return _prop_p2p_available_get (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self));
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->p2p_capable_cached;
}
gboolean
nm_supplicant_interface_get_p2p_group_joined (NMSupplicantInterface *self)
{
- return _prop_p2p_group_joined_get (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self));
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->p2p_group_joined_cached;
}
const char*
@@ -2894,7 +2903,7 @@ nm_supplicant_interface_get_p2p_group_path (NMSupplicantInterface *self)
gboolean
nm_supplicant_interface_get_p2p_group_owner (NMSupplicantInterface *self)
{
- return _prop_p2p_group_is_owner_get (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self));
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->p2p_group_owner_cached;
}
/*****************************************************************************/
@@ -2993,6 +3002,7 @@ nm_supplicant_interface_init (NMSupplicantInterface * self)
priv->state = NM_SUPPLICANT_INTERFACE_STATE_STARTING;
priv->supp_state = NM_SUPPLICANT_INTERFACE_STATE_INVALID;
+ priv->last_scan_msec = -1;
c_list_init (&self->supp_lst);
@@ -3288,14 +3298,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN);
- signals[SCAN_DONE] =
- g_signal_new (NM_SUPPLICANT_INTERFACE_SCAN_DONE,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
signals[WPS_CREDENTIALS] =
g_signal_new (NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS,
G_OBJECT_CLASS_TYPE (object_class),
diff --git a/src/supplicant/nm-supplicant-interface.h b/src/supplicant/nm-supplicant-interface.h
index 8964a4754f..eb414f26f5 100644
--- a/src/supplicant/nm-supplicant-interface.h
+++ b/src/supplicant/nm-supplicant-interface.h
@@ -35,12 +35,19 @@ typedef enum {
} NMSupplicantInterfaceState;
static inline gboolean
-NM_SUPPLICANT_INTERFACE_STATE_IS_OPERATIONAL (NMSupplicantInterfaceState state)
+nm_supplicant_interface_state_is_operational (NMSupplicantInterfaceState state)
{
return state > NM_SUPPLICANT_INTERFACE_STATE_STARTING
&& state < NM_SUPPLICANT_INTERFACE_STATE_DOWN;
}
+static inline gboolean
+nm_supplicant_interface_state_is_associated (NMSupplicantInterfaceState state)
+{
+ return state >= NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING
+ && state <= NM_SUPPLICANT_INTERFACE_STATE_COMPLETED;
+}
+
typedef enum {
NM_SUPPLICANT_AUTH_STATE_UNKNOWN,
NM_SUPPLICANT_AUTH_STATE_STARTED,
@@ -71,7 +78,6 @@ typedef enum {
#define NM_SUPPLICANT_INTERFACE_STATE "state"
#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"
#define NM_SUPPLICANT_INTERFACE_GROUP_FINISHED "group-finished"