diff --git a/clients/cloud-setup/main.c b/clients/cloud-setup/main.c index d46c88e424..4e1a9a4e4e 100644 --- a/clients/cloud-setup/main.c +++ b/clients/cloud-setup/main.c @@ -31,7 +31,7 @@ _provider_detect_cb (GObject *source, nm_assert (success != (!!error)); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; dd = user_data; @@ -219,7 +219,7 @@ _get_config_cb (GObject *source, config_dict = nmcs_provider_get_config_finish (NMCS_PROVIDER (source), result, &error); if (!config_dict) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) _LOGI ("failure to get meta data: %s", error->message); } else _LOGD ("meta data received"); @@ -426,7 +426,7 @@ try_again: &applied_version_id, &error); if (!applied_connection) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) _LOGD ("config device %s: device has no applied connection (%s). Skip", hwaddr, error->message); return any_changes; } @@ -477,7 +477,7 @@ try_again: goto try_again; } - if (!nm_utils_error_is_cancelled (error, FALSE)) { + if (!nm_utils_error_is_cancelled (error)) { _LOGD ("config device %s: failure to reapply connection \"%s\" (%s): %s", hwaddr, nm_connection_get_id (applied_connection), @@ -576,7 +576,7 @@ main (int argc, const char *const*argv) nmcs_wait_for_objects_register (nm_client_get_context_busy_watcher (nmc)); if (error) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) _LOGI ("failure to talk to NetworkManager: %s", error->message); goto done; } diff --git a/clients/cloud-setup/nm-cloud-setup-utils.c b/clients/cloud-setup/nm-cloud-setup-utils.c index 872ab44d3a..13c9566a8b 100644 --- a/clients/cloud-setup/nm-cloud-setup-utils.c +++ b/clients/cloud-setup/nm-cloud-setup-utils.c @@ -49,7 +49,7 @@ _nm_log_impl_cs (NMLogLevel level, break; } - ts = nm_utils_clock_gettime_ns (CLOCK_BOOTTIME); + ts = nm_utils_clock_gettime_nsec (CLOCK_BOOTTIME); g_print ("[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s %s\n", ts / NM_UTILS_NSEC_PER_SEC, @@ -294,7 +294,7 @@ _poll_done_cb (GObject *source, poll_task_data->probe_user_data, &error); - if (nm_utils_error_is_cancelled (error, FALSE)) { + if (nm_utils_error_is_cancelled (error)) { /* we already handle this differently. Nothing to do. */ return; } diff --git a/clients/cloud-setup/nm-http-client.c b/clients/cloud-setup/nm-http-client.c index 35f41fe775..94f3fe2b8a 100644 --- a/clients/cloud-setup/nm-http-client.c +++ b/clients/cloud-setup/nm-http-client.c @@ -163,7 +163,7 @@ _ehandle_complete (EHandleData *edata, &edata->cancellable_id); if (error_take) { - if (nm_utils_error_is_cancelled (error_take, FALSE)) + if (nm_utils_error_is_cancelled (error_take)) _LOG2T (edata, "cancelled"); else _LOG2D (edata, "failed with %s", error_take->message); @@ -422,7 +422,7 @@ _poll_get_probe_finish_fcn (GObject *source, &local_error); if (!success) { - if (nm_utils_error_is_cancelled (local_error, FALSE)) { + if (nm_utils_error_is_cancelled (local_error)) { g_propagate_error (error, g_steal_pointer (&local_error)); return TRUE; } diff --git a/clients/cloud-setup/nmcs-provider-ec2.c b/clients/cloud-setup/nmcs-provider-ec2.c index b6ac5a4c95..82ed094970 100644 --- a/clients/cloud-setup/nmcs-provider-ec2.c +++ b/clients/cloud-setup/nmcs-provider-ec2.c @@ -98,7 +98,7 @@ _detect_get_meta_data_done_cb (GObject *source, NULL, &get_error); - if (nm_utils_error_is_cancelled (get_error, FALSE)) { + if (nm_utils_error_is_cancelled (get_error)) { g_task_return_error (task, g_steal_pointer (&get_error)); return; } @@ -168,7 +168,7 @@ _get_config_task_return (GetConfigIfaceData *iface_data, nm_g_slice_free (iface_data); if (error_take) { - if (nm_utils_error_is_cancelled (error_take, FALSE)) + if (nm_utils_error_is_cancelled (error_take)) _LOGD ("get-config: cancelled"); else _LOGD ("get-config: failed: %s", error_take->message); @@ -204,7 +204,7 @@ _get_config_fetch_done_cb (NMHttpClient *http_client, NULL, &response_data, &error); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; get_config_data = iface_data->get_config_data; @@ -327,7 +327,7 @@ _get_config_metadata_ready_cb (GObject *source, .n_pending = 0, }; - if (nm_utils_error_is_cancelled (error, FALSE)) { + if (nm_utils_error_is_cancelled (error)) { _get_config_task_return (iface_data, g_steal_pointer (&error)); return; } diff --git a/clients/common/nm-polkit-listener.c b/clients/common/nm-polkit-listener.c index 58684015c5..9ecc92a688 100644 --- a/clients/common/nm-polkit-listener.c +++ b/clients/common/nm-polkit-listener.c @@ -233,7 +233,7 @@ agent_register_cb (GObject *source_object, res, &error); - if (nm_utils_error_is_cancelled (error, FALSE)) { + if (nm_utils_error_is_cancelled (error)) { return; } @@ -328,7 +328,7 @@ retrieve_session_id_cb (GObject *source_object, res, &error); - if (nm_utils_error_is_cancelled (error, FALSE)) { + if (nm_utils_error_is_cancelled (error)) { return; } diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 3fb067e046..f97e20c1c9 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -5846,7 +5846,7 @@ nm_utils_get_timestamp_msec (void) { gint64 ts; - ts = nm_utils_clock_gettime_ms (CLOCK_BOOTTIME); + ts = nm_utils_clock_gettime_msec (CLOCK_BOOTTIME); if (ts >= 0) return ts; @@ -5855,7 +5855,7 @@ nm_utils_get_timestamp_msec (void) * criminally old kernel, prior to 2.6.39 (released on 18 May, 2011). * That happens during buildcheck on old builders, we don't expect to * be actually runs on kernels that old. */ - ts = nm_utils_clock_gettime_ms (CLOCK_MONOTONIC); + ts = nm_utils_clock_gettime_msec (CLOCK_MONOTONIC); if (ts >= 0) return ts; } diff --git a/libnm/nm-client.c b/libnm/nm-client.c index a93a81c353..86160b0662 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -3142,7 +3142,7 @@ _dbus_get_managed_objects_cb (GObject *source, nm_assert ((!!ret) != (!!error)); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; priv = NM_CLIENT_GET_PRIVATE (self); @@ -3193,7 +3193,7 @@ _nm_client_get_settings_call_cb (GObject *source, GAsyncResult *result, gpointer ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; remote_connection = user_data; @@ -3432,7 +3432,7 @@ _dbus_check_permissions_start_cb (GObject *source, GAsyncResult *result, gpointe ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; self = user_data; @@ -4865,7 +4865,7 @@ activate_connection_cb (GObject *object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -5003,7 +5003,7 @@ _add_and_activate_connection_done (GObject *object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -5526,7 +5526,7 @@ _add_connection_cb (GObject *source, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -6268,7 +6268,7 @@ checkpoint_create_cb (GObject *object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -6942,7 +6942,7 @@ name_owner_get_cb (GObject *source, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; priv = NM_CLIENT_GET_PRIVATE (self); diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c index f04a7419f5..7b4db11ef3 100644 --- a/libnm/nm-libnm-utils.c +++ b/libnm/nm-libnm-utils.c @@ -89,7 +89,7 @@ _nml_dbus_log (NMLDBusLogLevel level, break; } - ts = nm_utils_clock_gettime_ns (CLOCK_BOOTTIME); + ts = nm_utils_clock_gettime_nsec (CLOCK_BOOTTIME); g_printerr ("libnm-dbus: %s[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s\n", prefix, diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c index eb653327d0..f102ecc752 100644 --- a/libnm/nm-secret-agent-old.c +++ b/libnm/nm-secret-agent-old.c @@ -1148,7 +1148,7 @@ _register_call_cb (GObject *source, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; nm_assert (!priv->registering_retry_source); @@ -1229,7 +1229,7 @@ _get_connection_unix_user_cb (GObject *source, guint32 sender_uid = 0; ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; self = user_data; @@ -1324,7 +1324,7 @@ _name_owner_get_cb (const char *name_owner, gpointer user_data) { if ( name_owner - || !nm_utils_error_is_cancelled (error, FALSE)) + || !nm_utils_error_is_cancelled (error)) _name_owner_changed (user_data, name_owner, FALSE); } diff --git a/shared/nm-glib-aux/nm-dbus-aux.c b/shared/nm-glib-aux/nm-dbus-aux.c index faf54e8bbc..7c55b5a750 100644 --- a/shared/nm-glib-aux/nm-dbus-aux.c +++ b/shared/nm-glib-aux/nm-dbus-aux.c @@ -56,7 +56,7 @@ nm_dbus_connection_call_get_name_owner (GDBusConnection *dbus_connection, /*****************************************************************************/ static void -_nm_dbus_connection_call_get_all_cb (GObject *source, +_nm_dbus_connection_call_default_cb (GObject *source, GAsyncResult *res, gpointer user_data) { @@ -96,10 +96,40 @@ nm_dbus_connection_call_get_all (GDBusConnection *dbus_connection, G_DBUS_CALL_FLAGS_NONE, timeout_msec, cancellable, - _nm_dbus_connection_call_get_all_cb, + _nm_dbus_connection_call_default_cb, nm_utils_user_data_pack (user_data, callback)); } +void nm_dbus_connection_call_set (GDBusConnection *dbus_connection, + const char *bus_name, + const char *object_path, + const char *interface_name, + const char *property_name, + GVariant *value, + int timeout_msec, + GCancellable *cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data) +{ + nm_assert (callback); + + g_dbus_connection_call (dbus_connection, + bus_name, + object_path, + DBUS_INTERFACE_PROPERTIES, + "Set", + g_variant_new ("(ssv)", + interface_name, + property_name, + value), + G_VARIANT_TYPE ("()"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec, + cancellable, + callback ? _nm_dbus_connection_call_default_cb : NULL, + callback ? nm_utils_user_data_pack (user_data, callback) : NULL); +} + /*****************************************************************************/ static void diff --git a/shared/nm-glib-aux/nm-dbus-aux.h b/shared/nm-glib-aux/nm-dbus-aux.h index 8ff14adc88..fcf394d1fe 100644 --- a/shared/nm-glib-aux/nm-dbus-aux.h +++ b/shared/nm-glib-aux/nm-dbus-aux.h @@ -128,6 +128,17 @@ void nm_dbus_connection_call_get_all (GDBusConnection *dbus_connection, NMDBusConnectionCallDefaultCb callback, gpointer user_data); +void nm_dbus_connection_call_set (GDBusConnection *dbus_connection, + const char *bus_name, + const char *object_path, + const char *interface_name, + const char *property_name, + GVariant *value, + int timeout_msec, + GCancellable *cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data); + /*****************************************************************************/ static inline guint diff --git a/shared/nm-glib-aux/nm-macros-internal.h b/shared/nm-glib-aux/nm-macros-internal.h index 65f2390edf..bce080579c 100644 --- a/shared/nm-glib-aux/nm-macros-internal.h +++ b/shared/nm-glib-aux/nm-macros-internal.h @@ -993,6 +993,7 @@ nm_str_realloc (char *str) (cond) ? (str) : (str_else), \ (cond) ? (suffix) : "" #define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)") +#define NM_PRINT_FMT_QUOTE_REF_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg)->str, "\"", "(null)") /*****************************************************************************/ @@ -1078,9 +1079,9 @@ NM_GOBJECT_PROPERTIES_DEFINE_NOTIFY (obj_type, obj_properties, _PropertyEnums, P #if _NM_CC_SUPPORT_AUTO_TYPE #define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \ ({ \ - _nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \ + _nm_auto_type _self_get_private = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \ \ - NM_PROPAGATE_CONST (_self, _self->_priv); \ + NM_PROPAGATE_CONST (_self_get_private, _self_get_private->_priv); \ }) #else #define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv) @@ -1428,6 +1429,14 @@ fcn_name (lookup_type val) \ : _flags & (~_val); \ }) +#define NM_FLAGS_ASSIGN_MASK(flags, mask, val) ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _mask = (mask); \ + const typeof(flags) _val = (val); \ + \ + ((_flags & ~_mask) | (_mask & _val)); \ + }) + /*****************************************************************************/ #define _NM_BACKPORT_SYMBOL_IMPL(version, return_type, orig_func, versioned_func, args_typed, args) \ diff --git a/shared/nm-glib-aux/nm-ref-string.h b/shared/nm-glib-aux/nm-ref-string.h index c80b75eab9..a71d27db3f 100644 --- a/shared/nm-glib-aux/nm-ref-string.h +++ b/shared/nm-glib-aux/nm-ref-string.h @@ -49,6 +49,18 @@ nm_ref_string_get_len (NMRefString *rstr) return rstr ? rstr->len : 0u; } +static inline gboolean +nm_ref_string_equals_str (NMRefString *rstr, const char *s) +{ + /* Note that rstr->len might be greater than strlen(rstr->str). This function does + * not cover that and would ignore everything after the first NUL byte. If you need + * that distinction, this function is not for you. */ + + return rstr + ? nm_streq (rstr->str, s) + : (s == NULL); +} + static inline gboolean NM_IS_REF_STRING (const NMRefString *rstr) { diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 44079dcf3a..74577c9c53 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -1643,16 +1643,13 @@ nm_utils_error_set_cancelled (GError **error, } gboolean -nm_utils_error_is_cancelled (GError *error, - gboolean consider_is_disposing) +nm_utils_error_is_cancelled_or_disposing (GError *error) { if (error) { if (error->domain == G_IO_ERROR) return NM_IN_SET (error->code, G_IO_ERROR_CANCELLED); - if (consider_is_disposing) { - if (error->domain == NM_UTILS_ERROR) - return NM_IN_SET (error->code, NM_UTILS_ERROR_CANCELLED_DISPOSING); - } + if (error->domain == NM_UTILS_ERROR) + return NM_IN_SET (error->code, NM_UTILS_ERROR_CANCELLED_DISPOSING); } return FALSE; } diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index ebb526152a..9f75c7f811 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -883,8 +883,15 @@ nm_utils_error_new_cancelled (gboolean is_disposing, return error; } -gboolean nm_utils_error_is_cancelled (GError *error, - gboolean consider_is_disposing); +gboolean nm_utils_error_is_cancelled_or_disposing (GError *error); + +static inline gboolean +nm_utils_error_is_cancelled (GError *error) +{ + return error + && error->code == G_IO_ERROR_CANCELLED + && error->domain == G_IO_ERROR; +} gboolean nm_utils_error_is_notfound (GError *error); @@ -1044,6 +1051,24 @@ nm_g_variant_unref_floating (GVariant *var) g_variant_unref (var); } +#define nm_g_variant_lookup(dictionary, ...) \ + ({ \ + GVariant *const _dictionary = (dictionary); \ + \ + ( _dictionary \ + && g_variant_lookup (_dictionary, __VA_ARGS__)); \ + }) + +static inline GVariant * +nm_g_variant_lookup_value (GVariant *dictionary, + const char *key, + const GVariantType *expected_type) +{ + return dictionary + ? g_variant_lookup_value (dictionary, key, expected_type) + : NULL; +} + static inline void nm_g_source_destroy_and_unref (GSource *source) { @@ -1321,18 +1346,6 @@ int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll) /*****************************************************************************/ -static inline const char * -nm_utils_dbus_normalize_object_path (const char *path) -{ - /* D-Bus does not allow an empty object path. Hence, whenever we mean NULL / no-object - * on D-Bus, it's path is actually "/". - * - * Normalize that away, and return %NULL in that case. */ - if (path && path[0] == '/' && path[1] == '\0') - return NULL; - return path; -} - #define NM_DEFINE_GDBUS_ARG_INFO_FULL(name_, ...) \ ((GDBusArgInfo *) (&((const GDBusArgInfo) { \ .ref_count = -1, \ @@ -1530,6 +1543,56 @@ guint8 *nm_utils_hexstr2bin_alloc (const char *hexstr, /*****************************************************************************/ +#define _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(scope, fcn_name, result_type, unknown_val, ...) \ +scope result_type \ +fcn_name (const char *name) \ +{ \ + static const struct { \ + const char *name; \ + result_type value; \ + } LIST[] = { \ + __VA_ARGS__ \ + }; \ + gssize idx; \ + \ + nm_assert (name); \ + \ + if (NM_MORE_ASSERTS > 5) { \ + static gboolean checked = FALSE; \ + int i; \ + \ + G_STATIC_ASSERT (G_N_ELEMENTS (LIST) > 1); \ + \ + if (!checked) { \ + checked = TRUE; \ + \ + for (i = 0; i < G_N_ELEMENTS (LIST); i++) { \ + nm_assert (LIST[i].name); \ + if (i > 0) \ + nm_assert (strcmp (LIST[i - 1].name, LIST[i].name) < 0); \ + } \ + } \ + } \ + \ + idx = nm_utils_array_find_binary_search (LIST, \ + sizeof (LIST[0]), \ + G_N_ELEMENTS (LIST), \ + &name, \ + nm_strcmp_p_with_data, \ + NULL); \ + if (idx >= 0) \ + return LIST[idx].value; \ + \ + { unknown_val; } \ +} + +#define NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(fcn_name, lookup_type, unknown_val, ...) \ + _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (, fcn_name, lookup_type, unknown_val, __VA_ARGS__) +#define NM_UTILS_STRING_TABLE_LOOKUP_DEFINE_STATIC(fcn_name, lookup_type, unknown_val, ...) \ + _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (static, fcn_name, lookup_type, unknown_val, __VA_ARGS__) + +/*****************************************************************************/ + static inline GTask * nm_g_task_new (gpointer source_object, GCancellable *cancellable, @@ -1558,4 +1621,18 @@ guint nm_utils_parse_debug_string (const char *string, const GDebugKey *keys, guint nkeys); +/*****************************************************************************/ + +static inline gboolean +nm_utils_strdup_reset (char **dst, const char *src) +{ + nm_assert (dst); + + if (nm_streq0 (*dst, src)) + return FALSE; + g_free (*dst); + *dst = g_strdup (src); + return TRUE; +} + #endif /* __NM_SHARED_UTILS_H__ */ diff --git a/shared/nm-glib-aux/nm-time-utils.c b/shared/nm-glib-aux/nm-time-utils.c index 6afaf05aa3..356ed1a5dc 100644 --- a/shared/nm-glib-aux/nm-time-utils.c +++ b/shared/nm-glib-aux/nm-time-utils.c @@ -312,21 +312,21 @@ nm_utils_monotonic_timestamp_from_boottime (guint64 boottime, gint64 timestamp_n } gint64 -nm_utils_clock_gettime_ns (clockid_t clockid) +nm_utils_clock_gettime_nsec (clockid_t clockid) { struct timespec tp; if (clock_gettime (clockid, &tp) != 0) return -NM_ERRNO_NATIVE (errno); - return nm_utils_timespec_to_ns (&tp); + return nm_utils_timespec_to_nsec (&tp); } gint64 -nm_utils_clock_gettime_ms (clockid_t clockid) +nm_utils_clock_gettime_msec (clockid_t clockid) { struct timespec tp; if (clock_gettime (clockid, &tp) != 0) return -NM_ERRNO_NATIVE (errno); - return nm_utils_timespec_to_ms (&tp); + return nm_utils_timespec_to_msec (&tp); } diff --git a/shared/nm-glib-aux/nm-time-utils.h b/shared/nm-glib-aux/nm-time-utils.h index fe48be0aed..190d949127 100644 --- a/shared/nm-glib-aux/nm-time-utils.h +++ b/shared/nm-glib-aux/nm-time-utils.h @@ -9,14 +9,14 @@ #include static inline gint64 -nm_utils_timespec_to_ns (const struct timespec *ts) +nm_utils_timespec_to_nsec (const struct timespec *ts) { return (((gint64) ts->tv_sec) * ((gint64) NM_UTILS_NSEC_PER_SEC)) + ((gint64) ts->tv_nsec); } static inline gint64 -nm_utils_timespec_to_ms (const struct timespec *ts) +nm_utils_timespec_to_msec (const struct timespec *ts) { return (((gint64) ts->tv_sec) * ((gint64) 1000)) + (((gint64) ts->tv_nsec) / ((gint64) NM_UTILS_NSEC_PER_SEC / 1000)); @@ -26,17 +26,25 @@ gint64 nm_utils_get_monotonic_timestamp_nsec (void); gint64 nm_utils_get_monotonic_timestamp_usec (void); gint64 nm_utils_get_monotonic_timestamp_msec (void); gint32 nm_utils_get_monotonic_timestamp_sec (void); + gint64 nm_utils_monotonic_timestamp_as_boottime (gint64 timestamp, gint64 timestamp_ticks_per_nsec); gint64 nm_utils_monotonic_timestamp_from_boottime (guint64 boottime, gint64 timestamp_nsec_per_tick); static inline gint64 -nm_utils_get_monotonic_timestamp_ns_cached (gint64 *cache_now) +nm_utils_get_monotonic_timestamp_nsec_cached (gint64 *cache_now) { return (*cache_now) ?: (*cache_now = nm_utils_get_monotonic_timestamp_nsec ()); } -gint64 nm_utils_clock_gettime_ns (clockid_t clockid); -gint64 nm_utils_clock_gettime_ms (clockid_t clockid); +static inline gint64 +nm_utils_get_monotonic_timestamp_msec_cached (gint64 *cache_now) +{ + return (*cache_now) + ?: (*cache_now = nm_utils_get_monotonic_timestamp_msec ()); +} + +gint64 nm_utils_clock_gettime_nsec (clockid_t clockid); +gint64 nm_utils_clock_gettime_msec (clockid_t clockid); #endif /* __NM_TIME_UTILS_H__ */ diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h index fc7025bf8e..adf2ba1b35 100644 --- a/shared/nm-utils/nm-test-utils.h +++ b/shared/nm-utils/nm-test-utils.h @@ -848,6 +848,15 @@ nmtst_get_rand_uint32 (void) return g_rand_int (nmtst_get_rand ()); } +static inline guint64 +nmtst_get_rand_uint64 (void) +{ + GRand *rand = nmtst_get_rand (); + + return (((guint64) g_rand_int (rand)) ) + | (((guint64) g_rand_int (rand)) << 32); +} + static inline guint nmtst_get_rand_uint (void) { diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index 84b8c28e88..c24f1306f8 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -1089,7 +1089,7 @@ _network_server_register_cb (GObject *source_object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; bzobj = user_data; @@ -2172,7 +2172,7 @@ _dbus_get_managed_objects_cb (GVariant *result, GVariant *ifaces; if ( !result - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; self = user_data; @@ -2475,7 +2475,7 @@ _connect_dun_step2_cb (NMBluez5DunContext *context, { BzDBusObj *bzobj; - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; bzobj = user_data; @@ -2517,7 +2517,7 @@ _connect_dun_step1_cb (GObject *source_object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; bzobj = user_data; @@ -2564,7 +2564,7 @@ _connect_nap_cb (GObject *source_object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; if (ret) diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c index 0d0354e21b..c253d4e28d 100644 --- a/src/devices/bluetooth/nm-bluez5-dun.c +++ b/src/devices/bluetooth/nm-bluez5-dun.c @@ -805,7 +805,7 @@ _context_invoke_callback (NMBluez5DunContext *context, if (!error) _LOGD (context, "connected via \"%s\"", context->rfcomm_tty_path); - else if (nm_utils_error_is_cancelled (error, FALSE)) + else if (nm_utils_error_is_cancelled (error)) _LOGD (context, "cancelled"); else _LOGD (context, "failed to connect: %s", error->message); diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 497810c36f..f59007b3c7 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -830,7 +830,7 @@ connect_bz_cb (NMBluezManager *bz_mgr, NMDeviceBtPrivate *priv; char sbuf[100]; - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; self = user_data; diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 164fa0a1e8..53221080c0 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -518,7 +518,7 @@ _bt_register_bridge_cb (GError *error, { NMDeviceBridge *self; - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; self = user_data; diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index c7c42eaa27..a87b772e8a 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -605,7 +605,7 @@ build_supplicant_config (NMDeviceEthernet *self, mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)), nm_device_get_ifindex (NM_DEVICE (self))); - config = nm_supplicant_config_new (FALSE, FALSE, FALSE, FALSE); + config = nm_supplicant_config_new (NM_SUPPL_CAP_MASK_NONE); security = nm_connection_get_setting_802_1x (connection); if (!nm_supplicant_config_add_setting_8021x (config, security, con_uuid, mtu, TRUE, error)) { @@ -623,7 +623,7 @@ supplicant_iface_assoc_cb (NMSupplicantInterface *iface, { NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); - if (error && !nm_utils_error_is_cancelled (error, TRUE)) { + 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, diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c index c9592a4971..c65bfd1566 100644 --- a/src/devices/nm-device-macsec.c +++ b/src/devices/nm-device-macsec.c @@ -226,7 +226,7 @@ build_supplicant_config (NMDeviceMacsec *self, GError **error) mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)), nm_device_get_ifindex (NM_DEVICE (self))); - config = nm_supplicant_config_new (FALSE, FALSE, FALSE, FALSE); + config = nm_supplicant_config_new (NM_SUPPL_CAP_MASK_NONE); s_macsec = nm_device_get_applied_setting (NM_DEVICE (self), NM_TYPE_SETTING_MACSEC); @@ -270,7 +270,7 @@ supplicant_iface_assoc_cb (NMSupplicantInterface *iface, { NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data); - if (error && !nm_utils_error_is_cancelled (error, TRUE)) { + 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, diff --git a/src/devices/nm-device-wireguard.c b/src/devices/nm-device-wireguard.c index a5fce0a604..063ffc3959 100644 --- a/src/devices/nm-device-wireguard.c +++ b/src/devices/nm-device-wireguard.c @@ -684,7 +684,7 @@ _peers_resolve_cb (GObject *source_object, list = g_resolver_lookup_by_name_finish (G_RESOLVER (source_object), res, &resolv_error); - if (nm_utils_error_is_cancelled (resolv_error, FALSE)) + if (nm_utils_error_is_cancelled (resolv_error)) return; peer_data = user_data; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 0f410807a6..763008048c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2719,7 +2719,7 @@ concheck_periodic_schedule_set (NMDevice *self, int addr_family, ConcheckSchedul switch (mode) { case CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART: priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (priv->concheck_x[IS_IPv4].p_max_interval, CONCHECK_P_PROBE_INTERVAL); - priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_ns_cached (&now_ns); + priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); if (concheck_periodic_schedule_do (self, addr_family, now_ns)) concheck_start (self, addr_family, NULL, NULL, TRUE); return; @@ -2740,7 +2740,7 @@ concheck_periodic_schedule_set (NMDevice *self, int addr_family, ConcheckSchedul } cur_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_max_interval * NM_UTILS_NSEC_PER_SEC); - nm_utils_get_monotonic_timestamp_ns_cached (&now_ns); + nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); priv->concheck_x[IS_IPv4].p_cur_interval = priv->concheck_x[IS_IPv4].p_max_interval; if (cur_expiry <= now_ns) { @@ -2763,7 +2763,7 @@ concheck_periodic_schedule_set (NMDevice *self, int addr_family, ConcheckSchedul case CONCHECK_SCHEDULE_CHECK_EXTERNAL: /* a external connectivity check delays our periodic check. We reset the counter. */ - priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_ns_cached (&now_ns); + priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); concheck_periodic_schedule_do (self, addr_family, now_ns); return; @@ -2794,7 +2794,7 @@ concheck_periodic_schedule_set (NMDevice *self, int addr_family, ConcheckSchedul * pretty close to now_ns. * * We want to reschedule the timeout at exp_expiry (aka now) + cur_interval. */ - nm_utils_get_monotonic_timestamp_ns_cached (&now_ns); + nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); exp_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (old_interval * NM_UTILS_NSEC_PER_SEC); new_expiry = exp_expiry + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); tdiff = NM_MAX (new_expiry - now_ns, 0); @@ -2833,7 +2833,7 @@ concheck_periodic_schedule_set (NMDevice *self, int addr_family, ConcheckSchedul * when we schedule checks be at precise intervals, without including the time it took for * the connectivity check. */ new_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); - tdiff = NM_MAX (new_expiry - nm_utils_get_monotonic_timestamp_ns_cached (&now_ns), 0); + tdiff = NM_MAX (new_expiry - nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns), 0); priv->concheck_x[IS_IPv4].p_cur_basetime_ns = now_ns + tdiff - (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); concheck_periodic_schedule_do (self, addr_family, now_ns); } @@ -6505,7 +6505,7 @@ sriov_params_cb (GError *error, gpointer data) nm_utils_user_data_unpack (data, &self, &plat_vfs); - if (nm_utils_error_is_cancelled (error, TRUE)) + if (nm_utils_error_is_cancelled_or_disposing (error)) return; priv = NM_DEVICE_GET_PRIVATE (self); @@ -10713,7 +10713,7 @@ fw_change_zone_cb (NMFirewallManager *firewall_manager, priv->fw_call = NULL; - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; switch (priv->fw_state) { @@ -15466,7 +15466,7 @@ sriov_deactivate_cb (GError *error, gpointer user_data) NMDevice *self; gpointer reason; - if (nm_utils_error_is_cancelled (error, TRUE)) + if (nm_utils_error_is_cancelled_or_disposing (error)) return; nm_utils_user_data_unpack (user_data, &self, &reason); diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c index ec4f5c746e..d2c7014186 100644 --- a/src/devices/ovs/nm-ovsdb.c +++ b/src/devices/ovs/nm-ovsdb.c @@ -1394,7 +1394,7 @@ static void _monitor_bridges_cb (NMOvsdb *self, json_t *result, GError *error, gpointer user_data) { if (error) { - if (!nm_utils_error_is_cancelled (error, TRUE)) { + if (!nm_utils_error_is_cancelled_or_disposing (error)) { _LOGI ("%s", error->message); ovsdb_disconnect (self, FALSE); } diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 356f590faa..2954b517d6 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -993,7 +993,7 @@ scan_cb (GObject *source, GAsyncResult *res, gpointer user_data) gs_free_error GError *error = NULL; variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant && nm_utils_error_is_cancelled (error, FALSE)) + if (!variant && nm_utils_error_is_cancelled (error)) return; priv = NM_DEVICE_IWD_GET_PRIVATE (self); @@ -1270,7 +1270,7 @@ wifi_secrets_cb (NMActRequest *req, priv->wifi_secrets_id = NULL; - if (nm_utils_error_is_cancelled (error, FALSE)) { + if (nm_utils_error_is_cancelled (error)) { g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "NM secrets request cancelled"); @@ -1366,7 +1366,7 @@ network_connect_cb (GObject *source, GAsyncResult *res, gpointer user_data) "Activation: (wifi) Network.Connect failed: %s", error->message); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; if (!NM_IN_SET (nm_device_get_state (device), NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_NEED_AUTH)) @@ -1438,7 +1438,7 @@ act_failed_cb (GObject *source, GAsyncResult *res, gpointer user_data) gs_free_error GError *error = NULL; variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant && nm_utils_error_is_cancelled (error, FALSE)) + if (!variant && nm_utils_error_is_cancelled (error)) return; /* Change state to FAILED unless already done by state_changed @@ -1467,7 +1467,7 @@ act_start_cb (GObject *source, GAsyncResult *res, gpointer user_data) "Activation: (wifi) Network.Connect failed: %s", error->message); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; if (!NM_IN_SET (nm_device_get_state (device), NM_DEVICE_STATE_CONFIG)) @@ -1587,7 +1587,7 @@ act_set_mode_cb (GObject *source, GAsyncResult *res, gpointer user_data) "Activation: (wifi) Setting Device.Mode failed: %s", error->message); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; if ( !NM_IN_SET (nm_device_get_state (device), NM_DEVICE_STATE_CONFIG) @@ -1647,7 +1647,7 @@ act_psk_cb (NMActRequest *req, NMDeviceIwdPrivate *priv; NMDevice *device; - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; priv = NM_DEVICE_IWD_GET_PRIVATE (self); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index f334858cb4..b8ef3da6d8 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -694,7 +694,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError } if (priv->sup_iface) { - if (nm_supplicant_interface_get_ap_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_NO) { + if (nm_supplicant_interface_get_capability (priv->sup_iface, NM_SUPPL_CAP_TYPE_AP) == NM_TERNARY_FALSE) { nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "wpa_supplicant does not support Access Point mode"); return FALSE; @@ -708,7 +708,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError } if (priv->sup_iface) { - if (nm_supplicant_interface_get_mesh_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_NO) { + if (nm_supplicant_interface_get_capability (priv->sup_iface, NM_SUPPL_CAP_TYPE_MESH) == NM_TERNARY_FALSE) { nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "wpa_supplicant does not support Mesh mode"); return FALSE; @@ -2171,7 +2171,7 @@ supplicant_iface_assoc_cb (NMSupplicantInterface *iface, NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); NMDevice *device = NM_DEVICE (self); - if ( error && !nm_utils_error_is_cancelled (error, TRUE) + if ( error && !nm_utils_error_is_cancelled_or_disposing (error) && nm_device_is_activating (device)) { cleanup_association_attempt (self, TRUE); nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); @@ -2481,15 +2481,11 @@ build_supplicant_config (NMDeviceWifi *self, s_wireless = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wireless != NULL, NULL); - config = nm_supplicant_config_new ( - nm_supplicant_interface_get_pmf_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES, - nm_supplicant_interface_get_fils_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES, - nm_supplicant_interface_get_ft_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES, - nm_supplicant_interface_get_sha384_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES); + config = nm_supplicant_config_new (nm_supplicant_interface_get_capabilities (priv->sup_iface)); /* Warn if AP mode may not be supported */ - if ( g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0 - && nm_supplicant_interface_get_ap_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_UNKNOWN) { + if ( nm_streq0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) + && nm_supplicant_interface_get_capability (priv->sup_iface, NM_SUPPL_CAP_TYPE_AP) != NM_TERNARY_TRUE) { _LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); } diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index e07fde543a..18f1a5a910 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -452,329 +452,6 @@ security_from_vardict (GVariant *security) /*****************************************************************************/ -static guint32 -get_max_rate_ht_20 (int mcs) -{ - switch (mcs) { - case 0: return 6500000; - case 1: - case 8: return 13000000; - case 2: - case 16: return 19500000; - case 3: - case 9: - case 24: return 26000000; - case 4: - case 10: - case 17: return 39000000; - case 5: - case 11: - case 25: return 52000000; - case 6: - case 18: return 58500000; - case 7: return 65000000; - case 12: - case 19: - case 26: return 78000000; - case 13: - case 27: return 104000000; - case 14: - case 20: return 117000000; - case 15: return 130000000; - case 21: - case 28: return 156000000; - case 22: return 175500000; - case 23: return 195000000; - case 29: return 208000000; - case 30: return 234000000; - case 31: return 260000000; - } - return 0; -} - -static guint32 -get_max_rate_ht_40 (int mcs) -{ - switch (mcs) { - case 0: return 13500000; - case 1: - case 8: return 27000000; - case 2: return 40500000; - case 3: - case 9: - case 24: return 54000000; - case 4: - case 10: - case 17: return 81000000; - case 5: - case 11: - case 25: return 108000000; - case 6: - case 18: return 121500000; - case 7: return 135000000; - case 12: - case 19: - case 26: return 162000000; - case 13: - case 27: return 216000000; - case 14: - case 20: return 243000000; - case 15: return 270000000; - case 16: return 40500000; - case 21: - case 28: return 324000000; - case 22: return 364500000; - case 23: return 405000000; - case 29: return 432000000; - case 30: return 486000000; - case 31: return 540000000; - } - return 0; -} - -static guint32 -get_max_rate_vht_80_ss1 (int mcs) -{ - switch (mcs) { - case 0: return 29300000; - case 1: return 58500000; - case 2: return 87800000; - case 3: return 117000000; - case 4: return 175500000; - case 5: return 234000000; - case 6: return 263300000; - case 7: return 292500000; - case 8: return 351000000; - case 9: return 390000000; - } - return 0; -} - -static guint32 -get_max_rate_vht_80_ss2 (int mcs) -{ - switch (mcs) { - case 0: return 58500000; - case 1: return 117000000; - case 2: return 175500000; - case 3: return 234000000; - case 4: return 351000000; - case 5: return 468000000; - case 6: return 526500000; - case 7: return 585000000; - case 8: return 702000000; - case 9: return 780000000; - } - return 0; -} - -static guint32 -get_max_rate_vht_80_ss3 (int mcs) -{ - switch (mcs) { - case 0: return 87800000; - case 1: return 175500000; - case 2: return 263300000; - case 3: return 351000000; - case 4: return 526500000; - case 5: return 702000000; - case 6: return 0; - case 7: return 877500000; - case 8: return 105300000; - case 9: return 117000000; - } - return 0; -} - -static guint32 -get_max_rate_vht_160_ss1 (int mcs) -{ - switch (mcs) { - case 0: return 58500000; - case 1: return 117000000; - case 2: return 175500000; - case 3: return 234000000; - case 4: return 351000000; - case 5: return 468000000; - case 6: return 526500000; - case 7: return 585000000; - case 8: return 702000000; - case 9: return 780000000; - } - return 0; -} - -static guint32 -get_max_rate_vht_160_ss2 (int mcs) -{ - switch (mcs) { - case 0: return 117000000; - case 1: return 234000000; - case 2: return 351000000; - case 3: return 468000000; - case 4: return 702000000; - case 5: return 936000000; - case 6: return 1053000000; - case 7: return 1170000000; - case 8: return 1404000000; - case 9: return 1560000000; - } - return 0; -} - -static guint32 -get_max_rate_vht_160_ss3 (int mcs) -{ - switch (mcs) { - case 0: return 175500000; - case 1: return 351000000; - case 2: return 526500000; - case 3: return 702000000; - case 4: return 1053000000; - case 5: return 1404000000; - case 6: return 1579500000; - case 7: return 1755000000; - case 8: return 2106000000; - case 9: return 0; - } - return 0; -} - -static gboolean -get_max_rate_ht (const guint8 *bytes, guint len, guint32 *out_maxrate) -{ - guint32 i; - guint8 ht_cap_info; - const guint8 *supported_mcs_set; - guint32 rate; - - /* http://standards.ieee.org/getieee802/download/802.11-2012.pdf - * https://mrncciew.com/2014/10/19/cwap-ht-capabilities-ie/ - */ - - if (len != 26) - return FALSE; - - ht_cap_info = bytes[0]; - supported_mcs_set = &bytes[3]; - *out_maxrate = 0; - - /* Find the maximum supported mcs rate */ - for (i = 0; i <= 76; i++) { - unsigned int mcs_octet = i / 8; - unsigned int MCS_RATE_BIT = 1 << i % 8; - - if (supported_mcs_set[mcs_octet] & MCS_RATE_BIT) { - /* Check for 40Mhz wide channel support */ - if (ht_cap_info & (1 << 1)) - rate = get_max_rate_ht_40 (i); - else - rate = get_max_rate_ht_20 (i); - - if (rate > *out_maxrate) - *out_maxrate = rate; - } - } - - return TRUE; -} - -static gboolean -get_max_rate_vht (const guint8 *bytes, guint len, guint32 *out_maxrate) -{ - guint32 mcs, m; - guint8 vht_cap, tx_map; - - /* https://tda802dot11.blogspot.it/2014/10/vht-capabilities-element-vht.html - * http://chimera.labs.oreilly.com/books/1234000001739/ch03.html#management_frames */ - - if (len != 12) - return FALSE; - - vht_cap = bytes[0]; - tx_map = bytes[8]; - - /* Check for mcs rates 8 and 9 support */ - if (tx_map & 0x2a) - mcs = 9; - else if (tx_map & 0x15) - mcs = 8; - else - mcs = 7; - - /* Check for 160Mhz wide channel support and - * spatial stream support */ - if (vht_cap & (1 << 2)) { - if (tx_map & 0x30) - m = get_max_rate_vht_160_ss3 (mcs); - else if (tx_map & 0x0C) - m = get_max_rate_vht_160_ss2 (mcs); - else - m = get_max_rate_vht_160_ss1 (mcs); - } else { - if (tx_map & 0x30) - m = get_max_rate_vht_80_ss3 (mcs); - else if (tx_map & 0x0C) - m = get_max_rate_vht_80_ss2 (mcs); - else - m = get_max_rate_vht_80_ss1 (mcs); - } - - *out_maxrate = m; - return TRUE; -} - -/* Management Frame Information Element IDs, ieee80211_eid */ -#define WLAN_EID_HT_CAPABILITY 45 -#define WLAN_EID_VHT_CAPABILITY 191 -#define WLAN_EID_VENDOR_SPECIFIC 221 - -static void -parse_ies (const guint8 *bytes, gsize len, guint32 *out_max_rate, gboolean *out_metered) -{ - guint8 id, elem_len; - guint32 m; - - *out_max_rate = 0; - *out_metered = FALSE; - - while (len) { - if (len < 2) - break; - - id = *bytes++; - elem_len = *bytes++; - len -= 2; - - if (elem_len > len) - break; - - switch (id) { - case WLAN_EID_HT_CAPABILITY: - if (get_max_rate_ht (bytes, elem_len, &m)) - *out_max_rate = NM_MAX (*out_max_rate, m); - break; - case WLAN_EID_VHT_CAPABILITY: - if (get_max_rate_vht (bytes, elem_len, &m)) - *out_max_rate = NM_MAX (*out_max_rate, m); - break; - case WLAN_EID_VENDOR_SPECIFIC: - if ( len == 8 - && bytes[0] == 0x00 /* OUI: Microsoft */ - && bytes[1] == 0x50 - && bytes[2] == 0xf2 - && bytes[3] == 0x11) /* OUI type: Network cost */ - *out_metered = (bytes[7] > 1); /* Cost level > 1 */ - break; - } - - len -= elem_len; - bytes += elem_len; - } -} - -/*****************************************************************************/ - gboolean nm_wifi_ap_update_from_properties (NMWifiAP *ap, const char *supplicant_path, @@ -872,7 +549,7 @@ nm_wifi_ap_update_from_properties (NMWifiAP *ap, v = g_variant_lookup_value (properties, "IEs", G_VARIANT_TYPE_BYTESTRING); if (v) { bytes = g_variant_get_fixed_array (v, &len, 1); - parse_ies (bytes, len, &rate, &metered); + nm_wifi_utils_parse_ies (bytes, len, &rate, &metered); max_rate = NM_MAX (max_rate, rate); g_variant_unref (v); priv->metered = metered; diff --git a/src/devices/wifi/nm-wifi-p2p-peer.c b/src/devices/wifi/nm-wifi-p2p-peer.c index 5b9ae18828..053fe3f3dd 100644 --- a/src/devices/wifi/nm-wifi-p2p-peer.c +++ b/src/devices/wifi/nm-wifi-p2p-peer.c @@ -162,18 +162,12 @@ nm_wifi_p2p_peer_get_name (const NMWifiP2PPeer *peer) } gboolean -nm_wifi_p2p_peer_set_name (NMWifiP2PPeer *peer, const char *name) +nm_wifi_p2p_peer_set_name (NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); - if (g_strcmp0 (name, priv->name) == 0) + if (!nm_utils_strdup_reset (&priv->name, str)) return FALSE; - - g_clear_pointer (&priv->name, g_free); - if (name) - priv->name = g_strdup (name); - _notify (peer, PROP_NAME); return TRUE; } @@ -187,18 +181,12 @@ nm_wifi_p2p_peer_get_manufacturer (const NMWifiP2PPeer *peer) } gboolean -nm_wifi_p2p_peer_set_manufacturer (NMWifiP2PPeer *peer, const char *manufacturer) +nm_wifi_p2p_peer_set_manufacturer (NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); - if (g_strcmp0 (manufacturer, priv->manufacturer) == 0) + if (!nm_utils_strdup_reset (&priv->manufacturer, str)) return FALSE; - - g_clear_pointer (&priv->manufacturer, g_free); - if (manufacturer) - priv->manufacturer = g_strdup (manufacturer); - _notify (peer, PROP_MANUFACTURER); return TRUE; } @@ -212,18 +200,12 @@ nm_wifi_p2p_peer_get_model (const NMWifiP2PPeer *peer) } gboolean -nm_wifi_p2p_peer_set_model (NMWifiP2PPeer *peer, const char *model) +nm_wifi_p2p_peer_set_model (NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); - if (g_strcmp0 (model, priv->model) == 0) + if (!nm_utils_strdup_reset (&priv->model, str)) return FALSE; - - g_clear_pointer (&priv->model, g_free); - if (model) - priv->model = g_strdup (model); - _notify (peer, PROP_MODEL); return TRUE; } @@ -237,18 +219,12 @@ nm_wifi_p2p_peer_get_model_number (const NMWifiP2PPeer *peer) } gboolean -nm_wifi_p2p_peer_set_model_number (NMWifiP2PPeer *peer, const char *model_number) +nm_wifi_p2p_peer_set_model_number (NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); - if (g_strcmp0 (model_number, priv->model_number) == 0) + if (!nm_utils_strdup_reset (&priv->model_number, str)) return FALSE; - - g_clear_pointer (&priv->model_number, g_free); - if (model_number) - priv->model_number = g_strdup (model_number); - _notify (peer, PROP_MODEL_NUMBER); return TRUE; } @@ -262,18 +238,12 @@ nm_wifi_p2p_peer_get_serial (const NMWifiP2PPeer *peer) } gboolean -nm_wifi_p2p_peer_set_serial (NMWifiP2PPeer *peer, const char *serial) +nm_wifi_p2p_peer_set_serial (NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); - if (g_strcmp0 (serial, priv->serial) == 0) + if (!nm_utils_strdup_reset (&priv->serial, str)) return FALSE; - - g_clear_pointer (&priv->serial, g_free); - if (serial) - priv->serial = g_strdup (serial); - _notify (peer, PROP_SERIAL); return TRUE; } @@ -310,7 +280,7 @@ nm_wifi_p2p_peer_get_groups (const NMWifiP2PPeer *peer) { g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); - return (const char * const*) NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->groups; + return (const char *const*) NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->groups; } const char * @@ -361,11 +331,7 @@ nm_wifi_p2p_peer_get_strength (NMWifiP2PPeer *peer) gboolean nm_wifi_p2p_peer_set_strength (NMWifiP2PPeer *peer, const gint8 strength) { - NMWifiP2PPeerPrivate *priv; - - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); - - priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); if (priv->strength != strength) { priv->strength = strength; diff --git a/src/devices/wifi/nm-wifi-utils.c b/src/devices/wifi/nm-wifi-utils.c index 7cb5f85bdd..0903dc8bba 100644 --- a/src/devices/wifi/nm-wifi-utils.c +++ b/src/devices/wifi/nm-wifi-utils.c @@ -786,25 +786,6 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, return TRUE; } -guint32 -nm_wifi_utils_level_to_quality (int val) -{ - if (val < 0) { - /* Assume dBm already; rough conversion: best = -40, worst = -100 */ - val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */ - val = 100 - (int) ((100.0 * (double) val) / 60.0); - } else if (val > 110 && val < 256) { - /* assume old-style WEXT 8-bit unsigned signal level */ - val -= 256; /* subtract 256 to convert to dBm */ - val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */ - val = 100 - (int) ((100.0 * (double) val) / 60.0); - } else { - /* Assume signal is a "quality" percentage */ - } - - return CLAMP (val, 0, 100); -} - gboolean nm_wifi_utils_is_manf_default_ssid (GBytes *ssid) { diff --git a/src/devices/wifi/nm-wifi-utils.h b/src/devices/wifi/nm-wifi-utils.h index 982080b903..505baa84b0 100644 --- a/src/devices/wifi/nm-wifi-utils.h +++ b/src/devices/wifi/nm-wifi-utils.h @@ -30,8 +30,6 @@ gboolean nm_wifi_utils_complete_connection (GBytes *ssid, gboolean lock_bssid, GError **error); -guint32 nm_wifi_utils_level_to_quality (int val); - gboolean nm_wifi_utils_is_manf_default_ssid (GBytes *ssid); NMIwdNetworkSecurity nm_wifi_connection_get_iwd_security (NMConnection *connection, diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c index da1d2598a8..23bdefabb8 100644 --- a/src/dhcp/nm-dhcp-nettools.c +++ b/src/dhcp/nm-dhcp-nettools.c @@ -398,7 +398,7 @@ lease_parse_address (NDhcp4ClientLease *lease, a_timestamp = ts / NM_UTILS_NSEC_PER_SEC; a_lifetime = NM_MIN (lifetime / NM_UTILS_NSEC_PER_SEC, NM_PLATFORM_LIFETIME_PERMANENT - 1); - a_expiry = time (NULL) + ((lifetime - (nm_utils_clock_gettime_ns (CLOCK_BOOTTIME) - nettools_basetime)) / NM_UTILS_NSEC_PER_SEC); + a_expiry = time (NULL) + ((lifetime - (nm_utils_clock_gettime_nsec (CLOCK_BOOTTIME) - nettools_basetime)) / NM_UTILS_NSEC_PER_SEC); } if (!lease_get_in_addr (lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, &a_netmask)) { diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c index 81a55834fd..1c430afdad 100644 --- a/src/dns/nm-dns-dnsmasq.c +++ b/src/dns/nm-dns-dnsmasq.c @@ -304,7 +304,7 @@ _gl_pid_spawn_notify (GlPidSpawnAsyncData *sdata, if (error) { nm_assert (pid == 0); nm_assert (!p_exit_code); - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) _LOGD ("spawn: dnsmasq failed: %s", error->message); } else if (p_exit_code) { /* the only caller already logged about this condition extensively. */ @@ -838,7 +838,7 @@ dnsmasq_update_done (GObject *source_object, GAsyncResult *res, gpointer user_da response = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; self = user_data; @@ -987,7 +987,7 @@ spawn_notify (GCancellable *cancellable, NMDnsDnsmasq *self; NMDnsDnsmasqPrivate *priv; - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; self = notify_user_data; diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 7b5053a5b6..3b120d7845 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -1398,7 +1398,7 @@ set_property (GObject *object, guint prop_id, case PROP_SPECIFIC_OBJECT: /* construct-only */ tmp = g_value_get_string (value); - tmp = nm_utils_dbus_normalize_object_path (tmp); + tmp = nm_dbus_path_not_empty (tmp); priv->specific_object = g_strdup (tmp); break; case PROP_DEFAULT: diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index cbbac2816b..9529c3e01a 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -2434,7 +2434,7 @@ _host_id_read_timestamp (gboolean use_secret_key_file, && stat (SECRET_KEY_FILE, &st) == 0) { /* don't check for overflow or timestamps in the future. We get whatever * (bogus) date is on the file. */ - *out_timestamp_ns = nm_utils_timespec_to_ns (&st.st_mtim); + *out_timestamp_ns = nm_utils_timespec_to_nsec (&st.st_mtim); return TRUE; } @@ -4073,6 +4073,359 @@ nm_utils_strdict_to_variant (GHashTable *options) /*****************************************************************************/ +static guint32 +get_max_rate_ht_20 (int mcs) +{ + switch (mcs) { + case 0: return 6500000; + case 1: + case 8: return 13000000; + case 2: + case 16: return 19500000; + case 3: + case 9: + case 24: return 26000000; + case 4: + case 10: + case 17: return 39000000; + case 5: + case 11: + case 25: return 52000000; + case 6: + case 18: return 58500000; + case 7: return 65000000; + case 12: + case 19: + case 26: return 78000000; + case 13: + case 27: return 104000000; + case 14: + case 20: return 117000000; + case 15: return 130000000; + case 21: + case 28: return 156000000; + case 22: return 175500000; + case 23: return 195000000; + case 29: return 208000000; + case 30: return 234000000; + case 31: return 260000000; + } + return 0; +} + +static guint32 +get_max_rate_ht_40 (int mcs) +{ + switch (mcs) { + case 0: return 13500000; + case 1: + case 8: return 27000000; + case 2: return 40500000; + case 3: + case 9: + case 24: return 54000000; + case 4: + case 10: + case 17: return 81000000; + case 5: + case 11: + case 25: return 108000000; + case 6: + case 18: return 121500000; + case 7: return 135000000; + case 12: + case 19: + case 26: return 162000000; + case 13: + case 27: return 216000000; + case 14: + case 20: return 243000000; + case 15: return 270000000; + case 16: return 40500000; + case 21: + case 28: return 324000000; + case 22: return 364500000; + case 23: return 405000000; + case 29: return 432000000; + case 30: return 486000000; + case 31: return 540000000; + } + return 0; +} + +static guint32 +get_max_rate_vht_80_ss1 (int mcs) +{ + switch (mcs) { + case 0: return 29300000; + case 1: return 58500000; + case 2: return 87800000; + case 3: return 117000000; + case 4: return 175500000; + case 5: return 234000000; + case 6: return 263300000; + case 7: return 292500000; + case 8: return 351000000; + case 9: return 390000000; + } + return 0; +} + +static guint32 +get_max_rate_vht_80_ss2 (int mcs) +{ + switch (mcs) { + case 0: return 58500000; + case 1: return 117000000; + case 2: return 175500000; + case 3: return 234000000; + case 4: return 351000000; + case 5: return 468000000; + case 6: return 526500000; + case 7: return 585000000; + case 8: return 702000000; + case 9: return 780000000; + } + return 0; +} + +static guint32 +get_max_rate_vht_80_ss3 (int mcs) +{ + switch (mcs) { + case 0: return 87800000; + case 1: return 175500000; + case 2: return 263300000; + case 3: return 351000000; + case 4: return 526500000; + case 5: return 702000000; + case 6: return 0; + case 7: return 877500000; + case 8: return 105300000; + case 9: return 117000000; + } + return 0; +} + +static guint32 +get_max_rate_vht_160_ss1 (int mcs) +{ + switch (mcs) { + case 0: return 58500000; + case 1: return 117000000; + case 2: return 175500000; + case 3: return 234000000; + case 4: return 351000000; + case 5: return 468000000; + case 6: return 526500000; + case 7: return 585000000; + case 8: return 702000000; + case 9: return 780000000; + } + return 0; +} + +static guint32 +get_max_rate_vht_160_ss2 (int mcs) +{ + switch (mcs) { + case 0: return 117000000; + case 1: return 234000000; + case 2: return 351000000; + case 3: return 468000000; + case 4: return 702000000; + case 5: return 936000000; + case 6: return 1053000000; + case 7: return 1170000000; + case 8: return 1404000000; + case 9: return 1560000000; + } + return 0; +} + +static guint32 +get_max_rate_vht_160_ss3 (int mcs) +{ + switch (mcs) { + case 0: return 175500000; + case 1: return 351000000; + case 2: return 526500000; + case 3: return 702000000; + case 4: return 1053000000; + case 5: return 1404000000; + case 6: return 1579500000; + case 7: return 1755000000; + case 8: return 2106000000; + case 9: return 0; + } + return 0; +} + +static gboolean +get_max_rate_ht (const guint8 *bytes, guint len, guint32 *out_maxrate) +{ + guint32 i; + guint8 ht_cap_info; + const guint8 *supported_mcs_set; + guint32 rate; + + /* http://standards.ieee.org/getieee802/download/802.11-2012.pdf + * https://mrncciew.com/2014/10/19/cwap-ht-capabilities-ie/ + */ + + if (len != 26) + return FALSE; + + ht_cap_info = bytes[0]; + supported_mcs_set = &bytes[3]; + *out_maxrate = 0; + + /* Find the maximum supported mcs rate */ + for (i = 0; i <= 76; i++) { + const unsigned mcs_octet = i / 8; + const unsigned MCS_RATE_BIT = 1 << i % 8; + + if (supported_mcs_set[mcs_octet] & MCS_RATE_BIT) { + /* Check for 40Mhz wide channel support */ + if (ht_cap_info & (1 << 1)) + rate = get_max_rate_ht_40 (i); + else + rate = get_max_rate_ht_20 (i); + + if (rate > *out_maxrate) + *out_maxrate = rate; + } + } + + return TRUE; +} + +static gboolean +get_max_rate_vht (const guint8 *bytes, guint len, guint32 *out_maxrate) +{ + guint32 mcs, m; + guint8 vht_cap, tx_map; + + /* https://tda802dot11.blogspot.it/2014/10/vht-capabilities-element-vht.html + * http://chimera.labs.oreilly.com/books/1234000001739/ch03.html#management_frames */ + + if (len != 12) + return FALSE; + + vht_cap = bytes[0]; + tx_map = bytes[8]; + + /* Check for mcs rates 8 and 9 support */ + if (tx_map & 0x2a) + mcs = 9; + else if (tx_map & 0x15) + mcs = 8; + else + mcs = 7; + + /* Check for 160Mhz wide channel support and + * spatial stream support */ + if (vht_cap & (1 << 2)) { + if (tx_map & 0x30) + m = get_max_rate_vht_160_ss3 (mcs); + else if (tx_map & 0x0C) + m = get_max_rate_vht_160_ss2 (mcs); + else + m = get_max_rate_vht_160_ss1 (mcs); + } else { + if (tx_map & 0x30) + m = get_max_rate_vht_80_ss3 (mcs); + else if (tx_map & 0x0C) + m = get_max_rate_vht_80_ss2 (mcs); + else + m = get_max_rate_vht_80_ss1 (mcs); + } + + *out_maxrate = m; + return TRUE; +} + +/* Management Frame Information Element IDs, ieee80211_eid */ +#define WLAN_EID_HT_CAPABILITY 45 +#define WLAN_EID_VHT_CAPABILITY 191 +#define WLAN_EID_VENDOR_SPECIFIC 221 + +void +nm_wifi_utils_parse_ies (const guint8 *bytes, + gsize len, + guint32 *out_max_rate, + gboolean *out_metered) +{ + guint8 id, elem_len; + guint32 m; + + NM_SET_OUT (out_max_rate, 0); + NM_SET_OUT (out_metered, FALSE); + + while (len) { + if (len < 2) + break; + + id = *bytes++; + elem_len = *bytes++; + len -= 2; + + if (elem_len > len) + break; + + switch (id) { + case WLAN_EID_HT_CAPABILITY: + if (out_max_rate) { + if (get_max_rate_ht (bytes, elem_len, &m)) + *out_max_rate = NM_MAX (*out_max_rate, m); + } + break; + case WLAN_EID_VHT_CAPABILITY: + if (out_max_rate) { + if (get_max_rate_vht (bytes, elem_len, &m)) + *out_max_rate = NM_MAX (*out_max_rate, m); + } + break; + case WLAN_EID_VENDOR_SPECIFIC: + if (out_metered) { + if ( len == 8 + && bytes[0] == 0x00 /* OUI: Microsoft */ + && bytes[1] == 0x50 + && bytes[2] == 0xf2 + && bytes[3] == 0x11) /* OUI type: Network cost */ + *out_metered = (bytes[7] > 1); /* Cost level > 1 */ + } + break; + } + + len -= elem_len; + bytes += elem_len; + } +} + +/*****************************************************************************/ + +guint8 +nm_wifi_utils_level_to_quality (int val) +{ + if (val < 0) { + /* Assume dBm already; rough conversion: best = -40, worst = -100 */ + val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */ + val = 100 - (int) ((100.0 * (double) val) / 60.0); + } else if (val > 110 && val < 256) { + /* assume old-style WEXT 8-bit unsigned signal level */ + val -= 256; /* subtract 256 to convert to dBm */ + val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */ + val = 100 - (int) ((100.0 * (double) val) / 60.0); + } else { + /* Assume signal is a "quality" percentage */ + } + + return CLAMP (val, 0, 100); +} + +/*****************************************************************************/ + NM_UTILS_ENUM2STR_DEFINE (nm_icmpv6_router_pref_to_string, NMIcmpv6RouterPref, NM_UTILS_ENUM2STR (NM_ICMPV6_ROUTER_PREF_LOW, "low"), NM_UTILS_ENUM2STR (NM_ICMPV6_ROUTER_PREF_MEDIUM, "medium"), diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index fbb7987573..14cdae3cdb 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -473,6 +473,15 @@ const char *nm_utils_parse_dns_domain (const char *domain, gboolean *is_routing) /*****************************************************************************/ +void nm_wifi_utils_parse_ies (const guint8 *bytes, + gsize len, + guint32 *out_max_rate, + gboolean *out_metered); + +guint8 nm_wifi_utils_level_to_quality (int val); + +/*****************************************************************************/ + #define NM_VPN_ROUTE_METRIC_DEFAULT 50 #define NM_UTILS_ERROR_MSG_REQ_AUTH_FAILED "Unable to authenticate the request" diff --git a/src/nm-firewall-manager.c b/src/nm-firewall-manager.c index cf6494bdb5..304b15f99a 100644 --- a/src/nm-firewall-manager.c +++ b/src/nm-firewall-manager.c @@ -265,7 +265,7 @@ _handle_dbus_cb (GObject *source, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; call_id = user_data; diff --git a/src/nm-manager.c b/src/nm-manager.c index 4bd58da22e..e6dec4cdf1 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -5333,9 +5333,9 @@ impl_manager_activate_connection (NMDBusObject *obj, g_variant_get (parameters, "(&o&o&o)", &connection_path, &device_path, &specific_object_path); - connection_path = nm_utils_dbus_normalize_object_path (connection_path); - specific_object_path = nm_utils_dbus_normalize_object_path (specific_object_path); - device_path = nm_utils_dbus_normalize_object_path (device_path); + connection_path = nm_dbus_path_not_empty (connection_path); + specific_object_path = nm_dbus_path_not_empty (specific_object_path); + device_path = nm_dbus_path_not_empty (device_path); /* If the connection path is given and valid, that connection is activated. * Otherwise the "best" connection for the device is chosen and activated, @@ -5623,8 +5623,8 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, } } - specific_object_path = nm_utils_dbus_normalize_object_path (specific_object_path); - device_path = nm_utils_dbus_normalize_object_path (device_path); + specific_object_path = nm_dbus_path_not_empty (specific_object_path); + device_path = nm_dbus_path_not_empty (device_path); /* Try to create a new connection with the given settings. * We allow empty settings for AddAndActivateConnection(). In that case, diff --git a/src/nm-types.h b/src/nm-types.h index 43b931dad3..22ec623e3b 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -43,6 +43,8 @@ typedef struct _NMConfigDeviceStateData NMConfigDeviceStateData; struct _NMDedupMultiIndex; +typedef struct _NMRefString NMRefString; + /*****************************************************************************/ typedef enum { diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 3ae5726d1c..b71576d5d2 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -741,7 +741,7 @@ _addrtime_timestamp_to_nm (guint32 timestamp, gint32 *out_now_nm) /* do all the calculations in milliseconds scale */ now_nm = nm_utils_get_monotonic_timestamp_msec (); - now_nl = nm_utils_clock_gettime_ms (CLOCK_MONOTONIC); + now_nl = nm_utils_clock_gettime_msec (CLOCK_MONOTONIC); nm_assert (now_nm >= 1000); nm_assert (now_nl >= 0); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 2b554cb4b9..7535958c7c 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1322,7 +1322,7 @@ nm_platform_link_get_ifindex (NMPlatform *self, const char *name) } const char * -nm_platform_if_indextoname (NMPlatform *self, int ifindex, char *out_ifname/* of size IFNAMSIZ */) +nm_platform_if_indextoname (NMPlatform *self, int ifindex, char out_ifname[static 16 /* IFNAMSIZ */]) { _CHECK_SELF_NETNS (self, klass, netns, FALSE); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 56788c182e..7edaaf58e3 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -1350,7 +1350,8 @@ int nm_platform_sysctl_ip_conf_get_rp_filter_ipv4 (NMPlatform *platform, gboolean consider_all, gboolean *out_due_to_all); -const char *nm_platform_if_indextoname (NMPlatform *self, int ifindex, char *out_ifname/* of size IFNAMSIZ */); +const char *nm_platform_if_indextoname (NMPlatform *self, int ifindex, + char out_ifname[static 16 /* IFNAMSIZ */]); int nm_platform_if_nametoindex (NMPlatform *self, const char *ifname); const NMPObject *nm_platform_link_get_obj (NMPlatform *self, diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index e5c727b49f..6159943a19 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -370,7 +370,7 @@ _dbus_call_cb (GObject *source, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; call_id = user_data; diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 52e9defd29..403b50edb2 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -30,13 +30,10 @@ typedef struct { typedef struct { GHashTable *config; GHashTable *blobs; - guint32 ap_scan; - gboolean fast_required; - gboolean dispose_has_run; - gboolean support_pmf; - gboolean support_fils; - gboolean support_ft; - gboolean support_sha384; + NMSupplCapMask capabilities; + guint32 ap_scan; + bool fast_required:1; + bool dispose_has_run:1; } NMSupplicantConfigPrivate; struct _NMSupplicantConfig { @@ -54,9 +51,15 @@ G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT) /*****************************************************************************/ +static gboolean +_get_capability (NMSupplicantConfigPrivate *priv, + NMSupplCapType type) +{ + return NM_SUPPL_CAP_MASK_GET (priv->capabilities, type) == NM_TERNARY_TRUE; +} + NMSupplicantConfig * -nm_supplicant_config_new (gboolean support_pmf, gboolean support_fils, - gboolean support_ft, gboolean support_sha384) +nm_supplicant_config_new (NMSupplCapMask capabilities) { NMSupplicantConfigPrivate *priv; NMSupplicantConfig *self; @@ -64,10 +67,7 @@ nm_supplicant_config_new (gboolean support_pmf, gboolean support_fils, self = g_object_new (NM_TYPE_SUPPLICANT_CONFIG, NULL); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); - priv->support_pmf = support_pmf; - priv->support_fils = support_fils; - priv->support_ft = support_ft; - priv->support_sha384 = support_sha384; + priv->capabilities = capabilities; return self; } @@ -768,7 +768,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, g_return_val_if_fail (!error || !*error, FALSE); /* Check if we actually support FILS */ - if (!priv->support_fils) { + if (!_get_capability (priv, NM_SUPPL_CAP_TYPE_FILS)) { if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED) { g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "Supplicant does not support FILS"); @@ -780,36 +780,40 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting); key_mgmt_conf = g_string_new (key_mgmt); if (nm_streq (key_mgmt, "wpa-psk")) { - if (priv->support_pmf) + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_PMF)) g_string_append (key_mgmt_conf, " wpa-psk-sha256"); - if (priv->support_ft) + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append (key_mgmt_conf, " ft-psk"); } else if (nm_streq (key_mgmt, "wpa-eap")) { - if (priv->support_pmf) + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_PMF)) g_string_append (key_mgmt_conf, " wpa-eap-sha256"); - if (priv->support_ft) + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append (key_mgmt_conf, " ft-eap"); - if (priv->support_ft && priv->support_sha384) + if ( _get_capability (priv, NM_SUPPL_CAP_TYPE_FT) + && _get_capability (priv, NM_SUPPL_CAP_TYPE_SHA384)) g_string_append (key_mgmt_conf, " ft-eap-sha384"); switch (fils) { case NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED: g_string_truncate (key_mgmt_conf, 0); - if (!priv->support_pmf) + if (!_get_capability (priv, NM_SUPPL_CAP_TYPE_PMF)) g_string_assign (key_mgmt_conf, "fils-sha256 fils-sha384"); /* fall-through */ case NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL: - if (priv->support_pmf) + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_PMF)) g_string_append (key_mgmt_conf, " fils-sha256 fils-sha384"); - if (priv->support_pmf && priv->support_ft) + if ( _get_capability (priv, NM_SUPPL_CAP_TYPE_PMF) + && _get_capability (priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append (key_mgmt_conf, " ft-fils-sha256"); - if (priv->support_pmf && priv->support_ft & priv->support_sha384) + if ( _get_capability (priv, NM_SUPPL_CAP_TYPE_PMF) + && _get_capability (priv, NM_SUPPL_CAP_TYPE_FT) + && _get_capability (priv, NM_SUPPL_CAP_TYPE_SHA384)) g_string_append (key_mgmt_conf, " ft-fils-sha384"); break; default: break; } } else if (nm_streq (key_mgmt, "sae")) { - if (priv->support_ft) + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append (key_mgmt_conf, " ft-sae"); } @@ -873,7 +877,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, /* Check if we actually support PMF */ set_pmf = TRUE; - if (!priv->support_pmf) { + if (!_get_capability (priv, NM_SUPPL_CAP_TYPE_PMF)) { if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) { g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "Supplicant does not support PMF"); diff --git a/src/supplicant/nm-supplicant-config.h b/src/supplicant/nm-supplicant-config.h index 361f9ac62e..e1da9a1eca 100644 --- a/src/supplicant/nm-supplicant-config.h +++ b/src/supplicant/nm-supplicant-config.h @@ -25,8 +25,7 @@ typedef struct _NMSupplicantConfigClass NMSupplicantConfigClass; GType nm_supplicant_config_get_type (void); -NMSupplicantConfig *nm_supplicant_config_new (gboolean support_pmf, gboolean support_fils, - gboolean support_ft, gboolean support_sha384); +NMSupplicantConfig *nm_supplicant_config_new (NMSupplCapMask capabilities); guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self); diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c index dca434c7c9..099a8c306a 100644 --- a/src/supplicant/nm-supplicant-interface.c +++ b/src/supplicant/nm-supplicant-interface.c @@ -16,16 +16,6 @@ #include "nm-core-internal.h" #include "nm-std-aux/nm-dbus-compat.h" -#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface" -#define WPAS_DBUS_IFACE_INTERFACE_WPS WPAS_DBUS_INTERFACE ".Interface.WPS" -#define WPAS_DBUS_IFACE_INTERFACE_P2P_DEVICE WPAS_DBUS_INTERFACE ".Interface.P2PDevice" -#define WPAS_DBUS_IFACE_BSS WPAS_DBUS_INTERFACE ".BSS" -#define WPAS_DBUS_IFACE_PEER WPAS_DBUS_INTERFACE ".Peer" -#define WPAS_DBUS_IFACE_GROUP WPAS_DBUS_INTERFACE ".Group" -#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network" -#define WPAS_ERROR_INVALID_IFACE WPAS_DBUS_INTERFACE ".InvalidInterface" -#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".InterfaceExists" - /*****************************************************************************/ typedef struct { @@ -80,11 +70,9 @@ enum { PEER_UPDATED, /* a new Peer appeared or an existing had properties changed */ PEER_REMOVED, /* supplicant removed Peer from its scan list */ SCAN_DONE, /* wifi scan is complete */ - CREDENTIALS_REQUEST, /* 802.1x identity or password requested */ WPS_CREDENTIALS, /* WPS credentials received */ GROUP_STARTED, /* a new Group (interface) was created */ GROUP_FINISHED, /* a Group (interface) has been finished */ - GROUP_FORMATION_FAILURE, /* P2P Group formation failed */ LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -99,32 +87,15 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSupplicantInterface, PROP_CURRENT_BSS, PROP_DRIVER, PROP_P2P_AVAILABLE, - PROP_FAST_SUPPORT, - PROP_AP_SUPPORT, - PROP_PMF_SUPPORT, - PROP_FILS_SUPPORT, - PROP_P2P_SUPPORT, - PROP_MESH_SUPPORT, - PROP_WFD_SUPPORT, - PROP_FT_SUPPORT, - PROP_SHA384_SUPPORT, + PROP_GLOBAL_CAPABILITIES, PROP_AUTH_STATE, ); -typedef struct { +typedef struct _NMSupplicantInterfacePrivate { char * dev; NMSupplicantDriver driver; - gboolean has_credreq; /* Whether querying 802.1x credentials is supported */ - NMSupplicantFeature fast_support; - NMSupplicantFeature ap_support; /* Lightweight AP mode support */ - NMSupplicantFeature pmf_support; - NMSupplicantFeature fils_support; - NMSupplicantFeature p2p_support; - NMSupplicantFeature mesh_support; - NMSupplicantFeature wfd_support; - NMSupplicantFeature ft_support_global; - NMSupplicantFeature ft_support_per_iface; - NMSupplicantFeature sha384_support; + NMSupplCapMask global_capabilities; + NMSupplCapMask iface_capabilities; guint32 max_scan_ssids; guint32 ready_count; @@ -132,11 +103,6 @@ typedef struct { NMSupplicantInterfaceState state; int disconnect_reason; - bool scanning:1; - - bool scan_done_pending:1; - bool scan_done_success:1; - GDBusProxy * wpas_proxy; GCancellable * init_cancellable; GDBusProxy * iface_proxy; @@ -144,12 +110,6 @@ typedef struct { GDBusProxy * p2p_proxy; GDBusProxy * group_proxy; - gboolean p2p_proxy_acquired; - gboolean group_proxy_acquired; - gboolean p2p_capable; - - gboolean p2p_group_owner; - WpsData *wps_data; AssocData * assoc_data; @@ -163,12 +123,19 @@ typedef struct { gint64 last_scan; /* timestamp as returned by nm_utils_get_monotonic_timestamp_msec() */ NMSupplicantAuthState auth_state; -} NMSupplicantInterfacePrivate; -struct _NMSupplicantInterface { - GObject parent; - NMSupplicantInterfacePrivate _priv; -}; + bool scanning:1; + + bool scan_done_pending:1; + bool scan_done_success:1; + + bool p2p_proxy_acquired:1; + bool group_proxy_acquired:1; + bool p2p_capable:1; + + bool p2p_group_owner:1; + +} NMSupplicantInterfacePrivate; struct _NMSupplicantInterfaceClass { GObjectClass parent; @@ -176,7 +143,7 @@ struct _NMSupplicantInterfaceClass { G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT) -#define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSupplicantInterface, NM_IS_SUPPLICANT_INTERFACE) +#define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR (self, NMSupplicantInterface, NM_IS_SUPPLICANT_INTERFACE) /*****************************************************************************/ @@ -219,6 +186,22 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_supplicant_interface_state_to_string, NMSupplican NM_UTILS_LOOKUP_STR_ITEM (NM_SUPPLICANT_INTERFACE_STATE_DOWN, "down"), ); +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE_STATIC ( + wpas_state_string_to_enum, + NMSupplicantInterfaceState, + { return NM_SUPPLICANT_INTERFACE_STATE_INVALID; }, + { "4way_handshake", NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE }, + { "associated", NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED }, + { "associating", NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING }, + { "authenticating", NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING }, + { "completed", NM_SUPPLICANT_INTERFACE_STATE_COMPLETED }, + { "disconnected", NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED }, + { "group_handshake", NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE }, + { "inactive", NM_SUPPLICANT_INTERFACE_STATE_INACTIVE }, + { "interface_disabled", NM_SUPPLICANT_INTERFACE_STATE_DISABLED }, + { "scanning", NM_SUPPLICANT_INTERFACE_STATE_SCANNING }, +); + /*****************************************************************************/ static void @@ -281,8 +264,7 @@ bss_proxy_acquired_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_da gboolean success; success = g_async_initable_init_finish (G_ASYNC_INITABLE (proxy), result, &error); - if ( !success - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -327,9 +309,9 @@ bss_add_new (NMSupplicantInterface *self, const char *object_path) bss_proxy = g_object_new (G_TYPE_DBUS_PROXY, "g-bus-type", G_BUS_TYPE_SYSTEM, "g-flags", G_DBUS_PROXY_FLAGS_NONE, - "g-name", WPAS_DBUS_SERVICE, + "g-name", NM_WPAS_DBUS_SERVICE, "g-object-path", object_path, - "g-interface-name", WPAS_DBUS_IFACE_BSS, + "g-interface-name", NM_WPAS_DBUS_IFACE_BSS, NULL); bss_data = g_slice_new0 (BssData); bss_data->proxy = bss_proxy; @@ -399,8 +381,7 @@ peer_proxy_acquired_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d gboolean success; success = g_async_initable_init_finish (G_ASYNC_INITABLE (proxy), result, &error); - if ( !success - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -443,9 +424,9 @@ peer_add_new (NMSupplicantInterface *self, const char *object_path) peer_proxy = g_object_new (G_TYPE_DBUS_PROXY, "g-bus-type", G_BUS_TYPE_SYSTEM, "g-flags", G_DBUS_PROXY_FLAGS_NONE, - "g-name", WPAS_DBUS_SERVICE, + "g-name", NM_WPAS_DBUS_SERVICE, "g-object-path", object_path, - "g-interface-name", WPAS_DBUS_IFACE_PEER, + "g-interface-name", NM_WPAS_DBUS_IFACE_PEER, NULL); peer_data = g_slice_new0 (PeerData); peer_data->proxy = peer_proxy; @@ -504,33 +485,6 @@ set_state (NMSupplicantInterface *self, NMSupplicantInterfaceState new_state) (int) priv->disconnect_reason); } -static NMSupplicantInterfaceState -wpas_state_string_to_enum (const char *str_state) -{ - if (!strcmp (str_state, "interface_disabled")) - return NM_SUPPLICANT_INTERFACE_STATE_DISABLED; - else if (!strcmp (str_state, "disconnected")) - return NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED; - else if (!strcmp (str_state, "inactive")) - return NM_SUPPLICANT_INTERFACE_STATE_INACTIVE; - else if (!strcmp (str_state, "scanning")) - return NM_SUPPLICANT_INTERFACE_STATE_SCANNING; - else if (!strcmp (str_state, "authenticating")) - return NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING; - else if (!strcmp (str_state, "associating")) - return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING; - else if (!strcmp (str_state, "associated")) - return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED; - else if (!strcmp (str_state, "4way_handshake")) - return NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE; - else if (!strcmp (str_state, "group_handshake")) - return NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE; - else if (!strcmp (str_state, "completed")) - return NM_SUPPLICANT_INTERFACE_STATE_COMPLETED; - - return NM_SUPPLICANT_INTERFACE_STATE_INVALID; -} - static void set_state_from_string (NMSupplicantInterface *self, const char *new_state) { @@ -612,9 +566,11 @@ parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities) g_free (array); } - priv->ft_support_per_iface = have_ft - ? NM_SUPPLICANT_FEATURE_YES - : NM_SUPPLICANT_FEATURE_NO; + priv->iface_capabilities = NM_SUPPL_CAP_MASK_SET (priv->iface_capabilities, + NM_SUPPL_CAP_TYPE_FT, + have_ft + ? NM_TERNARY_TRUE + : NM_TERNARY_FALSE); if (g_variant_lookup (capabilities, "Modes", "^a&s", &array)) { if (g_strv_contains (array, "p2p")) @@ -638,7 +594,7 @@ parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities) if (g_variant_lookup (capabilities, "MaxScanSSID", "i", &max_scan_ssids)) { /* We need active scan and SSID probe capabilities to care about MaxScanSSIDs */ if (max_scan_ssids > 0 && have_active && have_ssid) { - /* wpa_supplicant's WPAS_MAX_SCAN_SSIDS value is 16, but for speed + /* wpa_supplicant's NM_WPAS_MAX_SCAN_SSIDS value is 16, but for speed * and to ensure we don't disclose too many SSIDs from the hidden * list, we'll limit to 5. */ @@ -660,71 +616,6 @@ iface_check_ready (NMSupplicantInterface *self) } } -gboolean -nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self, - const char *field, - const char *value, - GError **error) -{ - NMSupplicantInterfacePrivate *priv; - gs_unref_variant GVariant *reply = NULL; - - g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - g_return_val_if_fail (priv->has_credreq == TRUE, FALSE); - - /* Need a network block object path */ - g_return_val_if_fail (priv->net_path, FALSE); - reply = g_dbus_proxy_call_sync (priv->iface_proxy, - "NetworkReply", - g_variant_new ("(oss)", - priv->net_path, - field, - value), - G_DBUS_CALL_FLAGS_NONE, - 5000, - NULL, - error); - if (error && *error) - g_dbus_error_strip_remote_error (*error); - - return !!reply; -} - -static void -iface_check_netreply_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) -{ - NMSupplicantInterface *self; - NMSupplicantInterfacePrivate *priv; - gs_unref_variant GVariant *variant = NULL; - gs_free_error GError *error = NULL; - - /* We know NetworkReply is supported if the NetworkReply method returned - * successfully (which is unexpected since we sent a bogus network - * object path) or if we got an "InvalidArgs" (which indicates NetworkReply - * is supported). We know it's not supported if we get an - * "UnknownMethod" error. - */ - - variant = g_dbus_proxy_call_finish (proxy, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_SUPPLICANT_INTERFACE (user_data); - priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - if (variant || _nm_dbus_error_has_name (error, "fi.w1.wpa_supplicant1.InvalidArgs")) - priv->has_credreq = TRUE; - - _LOGD ("supplicant %s network credentials requests", - priv->has_credreq ? "supports" : "does not support"); - - iface_check_ready (self); -} - static void iface_set_pmf_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) { @@ -733,7 +624,7 @@ iface_set_pmf_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) gs_free_error GError *error = NULL; variant = g_dbus_proxy_call_finish (proxy, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -767,58 +658,75 @@ nm_supplicant_interface_get_p2p_group_owner (NMSupplicantInterface *self) return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->p2p_group_owner; } -NMSupplicantFeature -nm_supplicant_interface_get_ap_support (NMSupplicantInterface *self) +static NMTernary +_get_capability (NMSupplicantInterfacePrivate *priv, + NMSupplCapType type) { - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->ap_support; + NMTernary value; + NMTernary iface_value; + + switch (type) { + case NM_SUPPL_CAP_TYPE_AP: + iface_value = NM_SUPPL_CAP_MASK_GET (priv->iface_capabilities, type); + value = NM_SUPPL_CAP_MASK_GET (priv->global_capabilities, type); + value = MAX (iface_value, value); + break; + case NM_SUPPL_CAP_TYPE_FT: + value = NM_SUPPL_CAP_MASK_GET (priv->global_capabilities, type); + if (value != NM_TERNARY_FALSE) { + iface_value = NM_SUPPL_CAP_MASK_GET (priv->iface_capabilities, type); + if (iface_value != NM_TERNARY_DEFAULT) + value = iface_value; + } + break; + default: + nm_assert (NM_SUPPL_CAP_MASK_GET (priv->iface_capabilities, type) == NM_TERNARY_DEFAULT); + value = NM_SUPPL_CAP_MASK_GET (priv->global_capabilities, type); + break; + } + return value; } -NMSupplicantFeature -nm_supplicant_interface_get_pmf_support (NMSupplicantInterface *self) +NMTernary +nm_supplicant_interface_get_capability (NMSupplicantInterface *self, + NMSupplCapType type) { - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->pmf_support; + return _get_capability (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self), type); } -NMSupplicantFeature -nm_supplicant_interface_get_fils_support (NMSupplicantInterface *self) +NMSupplCapMask +nm_supplicant_interface_get_capabilities (NMSupplicantInterface *self) { - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->fils_support; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplCapMask caps; + + caps = priv->global_capabilities; + caps = NM_SUPPL_CAP_MASK_SET (caps, NM_SUPPL_CAP_TYPE_AP, _get_capability (priv, NM_SUPPL_CAP_TYPE_AP)); + caps = NM_SUPPL_CAP_MASK_SET (caps, NM_SUPPL_CAP_TYPE_FT, _get_capability (priv, NM_SUPPL_CAP_TYPE_FT)); + + nm_assert (!NM_FLAGS_ANY (priv->iface_capabilities, + ~( NM_SUPPL_CAP_MASK_T_AP_MASK + | NM_SUPPL_CAP_MASK_T_FT_MASK))); + +#if NM_MORE_ASSERTS > 10 + { + NMSupplCapType type; + + for (type = 0; type < _NM_SUPPL_CAP_TYPE_NUM; type++) + nm_assert (NM_SUPPL_CAP_MASK_GET (caps, type) == _get_capability (priv, type)); + } +#endif + + return caps; } -NMSupplicantFeature -nm_supplicant_interface_get_p2p_support (NMSupplicantInterface *self) -{ - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->p2p_support; -} - -NMSupplicantFeature -nm_supplicant_interface_get_mesh_support (NMSupplicantInterface *self) -{ - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->mesh_support; -} - -NMSupplicantFeature -nm_supplicant_interface_get_wfd_support (NMSupplicantInterface *self) -{ - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->wfd_support; -} - -NMSupplicantFeature -nm_supplicant_interface_get_ft_support (NMSupplicantInterface *self) +void +nm_supplicant_interface_set_global_capabilities (NMSupplicantInterface *self, + NMSupplCapMask value) { NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - if (priv->ft_support_global == NM_SUPPLICANT_FEATURE_NO) - return NM_SUPPLICANT_FEATURE_NO; - if (priv->ft_support_per_iface != NM_SUPPLICANT_FEATURE_UNKNOWN) - return priv->ft_support_per_iface; - return priv->ft_support_global; -} - -NMSupplicantFeature -nm_supplicant_interface_get_sha384_support (NMSupplicantInterface *self) -{ - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->sha384_support; + priv->global_capabilities = value; } NMSupplicantAuthState @@ -827,91 +735,6 @@ nm_supplicant_interface_get_auth_state (NMSupplicantInterface *self) return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->auth_state; } -void -nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self, - NMSupplicantFeature ap_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - /* Use the best indicator of support between the supplicant global - * Capabilities property and the interface's introspection data. - */ - if (ap_support > priv->ap_support) - priv->ap_support = ap_support; -} - -void -nm_supplicant_interface_set_fast_support (NMSupplicantInterface *self, - NMSupplicantFeature fast_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->fast_support = fast_support; -} - -void -nm_supplicant_interface_set_pmf_support (NMSupplicantInterface *self, - NMSupplicantFeature pmf_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->pmf_support = pmf_support; -} - -void -nm_supplicant_interface_set_fils_support (NMSupplicantInterface *self, - NMSupplicantFeature fils_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->fils_support = fils_support; -} - -void -nm_supplicant_interface_set_p2p_support (NMSupplicantInterface *self, - NMSupplicantFeature p2p_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->p2p_support = p2p_support; -} - -void -nm_supplicant_interface_set_mesh_support (NMSupplicantInterface *self, - NMSupplicantFeature mesh_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->mesh_support = mesh_support; -} - -void -nm_supplicant_interface_set_wfd_support (NMSupplicantInterface *self, - NMSupplicantFeature wfd_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->wfd_support = wfd_support; -} - -void -nm_supplicant_interface_set_ft_support (NMSupplicantInterface *self, - NMSupplicantFeature ft_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->ft_support_global = ft_support; -} - -void -nm_supplicant_interface_set_sha384_support (NMSupplicantInterface *self, - NMSupplicantFeature sha384_support) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - priv->sha384_support = sha384_support; -} - /*****************************************************************************/ static void @@ -949,8 +772,7 @@ _wps_handle_start_cb (GObject *source_object, gs_free_error GError *error = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); - if ( !result - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; data = user_data; @@ -980,8 +802,7 @@ _wps_handle_set_pc_cb (GObject *source_object, guint8 bssid_buf[ETH_ALEN]; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); - if ( !result - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; data = user_data; @@ -1027,7 +848,7 @@ _wps_call_set_pc (WpsData *data) g_dbus_proxy_call (data->proxy, "org.freedesktop.DBus.Properties.Set", g_variant_new ("(ssv)", - WPAS_DBUS_IFACE_INTERFACE_WPS, + NM_WPAS_DBUS_IFACE_INTERFACE_WPS, "ProcessCredentials", g_variant_new_boolean (TRUE)), G_DBUS_CALL_FLAGS_NONE, @@ -1049,8 +870,7 @@ _wps_handle_proxy_cb (GObject *source_object, GDBusProxy *proxy; proxy = g_dbus_proxy_new_for_bus_finish (res, &error); - if ( !proxy - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; data = user_data; @@ -1081,8 +901,7 @@ _wps_handle_cancel_cb (GObject *source_object, gs_free_error GError *error = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); - if ( !result - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; data = user_data; @@ -1148,9 +967,9 @@ _wps_start (NMSupplicantInterface *self, g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, - WPAS_DBUS_SERVICE, + NM_WPAS_DBUS_SERVICE, priv->object_path, - WPAS_DBUS_IFACE_INTERFACE_WPS, + NM_WPAS_DBUS_IFACE_INTERFACE_WPS, data->cancellable, _wps_handle_proxy_cb, data); @@ -1220,22 +1039,30 @@ iface_introspect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data gs_unref_variant GVariant *variant = NULL; gs_free_error GError *error = NULL; const char *data; + NMTernary value; variant = _nm_dbus_proxy_call_finish (proxy, result, G_VARIANT_TYPE ("(s)"), &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - if (variant) { - g_variant_get (variant, "(&s)", &data); + if (NM_SUPPL_CAP_MASK_GET (priv->global_capabilities, NM_SUPPL_CAP_TYPE_AP) == NM_TERNARY_DEFAULT) { + /* if the global value is set, we trust it and ignore whatever we get from introspection. */ + } else { + value = NM_TERNARY_DEFAULT; + if (variant) { + g_variant_get (variant, "(&s)", &data); - /* The ProbeRequest method only exists if AP mode has been enabled */ - if (strstr (data, "ProbeRequest")) - priv->ap_support = NM_SUPPLICANT_FEATURE_YES; + /* The ProbeRequest method only exists if AP mode has been enabled */ + value = strstr (data, "ProbeRequest") + ? NM_TERNARY_TRUE + : NM_TERNARY_FALSE; + } + priv->iface_capabilities = NM_SUPPL_CAP_MASK_SET (priv->iface_capabilities, NM_SUPPL_CAP_TYPE_AP, value); } iface_check_ready (self); @@ -1323,20 +1150,6 @@ wpas_iface_bss_removed (GDBusProxy *proxy, bss_data_destroy (bss_data); } -static void -wpas_iface_network_request (GDBusProxy *proxy, - const char *path, - const char *field, - const char *message, - gpointer user_data) -{ - NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - if (priv->has_credreq && priv->net_path && !g_strcmp0 (path, priv->net_path)) - g_signal_emit (self, signals[CREDENTIALS_REQUEST], 0, field, message); -} - static void eap_changed (GDBusProxy *proxy, const char *status, @@ -1401,7 +1214,7 @@ props_changed_cb (GDBusProxy *proxy, } if (g_variant_lookup (changed_properties, "CurrentBSS", "&o", &s)) { - s = nm_utils_dbus_normalize_object_path (s); + s = nm_dbus_path_not_empty (s); if (!nm_streq0 (s, priv->current_bss)) { g_free (priv->current_bss); priv->current_bss = g_strdup (s); @@ -1500,8 +1313,7 @@ group_proxy_acquired_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ gboolean success; success = g_async_initable_init_finish (G_ASYNC_INITABLE (proxy), result, &error); - if ( !success - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -1559,9 +1371,9 @@ p2p_props_changed_cb (GDBusProxy *proxy, priv->group_proxy = g_object_new (G_TYPE_DBUS_PROXY, "g-bus-type", G_BUS_TYPE_SYSTEM, "g-flags", G_DBUS_PROXY_FLAGS_NONE, - "g-name", WPAS_DBUS_SERVICE, + "g-name", NM_WPAS_DBUS_SERVICE, "g-object-path", path, - "g-interface-name", WPAS_DBUS_IFACE_GROUP, + "g-interface-name", NM_WPAS_DBUS_IFACE_GROUP, NULL); g_signal_connect (priv->group_proxy, "g-properties-changed", G_CALLBACK (group_props_changed_cb), self); g_async_initable_init_async (G_ASYNC_INITABLE (priv->group_proxy), @@ -1646,16 +1458,6 @@ p2p_group_started (GDBusProxy *proxy, g_object_unref (iface); } -static void -p2p_group_formation_failure (GDBusProxy *proxy, - const char *group, - gpointer user_data) -{ - NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); - - g_signal_emit (self, signals[GROUP_FORMATION_FAILURE], 0, group); -} - static void p2p_group_finished (GDBusProxy *proxy, GVariant *params, @@ -1688,7 +1490,7 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ gs_free_error GError *error = NULL; if (!g_async_initable_init_finish (G_ASYNC_INITABLE (proxy), result, &error)) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + if (!nm_utils_error_is_cancelled (error)) { self = NM_SUPPLICANT_INTERFACE (user_data); _LOGW ("failed to acquire wpa_supplicant interface proxy: (%s)", error->message); set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN); @@ -1705,8 +1507,6 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ G_CALLBACK (wpas_iface_bss_added), self); _nm_dbus_signal_connect (priv->iface_proxy, "BSSRemoved", G_VARIANT_TYPE ("(o)"), G_CALLBACK (wpas_iface_bss_removed), self); - _nm_dbus_signal_connect (priv->iface_proxy, "NetworkRequest", G_VARIANT_TYPE ("(oss)"), - G_CALLBACK (wpas_iface_network_request), self); _nm_dbus_signal_connect (priv->iface_proxy, "EAP", G_VARIANT_TYPE ("(ss)"), G_CALLBACK (eap_changed), self); @@ -1714,7 +1514,7 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ g_dbus_proxy_call (priv->iface_proxy, DBUS_INTERFACE_PROPERTIES ".Set", g_variant_new ("(ssv)", - WPAS_DBUS_IFACE_INTERFACE, + NM_WPAS_DBUS_IFACE_INTERFACE, "BSSExpireAge", g_variant_new_uint32 (250)), G_DBUS_CALL_FLAGS_NONE, @@ -1725,7 +1525,7 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ g_dbus_proxy_call (priv->iface_proxy, DBUS_INTERFACE_PROPERTIES ".Set", g_variant_new ("(ssv)", - WPAS_DBUS_IFACE_INTERFACE, + NM_WPAS_DBUS_IFACE_INTERFACE, "BSSExpireCount", g_variant_new_uint32 (2)), G_DBUS_CALL_FLAGS_NONE, @@ -1734,28 +1534,13 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ NULL, NULL); - /* Check whether NetworkReply and AP mode are supported. - * ready_count was initialized to 1 in interface_add_done(). - */ - g_dbus_proxy_call (priv->iface_proxy, - "NetworkReply", - g_variant_new ("(oss)", - "/fff", - "foobar", - "foobar"), - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->init_cancellable, - (GAsyncReadyCallback) iface_check_netreply_cb, - self); - - if (priv->pmf_support == NM_SUPPLICANT_FEATURE_YES) { + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_PMF) == NM_TERNARY_TRUE) { /* Initialize global PMF setting to 'optional' */ priv->ready_count++; g_dbus_proxy_call (priv->iface_proxy, DBUS_INTERFACE_PROPERTIES ".Set", g_variant_new ("(ssv)", - WPAS_DBUS_IFACE_INTERFACE, + NM_WPAS_DBUS_IFACE_INTERFACE, "Pmf", g_variant_new_string ("1")), G_DBUS_CALL_FLAGS_NONE, @@ -1765,7 +1550,7 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ self); } - if (priv->ap_support == NM_SUPPLICANT_FEATURE_UNKNOWN) { + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_AP) == NM_TERNARY_DEFAULT) { /* If the global supplicant capabilities property is not present, we can * fall back to checking whether the ProbeRequest method is supported. If * neither of these works we have no way of determining if AP mode is @@ -1781,6 +1566,8 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ (GAsyncReadyCallback) iface_introspect_cb, self); } + + iface_check_ready (self); } static void @@ -1791,7 +1578,7 @@ on_p2p_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_da gs_free_error GError *error = NULL; if (!g_async_initable_init_finish (G_ASYNC_INITABLE (proxy), result, &error)) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + if (!nm_utils_error_is_cancelled (error)) { self = NM_SUPPLICANT_INTERFACE (user_data); priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); _LOGW ("failed to acquire wpa_supplicant p2p proxy: (%s)", error->message); @@ -1812,8 +1599,6 @@ on_p2p_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_da G_CALLBACK (p2p_device_lost), self); _nm_dbus_signal_connect (priv->p2p_proxy, "GroupStarted", G_VARIANT_TYPE ("(a{sv})"), G_CALLBACK (p2p_group_started), self); - _nm_dbus_signal_connect (priv->p2p_proxy, "GroupFormationFailure", G_VARIANT_TYPE ("(s)"), - G_CALLBACK (p2p_group_formation_failure), self); _nm_dbus_signal_connect (priv->p2p_proxy, "GroupFinished", G_VARIANT_TYPE ("(a{sv})"), G_CALLBACK (p2p_group_finished), self); /* TODO: @@ -1836,7 +1621,6 @@ interface_add_done (NMSupplicantInterface *self, const char *path) _LOGD ("interface added to supplicant"); - /* Iface ready check happens in iface_check_netreply_cb */ priv->ready_count = 1; priv->object_path = g_strdup (path); @@ -1844,9 +1628,9 @@ interface_add_done (NMSupplicantInterface *self, const char *path) priv->iface_proxy = g_object_new (G_TYPE_DBUS_PROXY, "g-bus-type", G_BUS_TYPE_SYSTEM, "g-flags", G_DBUS_PROXY_FLAGS_NONE, - "g-name", WPAS_DBUS_SERVICE, + "g-name", NM_WPAS_DBUS_SERVICE, "g-object-path", priv->object_path, - "g-interface-name", WPAS_DBUS_IFACE_INTERFACE, + "g-interface-name", NM_WPAS_DBUS_IFACE_INTERFACE, NULL); g_signal_connect (priv->iface_proxy, "g-properties-changed", G_CALLBACK (props_changed_cb), self); g_async_initable_init_async (G_ASYNC_INITABLE (priv->iface_proxy), @@ -1855,14 +1639,14 @@ interface_add_done (NMSupplicantInterface *self, const char *path) (GAsyncReadyCallback) on_iface_proxy_acquired, self); - if (priv->p2p_support == NM_SUPPLICANT_FEATURE_YES) { + if (_get_capability (priv, NM_SUPPL_CAP_TYPE_P2P) == NM_TERNARY_TRUE) { priv->ready_count++; priv->p2p_proxy = g_object_new (G_TYPE_DBUS_PROXY, "g-bus-type", G_BUS_TYPE_SYSTEM, "g-flags", G_DBUS_PROXY_FLAGS_NONE, - "g-name", WPAS_DBUS_SERVICE, + "g-name", NM_WPAS_DBUS_SERVICE, "g-object-path", priv->object_path, - "g-interface-name", WPAS_DBUS_IFACE_INTERFACE_P2P_DEVICE, + "g-interface-name", NM_WPAS_DBUS_IFACE_INTERFACE_P2P_DEVICE, NULL); g_signal_connect (priv->p2p_proxy, "g-properties-changed", G_CALLBACK (p2p_props_changed_cb), self); g_async_initable_init_async (G_ASYNC_INITABLE (priv->p2p_proxy), @@ -1884,7 +1668,7 @@ interface_get_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) variant = _nm_dbus_proxy_call_finish (proxy, result, G_VARIANT_TYPE ("(o)"), &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -1911,7 +1695,7 @@ interface_add_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) variant = _nm_dbus_proxy_call_finish (proxy, result, G_VARIANT_TYPE ("(o)"), &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -1920,7 +1704,7 @@ interface_add_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) if (variant) { g_variant_get (variant, "(&o)", &path); interface_add_done (self, path); - } else if (_nm_dbus_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) { + } else if (_nm_dbus_error_has_name (error, NM_WPAS_ERROR_EXISTS_ERROR)) { /* Interface already added, just get its object path */ g_dbus_proxy_call (priv->wpas_proxy, "GetInterface", @@ -1985,12 +1769,6 @@ interface_removed_cb (GDBusProxy *proxy, g_object_unref (self); } -#if HAVE_WEXT -#define DEFAULT_WIFI_DRIVER "nl80211,wext" -#else -#define DEFAULT_WIFI_DRIVER "nl80211" -#endif - static void on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) { @@ -2002,7 +1780,7 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d wpas_proxy = g_dbus_proxy_new_for_bus_finish (result, &error); if (!wpas_proxy) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + if (!nm_utils_error_is_cancelled (error)) { self = NM_SUPPLICANT_INTERFACE (user_data); _LOGW ("failed to acquire wpa_supplicant proxy: (%s)", error->message); set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN); @@ -2029,7 +1807,7 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d switch (priv->driver) { case NM_SUPPLICANT_DRIVER_WIRELESS: - driver_name = DEFAULT_WIFI_DRIVER; + driver_name = NM_WPAS_DEFAULT_WIFI_DRIVER; break; case NM_SUPPLICANT_DRIVER_WIRED: driver_name = "wired"; @@ -2083,9 +1861,9 @@ interface_add (NMSupplicantInterface *self) g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, - WPAS_DBUS_SERVICE, - WPAS_DBUS_PATH, - WPAS_DBUS_INTERFACE, + NM_WPAS_DBUS_SERVICE, + NM_WPAS_DBUS_PATH, + NM_WPAS_DBUS_INTERFACE, priv->init_cancellable, (GAsyncReadyCallback) on_wpas_proxy_acquired, self); @@ -2121,7 +1899,7 @@ log_result_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) reply = g_dbus_proxy_call_finish (proxy, result, &error); if ( !reply - && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) + && !nm_utils_error_is_cancelled (error) && !strstr (error->message, "fi.w1.wpa_supplicant1.NotConnected")) { g_dbus_error_strip_remote_error (error); nm_log_warn (_NMLOG_DOMAIN, "%s: failed to %s: %s", @@ -2276,7 +2054,7 @@ assoc_select_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ gs_free_error GError *error = NULL; reply = g_dbus_proxy_call_finish (proxy, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -2310,7 +2088,7 @@ assoc_add_blob_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) gs_free_error GError *error = NULL; reply = g_dbus_proxy_call_finish (proxy, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -2417,7 +2195,7 @@ assoc_set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_dat AddNetworkData *add_network_data; reply = g_dbus_proxy_call_finish (proxy, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -2504,7 +2282,7 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self, /* Make sure the supplicant supports EAP-FAST before trying to send * it an EAP-FAST configuration. */ - if ( priv->fast_support == NM_SUPPLICANT_FEATURE_NO + if ( _get_capability (priv, NM_SUPPL_CAP_TYPE_FAST) == NM_TERNARY_FALSE && nm_supplicant_config_fast_required (cfg)) { assoc_data->fail_on_idle_id = g_idle_add (assoc_fail_on_idle_cb, self); return; @@ -2514,7 +2292,7 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self, g_dbus_proxy_call (priv->iface_proxy, DBUS_INTERFACE_PROPERTIES ".Set", g_variant_new ("(ssv)", - WPAS_DBUS_IFACE_INTERFACE, + NM_WPAS_DBUS_IFACE_INTERFACE, "ApScan", g_variant_new_uint32 (nm_supplicant_config_get_ap_scan (priv->assoc_data->cfg))), G_DBUS_CALL_FLAGS_NONE, @@ -2534,7 +2312,7 @@ scan_request_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) gs_free_error GError *error = NULL; reply = g_dbus_proxy_call_finish (proxy, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (nm_utils_error_is_cancelled (error)) return; self = NM_SUPPLICANT_INTERFACE (user_data); @@ -2815,41 +2593,9 @@ set_property (GObject *object, /* construct-only */ priv->driver = g_value_get_uint (value); break; - case PROP_FAST_SUPPORT: + case PROP_GLOBAL_CAPABILITIES: /* construct-only */ - priv->fast_support = g_value_get_int (value); - break; - case PROP_AP_SUPPORT: - /* construct-only */ - priv->ap_support = g_value_get_int (value); - break; - case PROP_PMF_SUPPORT: - /* construct-only */ - priv->pmf_support = g_value_get_int (value); - break; - case PROP_FILS_SUPPORT: - /* construct-only */ - priv->fils_support = g_value_get_int (value); - break; - case PROP_P2P_SUPPORT: - /* construct-only */ - priv->p2p_support = g_value_get_int (value); - break; - case PROP_MESH_SUPPORT: - /* construct-only */ - priv->mesh_support = g_value_get_int (value); - break; - case PROP_WFD_SUPPORT: - /* construct-only */ - priv->wfd_support = g_value_get_int (value); - break; - case PROP_FT_SUPPORT: - /* construct-only */ - priv->ft_support_global = g_value_get_int (value); - break; - case PROP_SHA384_SUPPORT: - /* construct-only */ - priv->sha384_support = g_value_get_int (value); + priv->global_capabilities = g_value_get_uint64 (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -2860,7 +2606,16 @@ set_property (GObject *object, static void nm_supplicant_interface_init (NMSupplicantInterface * self) { - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInterfacePrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfacePrivate); + + self->_priv = priv; + + c_list_init (&self->supp_lst); + + nm_assert (priv->global_capabilities == NM_SUPPL_CAP_MASK_NONE); + nm_assert (priv->iface_capabilities == NM_SUPPL_CAP_MASK_NONE); priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT; priv->bss_proxies = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, bss_data_destroy); @@ -2871,33 +2626,16 @@ NMSupplicantInterface * nm_supplicant_interface_new (const char *ifname, const char *object_path, NMSupplicantDriver driver, - NMSupplicantFeature fast_support, - NMSupplicantFeature ap_support, - NMSupplicantFeature pmf_support, - NMSupplicantFeature fils_support, - NMSupplicantFeature p2p_support, - NMSupplicantFeature mesh_support, - NMSupplicantFeature wfd_support, - NMSupplicantFeature ft_support, - NMSupplicantFeature sha384_support) + NMSupplCapMask global_capabilities) { /* One of ifname or path need to be set */ - g_return_val_if_fail (ifname != NULL || object_path != NULL, NULL); - g_return_val_if_fail (ifname == NULL || object_path == NULL, NULL); + g_return_val_if_fail ((ifname != NULL) != (object_path != NULL), NULL); return g_object_new (NM_TYPE_SUPPLICANT_INTERFACE, NM_SUPPLICANT_INTERFACE_IFACE, ifname, NM_SUPPLICANT_INTERFACE_OBJECT_PATH, object_path, NM_SUPPLICANT_INTERFACE_DRIVER, (guint) driver, - NM_SUPPLICANT_INTERFACE_FAST_SUPPORT, (int) fast_support, - NM_SUPPLICANT_INTERFACE_AP_SUPPORT, (int) ap_support, - NM_SUPPLICANT_INTERFACE_PMF_SUPPORT, (int) pmf_support, - NM_SUPPLICANT_INTERFACE_FILS_SUPPORT, (int) fils_support, - NM_SUPPLICANT_INTERFACE_P2P_SUPPORT, (int) p2p_support, - NM_SUPPLICANT_INTERFACE_MESH_SUPPORT, (int) mesh_support, - NM_SUPPLICANT_INTERFACE_WFD_SUPPORT, (int) wfd_support, - NM_SUPPLICANT_INTERFACE_FT_SUPPORT, (int) ft_support, - NM_SUPPLICANT_INTERFACE_SHA384_SUPPORT, (int) sha384_support, + NM_SUPPLICANT_INTERFACE_GLOBAL_CAPABILITIES, (guint64) global_capabilities, NULL); } @@ -2907,6 +2645,8 @@ dispose (GObject *object) NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (object); NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + nm_assert (c_list_is_empty (&self->supp_lst)); + nm_supplicant_interface_cancel_wps (self); if (priv->wps_data) { /* we shut down, but an asynchronous Cancel request is pending. @@ -2956,7 +2696,9 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->dispose = dispose; + g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate)); + + object_class->dispose = dispose; object_class->set_property = set_property; object_class->get_property = get_property; @@ -3008,78 +2750,14 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_FAST_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_FAST_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_AP_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_AP_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_PMF_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_PMF_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_FILS_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_FILS_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_P2P_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_P2P_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_MESH_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_MESH_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_WFD_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_WFD_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_FT_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_FT_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_SHA384_SUPPORT] = - g_param_spec_int (NM_SUPPLICANT_INTERFACE_SHA384_SUPPORT, "", "", - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SUPPLICANT_FEATURE_YES, - NM_SUPPLICANT_FEATURE_UNKNOWN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); + obj_properties[PROP_GLOBAL_CAPABILITIES] = + g_param_spec_uint64 (NM_SUPPLICANT_INTERFACE_GLOBAL_CAPABILITIES, "", "", + 0, + NM_SUPPL_CAP_MASK_ALL, + 0, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_AUTH_STATE] = g_param_spec_uint (NM_SUPPLICANT_INTERFACE_AUTH_STATE, "", "", NM_SUPPLICANT_AUTH_STATE_UNKNOWN, @@ -3146,14 +2824,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - signals[CREDENTIALS_REQUEST] = - g_signal_new (NM_SUPPLICANT_INTERFACE_CREDENTIALS_REQUEST, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); - signals[WPS_CREDENTIALS] = g_signal_new (NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS, G_OBJECT_CLASS_TYPE (object_class), @@ -3177,12 +2847,4 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[GROUP_FORMATION_FAILURE] = - g_signal_new (NM_SUPPLICANT_INTERFACE_GROUP_FORMATION_FAILURE, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_STRING); } diff --git a/src/supplicant/nm-supplicant-interface.h b/src/supplicant/nm-supplicant-interface.h index 3580f75445..25dca98481 100644 --- a/src/supplicant/nm-supplicant-interface.h +++ b/src/supplicant/nm-supplicant-interface.h @@ -9,6 +9,8 @@ #include "nm-supplicant-types.h" +#include "c-list/src/c-list.h" + /* * Supplicant interface states * A mix of wpa_supplicant interface states and internal states. @@ -18,6 +20,7 @@ typedef enum { NM_SUPPLICANT_INTERFACE_STATE_INIT = 0, NM_SUPPLICANT_INTERFACE_STATE_STARTING, NM_SUPPLICANT_INTERFACE_STATE_READY, + NM_SUPPLICANT_INTERFACE_STATE_DISABLED, NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, NM_SUPPLICANT_INTERFACE_STATE_INACTIVE, @@ -28,6 +31,7 @@ typedef enum { NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE, NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE, NM_SUPPLICANT_INTERFACE_STATE_COMPLETED, + NM_SUPPLICANT_INTERFACE_STATE_DOWN, } NMSupplicantInterfaceState; @@ -46,57 +50,45 @@ 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)) -/* Properties */ -#define NM_SUPPLICANT_INTERFACE_IFACE "iface" -#define NM_SUPPLICANT_INTERFACE_OBJECT_PATH "object-path" -#define NM_SUPPLICANT_INTERFACE_SCANNING "scanning" -#define NM_SUPPLICANT_INTERFACE_CURRENT_BSS "current-bss" -#define NM_SUPPLICANT_INTERFACE_P2P_GROUP_JOINED "p2p-group-joined" -#define NM_SUPPLICANT_INTERFACE_P2P_GROUP_PATH "p2p-group-path" -#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_FAST_SUPPORT "fast-support" -#define NM_SUPPLICANT_INTERFACE_AP_SUPPORT "ap-support" -#define NM_SUPPLICANT_INTERFACE_PMF_SUPPORT "pmf-support" -#define NM_SUPPLICANT_INTERFACE_FILS_SUPPORT "fils-support" -#define NM_SUPPLICANT_INTERFACE_P2P_SUPPORT "p2p-support" -#define NM_SUPPLICANT_INTERFACE_MESH_SUPPORT "mesh-support" -#define NM_SUPPLICANT_INTERFACE_WFD_SUPPORT "wfd-support" -#define NM_SUPPLICANT_INTERFACE_FT_SUPPORT "ft-support" -#define NM_SUPPLICANT_INTERFACE_SHA384_SUPPORT "sha384-support" -#define NM_SUPPLICANT_INTERFACE_AUTH_STATE "auth-state" +#define NM_SUPPLICANT_INTERFACE_IFACE "iface" +#define NM_SUPPLICANT_INTERFACE_OBJECT_PATH "object-path" +#define NM_SUPPLICANT_INTERFACE_SCANNING "scanning" +#define NM_SUPPLICANT_INTERFACE_CURRENT_BSS "current-bss" +#define NM_SUPPLICANT_INTERFACE_P2P_GROUP_JOINED "p2p-group-joined" +#define NM_SUPPLICANT_INTERFACE_P2P_GROUP_PATH "p2p-group-path" +#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" -/* Signals */ -#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_SCAN_DONE "scan-done" -#define NM_SUPPLICANT_INTERFACE_CREDENTIALS_REQUEST "credentials-request" -#define NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS "wps-credentials" +#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_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" -#define NM_SUPPLICANT_INTERFACE_GROUP_FORMATION_FAILURE "group-formation-failure" typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass; +struct _NMSupplicantInterfacePrivate; + +struct _NMSupplicantInterface { + GObject parent; + CList supp_lst; + struct _NMSupplicantInterfacePrivate *_priv; +}; + GType nm_supplicant_interface_get_type (void); -NMSupplicantInterface * nm_supplicant_interface_new (const char *ifname, - const char *object_path, - NMSupplicantDriver driver, - NMSupplicantFeature fast_support, - NMSupplicantFeature ap_support, - NMSupplicantFeature pmf_support, - NMSupplicantFeature fils_support, - NMSupplicantFeature p2p_support, - NMSupplicantFeature mesh_support, - NMSupplicantFeature wfd_support, - NMSupplicantFeature ft_support, - NMSupplicantFeature sha384_support); +NMSupplicantInterface *nm_supplicant_interface_new (const char *ifname, + const char *object_path, + NMSupplicantDriver driver, + NMSupplCapMask global_capabilities); void nm_supplicant_interface_set_supplicant_available (NMSupplicantInterface *self, gboolean available); @@ -143,19 +135,12 @@ const char *nm_supplicant_interface_get_ifname (NMSupplicantInterface *self); guint nm_supplicant_interface_get_max_scan_ssids (NMSupplicantInterface *self); -gboolean nm_supplicant_interface_get_has_credentials_request (NMSupplicantInterface *self); - gboolean nm_supplicant_interface_get_p2p_group_joined (NMSupplicantInterface *self); const char* nm_supplicant_interface_get_p2p_group_path (NMSupplicantInterface *self); gboolean nm_supplicant_interface_get_p2p_group_owner (NMSupplicantInterface *self); -gboolean nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self, - const char *field, - const char *value, - GError **error); - void nm_supplicant_interface_p2p_start_find (NMSupplicantInterface *self, guint timeout); void nm_supplicant_interface_p2p_stop_find (NMSupplicantInterface *self); @@ -167,41 +152,13 @@ void nm_supplicant_interface_p2p_connect (NMSupplicantInterface * self, void nm_supplicant_interface_p2p_cancel_connect (NMSupplicantInterface * self); void nm_supplicant_interface_p2p_disconnect (NMSupplicantInterface * self); -NMSupplicantFeature nm_supplicant_interface_get_ap_support (NMSupplicantInterface *self); -NMSupplicantFeature nm_supplicant_interface_get_pmf_support (NMSupplicantInterface *self); -NMSupplicantFeature nm_supplicant_interface_get_fils_support (NMSupplicantInterface *self); -NMSupplicantFeature nm_supplicant_interface_get_p2p_support (NMSupplicantInterface *self); -NMSupplicantFeature nm_supplicant_interface_get_mesh_support (NMSupplicantInterface *self); -NMSupplicantFeature nm_supplicant_interface_get_wfd_support (NMSupplicantInterface *self); -NMSupplicantFeature nm_supplicant_interface_get_ft_support (NMSupplicantInterface *self); -NMSupplicantFeature nm_supplicant_interface_get_sha384_support (NMSupplicantInterface *self); +void nm_supplicant_interface_set_global_capabilities (NMSupplicantInterface *self, + NMSupplCapMask value); -void nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self, - NMSupplicantFeature apmode); +NMTernary nm_supplicant_interface_get_capability (NMSupplicantInterface *self, + NMSupplCapType type); -void nm_supplicant_interface_set_fast_support (NMSupplicantInterface *self, - NMSupplicantFeature fast_support); - -void nm_supplicant_interface_set_pmf_support (NMSupplicantInterface *self, - NMSupplicantFeature pmf_support); - -void nm_supplicant_interface_set_fils_support (NMSupplicantInterface *self, - NMSupplicantFeature fils_support); - -void nm_supplicant_interface_set_p2p_support (NMSupplicantInterface *self, - NMSupplicantFeature p2p_support); - -void nm_supplicant_interface_set_mesh_support (NMSupplicantInterface *self, - NMSupplicantFeature mesh_support); - -void nm_supplicant_interface_set_wfd_support (NMSupplicantInterface *self, - NMSupplicantFeature wfd_support); - -void nm_supplicant_interface_set_ft_support (NMSupplicantInterface *self, - NMSupplicantFeature ft_support); - -void nm_supplicant_interface_set_sha384_support (NMSupplicantInterface *self, - NMSupplicantFeature sha384_support); +NMSupplCapMask nm_supplicant_interface_get_capabilities (NMSupplicantInterface *self); void nm_supplicant_interface_enroll_wps (NMSupplicantInterface *self, const char *const type, diff --git a/src/supplicant/nm-supplicant-manager.c b/src/supplicant/nm-supplicant-manager.c index 49581f6e7e..65b910cade 100644 --- a/src/supplicant/nm-supplicant-manager.c +++ b/src/supplicant/nm-supplicant-manager.c @@ -15,22 +15,13 @@ /*****************************************************************************/ typedef struct { - GDBusProxy * proxy; - GCancellable * cancellable; - gboolean running; - - GSList *ifaces; - NMSupplicantFeature fast_support; - NMSupplicantFeature ap_support; - NMSupplicantFeature pmf_support; - NMSupplicantFeature fils_support; - NMSupplicantFeature p2p_support; - NMSupplicantFeature mesh_support; - NMSupplicantFeature wfd_support; - NMSupplicantFeature ft_support; - NMSupplicantFeature sha384_support; - guint die_count_reset_id; - guint die_count; + GDBusProxy *proxy; + GCancellable *cancellable; + CList supp_lst_head; + NMSupplCapMask capabilities; + guint die_count_reset_id; + guint die_count; + bool running:1; } NMSupplicantManagerPrivate; struct _NMSupplicantManager { @@ -57,6 +48,30 @@ NM_CACHED_QUARK_FCN ("nm-supplicant-error-quark", nm_supplicant_error_quark) /*****************************************************************************/ +static void +_caps_set (NMSupplicantManagerPrivate *priv, + NMSupplCapType type, + NMTernary value) +{ + priv->capabilities = NM_SUPPL_CAP_MASK_SET (priv->capabilities, type, value); +} + +static const char * +_caps_to_str (NMSupplicantManagerPrivate *priv, + NMSupplCapType type) +{ + NMTernary val; + + val = NM_SUPPL_CAP_MASK_GET (priv->capabilities, type);; + if (val == NM_TERNARY_TRUE) + return "supported"; + if (val == NM_TERNARY_FALSE) + return "not supported"; + return "possibly supported"; +} + +/*****************************************************************************/ + static gboolean die_count_exceeded (guint32 count) { @@ -80,20 +95,15 @@ _sup_iface_last_ref (gpointer data, gboolean is_last_ref) { NMSupplicantManager *self = data; - NMSupplicantManagerPrivate *priv; - NMSupplicantInterface *sup_iface = (NMSupplicantInterface *) object; + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + NMSupplicantInterface *sup_iface = NM_SUPPLICANT_INTERFACE (object); const char *op; - g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self)); - g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (sup_iface)); - g_return_if_fail (is_last_ref); + nm_assert (is_last_ref); + nm_assert (c_list_contains (&priv->supp_lst_head, &sup_iface->supp_lst)); - priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + c_list_unlink (&sup_iface->supp_lst); - if (!g_slist_find (priv->ifaces, sup_iface)) - g_return_if_reached (); - - /* Ask wpa_supplicant to remove this interface */ if ( priv->running && priv->proxy && (op = nm_supplicant_interface_get_object_path (sup_iface))) { @@ -107,8 +117,7 @@ _sup_iface_last_ref (gpointer data, NULL); } - priv->ifaces = g_slist_remove (priv->ifaces, sup_iface); - g_object_remove_toggle_ref ((GObject *) sup_iface, _sup_iface_last_ref, self); + g_object_remove_toggle_ref (G_OBJECT (sup_iface), _sup_iface_last_ref, self); } static void @@ -140,7 +149,6 @@ nm_supplicant_manager_set_wfd_ies (NMSupplicantManager *self, { NMSupplicantManagerPrivate *priv; GVariantBuilder params; - GVariant *val; g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self)); @@ -148,20 +156,12 @@ nm_supplicant_manager_set_wfd_ies (NMSupplicantManager *self, _LOGD ("setting WFD IEs for P2P operation"); - if (wfd_ies) - val = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - g_bytes_get_data (wfd_ies, NULL), - g_bytes_get_size (wfd_ies), - sizeof (guint8)); - else - val = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - NULL, 0, sizeof (guint8)); - g_variant_builder_init (¶ms, G_VARIANT_TYPE ("(ssv)")); g_variant_builder_add (¶ms, "s", g_dbus_proxy_get_interface_name (priv->proxy)); g_variant_builder_add (¶ms, "s", "WFDIEs"); - g_variant_builder_add_value (¶ms, g_variant_new_variant (val)); + g_variant_builder_add_value (¶ms, + g_variant_new_variant (nm_utils_gbytes_to_variant_ay (wfd_ies))); g_dbus_connection_call (g_dbus_proxy_get_connection (priv->proxy), g_dbus_proxy_get_name (priv->proxy), @@ -196,8 +196,7 @@ nm_supplicant_manager_create_interface (NMSupplicantManager *self, NMSupplicantDriver driver) { NMSupplicantManagerPrivate *priv; - NMSupplicantInterface *iface; - GSList *ifaces; + NMSupplicantInterface *sup_iface; g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL); g_return_val_if_fail (ifname != NULL, NULL); @@ -206,27 +205,18 @@ nm_supplicant_manager_create_interface (NMSupplicantManager *self, _LOGD ("(%s): creating new supplicant interface", ifname); - /* assert against not requesting duplicate interfaces. */ - for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) { - if (g_strcmp0 (nm_supplicant_interface_get_ifname (ifaces->data), ifname) == 0) + c_list_for_each_entry (sup_iface, &priv->supp_lst_head, supp_lst) { + if (nm_streq0 (nm_supplicant_interface_get_ifname (sup_iface), ifname)) g_return_val_if_reached (NULL); } - iface = nm_supplicant_interface_new (ifname, - NULL, - driver, - priv->fast_support, - priv->ap_support, - priv->pmf_support, - priv->fils_support, - priv->p2p_support, - priv->mesh_support, - priv->wfd_support, - priv->ft_support, - priv->sha384_support); + sup_iface = nm_supplicant_interface_new (ifname, + NULL, + driver, + priv->capabilities); - priv->ifaces = g_slist_prepend (priv->ifaces, iface); - g_object_add_toggle_ref ((GObject *) iface, _sup_iface_last_ref, self); + c_list_link_tail (&priv->supp_lst_head, &sup_iface->supp_lst); + g_object_add_toggle_ref (G_OBJECT (sup_iface), _sup_iface_last_ref, self); /* If we're making the supplicant take a time out for a bit, don't * let the supplicant interface start immediately, just let it hang @@ -234,9 +224,9 @@ nm_supplicant_manager_create_interface (NMSupplicantManager *self, * again. */ if (is_available (self)) - nm_supplicant_interface_set_supplicant_available (iface, TRUE); + nm_supplicant_interface_set_supplicant_available (sup_iface, TRUE); - return iface; + return sup_iface; } /** @@ -256,8 +246,7 @@ nm_supplicant_manager_create_interface_from_path (NMSupplicantManager *self, const char *object_path) { NMSupplicantManagerPrivate *priv; - NMSupplicantInterface *iface; - GSList *ifaces; + NMSupplicantInterface *sup_iface; g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL); g_return_val_if_fail (object_path != NULL, NULL); @@ -266,27 +255,18 @@ nm_supplicant_manager_create_interface_from_path (NMSupplicantManager *self, _LOGD ("creating new supplicant interface for dbus path %s", object_path); - /* assert against not requesting duplicate interfaces. */ - for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) { - if (g_strcmp0 (nm_supplicant_interface_get_object_path (ifaces->data), object_path) == 0) + c_list_for_each_entry (sup_iface, &priv->supp_lst_head, supp_lst) { + if (nm_streq0 (nm_supplicant_interface_get_object_path (sup_iface), object_path)) g_return_val_if_reached (NULL); } - iface = nm_supplicant_interface_new (NULL, - object_path, - NM_SUPPLICANT_DRIVER_WIRELESS, - priv->fast_support, - priv->ap_support, - priv->pmf_support, - priv->fils_support, - priv->p2p_support, - priv->mesh_support, - priv->wfd_support, - priv->ft_support, - priv->sha384_support); + sup_iface = nm_supplicant_interface_new (NULL, + object_path, + NM_SUPPLICANT_DRIVER_WIRELESS, + priv->capabilities); - priv->ifaces = g_slist_prepend (priv->ifaces, iface); - g_object_add_toggle_ref ((GObject *) iface, _sup_iface_last_ref, self); + c_list_link_tail (&priv->supp_lst_head, &sup_iface->supp_lst); + g_object_add_toggle_ref (G_OBJECT (sup_iface), _sup_iface_last_ref, self); /* If we're making the supplicant take a time out for a bit, don't * let the supplicant interface start immediately, just let it hang @@ -294,16 +274,16 @@ nm_supplicant_manager_create_interface_from_path (NMSupplicantManager *self, * again. */ if (is_available (self)) - nm_supplicant_interface_set_supplicant_available (iface, TRUE); + nm_supplicant_interface_set_supplicant_available (sup_iface, TRUE); - return iface; + return sup_iface; } static void update_capabilities (NMSupplicantManager *self) { NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - GSList *ifaces; + NMSupplicantInterface *sup_iface; const char **array; GVariant *value; @@ -316,82 +296,38 @@ update_capabilities (NMSupplicantManager *self) * * dbus: Add global capabilities property */ - priv->ap_support = NM_SUPPLICANT_FEATURE_UNKNOWN; - priv->pmf_support = NM_SUPPLICANT_FEATURE_UNKNOWN; - priv->fils_support = NM_SUPPLICANT_FEATURE_UNKNOWN; + _caps_set (priv, NM_SUPPL_CAP_TYPE_AP, NM_TERNARY_DEFAULT); + _caps_set (priv, NM_SUPPL_CAP_TYPE_PMF, NM_TERNARY_DEFAULT); + _caps_set (priv, NM_SUPPL_CAP_TYPE_FILS, NM_TERNARY_DEFAULT); + /* Support for the following is newer than the capabilities property */ - priv->p2p_support = NM_SUPPLICANT_FEATURE_NO; - priv->ft_support = NM_SUPPLICANT_FEATURE_NO; - priv->sha384_support = NM_SUPPLICANT_FEATURE_NO; - priv->mesh_support = NM_SUPPLICANT_FEATURE_NO; + _caps_set (priv, NM_SUPPL_CAP_TYPE_P2P, NM_TERNARY_FALSE); + _caps_set (priv, NM_SUPPL_CAP_TYPE_FT, NM_TERNARY_FALSE); + _caps_set (priv, NM_SUPPL_CAP_TYPE_SHA384, NM_TERNARY_FALSE); + _caps_set (priv, NM_SUPPL_CAP_TYPE_MESH, NM_TERNARY_FALSE); value = g_dbus_proxy_get_cached_property (priv->proxy, "Capabilities"); if (value) { if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) { array = g_variant_get_strv (value, NULL); - priv->ap_support = NM_SUPPLICANT_FEATURE_NO; - priv->pmf_support = NM_SUPPLICANT_FEATURE_NO; - priv->fils_support = NM_SUPPLICANT_FEATURE_NO; - priv->p2p_support = NM_SUPPLICANT_FEATURE_NO; - priv->ft_support = NM_SUPPLICANT_FEATURE_NO; - priv->sha384_support = NM_SUPPLICANT_FEATURE_NO; - priv->mesh_support = NM_SUPPLICANT_FEATURE_NO; + _caps_set (priv, NM_SUPPL_CAP_TYPE_AP, NM_TERNARY_FALSE); + _caps_set (priv, NM_SUPPL_CAP_TYPE_PMF, NM_TERNARY_FALSE); + _caps_set (priv, NM_SUPPL_CAP_TYPE_FILS, NM_TERNARY_FALSE); if (array) { - if (g_strv_contains (array, "ap")) - priv->ap_support = NM_SUPPLICANT_FEATURE_YES; - if (g_strv_contains (array, "pmf")) - priv->pmf_support = NM_SUPPLICANT_FEATURE_YES; - if (g_strv_contains (array, "fils")) - priv->fils_support = NM_SUPPLICANT_FEATURE_YES; - if (g_strv_contains (array, "p2p")) - priv->p2p_support = NM_SUPPLICANT_FEATURE_YES; - if (g_strv_contains (array, "ft")) - priv->ft_support = NM_SUPPLICANT_FEATURE_YES; - if (g_strv_contains (array, "sha384")) - priv->sha384_support = NM_SUPPLICANT_FEATURE_YES; - if (g_strv_contains (array, "mesh")) - priv->mesh_support = NM_SUPPLICANT_FEATURE_YES; + if (g_strv_contains (array, "ap")) _caps_set (priv, NM_SUPPL_CAP_TYPE_AP, NM_TERNARY_TRUE); + if (g_strv_contains (array, "pmf")) _caps_set (priv, NM_SUPPL_CAP_TYPE_PMF, NM_TERNARY_TRUE); + if (g_strv_contains (array, "fils")) _caps_set (priv, NM_SUPPL_CAP_TYPE_FILS, NM_TERNARY_TRUE); + if (g_strv_contains (array, "p2p")) _caps_set (priv, NM_SUPPL_CAP_TYPE_P2P, NM_TERNARY_TRUE); + if (g_strv_contains (array, "ft")) _caps_set (priv, NM_SUPPL_CAP_TYPE_FT, NM_TERNARY_TRUE); + if (g_strv_contains (array, "sha384")) _caps_set (priv, NM_SUPPL_CAP_TYPE_SHA384, NM_TERNARY_TRUE); + if (g_strv_contains (array, "mesh")) _caps_set (priv, NM_SUPPL_CAP_TYPE_MESH, NM_TERNARY_TRUE); g_free (array); } } g_variant_unref (value); } - /* Tell all interfaces about results of the AP/PMF/FILS/P2P/FT/SHA384 check */ - for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) { - nm_supplicant_interface_set_ap_support (ifaces->data, priv->ap_support); - nm_supplicant_interface_set_pmf_support (ifaces->data, priv->pmf_support); - nm_supplicant_interface_set_fils_support (ifaces->data, priv->fils_support); - nm_supplicant_interface_set_p2p_support (ifaces->data, priv->p2p_support); - nm_supplicant_interface_set_ft_support (ifaces->data, priv->ft_support); - nm_supplicant_interface_set_sha384_support (ifaces->data, priv->sha384_support); - nm_supplicant_interface_set_mesh_support (ifaces->data, priv->mesh_support); - } - - _LOGD ("AP mode is %ssupported", - (priv->ap_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->ap_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - _LOGD ("PMF is %ssupported", - (priv->pmf_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->pmf_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - _LOGD ("FILS is %ssupported", - (priv->fils_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->fils_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - _LOGD ("P2P is %ssupported", - (priv->p2p_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->p2p_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - _LOGD ("FT is %ssupported", - (priv->ft_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->ft_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - _LOGD ("SHA384 is %ssupported", - (priv->sha384_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->sha384_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - _LOGD ("Mesh is %ssupported", - (priv->mesh_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->mesh_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - - /* EAP-FAST */ - priv->fast_support = NM_SUPPLICANT_FEATURE_NO; + _caps_set (priv, NM_SUPPL_CAP_TYPE_FAST, NM_TERNARY_FALSE); value = g_dbus_proxy_get_cached_property (priv->proxy, "EapMethods"); if (value) { if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) { @@ -401,7 +337,7 @@ update_capabilities (NMSupplicantManager *self) for (a = array; *a; a++) { if (g_ascii_strcasecmp (*a, "FAST") == 0) { - priv->fast_support = NM_SUPPLICANT_FEATURE_YES; + _caps_set (priv, NM_SUPPL_CAP_TYPE_FAST, NM_TERNARY_TRUE); break; } } @@ -411,46 +347,51 @@ update_capabilities (NMSupplicantManager *self) g_variant_unref (value); } - for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) - nm_supplicant_interface_set_fast_support (ifaces->data, priv->fast_support); - - _LOGD ("EAP-FAST is %ssupported", - (priv->fast_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->fast_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); - - priv->wfd_support = NM_SUPPLICANT_FEATURE_NO; + _caps_set (priv, NM_SUPPL_CAP_TYPE_WFD, NM_TERNARY_FALSE); value = g_dbus_proxy_get_cached_property (priv->proxy, "WFDIEs"); if (value) { - priv->wfd_support = NM_SUPPLICANT_FEATURE_YES; + _caps_set (priv, NM_SUPPL_CAP_TYPE_WFD, NM_TERNARY_TRUE); g_variant_unref (value); } - for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) - nm_supplicant_interface_set_wfd_support (ifaces->data, priv->fast_support); + _LOGD ("AP mode is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_AP)); + _LOGD ("PMF is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_PMF)); + _LOGD ("FILS is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_FILS)); + _LOGD ("P2P is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_P2P)); + _LOGD ("FT is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_FT)); + _LOGD ("SHA384 is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_SHA384)); + _LOGD ("Mesh is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_MESH)); + _LOGD ("EAP-FAST is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_FAST)); + _LOGD ("WFD is %s", _caps_to_str (priv, NM_SUPPL_CAP_TYPE_WFD)); - _LOGD ("WFD is %ssupported", - (priv->wfd_support == NM_SUPPLICANT_FEATURE_YES) ? "" : - (priv->wfd_support == NM_SUPPLICANT_FEATURE_NO) ? "not " : "possibly "); + c_list_for_each_entry (sup_iface, &priv->supp_lst_head, supp_lst) { + nm_supplicant_interface_set_global_capabilities (sup_iface, + priv->capabilities); + } } static void availability_changed (NMSupplicantManager *self, gboolean available) { NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - GSList *ifaces, *iter; + gs_unref_ptrarray GPtrArray *sup_ifaces = NULL; + NMSupplicantInterface *sup_iface; + gsize i, n; - if (!priv->ifaces) + n = c_list_length (&priv->supp_lst_head); + if (n == 0) return; /* setting the supplicant as unavailable might cause the caller to unref * the supplicant (and thus remove the instance from the list of interfaces. * Delay that by taking an additional reference first. */ - ifaces = g_slist_copy (priv->ifaces); - for (iter = ifaces; iter; iter = iter->next) - g_object_ref (iter->data); - for (iter = ifaces; iter; iter = iter->next) - nm_supplicant_interface_set_supplicant_available (iter->data, available); - g_slist_free_full (ifaces, g_object_unref); + + sup_ifaces = g_ptr_array_new_full (n, g_object_unref); + c_list_for_each_entry (sup_iface, &priv->supp_lst_head, supp_lst) + g_ptr_array_add (sup_ifaces, g_object_ref (sup_iface)); + + for (i = 0; i < n; i++) + nm_supplicant_interface_set_supplicant_available (sup_ifaces->pdata[i], available); } static void @@ -523,12 +464,7 @@ name_owner_cb (GDBusProxy *proxy, GParamSpec *pspec, gpointer user_data) priv->die_count); } - priv->ap_support = NM_SUPPLICANT_FEATURE_UNKNOWN; - priv->fast_support = NM_SUPPLICANT_FEATURE_UNKNOWN; - priv->pmf_support = NM_SUPPLICANT_FEATURE_UNKNOWN; - priv->fils_support = NM_SUPPLICANT_FEATURE_UNKNOWN; - priv->ft_support = NM_SUPPLICANT_FEATURE_UNKNOWN; - priv->sha384_support = NM_SUPPLICANT_FEATURE_UNKNOWN; + priv->capabilities = NM_SUPPL_CAP_MASK_NONE; set_running (self, FALSE); } @@ -569,13 +505,17 @@ nm_supplicant_manager_init (NMSupplicantManager *self) { NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + nm_assert (priv->capabilities == NM_SUPPL_CAP_MASK_NONE); + + c_list_init (&priv->supp_lst_head); + priv->cancellable = g_cancellable_new (); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, - WPAS_DBUS_SERVICE, - WPAS_DBUS_PATH, - WPAS_DBUS_INTERFACE, + NM_WPAS_DBUS_SERVICE, + NM_WPAS_DBUS_PATH, + NM_WPAS_DBUS_INTERFACE, priv->cancellable, (GAsyncReadyCallback) on_proxy_acquired, self); @@ -586,17 +526,15 @@ dispose (GObject *object) { NMSupplicantManager *self = (NMSupplicantManager *) object; NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - GSList *ifaces; + NMSupplicantInterface *sup_iface; nm_clear_g_source (&priv->die_count_reset_id); nm_clear_g_cancellable (&priv->cancellable); - if (priv->ifaces) { - for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) - g_object_remove_toggle_ref (ifaces->data, _sup_iface_last_ref, self); - g_slist_free (priv->ifaces); - priv->ifaces = NULL; + while ((sup_iface = c_list_first_entry (&priv->supp_lst_head, NMSupplicantInterface, supp_lst))) { + c_list_unlink (&sup_iface->supp_lst); + g_object_remove_toggle_ref (G_OBJECT (sup_iface), _sup_iface_last_ref, self); } g_clear_object (&priv->proxy); diff --git a/src/supplicant/nm-supplicant-types.h b/src/supplicant/nm-supplicant-types.h index 2b3563548b..de0283b24a 100644 --- a/src/supplicant/nm-supplicant-types.h +++ b/src/supplicant/nm-supplicant-types.h @@ -6,19 +6,114 @@ #ifndef __NETWORKMANAGER_SUPPLICANT_TYPES_H__ #define __NETWORKMANAGER_SUPPLICANT_TYPES_H__ -#define WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1" -#define WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1" -#define WPAS_DBUS_INTERFACE "fi.w1.wpa_supplicant1" +#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" + +#if HAVE_WEXT +#define NM_WPAS_DEFAULT_WIFI_DRIVER "nl80211,wext" +#else +#define NM_WPAS_DEFAULT_WIFI_DRIVER "nl80211" +#endif + +#define NM_WPAS_DBUS_IFACE_INTERFACE NM_WPAS_DBUS_INTERFACE ".Interface" +#define NM_WPAS_DBUS_IFACE_INTERFACE_WPS NM_WPAS_DBUS_INTERFACE ".Interface.WPS" +#define NM_WPAS_DBUS_IFACE_INTERFACE_P2P_DEVICE NM_WPAS_DBUS_INTERFACE ".Interface.P2PDevice" +#define NM_WPAS_DBUS_IFACE_BSS NM_WPAS_DBUS_INTERFACE ".BSS" +#define NM_WPAS_DBUS_IFACE_PEER NM_WPAS_DBUS_INTERFACE ".Peer" +#define NM_WPAS_DBUS_IFACE_GROUP NM_WPAS_DBUS_INTERFACE ".Group" +#define NM_WPAS_DBUS_IFACE_NETWORK NM_WPAS_DBUS_INTERFACE ".Network" +#define NM_WPAS_ERROR_INVALID_IFACE NM_WPAS_DBUS_INTERFACE ".InvalidInterface" +#define NM_WPAS_ERROR_EXISTS_ERROR NM_WPAS_DBUS_INTERFACE ".InterfaceExists" +#define NM_WPAS_ERROR_UNKNOWN_IFACE NM_WPAS_DBUS_INTERFACE ".InterfaceUnknown" typedef struct _NMSupplicantManager NMSupplicantManager; typedef struct _NMSupplicantInterface NMSupplicantInterface; typedef struct _NMSupplicantConfig NMSupplicantConfig; +/*****************************************************************************/ + typedef enum { - NM_SUPPLICANT_FEATURE_UNKNOWN = 0, /* Can't detect whether supported or not */ - NM_SUPPLICANT_FEATURE_NO = 1, /* Feature definitely not supported */ - NM_SUPPLICANT_FEATURE_YES = 2, /* Feature definitely supported */ -} NMSupplicantFeature; + NM_SUPPL_CAP_TYPE_AP = 0, + NM_SUPPL_CAP_TYPE_FAST, + NM_SUPPL_CAP_TYPE_PMF, + NM_SUPPL_CAP_TYPE_FILS, + NM_SUPPL_CAP_TYPE_P2P, + NM_SUPPL_CAP_TYPE_MESH, + NM_SUPPL_CAP_TYPE_WFD, + NM_SUPPL_CAP_TYPE_FT, + NM_SUPPL_CAP_TYPE_SHA384, + _NM_SUPPL_CAP_TYPE_NUM, +} NMSupplCapType; + +#define NM_SUPPL_CAP_MASK_NO(type) ((NMSupplCapMask) (1llu << ((type) * 2u))) +#define NM_SUPPL_CAP_MASK_YES(type) ((NMSupplCapMask) (2llu << ((type) * 2u))) +#define NM_SUPPL_CAP_MASK_MASK(type) ((NMSupplCapMask) (3llu << ((type) * 2u))) + +typedef enum { + NM_SUPPL_CAP_MASK_NONE = 0, + NM_SUPPL_CAP_MASK_ALL = ((1llu << (_NM_SUPPL_CAP_TYPE_NUM * 2)) - 1), + +/* usually it's bad to use macros to define enum values (because you cannot find them with ctags/cscope + * anymore. In this case, still do it because the alternative is ugly too. */ +#define _NM_SUPPL_CAP_MASK_DEFINE(type) \ + NM_SUPPL_CAP_MASK_T_##type##_NO = (1llu << ((NM_SUPPL_CAP_TYPE_##type) * 2u)), \ + NM_SUPPL_CAP_MASK_T_##type##_YES = (2llu << ((NM_SUPPL_CAP_TYPE_##type) * 2u)), \ + NM_SUPPL_CAP_MASK_T_##type##_MASK = (3llu << ((NM_SUPPL_CAP_TYPE_##type) * 2u)) + _NM_SUPPL_CAP_MASK_DEFINE (AP), + _NM_SUPPL_CAP_MASK_DEFINE (FAST), + _NM_SUPPL_CAP_MASK_DEFINE (PMF), + _NM_SUPPL_CAP_MASK_DEFINE (FILS), + _NM_SUPPL_CAP_MASK_DEFINE (P2P), + _NM_SUPPL_CAP_MASK_DEFINE (MESH), + _NM_SUPPL_CAP_MASK_DEFINE (WFD), + _NM_SUPPL_CAP_MASK_DEFINE (FT), + _NM_SUPPL_CAP_MASK_DEFINE (SHA384), +#undef _NM_SUPPL_CAP_MASK_DEFINE +} NMSupplCapMask; + +static inline NMSupplCapMask +NM_SUPPL_CAP_MASK_SET (NMSupplCapMask features, NMSupplCapType type, NMTernary value) +{ + nm_assert (_NM_INT_NOT_NEGATIVE (type)); + nm_assert (type < _NM_SUPPL_CAP_TYPE_NUM); + nm_assert (NM_IN_SET (value, NM_TERNARY_DEFAULT, + NM_TERNARY_TRUE, + NM_TERNARY_FALSE)); + nm_assert (!(features & ~NM_SUPPL_CAP_MASK_ALL)); + + features &= ~NM_SUPPL_CAP_MASK_MASK (type); + switch (value) { + case NM_TERNARY_FALSE: + features |= NM_SUPPL_CAP_MASK_NO (type); + break; + case NM_TERNARY_TRUE: + features |= NM_SUPPL_CAP_MASK_YES (type); + break; + case NM_TERNARY_DEFAULT: + break; + } + + return features; +} + +static inline NMTernary +NM_SUPPL_CAP_MASK_GET (NMSupplCapMask features, NMSupplCapType type) +{ + int f; + + nm_assert (_NM_INT_NOT_NEGATIVE (type)); + nm_assert (type < _NM_SUPPL_CAP_TYPE_NUM); + nm_assert (!(features & ~NM_SUPPL_CAP_MASK_ALL)); + + f = ((int) (features >> (2 * (int) type))) & 0x3; + + nm_assert (NM_IN_SET (f, 0, 1, 2)); + + return (NMTernary) (f - 1); +} + +/*****************************************************************************/ /** * NMSupplicantError: diff --git a/src/supplicant/tests/test-supplicant-config.c b/src/supplicant/tests/test-supplicant-config.c index 008735b423..f9c71f1251 100644 --- a/src/supplicant/tests/test-supplicant-config.c +++ b/src/supplicant/tests/test-supplicant-config.c @@ -86,8 +86,7 @@ static GVariant * build_supplicant_config (NMConnection *connection, guint mtu, guint fixed_freq, - gboolean support_pmf, - gboolean support_fils) + NMSupplCapMask capabilities) { gs_unref_object NMSupplicantConfig *config = NULL; gs_free_error GError *error = NULL; @@ -96,7 +95,7 @@ build_supplicant_config (NMConnection *connection, NMSetting8021x *s_8021x; gboolean success; - config = nm_supplicant_config_new (support_pmf, support_fils, FALSE, FALSE); + config = nm_supplicant_config_new (capabilities); s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); @@ -195,7 +194,7 @@ test_wifi_open (void) NMTST_EXPECT_NM_INFO ("Config: added 'bssid' value '11:22:33:44:55:66'*"); NMTST_EXPECT_NM_INFO ("Config: added 'freq_list' value *"); NMTST_EXPECT_NM_INFO ("Config: added 'key_mgmt' value 'NONE'"); - config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE); + config_dict = build_supplicant_config (connection, 1500, 0, NM_SUPPL_CAP_MASK_T_PMF_YES | NM_SUPPL_CAP_MASK_T_FILS_YES); g_test_assert_expected_messages (); g_assert (config_dict); @@ -252,7 +251,7 @@ test_wifi_wep_key (const char *detail, if (!test_bssid) NMTST_EXPECT_NM_INFO ("Config: added 'bgscan' value 'simple:30:-70:86400'*"); - config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE); + config_dict = build_supplicant_config (connection, 1500, 0, NM_SUPPL_CAP_MASK_T_PMF_YES | NM_SUPPL_CAP_MASK_T_FILS_YES); g_test_assert_expected_messages (); g_assert (config_dict); @@ -352,7 +351,7 @@ test_wifi_wpa_psk (const char *detail, default: break; } - config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE); + config_dict = build_supplicant_config (connection, 1500, 0, NM_SUPPL_CAP_MASK_T_PMF_YES | NM_SUPPL_CAP_MASK_T_FILS_YES); g_test_assert_expected_messages (); g_assert (config_dict); @@ -416,7 +415,7 @@ test_wifi_sae_psk (const char *psk) NMTST_EXPECT_NM_INFO ("Config: added 'proto' value 'RSN'"); NMTST_EXPECT_NM_INFO ("Config: added 'pairwise' value 'TKIP CCMP'"); NMTST_EXPECT_NM_INFO ("Config: added 'group' value 'TKIP CCMP'"); - config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE); + config_dict = build_supplicant_config (connection, 1500, 0, NM_SUPPL_CAP_MASK_T_PMF_YES | NM_SUPPL_CAP_MASK_T_FILS_YES); g_test_assert_expected_messages (); g_assert (config_dict); @@ -524,7 +523,7 @@ test_wifi_eap_locked_bssid (void) NMTST_EXPECT_NM_INFO ("Config: added 'ca_cert' value '*/test-ca-cert.pem'"); NMTST_EXPECT_NM_INFO ("Config: added 'private_key' value '*/test-cert.p12'"); NMTST_EXPECT_NM_INFO ("Config: added 'proactive_key_caching' value '1'"); - config_dict = build_supplicant_config (connection, mtu, 0, FALSE, FALSE); + config_dict = build_supplicant_config (connection, mtu, 0, NM_SUPPL_CAP_MASK_NONE); g_test_assert_expected_messages (); g_assert (config_dict); @@ -565,7 +564,7 @@ test_wifi_eap_unlocked_bssid (void) NMTST_EXPECT_NM_INFO ("Config: added 'private_key' value '*/test-cert.p12'"); NMTST_EXPECT_NM_INFO ("Config: added 'proactive_key_caching' value '1'"); NMTST_EXPECT_NM_INFO ("Config: added 'bgscan' value 'simple:30:-65:300'"); - config_dict = build_supplicant_config (connection, mtu, 0, FALSE, TRUE); + config_dict = build_supplicant_config (connection, mtu, 0, NM_SUPPL_CAP_MASK_T_FILS_YES); g_test_assert_expected_messages (); g_assert (config_dict); @@ -606,7 +605,7 @@ test_wifi_eap_fils_disabled (void) NMTST_EXPECT_NM_INFO ("Config: added 'private_key' value '*/test-cert.p12'"); NMTST_EXPECT_NM_INFO ("Config: added 'proactive_key_caching' value '1'"); NMTST_EXPECT_NM_INFO ("Config: added 'bgscan' value 'simple:30:-65:300'"); - config_dict = build_supplicant_config (connection, mtu, 0, TRUE, TRUE); + config_dict = build_supplicant_config (connection, mtu, 0, NM_SUPPL_CAP_MASK_T_PMF_YES | NM_SUPPL_CAP_MASK_T_FILS_YES); g_test_assert_expected_messages (); g_assert (config_dict); @@ -621,6 +620,44 @@ test_wifi_eap_fils_disabled (void) validate_opt ("wifi-eap", config_dict, "bgscan", TYPE_BYTES, bgscan); } +/*****************************************************************************/ + +static void +test_suppl_cap_mask (void) +{ + NMSupplCapType type; + + g_assert_cmpint (NM_SUPPL_CAP_MASK_GET (NM_SUPPL_CAP_MASK_T_AP_NO, NM_SUPPL_CAP_TYPE_AP), ==, NM_TERNARY_FALSE); + g_assert_cmpint (NM_SUPPL_CAP_MASK_GET (NM_SUPPL_CAP_MASK_T_AP_YES, NM_SUPPL_CAP_TYPE_AP), ==, NM_TERNARY_TRUE); + g_assert_cmpint (NM_SUPPL_CAP_MASK_GET (NM_SUPPL_CAP_MASK_NONE, NM_SUPPL_CAP_TYPE_AP), ==, NM_TERNARY_DEFAULT); + + g_assert_cmpint (NM_SUPPL_CAP_MASK_GET (NM_SUPPL_CAP_MASK_T_FILS_NO, NM_SUPPL_CAP_TYPE_FILS), ==, NM_TERNARY_FALSE); + g_assert_cmpint (NM_SUPPL_CAP_MASK_GET (NM_SUPPL_CAP_MASK_T_FILS_YES, NM_SUPPL_CAP_TYPE_FILS), ==, NM_TERNARY_TRUE); + g_assert_cmpint (NM_SUPPL_CAP_MASK_GET (NM_SUPPL_CAP_MASK_NONE, NM_SUPPL_CAP_TYPE_FILS), ==, NM_TERNARY_DEFAULT); + + for (type = 0; type < _NM_SUPPL_CAP_TYPE_NUM; type++) { + NMTernary value; + NMSupplCapMask feature; + NMSupplCapMask feature2; + + feature = nmtst_get_rand_bool () + ? 0u + : nmtst_get_rand_uint64 (); + feature &= NM_SUPPL_CAP_MASK_ALL; + + value = nmtst_rand_select (NM_TERNARY_DEFAULT, + NM_TERNARY_FALSE, + NM_TERNARY_TRUE); + + feature2 = NM_SUPPL_CAP_MASK_SET (feature, type, value); + + g_assert_cmpint (NM_SUPPL_CAP_MASK_GET (feature2, type), ==, value); + g_assert_cmpint (feature & ~NM_SUPPL_CAP_MASK_MASK (type), ==, feature2 & ~NM_SUPPL_CAP_MASK_MASK (type)); + } +} + +/*****************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -634,6 +671,7 @@ int main (int argc, char **argv) g_test_add_func ("/supplicant-config/wifi-eap/unlocked-bssid", test_wifi_eap_unlocked_bssid); g_test_add_func ("/supplicant-config/wifi-eap/fils-disabled", test_wifi_eap_fils_disabled); g_test_add_func ("/supplicant-config/wifi-sae", test_wifi_sae); + g_test_add_func ("/supplicant-config/test_suppl_cap_mask", test_suppl_cap_mask); return g_test_run (); } diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c index 97ff5b84be..21368b01dc 100644 --- a/src/vpn/nm-vpn-connection.c +++ b/src/vpn/nm-vpn-connection.c @@ -1194,7 +1194,7 @@ fw_change_zone_cb (NMFirewallManager *firewall_manager, priv->fw_call = NULL; - if (nm_utils_error_is_cancelled (error, FALSE)) + if (nm_utils_error_is_cancelled (error)) return; if (error) {