Only disconnect the specific service if asked for it
[connman] / src / service.c
index 7b7717f..789cc9d 100644 (file)
@@ -174,14 +174,14 @@ static void state_changed(struct connman_service *service)
 }
 
 static DBusMessage *get_properties(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+                                       DBusMessage *msg, void *user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
        DBusMessage *reply;
        DBusMessageIter array, dict;
        const char *str;
 
-       DBG("conn %p", conn);
+       DBG("service %p", service);
 
        reply = dbus_message_new_method_return(msg);
        if (reply == NULL)
@@ -237,14 +237,14 @@ static DBusMessage *get_properties(DBusConnection *conn,
 }
 
 static DBusMessage *set_property(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+                                       DBusMessage *msg, void *user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
        DBusMessageIter iter, value;
        const char *name;
        int type;
 
-       DBG("conn %p", conn);
+       DBG("service %p", service);
 
        if (dbus_message_iter_init(msg, &iter) == FALSE)
                return __connman_error_invalid_arguments(msg);
@@ -292,6 +292,9 @@ static gboolean connect_timeout(gpointer user_data)
 
        service->timeout = 0;
 
+       if (service->network != NULL)
+               __connman_network_disconnect(service->network);
+
        if (service->pending != NULL) {
                DBusMessage *reply;
 
@@ -301,15 +304,20 @@ static gboolean connect_timeout(gpointer user_data)
 
                dbus_message_unref(service->pending);
                service->pending = NULL;
+
+               __connman_service_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_FAILURE);
        }
 
        return FALSE;
 }
 
 static DBusMessage *connect_service(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+                                       DBusMessage *msg, void *user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
+
+       DBG("service %p", service);
 
        if (service->pending != NULL)
                return __connman_error_in_progress(msg);
@@ -351,9 +359,11 @@ static DBusMessage *connect_service(DBusConnection *conn,
 }
 
 static DBusMessage *disconnect_service(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+                                       DBusMessage *msg, void *user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
+
+       DBG("service %p", service);
 
        if (service->pending != NULL) {
                DBusMessage *reply;
@@ -393,19 +403,26 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
 }
 
 static DBusMessage *remove_service(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+                                       DBusMessage *msg, void *user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
+
+       DBG("service %p", service);
 
        if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
                return __connman_error_not_supported(msg);
 
+       if (service->favorite == FALSE)
+               return __connman_error_not_supported(msg);
+
        if (service->network != NULL) {
-               int err;
+               struct connman_device *device;
 
-               err = __connman_network_disconnect(service->network);
-               if (err < 0 && err != -EINPROGRESS)
-                       return __connman_error_failed(msg, -err);
+               device = connman_network_get_device(service->network);
+               if (device != NULL)
+                       __connman_device_disconnect(device);
+
+               __connman_network_disconnect(service->network);
        }
 
        connman_service_set_favorite(service, FALSE);
@@ -415,9 +432,11 @@ static DBusMessage *remove_service(DBusConnection *conn,
 }
 
 static DBusMessage *move_before(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+                                       DBusMessage *msg, void *user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
+
+       DBG("service %p", service);
 
        if (service->favorite == FALSE)
                return __connman_error_not_supported(msg);
@@ -426,9 +445,11 @@ static DBusMessage *move_before(DBusConnection *conn,
 }
 
 static DBusMessage *move_after(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+                                       DBusMessage *msg, void *user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
+
+       DBG("service %p", service);
 
        if (service->favorite == FALSE)
                return __connman_error_not_supported(msg);
@@ -453,9 +474,9 @@ static GDBusSignalTable service_signals[] = {
        { },
 };
 
-static void service_free(gpointer data)
+static void service_free(gpointer user_data)
 {
-       struct connman_service *service = data;
+       struct connman_service *service = user_data;
        char *path = service->path;
 
        DBG("service %p", service);
@@ -579,6 +600,13 @@ static gint service_compare(gconstpointer a, gconstpointer b,
        struct connman_service *service_a = (void *) a;
        struct connman_service *service_b = (void *) b;
 
+       if (service_a->state != service_b->state) {
+               if (service_a->state == CONNMAN_SERVICE_STATE_READY)
+                       return -1;
+               if (service_b->state == CONNMAN_SERVICE_STATE_READY)
+                       return 1;
+       }
+
        if (service_a->order > service_b->order)
                return -1;
 
@@ -656,6 +684,8 @@ int __connman_service_set_carrier(struct connman_service *service,
 int __connman_service_indicate_state(struct connman_service *service,
                                        enum connman_service_state state)
 {
+       GSequenceIter *iter;
+
        DBG("service %p state %d", service, state);
 
        if (service == NULL)
@@ -694,7 +724,6 @@ int __connman_service_indicate_state(struct connman_service *service,
                        dbus_message_unref(service->pending);
                        service->pending = NULL;
                }
-
        }
 
        if (state == CONNMAN_SERVICE_STATE_FAILURE) {
@@ -711,8 +740,17 @@ int __connman_service_indicate_state(struct connman_service *service,
                        dbus_message_unref(service->pending);
                        service->pending = NULL;
                }
+
+               service->state = CONNMAN_SERVICE_STATE_IDLE;
+               state_changed(service);
        }
 
+       iter = g_hash_table_lookup(service_hash, service->identifier);
+       if (iter != NULL)
+               g_sequence_sort_changed(iter, service_compare, NULL);
+
+       __connman_profile_changed();
+
        return 0;
 }
 
@@ -1052,6 +1090,8 @@ struct connman_service *__connman_service_create_from_network(struct connman_net
 
        service->type = convert_network_type(network);
 
+       service->state = CONNMAN_SERVICE_STATE_IDLE;
+
        update_from_network(service, network);
 
        service_register(service);
@@ -1147,6 +1187,10 @@ static int service_save(struct connman_service *service)
        g_free(data);
 
 update:
+       if (service->name != NULL)
+               g_key_file_set_string(keyfile, service->identifier,
+                                               "Name", service->name);
+
        switch (service->type) {
        case CONNMAN_SERVICE_TYPE_UNKNOWN:
        case CONNMAN_SERVICE_TYPE_ETHERNET: