summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2022-03-21 10:19:37 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2022-03-29 09:34:07 +0200
commit580ef03bee96aec3d361d95569c88207ac0ddddb (patch)
tree541613dd2a5012cda12850e92c95d79cb2cb41e9
parent2343148da81a06c5776c5ca80f26e30a72b8c758 (diff)
downloadNetworkManager-580ef03bee96aec3d361d95569c88207ac0ddddb.tar.gz
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.xml10
-rw-r--r--src/core/nm-manager.c75
-rw-r--r--src/core/nm-manager.h1
-rw-r--r--src/core/nm-rfkill-manager.c14
-rw-r--r--src/core/nm-rfkill-manager.h2
-rw-r--r--src/libnm-core-public/nm-dbus-interface.h18
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__ */