diff options
author | Dan Williams <dcbw@redhat.com> | 2013-05-31 14:11:56 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-05-06 14:15:50 -0500 |
commit | 876ec0c755f83d7fc79af7b7cf61d268a6984464 (patch) | |
tree | dc212a68cf160c3b16f95203e4f85838d7907b51 | |
parent | b7647665173415526e11a927906b5b73fb3ea166 (diff) | |
download | NetworkManager-876ec0c755f83d7fc79af7b7cf61d268a6984464.tar.gz |
rfkill: toggle WWAN rfkill state on user enable/disable
Poke the kernel's WWAN rfkill state when the user changes our
WWANEnabled property, the same as we do for WiFi. Also restore
saved WWAN state on startup, as we do for WiFi. No good reason
why WWAN should be different here.
-rw-r--r-- | src/nm-manager.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c index 79c0518c5a..d685dbe2c5 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -146,7 +146,7 @@ static void policy_activating_device_changed (GObject *object, GParamSpec *pspec static NMDevice *find_device_by_ip_iface (NMManager *self, const gchar *iface); -static void rfkill_change_wifi (const char *desc, gboolean enabled); +static void rfkill_change (const char *desc, RfKillType rtype, gboolean enabled); static gboolean find_master (NMManager *self, NMConnection *connection, @@ -4506,6 +4506,7 @@ authority_changed_cb (gpointer user_data) #define KERN_RFKILL_OP_CHANGE_ALL 3 #define KERN_RFKILL_TYPE_WLAN 1 +#define KERN_RFKILL_TYPE_WWAN 5 struct rfkill_event { __u32 idx; __u8 type; @@ -4514,18 +4515,19 @@ struct rfkill_event { } __attribute__((packed)); static void -rfkill_change_wifi (const char *desc, gboolean enabled) +rfkill_change (const char *desc, RfKillType rtype, gboolean enabled) { int fd; struct rfkill_event event; ssize_t len; + g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN); + errno = 0; fd = open ("/dev/rfkill", O_RDWR); if (fd < 0) { if (errno == EACCES) - nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device " - "for WiFi radio control", desc); + nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device", desc); return; } @@ -4538,7 +4540,16 @@ rfkill_change_wifi (const char *desc, gboolean enabled) memset (&event, 0, sizeof (event)); event.op = KERN_RFKILL_OP_CHANGE_ALL; - event.type = KERN_RFKILL_TYPE_WLAN; + switch (rtype) { + case RFKILL_TYPE_WLAN: + event.type = KERN_RFKILL_TYPE_WLAN; + break; + case RFKILL_TYPE_WWAN: + event.type = KERN_RFKILL_TYPE_WWAN; + break; + default: + g_assert_not_reached (); + } event.soft = enabled ? 0 : 1; len = write (fd, &event, sizeof (event)); @@ -4565,6 +4576,10 @@ manager_radio_user_toggled (NMManager *self, GError *error = NULL; gboolean old_enabled, new_enabled; + /* Don't touch devices if asleep/networking disabled */ + if (manager_sleeping (self)) + return; + if (rstate->desc) { nm_log_dbg (LOGD_RFKILL, "(%s): setting radio %s by user", rstate->desc, @@ -4598,11 +4613,11 @@ manager_radio_user_toggled (NMManager *self, rstate->user_enabled = enabled; new_enabled = radio_enabled_for_rstate (rstate, FALSE); if (new_enabled != old_enabled) { - manager_update_radio_enabled (self, rstate, new_enabled); + /* Try to change the kernel rfkill state */ + if (rstate->rtype == RFKILL_TYPE_WLAN || rstate->rtype == RFKILL_TYPE_WWAN) + rfkill_change (rstate->desc, rstate->rtype, new_enabled); - /* For WiFi only (for now) set the actual kernel rfkill state */ - if (rstate->rtype == RFKILL_TYPE_WLAN) - rfkill_change_wifi (rstate->desc, new_enabled); + manager_update_radio_enabled (self, rstate, new_enabled); } } @@ -4755,11 +4770,13 @@ nm_manager_new (NMSettings *settings, G_CALLBACK (rfkill_manager_rfkill_changed_cb), singleton); - /* Force kernel WiFi rfkill state to follow NM saved wifi state in case - * the BIOS doesn't save rfkill state, and to be consistent with user - * changes to the WirelessEnabled property which toggles kernel rfkill. + /* Force kernel WiFi/WWAN rfkill state to follow NM saved WiFi/WWAN state + * in case the BIOS doesn't save rfkill state, and to be consistent with user + * changes to the WirelessEnabled/WWANEnabled properties which toggle kernel + * rfkill. */ - rfkill_change_wifi (priv->radio_states[RFKILL_TYPE_WLAN].desc, initial_wifi_enabled); + rfkill_change (priv->radio_states[RFKILL_TYPE_WLAN].desc, RFKILL_TYPE_WLAN, initial_wifi_enabled); + rfkill_change (priv->radio_states[RFKILL_TYPE_WWAN].desc, RFKILL_TYPE_WWAN, initial_wwan_enabled); load_device_factories (singleton); |