From 6c47db77851dcd782625ea9a43e9070da6d1ba13 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 12 May 2009 19:26:25 -0700 Subject: [PATCH] Fix service state signal emission and error handling --- include/network.h | 2 + plugins/supplicant.c | 6 +++ src/connection.c | 6 ++- src/connman.h | 7 ++-- src/device.c | 15 ++++---- src/error.c | 9 ++++- src/network.c | 49 +++++++++++++++++++++++-- src/service.c | 101 ++++++++++++++++++++------------------------------- 8 files changed, 114 insertions(+), 81 deletions(-) diff --git a/include/network.h b/include/network.h index 02caa59..cd00db7 100644 --- a/include/network.h +++ b/include/network.h @@ -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); diff --git a/plugins/supplicant.c b/plugins/supplicant.c index b92793c..ae51548 100644 --- a/plugins/supplicant.c +++ b/plugins/supplicant.c @@ -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; } diff --git a/src/connection.c b/src/connection.c index 0d544eb..b0039a6 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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); diff --git a/src/connman.h b/src/connman.h index 0edade4..00a29e4 100644 --- a/src/connman.h +++ b/src/connman.h @@ -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 diff --git a/src/device.c b/src/device.c index f33d601..0af3ccd 100644 --- a/src/device.c +++ b/src/device.c @@ -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); } diff --git a/src/error.c b/src/error.c index f8f6fdc..2c361bc 100644 --- a/src/error.c +++ b/src/error.c @@ -23,14 +23,19 @@ #include #endif +#include +#include + #include #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) diff --git a/src/network.c b/src/network.c index f2b9da2..44503c1 100644 --- a/src/network.c +++ b/src/network.c @@ -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; diff --git a/src/service.c b/src/service.c index 045b544..2c64fd5 100644 --- a/src/service.c +++ b/src/service.c @@ -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; } -- 2.7.4