diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2022-03-21 10:19:37 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2022-03-29 09:34:07 +0200 |
commit | 580ef03bee96aec3d361d95569c88207ac0ddddb (patch) | |
tree | 541613dd2a5012cda12850e92c95d79cb2cb41e9 | |
parent | 2343148da81a06c5776c5ca80f26e30a72b8c758 (diff) |
core: export radio flags
Introduce a RadioFlags property on the manager object. For now it
contains two bits WLAN_AVAILABLE, WWAN_AVAILABLE to indicate whether
any radio interface is present in the system. The presence of a radio
is detected by looking at devices and rfkill switches.
In future, any radio-related read-only boolean flag can be exposed via
this property, including the already existing WirelessHardwareEnabled
and WwanHardwareEnabled properties.
-rw-r--r-- | introspection/org.freedesktop.NetworkManager.xml | 10 | ||||
-rw-r--r-- | src/core/nm-manager.c | 75 | ||||
-rw-r--r-- | src/core/nm-manager.h | 1 | ||||
-rw-r--r-- | src/core/nm-rfkill-manager.c | 14 | ||||
-rw-r--r-- | src/core/nm-rfkill-manager.h | 2 | ||||
-rw-r--r-- | src/libnm-core-public/nm-dbus-interface.h | 18 |
6 files changed, 107 insertions, 13 deletions
diff --git a/introspection/org.freedesktop.NetworkManager.xml b/introspection/org.freedesktop.NetworkManager.xml index b0ac658b2d..65859881ba 100644 --- a/introspection/org.freedesktop.NetworkManager.xml +++ b/introspection/org.freedesktop.NetworkManager.xml @@ -385,6 +385,16 @@ <property name="WimaxHardwareEnabled" type="b" access="read"/> <!-- + RadioFlags: + @since: 1.38 + + Flags related to radio devices. See <link + linkend="NMRadioFlags">NMRadioFlags</link> for the list of flags + supported. + --> + <property name="RadioFlags" type="u" access="read"/> + + <!-- ActiveConnections: List of active connection object paths. diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 05650f79bf..a152344c52 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -60,6 +60,7 @@ typedef struct { } RfkillTypeDesc; typedef struct { + bool available : 1; bool user_enabled : 1; bool sw_enabled : 1; bool hw_enabled : 1; @@ -122,6 +123,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMManager, PROP_WWAN_HARDWARE_ENABLED, PROP_WIMAX_ENABLED, PROP_WIMAX_HARDWARE_ENABLED, + PROP_RADIO_FLAGS, PROP_ACTIVE_CONNECTIONS, PROP_CONNECTIVITY, PROP_CONNECTIVITY_CHECK_AVAILABLE, @@ -193,6 +195,8 @@ typedef struct { guint devices_inited_id; + guint radio_flags; + NMConnectivityState connectivity_state; guint8 device_state_prune_ratelimit_count; @@ -396,6 +400,8 @@ static void _activation_auth_done(NMManager *self, gboolean success, const char *error_desc); +static void _rfkill_update(NMManager *self, NMRfkillType rtype); + /*****************************************************************************/ static NM_CACHED_QUARK_FCN("autoconnect-root", autoconnect_root_quark); @@ -1715,6 +1721,7 @@ remove_device(NMManager *self, NMDevice *device, gboolean quitting) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); gboolean unmanage = FALSE; + NMRfkillType rtype; _LOG2D(LOGD_DEVICE, device, @@ -1755,6 +1762,10 @@ remove_device(NMManager *self, NMDevice *device, gboolean quitting) _parent_notify_changed(self, device, TRUE); + rtype = nm_device_get_rfkill_type(device); + if (rtype != NM_RFKILL_TYPE_UNKNOWN) + _rfkill_update(self, rtype); + if (nm_device_is_real(device)) { gboolean unconfigure_ip_config = !quitting || unmanage; @@ -2318,33 +2329,48 @@ _rfkill_radio_state_get_enabled(const RfkillRadioState *rstate, gboolean check_c } static void -_rfkill_radio_state_set_from_manager(NMRfkillManager *rfkill_mgr, - NMRfkillType rtype, - RfkillRadioState *rstate) +_rfkill_radio_state_set_from_manager(NMManager *self, NMRfkillType rtype, RfkillRadioState *rstate) { - switch (nm_rfkill_manager_get_rfkill_state(rfkill_mgr, rtype)) { + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); + NMDevice *device; + + switch (nm_rfkill_manager_get_rfkill_state(priv->rfkill_mgr, rtype)) { case NM_RFKILL_STATE_UNAVAILABLE: rstate->sw_enabled = TRUE; rstate->hw_enabled = TRUE; rstate->os_owner = TRUE; + + /* A rfkill-type is available when there is a compatible + * killswitch or a compatible device. */ + c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { + if (nm_device_get_rfkill_type(device) == rtype) { + rstate->available = TRUE; + return; + } + } + rstate->available = FALSE; return; case NM_RFKILL_STATE_UNBLOCKED: + rstate->available = TRUE; rstate->sw_enabled = TRUE; rstate->hw_enabled = TRUE; rstate->os_owner = TRUE; return; case NM_RFKILL_STATE_SOFT_BLOCKED: + rstate->available = TRUE; rstate->sw_enabled = FALSE; rstate->hw_enabled = TRUE; rstate->os_owner = TRUE; return; case NM_RFKILL_STATE_HARD_BLOCKED: + rstate->available = TRUE; rstate->sw_enabled = FALSE; rstate->hw_enabled = FALSE; /* In case the OS doesn't own the NIC, we would be in NM_RFKILL_STATE_HARD_BLOCKED */ rstate->os_owner = TRUE; return; case NM_RFKILL_STATE_HARD_BLOCKED_OS_NOT_OWNER: + rstate->available = TRUE; rstate->sw_enabled = FALSE; rstate->hw_enabled = FALSE; rstate->os_owner = FALSE; @@ -2397,20 +2423,23 @@ _rfkill_update_one_type(NMManager *self, NMRfkillType rtype) gboolean old_rfkilled; gboolean new_rfkilled; gboolean old_hwe; + guint old_radio_flags; nm_assert(_NM_INT_NOT_NEGATIVE(rtype) && rtype < G_N_ELEMENTS(priv->radio_states)); - old_enabled = _rfkill_radio_state_get_enabled(rstate, TRUE); - old_rfkilled = rstate->hw_enabled && rstate->sw_enabled; - old_hwe = rstate->hw_enabled; + old_enabled = _rfkill_radio_state_get_enabled(rstate, TRUE); + old_rfkilled = rstate->hw_enabled && rstate->sw_enabled; + old_hwe = rstate->hw_enabled; + old_radio_flags = priv->radio_flags; /* recheck kernel rfkill state */ - _rfkill_radio_state_set_from_manager(priv->rfkill_mgr, rtype, rstate); + _rfkill_radio_state_set_from_manager(self, rtype, rstate); /* Print out all states affecting device enablement */ _LOGD(LOGD_RFKILL, - "rfkill: %s hw-enabled %d sw-enabled %d os-owner %d", + "rfkill: %s available %d hw-enabled %d sw-enabled %d os-owner %d", nm_rfkill_type_to_string(rtype), + rstate->available, rstate->hw_enabled, rstate->sw_enabled, rstate->os_owner); @@ -2424,9 +2453,15 @@ _rfkill_update_one_type(NMManager *self, NMRfkillType rtype) new_rfkilled ? "enabled" : "disabled"); } - /* Send out property changed signal for HW enabled */ - if (rstate->hw_enabled != old_hwe) - _notify(self, _rfkill_type_desc[rtype].hw_prop_id); + priv->radio_flags = NM_FLAGS_ASSIGN(priv->radio_flags, + (guint) nm_rfkill_type_to_radio_available_flag(rtype), + rstate->available); + + /* Send out property changed signal for HW available and enabled */ + nm_gobject_notify_together(self, + rstate->hw_enabled != old_hwe ? _rfkill_type_desc[rtype].hw_prop_id + : PROP_0, + priv->radio_flags != old_radio_flags ? PROP_RADIO_FLAGS : PROP_0); /* And finally update the actual device radio state itself; respect the * daemon state here because this is never called from user-triggered @@ -7099,7 +7134,7 @@ nm_manager_start(NMManager *self, GError **error) gboolean enabled; /* recheck kernel rfkill state */ - _rfkill_radio_state_set_from_manager(priv->rfkill_mgr, rtype, rstate); + _rfkill_radio_state_set_from_manager(self, rtype, rstate); _LOGI(LOGD_RFKILL, "rfkill: %s %s by radio killswitch; %s by state file", @@ -8081,6 +8116,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_WIMAX_HARDWARE_ENABLED: g_value_set_boolean(value, FALSE); break; + case PROP_RADIO_FLAGS: + g_value_set_uint(value, priv->radio_flags); + break; case PROP_ACTIVE_CONNECTIONS: ptrarr = g_ptr_array_new(); c_list_for_each_entry_prev (ac, @@ -8536,6 +8574,9 @@ static const NMDBusInterfaceInfoExtended interface_info_manager = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WimaxHardwareEnabled", "b", NM_MANAGER_WIMAX_HARDWARE_ENABLED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RadioFlags", + "u", + NM_MANAGER_RADIO_FLAGS), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ActiveConnections", "ao", NM_MANAGER_ACTIVE_CONNECTIONS), @@ -8680,6 +8721,14 @@ nm_manager_class_init(NMManagerClass *manager_class) TRUE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_RADIO_FLAGS] = g_param_spec_uint(NM_MANAGER_RADIO_FLAGS, + "", + "", + 0, + G_MAXUINT32, + NM_RADIO_FLAG_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ACTIVE_CONNECTIONS] = g_param_spec_boxed(NM_MANAGER_ACTIVE_CONNECTIONS, "", diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h index 385cdfe08f..f8563c3aa1 100644 --- a/src/core/nm-manager.h +++ b/src/core/nm-manager.h @@ -30,6 +30,7 @@ #define NM_MANAGER_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled" #define NM_MANAGER_WIMAX_ENABLED "wimax-enabled" #define NM_MANAGER_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled" +#define NM_MANAGER_RADIO_FLAGS "radio-flags" #define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections" #define NM_MANAGER_CONNECTIVITY "connectivity" #define NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE "connectivity-check-available" diff --git a/src/core/nm-rfkill-manager.c b/src/core/nm-rfkill-manager.c index 60404c5321..03333899b0 100644 --- a/src/core/nm-rfkill-manager.c +++ b/src/core/nm-rfkill-manager.c @@ -66,6 +66,20 @@ nm_rfkill_manager_get_rfkill_state(NMRfkillManager *self, NMRfkillType rtype) return NM_RFKILL_MANAGER_GET_PRIVATE(self)->rfkill_states[rtype]; } +NMRadioFlags +nm_rfkill_type_to_radio_available_flag(NMRfkillType type) +{ + switch (type) { + case NM_RFKILL_TYPE_WLAN: + return NM_RADIO_FLAG_WLAN_AVAILABLE; + case NM_RFKILL_TYPE_WWAN: + return NM_RADIO_FLAG_WWAN_AVAILABLE; + case NM_RFKILL_TYPE_UNKNOWN: + break; + } + return nm_assert_unreachable_val(NM_RADIO_FLAG_NONE); +} + const char * nm_rfkill_type_to_string(NMRfkillType type) { diff --git a/src/core/nm-rfkill-manager.h b/src/core/nm-rfkill-manager.h index acca144532..88d0421a77 100644 --- a/src/core/nm-rfkill-manager.h +++ b/src/core/nm-rfkill-manager.h @@ -55,4 +55,6 @@ NMRfkillManager *nm_rfkill_manager_new(void); NMRfkillState nm_rfkill_manager_get_rfkill_state(NMRfkillManager *manager, NMRfkillType rtype); +NMRadioFlags nm_rfkill_type_to_radio_available_flag(NMRfkillType type); + #endif /* __NM_RFKILL_MANAGER_H__ */ diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index 1881c141ac..94622793d9 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -1297,4 +1297,22 @@ typedef enum { NM_CLIENT_PERMISSION_RESULT_NO } NMClientPermissionResult; +/** + * NMRadioFlags: + * @NM_RADIO_FLAG_NONE: an alias for numeric zero, no flags set. + * @NM_RADIO_FLAG_WLAN_AVAILABLE: A Wireless LAN device or rfkill switch + * is detected in the system. + * @NM_RADIO_FLAG_WWAN_AVAILABLE: A Wireless WAN device or rfkill switch + * is detected in the system. + * + * Flags related to radio interfaces. + * + * Since: 1.38 + */ +typedef enum /*< flags >*/ { + NM_RADIO_FLAG_NONE = 0, + NM_RADIO_FLAG_WLAN_AVAILABLE = 0x1, + NM_RADIO_FLAG_WWAN_AVAILABLE = 0x2, +} NMRadioFlags; + #endif /* __NM_DBUS_INTERFACE_H__ */ |