Add support for RFKILL changes of the WiFi subsystem
authorMarcel Holtmann <marcel@holtmann.org>
Wed, 22 Jul 2009 18:18:16 +0000 (20:18 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 22 Jul 2009 18:18:16 +0000 (20:18 +0200)
src/connman.h
src/device.c
src/rfkill.c
src/udev-compat.c
src/udev.c

index 0519ac5..d23ff63 100644 (file)
@@ -204,6 +204,7 @@ int __connman_udev_init(void);
 void __connman_udev_cleanup(void);
 char *__connman_udev_get_devtype(const char *ifname);
 char *__connman_udev_get_mbm_devnode(const char *ifname);
+void __connman_udev_rfkill(const char *sysname, connman_bool_t blocked);
 
 #include <connman/device.h>
 
@@ -212,6 +213,13 @@ void __connman_device_cleanup(void);
 
 enum connman_service_type __connman_device_get_service_type(struct connman_device *device);
 
+int __connman_device_get_phyindex(struct connman_device *device);
+void __connman_device_set_phyindex(struct connman_device *device,
+                                                       int phyindex);
+int __connman_device_set_blocked(struct connman_device *device,
+                                               connman_bool_t blocked);
+
+
 void __connman_device_increase_connections(struct connman_device *device);
 void __connman_device_decrease_connections(struct connman_device *device);
 
index ad44c7c..e6a9a03 100644 (file)
@@ -50,6 +50,7 @@ struct connman_device {
        char *interface;
        char *control;
        char *ident;
+       int phyindex;
        unsigned int connections;
        guint scan_timeout;
        struct connman_ipconfig *ipconfig;
@@ -897,6 +898,8 @@ struct connman_device *connman_device_create(const char *node,
 
        device->powered_persistent = TRUE;
 
+       device->phyindex = -1;
+
        switch (type) {
        case CONNMAN_DEVICE_TYPE_UNKNOWN:
        case CONNMAN_DEVICE_TYPE_VENDOR:
@@ -1022,6 +1025,17 @@ int connman_device_get_index(struct connman_device *device)
        return device->element.index;
 }
 
+int __connman_device_get_phyindex(struct connman_device *device)
+{
+       return device->phyindex;
+}
+
+void __connman_device_set_phyindex(struct connman_device *device,
+                                                       int phyindex)
+{
+       device->phyindex = phyindex;
+}
+
 /**
  * connman_device_set_interface:
  * @device: device structure
@@ -1177,6 +1191,24 @@ int connman_device_set_powered(struct connman_device *device,
        return 0;
 }
 
+int __connman_device_set_blocked(struct connman_device *device,
+                                               connman_bool_t blocked)
+{
+       connman_bool_t powered;
+
+       DBG("device %p blocked %d", device, blocked);
+
+       if (device->offlinemode == TRUE)
+               return 0;
+
+       if (blocked == FALSE)
+               powered = device->powered_persistent;
+       else
+               powered = FALSE;
+
+       return set_powered(device, powered);
+}
+
 /**
  * connman_device_set_carrier:
  * @device: device structure
index 84693b4..ad624ff 100644 (file)
@@ -61,6 +61,8 @@ static gboolean rfkill_event(GIOChannel *chan,
 {
        unsigned char buf[32];
        struct rfkill_event *event = (void *) buf;
+       char sysname[32];
+       connman_bool_t blocked;
        gsize len;
        GIOError err;
 
@@ -79,10 +81,23 @@ static gboolean rfkill_event(GIOChannel *chan,
        if (len != sizeof(struct rfkill_event))
                return TRUE;
 
-       connman_info("RFKILL event: idx %u type %u op %u soft %u hard %u",
+       DBG("idx %u type %u op %u soft %u hard %u",
                                        event->idx, event->type, event->op,
                                                event->soft, event->hard);
 
+       snprintf(sysname, sizeof(sysname) - 1, "rfkill%d", event->idx);
+
+       blocked = (event->soft || event->hard) ? TRUE : FALSE;
+
+       switch (event->type) {
+       case RFKILL_TYPE_ALL:
+       case RFKILL_TYPE_WLAN:
+               __connman_udev_rfkill(sysname, blocked);
+               break;
+       default:
+               break;
+       }
+
        return TRUE;
 }
 
index 270d3ca..448a18f 100644 (file)
@@ -120,6 +120,11 @@ char *__connman_udev_get_mbm_devnode(const char *ifname)
        return NULL;
 }
 
+void __connman_udev_rfkill(const char *sysname, connman_bool_t blocked)
+{
+       DBG("sysname %s blocked %d", sysname, blocked);
+}
+
 int __connman_udev_init(void)
 {
        int err;
index dc084c1..a1b9223 100644 (file)
@@ -76,7 +76,7 @@ static void add_device(struct udev_device *udev_device)
        struct udev_list_entry *entry;
        struct connman_device *device;
        enum connman_device_type devtype;
-       const char *systype;
+       const char *value, *systype;
        int index = -1;
 
        DBG("");
@@ -128,6 +128,10 @@ static void add_device(struct udev_device *udev_device)
        if (device == NULL)
                return;
 
+       value = udev_device_get_sysattr_value(udev_device, "phy80211/index");
+       if (value != NULL)
+               __connman_device_set_phyindex(device, atoi(value));
+
        if (connman_device_register(device) < 0) {
                connman_device_unref(device);
                return;
@@ -378,6 +382,42 @@ 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;
+       const char *value;
+
+       device = udev_device_new_from_subsystem_sysname(udev_ctx,
+                                                       "rfkill", sysname);
+       if (device == NULL)
+               return;
+
+       parent = udev_device_get_parent(device);
+       if (parent == NULL)
+               return;
+
+       value = udev_device_get_sysattr_value(parent, "index");
+       if (value == NULL)
+               return;
+
+       phyindex_rfkill(atoi(value), blocked);
+}
+
 int __connman_udev_init(void)
 {
        GIOChannel *channel;