Handle enabled/disabled cases for technology interface
authorMarcel Holtmann <marcel@holtmann.org>
Tue, 26 Jan 2010 07:30:31 +0000 (08:30 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 26 Jan 2010 07:30:31 +0000 (08:30 +0100)
src/connman.h
src/device.c
src/technology.c

index be160ab..4d869bb 100644 (file)
@@ -273,6 +273,8 @@ void __connman_technology_list(DBusMessageIter *iter, void *user_data);
 
 int __connman_technology_add_device(struct connman_device *device);
 int __connman_technology_remove_device(struct connman_device *device);
+int __connman_technology_enable_device(struct connman_device *device);
+int __connman_technology_disable_device(struct connman_device *device);
 int __connman_technology_add_rfkill(unsigned int index,
                                        enum connman_service_type type,
                                                connman_bool_t softblock,
index c78e421..8255949 100644 (file)
@@ -203,7 +203,6 @@ static void powered_changed(struct connman_device *device)
 static int set_powered(struct connman_device *device, connman_bool_t powered)
 {
        struct connman_device_driver *driver = device->driver;
-       enum connman_service_type type;
        int err;
 
        DBG("device %p powered %d", device, powered);
@@ -214,15 +213,13 @@ static int set_powered(struct connman_device *device, connman_bool_t powered)
        if (!driver)
                return -EINVAL;
 
-       type = __connman_device_get_service_type(device);
-
        if (powered == TRUE) {
                if (driver->enable) {
                        device->powered_pending = powered;
 
                        err = driver->enable(device);
                        if (err == 0)
-                               __connman_notifier_enable(type);
+                               __connman_technology_enable_device(device);
                } else
                        err = -EINVAL;
        } else {
@@ -237,7 +234,7 @@ static int set_powered(struct connman_device *device, connman_bool_t powered)
                if (driver->disable) {
                        err = driver->disable(device);
                        if (err == 0)
-                               __connman_notifier_disable(type);
+                               __connman_technology_disable_device(device);
                } else
                        err = -EINVAL;
        }
@@ -511,7 +508,6 @@ static void unregister_interface(struct connman_element *element)
 
 static int setup_device(struct connman_device *device)
 {
-       enum connman_service_type type;
        int err;
 
        DBG("device %p", device);
@@ -526,9 +522,6 @@ static int setup_device(struct connman_device *device)
 
        __connman_technology_add_device(device);
 
-       type = __connman_device_get_service_type(device);
-       __connman_notifier_register(type);
-
        switch (device->mode) {
        case CONNMAN_DEVICE_MODE_UNKNOWN:
        case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
@@ -571,8 +564,6 @@ static void probe_driver(struct connman_element *element, gpointer user_data)
 
 static void remove_device(struct connman_device *device)
 {
-       enum connman_service_type type;
-
        DBG("device %p", device);
 
        __connman_device_disable(device);
@@ -584,9 +575,6 @@ static void remove_device(struct connman_device *device)
                break;
        }
 
-       type = __connman_device_get_service_type(device);
-       __connman_notifier_unregister(type);
-
        __connman_technology_remove_device(device);
 
        unregister_interface(&device->element);
@@ -967,8 +955,6 @@ enum connman_device_mode connman_device_get_mode(struct connman_device *device)
 int connman_device_set_powered(struct connman_device *device,
                                                connman_bool_t powered)
 {
-       enum connman_service_type type;
-
        DBG("driver %p powered %d", device, powered);
 
        if (device->timeout > 0) {
@@ -990,12 +976,10 @@ int connman_device_set_powered(struct connman_device *device,
        device->powered = powered;
        device->powered_pending = powered;
 
-       type = __connman_device_get_service_type(device);
-
        if (device->powered == TRUE)
-               __connman_notifier_enable(type);
+               __connman_technology_enable_device(device);
        else
-               __connman_notifier_disable(type);
+               __connman_technology_disable_device(device);
 
        if (device->registered == FALSE)
                return 0;
@@ -1050,7 +1034,6 @@ int __connman_device_scan(struct connman_device *device)
 
 int __connman_device_enable(struct connman_device *device)
 {
-       enum connman_service_type type;
        int err;
 
        DBG("device %p", device);
@@ -1069,8 +1052,7 @@ int __connman_device_enable(struct connman_device *device)
 
        device->powered = TRUE;
 
-       type = __connman_device_get_service_type(device);
-       __connman_notifier_enable(type);
+       __connman_technology_enable_device(device);
 
        return 0;
 }
@@ -1088,7 +1070,6 @@ int __connman_device_enable_persistent(struct connman_device *device)
 
 int __connman_device_disable(struct connman_device *device)
 {
-       enum connman_service_type type;
        int err;
 
        DBG("device %p", device);
@@ -1116,8 +1097,7 @@ int __connman_device_disable(struct connman_device *device)
 
        device->powered = FALSE;
 
-       type = __connman_device_get_service_type(device);
-       __connman_notifier_disable(type);
+       __connman_technology_disable_device(device);
 
        return 0;
 }
index fcfd9d8..8b06a77 100644 (file)
@@ -53,6 +53,7 @@ struct connman_technology {
        char *path;
        GHashTable *rfkill_list;
        GSList *device_list;
+       gint enabled;
 };
 
 static void free_rfkill(gpointer data)
@@ -316,6 +317,7 @@ int __connman_technology_add_device(struct connman_device *device)
        DBG("device %p", device);
 
        type = __connman_device_get_service_type(device);
+       __connman_notifier_register(type);
 
        technology = technology_get(type);
        if (technology == NULL)
@@ -338,9 +340,13 @@ int __connman_technology_add_device(struct connman_device *device)
 int __connman_technology_remove_device(struct connman_device *device)
 {
        struct connman_technology *technology;
+       enum connman_service_type type;
 
        DBG("device %p", device);
 
+       type = __connman_device_get_service_type(device);
+       __connman_notifier_unregister(type);
+
        technology = g_hash_table_lookup(device_table, device);
        if (technology == NULL)
                return -ENXIO;
@@ -359,6 +365,50 @@ int __connman_technology_remove_device(struct connman_device *device)
        return 0;
 }
 
+int __connman_technology_enable_device(struct connman_device *device)
+{
+       struct connman_technology *technology;
+       enum connman_service_type type;
+
+       DBG("device %p", device);
+
+       type = __connman_device_get_service_type(device);
+       __connman_notifier_enable(type);
+
+       technology = g_hash_table_lookup(device_table, device);
+       if (technology == NULL)
+               return -ENXIO;
+
+       if (g_atomic_int_exchange_and_add(&technology->enabled, 1) == 0) {
+               technology->state = CONNMAN_TECHNOLOGY_STATE_ENABLED;
+               state_changed(technology);
+       }
+
+       return 0;
+}
+
+int __connman_technology_disable_device(struct connman_device *device)
+{
+       struct connman_technology *technology;
+       enum connman_service_type type;
+
+       DBG("device %p", device);
+
+       type = __connman_device_get_service_type(device);
+       __connman_notifier_disable(type);
+
+       technology = g_hash_table_lookup(device_table, device);
+       if (technology == NULL)
+               return -ENXIO;
+
+       if (g_atomic_int_dec_and_test(&technology->enabled) == TRUE) {
+               technology->state = CONNMAN_TECHNOLOGY_STATE_AVAILABLE;
+               state_changed(technology);
+       }
+
+       return 0;
+}
+
 int __connman_technology_add_rfkill(unsigned int index,
                                        enum connman_service_type type,
                                                connman_bool_t softblock,