195
195
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
197
197
RfKillState poll_states[RFKILL_TYPE_MAX];
198
RfKillState platform_states[RFKILL_TYPE_MAX];
198
199
gboolean platform_checked[RFKILL_TYPE_MAX];
201
202
/* Default state is unblocked */
202
203
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
203
204
poll_states[i] = RFKILL_UNBLOCKED;
205
platform_states[i] = RFKILL_UNBLOCKED;
204
206
platform_checked[i] = FALSE;
207
/* Perform two passes here; the first pass is for non-platform switches,
208
* which typically if hardkilled cannot be changed except by a physical
209
* hardware switch. The second pass checks platform killswitches, which
210
* take precedence over device killswitches, because typically platform
211
* killswitches control device killswitches. That is, a hardblocked device
212
* switch can often be unblocked by a platform switch. Thus if we have
213
* a hardblocked device switch and a softblocked platform switch, the
214
* combined state should be softblocked since the platform switch can be
215
* unblocked to change the device switch.
218
/* Device switches first */
209
/* Poll the states of all killswitches */
219
210
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
220
211
Killswitch *ks = iter->data;
221
212
GUdevDevice *device;
222
213
RfKillState dev_state;
225
if (ks->platform == FALSE) {
226
device = g_udev_client_query_by_subsystem_and_name (priv->client, "rfkill", ks->name);
228
sysfs_state = g_udev_device_get_property_as_int (device, "RFKILL_STATE");
229
dev_state = sysfs_state_to_nm_state (sysfs_state);
216
device = g_udev_client_query_by_subsystem_and_name (priv->client, "rfkill", ks->name);
218
sysfs_state = g_udev_device_get_property_as_int (device, "RFKILL_STATE");
219
dev_state = sysfs_state_to_nm_state (sysfs_state);
220
if (ks->platform == FALSE) {
230
221
if (dev_state > poll_states[ks->rtype])
231
222
poll_states[ks->rtype] = dev_state;
232
g_object_unref (device);
237
/* Platform switches next; their state overwrites device state */
238
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
239
Killswitch *ks = iter->data;
241
RfKillState dev_state;
244
if (ks->platform == TRUE) {
245
device = g_udev_client_query_by_subsystem_and_name (priv->client, "rfkill", ks->name);
247
sysfs_state = g_udev_device_get_property_as_int (device, "RFKILL_STATE");
248
dev_state = sysfs_state_to_nm_state (sysfs_state);
250
if (platform_checked[ks->rtype] == FALSE) {
251
/* Overwrite device state with platform state for first
252
* platform switch found.
254
poll_states[ks->rtype] = dev_state;
255
platform_checked[ks->rtype] = TRUE;
257
/* If there are multiple platform switches of the same type,
258
* take the "worst" state for all of that type.
260
if (dev_state > poll_states[ks->rtype])
261
poll_states[ks->rtype] = dev_state;
263
g_object_unref (device);
224
platform_checked[ks->rtype] = TRUE;
225
if (dev_state > platform_states[ks->rtype])
226
platform_states[ks->rtype] = dev_state;
228
g_object_unref (device);
268
232
/* Log and emit change signal for final rfkill states */
269
233
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
234
if (platform_checked[i] == TRUE) {
235
/* blocked platform switch state overrides device state, otherwise
236
* let the device state stand. (bgo #655773)
238
if (platform_states[i] != RFKILL_UNBLOCKED)
239
poll_states[i] = platform_states[i];
270
242
if (poll_states[i] != priv->rfkill_states[i]) {
271
243
nm_log_dbg (LOGD_RFKILL, "%s rfkill state now '%s'",
272
244
rfkill_type_to_desc (i),