summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-07-22 20:52:53 +0200
committerMarcel Holtmann <marcel@holtmann.org>2009-07-22 20:52:53 +0200
commit3b6cb8f2cfe097a175c6d5665500aa68ad55fb44 (patch)
tree57af0c7b59f4271f511d121d989bb62452ac64b6
parent9a5e082b2b2d2dac9f08ee6d40d42d40dbc3c634 (diff)
downloadconnman-3b6cb8f2cfe097a175c6d5665500aa68ad55fb44.tar.gz
connman-3b6cb8f2cfe097a175c6d5665500aa68ad55fb44.tar.bz2
connman-3b6cb8f2cfe097a175c6d5665500aa68ad55fb44.zip
Handle the RFKILL change events from udev
-rw-r--r--src/udev.c114
1 files changed, 87 insertions, 27 deletions
diff --git a/src/udev.c b/src/udev.c
index a1b92236..b14b6251 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;