technology: Modify technology enable/disable APIs
authorAlok Barsode <alok.barsode@linux.intel.com>
Wed, 24 Aug 2011 13:44:10 +0000 (16:44 +0300)
committerSamuel Ortiz <sameo@linux.intel.com>
Thu, 25 Aug 2011 09:14:21 +0000 (11:14 +0200)
Add the pending dbus message per technology. Also move the pending
timeout from manager to technology.

src/connman.h
src/manager.c
src/technology.c

index 272b334..0a44805 100644 (file)
@@ -315,9 +315,9 @@ 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_enabled(enum connman_service_type type);
-int __connman_technology_enable(enum connman_service_type type);
+int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg);
 int __connman_technology_disabled(enum connman_service_type type);
-int __connman_technology_disable(enum connman_service_type type);
+int __connman_technology_disable(enum connman_service_type type, DBusMessage *msg);
 
 int __connman_technology_add_rfkill(unsigned int index,
                                        enum connman_service_type type,
index a276e0b..54de643 100644 (file)
@@ -221,59 +221,6 @@ static DBusMessage *request_scan(DBusConnection *conn,
 
 static DBusConnection *connection = NULL;
 
-static enum connman_service_type technology_type;
-static connman_bool_t technology_enabled;
-static DBusMessage *technology_pending = NULL;
-static guint technology_timeout = 0;
-
-static void technology_reply(int error)
-{
-       DBG("");
-
-       if (technology_timeout > 0) {
-               g_source_remove(technology_timeout);
-               technology_timeout = 0;
-       }
-
-       if (technology_pending != NULL) {
-               if (error > 0) {
-                       DBusMessage *reply;
-
-                       reply = __connman_error_failed(technology_pending,
-                                                               error);
-                       if (reply != NULL)
-                               g_dbus_send_message(connection, reply);
-               } else
-                       g_dbus_send_reply(connection, technology_pending,
-                                                       DBUS_TYPE_INVALID);
-
-               dbus_message_unref(technology_pending);
-               technology_pending = NULL;
-       }
-
-       technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
-}
-
-static gboolean technology_abort(gpointer user_data)
-{
-       DBG("");
-
-       technology_timeout = 0;
-
-       technology_reply(ETIMEDOUT);
-
-       return FALSE;
-}
-
-static void technology_notify(enum connman_service_type type,
-                                               connman_bool_t enabled)
-{
-       DBG("type %d enabled %d", type, enabled);
-
-       if (type == technology_type && enabled == technology_enabled)
-               technology_reply(0);
-}
-
 static void session_mode_notify(void)
 {
        DBusMessage *reply;
@@ -301,7 +248,6 @@ static void idle_state(connman_bool_t idle)
 static struct connman_notifier technology_notifier = {
        .name           = "manager",
        .priority       = CONNMAN_NOTIFIER_PRIORITY_HIGH,
-       .service_enabled= technology_notify,
        .idle_state     = idle_state,
 };
 
@@ -310,13 +256,9 @@ static DBusMessage *enable_technology(DBusConnection *conn,
 {
        enum connman_service_type type;
        const char *str;
-       int err;
 
        DBG("conn %p", conn);
 
-       if (technology_pending != NULL)
-               return __connman_error_in_progress(msg);
-
        dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
                                                        DBUS_TYPE_INVALID);
 
@@ -339,16 +281,7 @@ static DBusMessage *enable_technology(DBusConnection *conn,
        if (__connman_notifier_is_enabled(type) == TRUE)
                return __connman_error_already_enabled(msg);
 
-       technology_type = type;
-       technology_enabled = TRUE;
-       technology_pending = dbus_message_ref(msg);
-
-       err = __connman_technology_enable(type);
-       if (err < 0)
-               technology_reply(-err);
-       else
-               technology_timeout = g_timeout_add_seconds(15,
-                                               technology_abort, NULL);
+        __connman_technology_enable(type, msg);
 
        return NULL;
 }
@@ -358,13 +291,9 @@ static DBusMessage *disable_technology(DBusConnection *conn,
 {
        enum connman_service_type type;
        const char *str;
-       int err;
 
        DBG("conn %p", conn);
 
-       if (technology_pending != NULL)
-               return __connman_error_in_progress(msg);
-
        dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
                                                        DBUS_TYPE_INVALID);
 
@@ -387,16 +316,7 @@ static DBusMessage *disable_technology(DBusConnection *conn,
        if (__connman_notifier_is_enabled(type) == FALSE)
                return __connman_error_already_disabled(msg);
 
-       technology_type = type;
-       technology_enabled = FALSE;
-       technology_pending = dbus_message_ref(msg);
-
-       err = __connman_technology_disable(type);
-       if (err < 0)
-               technology_reply(-err);
-       else
-               technology_timeout = g_timeout_add_seconds(10,
-                                               technology_abort, NULL);
+       __connman_technology_disable(type, msg);
 
        return NULL;
 }
@@ -729,11 +649,11 @@ void __connman_manager_cleanup(void)
 {
        DBG("");
 
-       connman_notifier_unregister(&technology_notifier);
-
        if (connection == NULL)
                return;
 
+       connman_notifier_unregister(&technology_notifier);
+
        g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
                                                CONNMAN_MANAGER_INTERFACE);
 
index 2e91b41..cc44658 100644 (file)
@@ -68,6 +68,9 @@ struct connman_technology {
 
        struct connman_technology_driver *driver;
        void *driver_data;
+
+       DBusMessage *pending_reply;
+       guint pending_timeout;
 };
 
 static GSList *driver_list = NULL;
@@ -479,6 +482,7 @@ static struct connman_technology *technology_get(enum connman_service_type type)
                                                        NULL, free_rfkill);
        technology->device_list = NULL;
 
+       technology->pending_reply = NULL;
        technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
 
        if (g_dbus_register_interface(connection, technology->path,
@@ -675,6 +679,25 @@ int __connman_technology_remove_device(struct connman_device *device)
        return 0;
 }
 
+static gboolean technology_pending_reply(gpointer user_data)
+{
+       struct connman_technology *technology = user_data;
+       DBusMessage *reply;
+
+       /* Power request timedout, send ETIMEDOUT. */
+       if (technology->pending_reply != NULL) {
+               reply = __connman_error_failed(technology->pending_reply, ETIMEDOUT);
+               if (reply != NULL)
+                       g_dbus_send_message(connection, reply);
+
+               dbus_message_unref(technology->pending_reply);
+               technology->pending_reply = NULL;
+               technology->pending_timeout = 0;
+       }
+
+       return FALSE;
+}
+
 int __connman_technology_enabled(enum connman_service_type type)
 {
        struct connman_technology *technology;
@@ -698,21 +721,39 @@ int __connman_technology_enabled(enum connman_service_type type)
                __connman_profile_save_default();
        }
 
+       if (technology->pending_reply != NULL) {
+               g_dbus_send_reply(connection, technology->pending_reply, DBUS_TYPE_INVALID);
+               dbus_message_unref(technology->pending_reply);
+               technology->pending_reply = NULL;
+               technology->pending_timeout = 0;
+       }
+
        return 0;
 }
 
-int __connman_technology_enable(enum connman_service_type type)
+int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg)
 {
        struct connman_technology *technology;
        GSList *list;
-       int err;
+       int err = 0;
        int ret = -ENODEV;
+       DBusMessage *reply;
 
        DBG("type %d enable", type);
 
        technology = technology_find(type);
-       if (technology == NULL)
-               return -ENXIO;
+       if (technology == NULL) {
+               err = -ENXIO;
+               goto done;
+       }
+
+       if (technology->pending_reply != NULL) {
+               err = -EBUSY;
+               goto done;
+       }
+
+       if (msg != NULL)
+               technology->pending_reply = dbus_message_ref(msg);
 
        for (list = technology->device_list; list; list = list->next) {
                struct connman_device *device = list->data;
@@ -720,15 +761,29 @@ int __connman_technology_enable(enum connman_service_type type)
                err = __connman_device_enable_persistent(device);
                /*
                 * err = 0 : Device was enabled right away.
-                * err = -EINPROGRESS : DBus call was successful.
                 * If atleast one device gets enabled, we consider
                 * the technology to be enabled.
                 */
-               if (err == 0 || err == -EINPROGRESS)
+               if (err == 0)
                        ret = 0;
        }
 
-       return ret;
+done:
+       if (ret == 0)
+               return ret;
+
+       if (msg != NULL) {
+               if (err == -EINPROGRESS)
+                       technology->pending_timeout = g_timeout_add_seconds(10,
+                                       technology_pending_reply, technology);
+               else {
+                       reply = __connman_error_failed(msg, -err);
+                       if (reply != NULL)
+                               g_dbus_send_message(connection, reply);
+               }
+       }
+
+       return err;
 }
 
 int __connman_technology_disabled(enum connman_service_type type)
@@ -740,6 +795,12 @@ int __connman_technology_disabled(enum connman_service_type type)
        if (technology == NULL)
                return -ENXIO;
 
+       if (technology->pending_reply != NULL) {
+               g_dbus_send_reply(connection, technology->pending_reply, DBUS_TYPE_INVALID);
+               dbus_message_unref(technology->pending_reply);
+               technology->pending_reply = NULL;
+       }
+
        if (g_atomic_int_dec_and_test(&technology->enabled) == TRUE) {
                __connman_notifier_disable(type);
 
@@ -760,28 +821,54 @@ int __connman_technology_disabled(enum connman_service_type type)
        return 0;
 }
 
-int __connman_technology_disable(enum connman_service_type type)
+int __connman_technology_disable(enum connman_service_type type, DBusMessage *msg)
 {
        struct connman_technology *technology;
        GSList *list;
-       int err;
+       int err = 0;
        int ret = -ENODEV;
+       DBusMessage *reply;
 
        DBG("type %d disable", type);
 
        technology = technology_find(type);
-       if (technology == NULL)
-               return -ENXIO;
+       if (technology == NULL) {
+               err = -ENXIO;
+               goto done;
+       }
+
+       if (technology->pending_reply != NULL) {
+               err = -EBUSY;
+               goto done;
+       }
+
+       if (msg != NULL)
+               technology->pending_reply = dbus_message_ref(msg);
 
        for (list = technology->device_list; list; list = list->next) {
                struct connman_device *device = list->data;
 
                err = __connman_device_disable_persistent(device);
-               if (err == 0 || err == -EINPROGRESS)
+               if (err == 0)
                        ret = 0;
        }
 
-       return ret;
+done:
+       if (ret == 0)
+               return ret;
+
+       if (msg != NULL) {
+               if (err == -EINPROGRESS)
+                       technology->pending_timeout = g_timeout_add_seconds(10,
+                                       technology_pending_reply, technology);
+               else {
+                       reply = __connman_error_failed(msg, -err);
+                       if (reply != NULL)
+                               g_dbus_send_message(connection, reply);
+               }
+       }
+
+       return err;
 }
 
 static void technology_blocked(struct connman_technology *technology,