Fix service state signal emission and error handling
authorMarcel Holtmann <marcel@holtmann.org>
Wed, 13 May 2009 02:26:25 +0000 (19:26 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 13 May 2009 02:26:25 +0000 (19:26 -0700)
include/network.h
plugins/supplicant.c
src/connection.c
src/connman.h
src/device.c
src/error.c
src/network.c
src/service.c

index 02caa59..cd00db7 100644 (file)
@@ -74,6 +74,8 @@ extern void connman_network_set_group(struct connman_network *network,
 extern int connman_network_set_available(struct connman_network *network,
                                                connman_bool_t available);
 extern connman_bool_t connman_network_get_available(struct connman_network *network);
+extern int connman_network_set_associating(struct connman_network *network,
+                                               connman_bool_t associating);
 extern int connman_network_set_connected(struct connman_network *network,
                                                connman_bool_t connected);
 extern connman_bool_t connman_network_get_connected(struct connman_network *network);
index b92793c..ae51548 100644 (file)
@@ -1343,7 +1343,11 @@ static void state_change(struct supplicant_task *task, DBusMessage *msg)
                connman_network_set_connected(task->network, FALSE);
                connman_device_set_scanning(task->device, FALSE);
                break;
+       case WPA_ASSOCIATING:
+               connman_network_set_associating(task->network, TRUE);
+               break;
        default:
+               connman_network_set_associating(task->network, FALSE);
                break;
        }
 }
@@ -1500,6 +1504,8 @@ int supplicant_connect(struct connman_network *network)
 
        enable_network(task);
 
+       connman_network_set_associating(task->network, TRUE);
+
        return 0;
 }
 
index 0d544eb..b0039a6 100644 (file)
@@ -487,7 +487,8 @@ static int connection_probe(struct connman_element *element)
                return -ENODEV;
 
        service = __connman_element_get_service(element);
-       __connman_service_ready(service);
+       __connman_service_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_READY);
 
        if (gateway == NULL)
                return 0;
@@ -519,7 +520,8 @@ static void connection_remove(struct connman_element *element)
        DBG("element %p name %s", element, element->name);
 
        service = __connman_element_get_service(element);
-       __connman_service_disconnect(service);
+       __connman_service_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_DISCONNECT);
 
        unregister_interface(element);
 
index 0edade4..00a29e4 100644 (file)
@@ -32,7 +32,7 @@
 int __connman_dbus_init(DBusConnection *conn);
 void __connman_dbus_cleanup(void);
 
-DBusMessage *__connman_error_failed(DBusMessage *msg);
+DBusMessage *__connman_error_failed(DBusMessage *msg, int errnum);
 DBusMessage *__connman_error_invalid_arguments(DBusMessage *msg);
 DBusMessage *__connman_error_permission_denied(DBusMessage *msg);
 DBusMessage *__connman_error_not_supported(DBusMessage *msg);
@@ -233,9 +233,8 @@ struct connman_service *__connman_service_create_from_network(struct connman_net
 
 int __connman_service_set_carrier(struct connman_service *service,
                                                connman_bool_t carrier);
-int __connman_service_indicate_configuration(struct connman_service *service);
-int __connman_service_ready(struct connman_service *service);
-int __connman_service_disconnect(struct connman_service *service);
+int __connman_service_indicate_state(struct connman_service *service,
+                                       enum connman_service_state state);
 
 #include <connman/notifier.h>
 
index f33d601..0af3ccd 100644 (file)
@@ -207,7 +207,8 @@ static int set_carrier(struct connman_device *device, connman_bool_t carrier)
 
                        device->disconnected = FALSE;
 
-                       __connman_service_indicate_configuration(service);
+                       __connman_service_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_CONFIGURATION);
                }
        } else
                connman_element_unregister_children(&device->element);
@@ -452,7 +453,7 @@ static DBusMessage *set_property(DBusConnection *conn,
 
                err = set_powered(device, powered);
                if (err < 0 && err != -EINPROGRESS)
-                       return __connman_error_failed(msg);
+                       return __connman_error_failed(msg, -err);
        } else if (g_str_equal(name, "Policy") == TRUE) {
                enum connman_device_policy policy;
                const char *str;
@@ -468,7 +469,7 @@ static DBusMessage *set_property(DBusConnection *conn,
 
                err = set_policy(conn, device, policy);
                if (err < 0)
-                       return __connman_error_failed(msg);
+                       return __connman_error_failed(msg, -err);
        } else if (g_str_equal(name, "Priority") == TRUE) {
                connman_uint8_t priority;
 
@@ -556,7 +557,7 @@ static DBusMessage *join_network(DBusConnection *conn,
 
        network = connman_network_create("00_00_00_00_00_00", type);
        if (network == NULL)
-               return __connman_error_failed(msg);
+               return __connman_error_failed(msg, ENOMEM);
 
        while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
                DBusMessageIter entry, value;
@@ -592,7 +593,7 @@ static DBusMessage *join_network(DBusConnection *conn,
        connman_network_unref(network);
 
        if (err < 0)
-               return __connman_error_failed(msg);
+               return __connman_error_failed(msg, -err);
 
        return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
@@ -642,11 +643,11 @@ static DBusMessage *propose_scan(DBusConnection *conn,
                return __connman_error_not_supported(msg);
 
        if (device->powered == FALSE)
-               return __connman_error_failed(msg);
+               return __connman_error_failed(msg, EINVAL);
 
        err = device->driver->scan(device);
        if (err < 0)
-               return __connman_error_failed(msg);
+               return __connman_error_failed(msg, -err);
 
        return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
index f8f6fdc..2c361bc 100644 (file)
 #include <config.h>
 #endif
 
+#include <errno.h>
+#include <string.h>
+
 #include <gdbus.h>
 
 #include "connman.h"
 
-DBusMessage *__connman_error_failed(DBusMessage *msg)
+DBusMessage *__connman_error_failed(DBusMessage *msg, int errnum)
 {
+       const char *str = strerror(errnum);
+
        return g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
-                                                       ".Failed", NULL);
+                                                       ".Failed", str);
 }
 
 DBusMessage *__connman_error_invalid_arguments(DBusMessage *msg)
index f2b9da2..44503c1 100644 (file)
@@ -33,6 +33,7 @@ struct connman_network {
        struct connman_element element;
        enum connman_network_type type;
        enum connman_network_protocol protocol;
+       connman_bool_t associating;
        connman_bool_t secondary;
        connman_bool_t available;
        connman_bool_t connected;
@@ -239,7 +240,7 @@ static DBusMessage *do_connect(DBusConnection *conn,
                return __connman_error_permission_denied(msg);
 
        if (network->connected == TRUE)
-               return __connman_error_failed(msg);
+               return __connman_error_failed(msg, EALREADY);
 
        if (network->driver && network->driver->connect) {
                enum connman_device_mode mode;
@@ -250,7 +251,7 @@ static DBusMessage *do_connect(DBusConnection *conn,
 
                err = network->driver->connect(network);
                if (err < 0 && err != -EINPROGRESS)
-                       return __connman_error_failed(msg);
+                       return __connman_error_failed(msg, -err);
        } else
                network->connected = TRUE;
 
@@ -270,7 +271,7 @@ static DBusMessage *do_disconnect(DBusConnection *conn,
                return __connman_error_permission_denied(msg);
 
        if (network->connected == FALSE)
-               return __connman_error_failed(msg);
+               return __connman_error_failed(msg, EINVAL);
 
        connman_element_unregister_children(&network->element);
 
@@ -279,7 +280,7 @@ static DBusMessage *do_disconnect(DBusConnection *conn,
        if (network->driver && network->driver->disconnect) {
                err = network->driver->disconnect(network);
                if (err < 0 && err != -EINPROGRESS)
-                       return __connman_error_failed(msg);
+                       return __connman_error_failed(msg, -err);
        } else
                network->connected = FALSE;
 
@@ -683,6 +684,9 @@ connman_bool_t connman_network_get_available(struct connman_network *network)
 static gboolean set_connected(gpointer user_data)
 {
        struct connman_network *network = user_data;
+       struct connman_service *service;
+
+       service = __connman_service_lookup_from_network(network);
 
        if (network->connected == TRUE) {
                struct connman_element *element;
@@ -713,8 +717,14 @@ static gboolean set_connected(gpointer user_data)
                        if (connman_element_register(element,
                                                &network->element) < 0)
                                connman_element_unref(element);
+
+                       __connman_service_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_CONFIGURATION);
                }
        } else {
+               __connman_service_indicate_state(service,
+                                               CONNMAN_SERVICE_STATE_IDLE);
+
                connman_element_unregister_children(&network->element);
 
                __connman_device_set_network(network->device, NULL);
@@ -726,6 +736,34 @@ static gboolean set_connected(gpointer user_data)
 }
 
 /**
+ * connman_network_set_associating:
+ * @network: network structure
+ * @associating: associating state
+ *
+ * Change associating state of network
+ */
+int connman_network_set_associating(struct connman_network *network,
+                                               connman_bool_t associating)
+{
+       DBG("network %p associating %d", network, associating);
+
+       if (network->associating == associating)
+               return -EALREADY;
+
+       network->associating = associating;
+
+       if (associating == TRUE) {
+               struct connman_service *service;
+
+               service = __connman_service_lookup_from_network(network);
+               __connman_service_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_ASSOCIATION);
+       }
+
+       return 0;
+}
+
+/**
  * connman_network_set_connected:
  * @network: network structure
  * @connected: connected state
@@ -746,6 +784,9 @@ int connman_network_set_connected(struct connman_network *network,
 
        network->connected = connected;
 
+       if (connected == TRUE)
+               network->associating = FALSE;
+
        if (network->registered == FALSE) {
                g_idle_add(set_connected, network);
                return 0;
index 045b544..2c64fd5 100644 (file)
@@ -290,27 +290,20 @@ static DBusMessage *connect_service(DBusConnection *conn,
        if (service->network != NULL) {
                int err;
 
+               connman_network_set_string(service->network,
+                               "WiFi.Passphrase", service->passphrase);
+
                err = connman_network_connect(service->network);
                if (err < 0 && err != -EINPROGRESS)
-                       return __connman_error_failed(msg);
-
-               service->state = CONNMAN_SERVICE_STATE_ASSOCIATION;
-
-               state_changed(service);
+                       return __connman_error_failed(msg, -err);
 
                return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-       }
-
-       if (service->device != NULL) {
+       } else if (service->device != NULL) {
                if (service->favorite == FALSE)
                        return __connman_error_no_carrier(msg);
 
                if (__connman_device_connect(service->device) < 0)
-                       return __connman_error_failed(msg);
-
-               service->state = CONNMAN_SERVICE_STATE_READY;
-
-               state_changed(service);
+                       return __connman_error_failed(msg, EINVAL);
 
                return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
        }
@@ -328,25 +321,18 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
 
                err = __connman_network_disconnect(service->network);
                if (err < 0 && err != -EINPROGRESS)
-                       return __connman_error_failed(msg);
-
-               service->state = CONNMAN_SERVICE_STATE_DISCONNECT;
-
-               state_changed(service);
+                       return __connman_error_failed(msg, -err);
 
                return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-       }
+       } else if (service->device != NULL) {
+               int err;
 
-       if (service->device != NULL) {
                if (service->favorite == FALSE)
                        return __connman_error_no_carrier(msg);
 
-               if (__connman_device_connect(service->device) < 0)
-                       return __connman_error_failed(msg);
-
-               service->state = CONNMAN_SERVICE_STATE_IDLE;
-
-               state_changed(service);
+               err = __connman_device_disconnect(service->device);
+               if (err < 0)
+                       return __connman_error_failed(msg, -err);
 
                return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
        }
@@ -367,11 +353,7 @@ static DBusMessage *remove_service(DBusConnection *conn,
 
                err = __connman_network_disconnect(service->network);
                if (err < 0 && err != -EINPROGRESS)
-                       return __connman_error_failed(msg);
-
-               service->state = CONNMAN_SERVICE_STATE_DISCONNECT;
-
-               state_changed(service);
+                       return __connman_error_failed(msg, -err);
        }
 
        connman_service_set_favorite(service, FALSE);
@@ -597,54 +579,49 @@ int __connman_service_set_carrier(struct connman_service *service,
                break;
        }
 
-       if (carrier == TRUE)
-               service->state = CONNMAN_SERVICE_STATE_CARRIER;
-       else
-               service->state = CONNMAN_SERVICE_STATE_IDLE;
+       if (carrier == FALSE) {
+               service->state = CONNMAN_SERVICE_STATE_DISCONNECT;
+               state_changed(service);
 
-       state_changed(service);
+               service->state = CONNMAN_SERVICE_STATE_IDLE;
+               state_changed(service);
+       } else {
+               service->state = CONNMAN_SERVICE_STATE_CARRIER;
+               state_changed(service);
+       }
 
        return connman_service_set_favorite(service, carrier);
 }
 
-int __connman_service_indicate_configuration(struct connman_service *service)
+int __connman_service_indicate_state(struct connman_service *service,
+                                       enum connman_service_state state)
 {
-       DBG("service %p", service);
+       DBG("service %p state %d", service, state);
 
        if (service == NULL)
                return -EINVAL;
 
-       service->state = CONNMAN_SERVICE_STATE_CONFIGURATION;
+       if (state == CONNMAN_SERVICE_STATE_CARRIER)
+               return __connman_service_set_carrier(service, TRUE);
 
-       state_changed(service);
-
-       return 0;
-}
-
-int __connman_service_ready(struct connman_service *service)
-{
-       DBG("service %p", service);
+       if (service->state == state)
+               return -EALREADY;
 
-       if (service == NULL)
+       if (service->state == CONNMAN_SERVICE_STATE_IDLE &&
+                               state == CONNMAN_SERVICE_STATE_DISCONNECT)
                return -EINVAL;
 
-       service->state = CONNMAN_SERVICE_STATE_READY;
+       if (state == CONNMAN_SERVICE_STATE_IDLE &&
+                       service->state != CONNMAN_SERVICE_STATE_DISCONNECT) {
+               service->state = CONNMAN_SERVICE_STATE_DISCONNECT;
+               state_changed(service);
+       }
 
+       service->state = state;
        state_changed(service);
 
-       return 0;
-}
-
-int __connman_service_disconnect(struct connman_service *service)
-{
-       DBG("service %p", service);
-
-       if (service == NULL)
-               return -EINVAL;
-
-       service->state = CONNMAN_SERVICE_STATE_DISCONNECT;
-
-       state_changed(service);
+       if (state == CONNMAN_SERVICE_STATE_READY)
+               return connman_service_set_favorite(service, TRUE);
 
        return 0;
 }