From 3b6cb8f2cfe097a175c6d5665500aa68ad55fb44 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Jul 2009 20:52:53 +0200 Subject: [PATCH] Handle the RFKILL change events from udev --- src/udev.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 27 deletions(-) diff --git a/src/udev.c b/src/udev.c index a1b9223..b14b625 100644 --- a/src/udev.c +++ b/src/udev.c @@ -71,7 +71,7 @@ static struct connman_device *find_device(int index) return NULL; } -static void add_device(struct udev_device *udev_device) +static void add_net_device(struct udev_device *udev_device) { struct udev_list_entry *entry; struct connman_device *device; @@ -140,7 +140,7 @@ static void add_device(struct udev_device *udev_device) device_list = g_slist_append(device_list, device); } -static void remove_device(struct udev_device *udev_device) +static void remove_net_device(struct udev_device *udev_device) { struct udev_list_entry *entry; struct connman_device *device; @@ -174,6 +174,67 @@ static void remove_device(struct udev_device *udev_device) connman_device_unref(device); } +static void phyindex_rfkill(int phyindex, connman_bool_t blocked) +{ + GSList *list; + + if (phyindex < 0) + return; + + for (list = device_list; list; list = list->next) { + struct connman_device *device = list->data; + + if (__connman_device_get_phyindex(device) == phyindex) + __connman_device_set_blocked(device, blocked); + } +} + +static void change_rfkill_device(struct udev_device *device) +{ + struct udev_device *parent; + struct udev_list_entry *entry; + connman_bool_t blocked; + const char *value, *type = NULL; + int state = -1; + + entry = udev_device_get_properties_list_entry(device); + while (entry) { + const char *name = udev_list_entry_get_name(entry); + + if (g_str_has_prefix(name, "RFKILL_STATE") == TRUE) { + value = udev_list_entry_get_value(entry); + if (value != NULL) + state = atoi(value); + } else if (g_str_has_prefix(name, "RFKILL_TYPE") == TRUE) + type = udev_list_entry_get_value(entry); + + entry = udev_list_entry_get_next(entry); + } + + if (type == NULL || state < 0) + return; + + if (g_str_equal(type, "wlan") == FALSE) + return; + + parent = udev_device_get_parent(device); + if (parent == NULL) + return; + + value = udev_device_get_sysattr_value(parent, "index"); + if (value == NULL) + return; + + blocked = (state != 1) ? TRUE : FALSE; + + phyindex_rfkill(atoi(value), blocked); +} + +static void add_rfkill_device(struct udev_device *device) +{ + change_rfkill_device(device); +} + static void print_properties(struct udev_device *device, const char *prefix) { struct udev_list_entry *entry; @@ -245,6 +306,7 @@ static void enumerate_devices(struct udev *context) return; udev_enumerate_add_match_subsystem(enumerate, "net"); + udev_enumerate_add_match_subsystem(enumerate, "rfkill"); udev_enumerate_scan_devices(enumerate); @@ -254,12 +316,20 @@ static void enumerate_devices(struct udev *context) struct udev_device *device; device = udev_device_new_from_syspath(context, syspath); + if (device != NULL) { + const char *subsystem; - print_device(device, "coldplug"); + print_device(device, "coldplug"); - add_device(device); + subsystem = udev_device_get_subsystem(device); - udev_device_unref(device); + if (g_strcmp0(subsystem, "net") == 0) + add_net_device(device); + else if (g_strcmp0(subsystem, "rfkill") == 0) + add_rfkill_device(device); + + udev_device_unref(device); + } entry = udev_list_entry_get_next(entry); } @@ -282,19 +352,24 @@ static gboolean udev_event(GIOChannel *channel, if (subsystem == NULL) goto done; - if (g_str_equal(subsystem, "net") == FALSE) - goto done; - action = udev_device_get_action(device); if (action == NULL) goto done; print_device(device, action); - if (g_str_equal(action, "add") == TRUE) - add_device(device); - else if (g_str_equal(action, "remove") == TRUE) - remove_device(device); + if (g_str_equal(action, "add") == TRUE) { + if (g_str_equal(subsystem, "net") == TRUE) + add_net_device(device); + else if (g_str_equal(subsystem, "rfkill") == TRUE) + add_rfkill_device(device); + } else if (g_str_equal(action, "remove") == TRUE) { + if (g_str_equal(subsystem, "net") == TRUE) + remove_net_device(device); + } else if (g_str_equal(action, "change") == TRUE) { + if (g_str_equal(subsystem, "rfkill") == TRUE) + change_rfkill_device(device); + } done: udev_device_unref(device); @@ -382,21 +457,6 @@ done: return devnode; } -static void phyindex_rfkill(int phyindex, connman_bool_t blocked) -{ - GSList *list; - - if (phyindex < 0) - return; - - for (list = device_list; list; list = list->next) { - struct connman_device *device = list->data; - - if (__connman_device_get_phyindex(device) == phyindex) - __connman_device_set_blocked(device, blocked); - } -} - void __connman_udev_rfkill(const char *sysname, connman_bool_t blocked) { struct udev_device *device, *parent; -- 2.7.4