X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fservice.c;h=de28264e7923d7ad04842ef09a831147ff5e9c73;hb=54de1195cf2aba7f0577ad4b70f89d8978d205ff;hp=fd1340ef7874408920a6ab217e020fd36815d89a;hpb=7a9dfdbfb58088a6b656579fd5596c3821171216;p=framework%2Fconnectivity%2Fconnman.git diff --git a/src/service.c b/src/service.c index fd1340e..de28264 100644 --- a/src/service.c +++ b/src/service.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -42,8 +42,8 @@ static DBusConnection *connection = NULL; static GSequence *service_list = NULL; static GHashTable *service_hash = NULL; static GSList *counter_list = NULL; - static unsigned int autoconnect_timeout = 0; +static struct connman_service *current_default = NULL; struct connman_stats { connman_bool_t valid; @@ -116,6 +116,8 @@ struct connman_service { connman_bool_t wps; int online_check_count; connman_bool_t do_split_routing; + connman_bool_t new_service; + connman_bool_t hidden_service; }; struct find_data { @@ -322,8 +324,11 @@ static int service_load(struct connman_service *service) DBG("service %p", service); keyfile = connman_storage_load_service(service->identifier); - if (keyfile == NULL) + if (keyfile == NULL) { + service->new_service = TRUE; return -EIO; + } else + service->new_service = FALSE; switch (service->type) { case CONNMAN_SERVICE_TYPE_UNKNOWN: @@ -482,6 +487,9 @@ static int service_load(struct connman_service *service) service->pac = str; } + service->hidden_service = g_key_file_get_boolean(keyfile, + service->identifier, "Hidden", NULL); + done: g_key_file_free(keyfile); @@ -496,7 +504,10 @@ static int service_save(struct connman_service *service) const char *cst_str = NULL; int err = 0; - DBG("service %p", service); + DBG("service %p new %d", service, service->new_service); + + if (service->new_service == TRUE) + return -ESRCH; keyfile = __connman_storage_open_service(service->identifier); if (keyfile == NULL) @@ -661,6 +672,10 @@ static int service_save(struct connman_service *service) g_key_file_remove_key(keyfile, service->identifier, "Proxy.URL", NULL); + if (service->hidden_service == TRUE) + g_key_file_set_boolean(keyfile, service->identifier, "Hidden", + TRUE); + done: __connman_storage_save_service(keyfile, service->identifier); @@ -825,6 +840,74 @@ static connman_bool_t is_connected(struct connman_service *service) return is_connected_state(service, service->state); } +static const char *nameserver_get_ifname(struct connman_service *service) +{ + const char *ifname; + + if (service->ipconfig_ipv4) + ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv4); + else if (service->ipconfig_ipv6) + ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv6); + else + ifname = NULL; + + if (ifname == NULL) + return NULL; + + switch (combine_state(service->state_ipv4, service->state_ipv6)) { + case CONNMAN_SERVICE_STATE_UNKNOWN: + case CONNMAN_SERVICE_STATE_IDLE: + case CONNMAN_SERVICE_STATE_ASSOCIATION: + case CONNMAN_SERVICE_STATE_CONFIGURATION: + case CONNMAN_SERVICE_STATE_FAILURE: + case CONNMAN_SERVICE_STATE_DISCONNECT: + return NULL; + case CONNMAN_SERVICE_STATE_READY: + case CONNMAN_SERVICE_STATE_ONLINE: + break; + } + + return ifname; +} + +static void remove_nameservers(struct connman_service *service, + const char* interface, char **ns) +{ + const char *ifname = interface; + int i; + + if (ns == NULL) + return; + + if (interface == NULL) + ifname = nameserver_get_ifname(service); + + if (ifname == NULL) + return; + + for (i = 0; ns[i] != NULL; i++) + connman_resolver_remove(ifname, NULL, ns[i]); +} + +static void remove_searchdomains(struct connman_service *service, + const char *interface, char **sd) +{ + const char *ifname = interface; + int i; + + if (sd == NULL) + return; + + if (interface == NULL) + ifname = nameserver_get_ifname(service); + + if (ifname == NULL) + return; + + for (i = 0; sd[i] != NULL; i++) + connman_resolver_remove(ifname, sd[i], NULL); +} + static void update_nameservers(struct connman_service *service) { const char *ifname; @@ -857,25 +940,38 @@ static void update_nameservers(struct connman_service *service) if (service->nameservers_config != NULL) { int i; - for (i = 0; service->nameservers_config[i] != NULL; i++) { + remove_nameservers(service, ifname, service->nameservers); + + i = g_strv_length(service->nameservers_config); + while (i != 0) { + i--; connman_resolver_append(ifname, NULL, - service->nameservers_config[i]); + service->nameservers_config[i]); } } else if (service->nameservers != NULL) { int i; - for (i = 0; service->nameservers[i] != NULL; i++) { + i = g_strv_length(service->nameservers); + while (i != 0) { + i--; connman_resolver_append(ifname, NULL, - service->nameservers[i]); + service->nameservers[i]); } } if (service->domains != NULL) { + char *searchdomains[2] = {NULL, NULL}; int i; - for (i = 0; service->domains[i]; i++) + searchdomains[0] = service->domainname; + remove_searchdomains(service, ifname, searchdomains); + + i = g_strv_length(service->domains); + while (i != 0) { + i--; connman_resolver_append(ifname, service->domains[i], NULL); + } } else if (service->domainname != NULL) connman_resolver_append(ifname, service->domainname, NULL); @@ -1256,6 +1352,13 @@ static void default_changed(void) { struct connman_service *service = __connman_service_get_default(); + if (service == current_default) + return; + + __connman_service_timeserver_changed(current_default, NULL); + + current_default = service; + __connman_notifier_default_changed(service); } @@ -1416,14 +1519,14 @@ static void append_ipv6config(DBusMessageIter *iter, void *user_data) iter); } -static void append_nameserver(DBusMessageIter *iter, char ***nameservers) +static void append_nameservers(DBusMessageIter *iter, char **servers) { - char **servers; int i; - servers = *nameservers; + DBG("%p", servers); for (i = 0; servers[i] != NULL; i++) { + DBG("servers[%d] %s", i, servers[i]); dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &servers[i]); } @@ -1437,29 +1540,39 @@ static void append_dns(DBusMessageIter *iter, void *user_data) return; if (service->nameservers_config != NULL) { - append_nameserver(iter, &service->nameservers_config); + append_nameservers(iter, service->nameservers_config); return; } else { if (service->nameservers != NULL) - append_nameserver(iter, &service->nameservers); + append_nameservers(iter, service->nameservers); if (service->nameservers_auto != NULL) - append_nameserver(iter, &service->nameservers_auto); + append_nameservers(iter, service->nameservers_auto); } } static void append_dnsconfig(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; - int i; if (service->nameservers_config == NULL) return; - for (i = 0; service->nameservers_config[i]; i++) { - dbus_message_iter_append_basic(iter, - DBUS_TYPE_STRING, - &service->nameservers_config[i]); + append_nameservers(iter, service->nameservers_config); +} + +static void append_ts(DBusMessageIter *iter, void *user_data) +{ + GSList *list = user_data; + + while (list != NULL) { + char *timeserver = list->data; + + if (timeserver != NULL) + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, + ×erver); + + list = g_slist_next(list); } } @@ -1478,32 +1591,32 @@ static void append_tsconfig(DBusMessageIter *iter, void *user_data) } } -static void append_domain(DBusMessageIter *iter, void *user_data) +static void append_domainconfig(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; + int i; - if (is_connected(service) == FALSE && - is_connecting(service) == FALSE) - return; - - if (service->domainname == NULL) + if (service->domains == NULL) return; - dbus_message_iter_append_basic(iter, - DBUS_TYPE_STRING, &service->domainname); + for (i = 0; service->domains[i]; i++) + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &service->domains[i]); } -static void append_domainconfig(DBusMessageIter *iter, void *user_data) +static void append_domain(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; - int i; - if (service->domains == NULL) + if (is_connected(service) == FALSE && + is_connecting(service) == FALSE) return; - for (i = 0; service->domains[i]; i++) + if (service->domains != NULL) + append_domainconfig(iter, user_data); + else if (service->domainname != NULL) dbus_message_iter_append_basic(iter, - DBUS_TYPE_STRING, &service->domains[i]); + DBUS_TYPE_STRING, &service->domainname); } static void append_proxies(DBusMessageIter *iter, void *user_data) @@ -1719,6 +1832,15 @@ static void proxy_configuration_changed(struct connman_service *service) proxy_changed(service); } +static void timeservers_configuration_changed(struct connman_service *service) +{ + connman_dbus_property_changed_array(service->path, + CONNMAN_SERVICE_INTERFACE, + "Timeservers.Configuration", + DBUS_TYPE_STRING, + append_tsconfig, service); +} + static void link_changed(struct connman_service *service) { connman_dbus_property_changed_dict(service->path, @@ -2019,6 +2141,7 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, struct connman_service *service) { const char *str; + GSList *list; str = __connman_service_type2string(service->type); if (str != NULL) @@ -2098,6 +2221,17 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, connman_dbus_dict_append_array(dict, "Nameservers.Configuration", DBUS_TYPE_STRING, append_dnsconfig, service); + if (service->state == CONNMAN_SERVICE_STATE_READY || + service->state == CONNMAN_SERVICE_STATE_ONLINE) + list = __connman_timeserver_get_all(service); + else + list = NULL; + + connman_dbus_dict_append_array(dict, "Timeservers", + DBUS_TYPE_STRING, append_ts, list); + + g_slist_free_full(list, g_free); + connman_dbus_dict_append_array(dict, "Timeservers.Configuration", DBUS_TYPE_STRING, append_tsconfig, service); @@ -2182,6 +2316,14 @@ int __connman_service_get_index(struct connman_service *service) return -1; } +void __connman_service_set_hidden(struct connman_service *service) +{ + if (service == NULL || service->hidden == TRUE) + return; + + service->hidden_service = TRUE; +} + void __connman_service_set_domainname(struct connman_service *service, const char *domainname) { @@ -2432,6 +2574,17 @@ int __connman_service_timeserver_remove(struct connman_service *service, return 0; } +void __connman_service_timeserver_changed(struct connman_service *service, + GSList *ts_list) +{ + if (service == NULL) + return; + + connman_dbus_property_changed_array(service->path, + CONNMAN_SERVICE_INTERFACE, "Timeservers", + DBUS_TYPE_STRING, append_ts, ts_list); +} + void __connman_service_set_pac(struct connman_service *service, const char *pac) { @@ -2858,7 +3011,8 @@ static DBusMessage *set_property(DBusConnection *conn, return __connman_error_invalid_arguments(msg); index = connman_network_get_index(service->network); - gw = __connman_ipconfig_get_gateway_from_index(index); + gw = __connman_ipconfig_get_gateway_from_index(index, + CONNMAN_IPCONFIG_TYPE_ALL); if (gw && strlen(gw)) __connman_service_nameserver_del_routes(service, @@ -2876,6 +3030,7 @@ static DBusMessage *set_property(DBusConnection *conn, g_string_append(str, val); } + remove_nameservers(service, NULL, service->nameservers_config); g_strfreev(service->nameservers_config); if (str->len > 0) { @@ -2906,10 +3061,15 @@ static DBusMessage *set_property(DBusConnection *conn, while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) { const char *val; + GSList *new_head; + dbus_message_iter_get_basic(&entry, &val); - list = g_slist_prepend(list, strdup(val)); - count++; + new_head = __connman_timeserver_add_list(list, val); + if (list != new_head) { + count++; + list = new_head; + } dbus_message_iter_next(&entry); } @@ -2928,6 +3088,7 @@ static DBusMessage *set_property(DBusConnection *conn, } service_save(service); + timeservers_configuration_changed(service); __connman_timeserver_sync(service); } else if (g_str_equal(name, "Domains.Configuration") == TRUE) { @@ -2953,6 +3114,7 @@ static DBusMessage *set_property(DBusConnection *conn, g_string_append(str, val); } + remove_searchdomains(service, NULL, service->domains); g_strfreev(service->domains); if (str->len > 0) @@ -3706,7 +3868,7 @@ static void service_schedule_added(struct connman_service *service) DBG("service %p", service); g_hash_table_remove(services_notify->remove, service->path); - g_hash_table_insert(services_notify->add, service->path, service); + g_hash_table_replace(services_notify->add, service->path, service); service_schedule_changed(); } @@ -3721,28 +3883,40 @@ static void service_schedule_removed(struct connman_service *service) } g_hash_table_remove(services_notify->add, service->path); - g_hash_table_insert(services_notify->remove, g_strdup(service->path), + g_hash_table_replace(services_notify->remove, g_strdup(service->path), NULL); service_schedule_changed(); } -static GDBusMethodTable service_methods[] = { - { "GetProperties", "", "a{sv}", get_properties }, - { "SetProperty", "sv", "", set_property }, - { "ClearProperty", "s", "", clear_property }, - { "Connect", "", "", connect_service, - G_DBUS_METHOD_FLAG_ASYNC }, - { "Disconnect", "", "", disconnect_service }, - { "Remove", "", "", remove_service }, - { "MoveBefore", "o", "", move_before }, - { "MoveAfter", "o", "", move_after }, - { "ResetCounters", "", "", reset_counters }, +static const GDBusMethodTable service_methods[] = { + { GDBUS_DEPRECATED_METHOD("GetProperties", + NULL, GDBUS_ARGS({ "properties", "a{sv}" }), + get_properties) }, + { GDBUS_METHOD("SetProperty", + GDBUS_ARGS({ "name", "s" }, { "value", "v" }), + NULL, set_property) }, + { GDBUS_METHOD("ClearProperty", + GDBUS_ARGS({ "name", "s" }), NULL, + clear_property) }, + { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, + connect_service) }, + { GDBUS_METHOD("Disconnect", NULL, NULL, + disconnect_service) }, + { GDBUS_METHOD("Remove", NULL, NULL, remove_service) }, + { GDBUS_METHOD("MoveBefore", + GDBUS_ARGS({ "service", "o" }), NULL, + move_before) }, + { GDBUS_METHOD("MoveAfter", + GDBUS_ARGS({ "service", "o" }), NULL, + move_after) }, + { GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) }, { }, }; -static GDBusSignalTable service_signals[] = { - { "PropertyChanged", "sv" }, +static const GDBusSignalTable service_signals[] = { + { GDBUS_SIGNAL("PropertyChanged", + GDBUS_ARGS({ "name", "s" }, { "value", "v" })) }, { }, }; @@ -4193,8 +4367,10 @@ int __connman_service_set_favorite(struct connman_service *service, favorite_changed(service); - g_sequence_sort_changed(iter, service_compare, NULL); - service_schedule_changed(); + if (g_sequence_get_length(service_list) > 1) { + g_sequence_sort_changed(iter, service_compare, NULL); + service_schedule_changed(); + } __connman_connection_update_gateway(); @@ -4245,6 +4421,13 @@ void __connman_service_set_string(struct connman_service *service, } } +void __connman_service_set_userconnect(struct connman_service *service, + connman_bool_t userconnect) +{ + if (service != NULL) + service->userconnect = userconnect; +} + static void service_complete(struct connman_service *service) { reply_pending(service, EIO); @@ -4262,9 +4445,12 @@ static void report_error_cb(struct connman_service *service, if (retry == TRUE) __connman_service_connect(service); else { + /* It is not relevant to stay on Failure state + * when failing is due to wrong user input */ + service->state = CONNMAN_SERVICE_STATE_IDLE; + service_complete(service); __connman_connection_update_gateway(); - __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN); } } @@ -4295,23 +4481,35 @@ int __connman_service_add_passphrase(struct connman_service *service, return err; } -static int check_wpspin(const char *wpspin) +static int check_wpspin(struct connman_service *service, const char *wpspin) { + int length; guint i; if (wpspin == NULL) return 0; + length = strlen(wpspin); + + /* If 0, it will mean user wants to use PBC method */ + if (length == 0) { + connman_network_set_string(service->network, + "WiFi.PinWPS", NULL); + return 0; + } + /* A WPS PIN is always 8 chars length, * its content is in digit representation. */ - if (strlen(wpspin) != 8) + if (length != 8) return -ENOKEY; for (i = 0; i < 8; i++) if (!isdigit((unsigned char) wpspin[i])) return -ENOKEY; + connman_network_set_string(service->network, "WiFi.PinWPS", wpspin); + return 0; } @@ -4320,13 +4518,23 @@ static void request_input_cb (struct connman_service *service, const char *name, int name_len, const char *identity, const char *passphrase, gboolean wps, const char *wpspin, - void *user_data) + const char *error, void *user_data) { struct connman_device *device; int err = 0; DBG ("RequestInput return, %p", service); + if (error != NULL) { + DBG("error: %s", error); + + if (g_strcmp0(error, + "net.connman.Agent.Error.Canceled") == 0) { + err = -EINVAL; + goto done; + } + } + if (service->hidden == TRUE && name_len > 0 && name_len <= 32) { device = connman_network_get_device(service->network); __connman_device_request_hidden_scan(device, @@ -4335,19 +4543,16 @@ static void request_input_cb (struct connman_service *service, } if (values_received == FALSE || service->hidden == TRUE) { - service_complete(service); - __connman_connection_update_gateway(); - __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN); - return; + err = -EINVAL; + goto done; } - err = check_wpspin(wpspin); - if (err < 0) - goto done; - if (service->network != NULL) { - connman_network_set_bool(service->network, "Wifi.UseWPS", wps); - connman_network_set_string(service->network, "Wifi.PinWPS", - wpspin); + if (wps == TRUE && service->network != NULL) { + err = check_wpspin(service, wpspin); + if (err < 0) + goto done; + + connman_network_set_bool(service->network, "WiFi.UseWPS", wps); } if (identity != NULL) @@ -4369,6 +4574,13 @@ static void request_input_cb (struct connman_service *service, __connman_agent_report_error(service, error2string(service->error), report_error_cb, NULL); + } else { + /* It is not relevant to stay on Failure state + * when failing is due to wrong user input */ + service->state = CONNMAN_SERVICE_STATE_IDLE; + + service_complete(service); + __connman_connection_update_gateway(); } } @@ -4459,6 +4671,9 @@ static int service_indicate_state(struct connman_service *service) __connman_service_auto_connect(); } + if (old_state == CONNMAN_SERVICE_STATE_ONLINE) + __connman_notifier_leave_online(service->type); + service->state = new_state; state_changed(service); @@ -4470,7 +4685,12 @@ static int service_indicate_state(struct connman_service *service) } if (new_state == CONNMAN_SERVICE_STATE_CONFIGURATION) { - if (__connman_stats_service_register(service) == 0) { + if (service->new_service == FALSE && + __connman_stats_service_register(service) == 0) { + /* + * For new services the statistics are updated after + * we have successfully connected. + */ __connman_stats_get(service, FALSE, &service->stats.data); __connman_stats_get(service, TRUE, @@ -4484,13 +4704,26 @@ static int service_indicate_state(struct connman_service *service) reconnect = get_reconnect_state(service); if (reconnect == TRUE) __connman_service_auto_connect(); - - __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN); } if (new_state == CONNMAN_SERVICE_STATE_READY) { enum connman_ipconfig_method method; + if (service->new_service == TRUE && + __connman_stats_service_register(service) == 0) { + /* + * This is normally done after configuring state + * but for new service do this after we have connected + * successfully. + */ + __connman_stats_get(service, FALSE, + &service->stats.data); + __connman_stats_get(service, TRUE, + &service->stats_roaming.data); + } + + service->new_service = FALSE; + service_update_preferred_order(def_service, service, new_state); set_reconnect_state(service, TRUE); @@ -4534,7 +4767,7 @@ static int service_indicate_state(struct connman_service *service) } else if (new_state == CONNMAN_SERVICE_STATE_DISCONNECT) { def_service = __connman_service_get_default(); - if (__connman_notifier_count_connected() == 0 && + if (__connman_notifier_is_connected() == FALSE && def_service != NULL && def_service->provider != NULL) __connman_provider_disconnect(def_service->provider); @@ -4563,24 +4796,24 @@ static int service_indicate_state(struct connman_service *service) if (service->userconnect == TRUE && __connman_agent_report_error(service, error2string(service->error), - report_error_cb, NULL) == -EIO) + report_error_cb, NULL) == -EINPROGRESS) return 0; service_complete(service); - - __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN); } else service->error = CONNMAN_SERVICE_ERROR_UNKNOWN; iter = g_hash_table_lookup(service_hash, service->identifier); - if (iter != NULL) { + if (iter != NULL && g_sequence_get_length(service_list) > 1) { g_sequence_sort_changed(iter, service_compare, NULL); service_schedule_changed(); } __connman_connection_update_gateway(); - if (new_state == CONNMAN_SERVICE_STATE_ONLINE) + if (new_state == CONNMAN_SERVICE_STATE_ONLINE) { + __connman_notifier_enter_online(service->type); default_changed(); + } return 0; } @@ -4643,12 +4876,7 @@ int __connman_service_clear_error(struct connman_service *service) int __connman_service_indicate_default(struct connman_service *service) { - struct connman_service *current = __connman_service_get_default(); - - DBG("service %p default %p", service, current); - - if (current == service) - return 0; + DBG("service %p", service); default_changed(); @@ -4772,7 +5000,8 @@ int __connman_service_online_check_failed(struct connman_service *service, /* currently we only retry IPv6 stuff */ if (type == CONNMAN_IPCONFIG_TYPE_IPV4 || service->online_check_count != 1) { - __connman_service_auto_connect(); + connman_warn("Online check failed for %p %s", service, + service->name); return 0; } @@ -5101,13 +5330,6 @@ int __connman_service_connect(struct connman_service *service) return -EINPROGRESS; } - __connman_service_ipconfig_indicate_state(service, - CONNMAN_SERVICE_STATE_FAILURE, - CONNMAN_IPCONFIG_TYPE_IPV4); - __connman_service_ipconfig_indicate_state(service, - CONNMAN_SERVICE_STATE_FAILURE, - CONNMAN_IPCONFIG_TYPE_IPV6); - if (service->network != NULL) __connman_network_disconnect(service->network); else if (service->type == CONNMAN_SERVICE_TYPE_VPN && @@ -5116,10 +5338,8 @@ int __connman_service_connect(struct connman_service *service) if (service->userconnect == TRUE) { if (err == -ENOKEY || err == -EPERM) { - if (__connman_agent_request_passphrase_input(service, - request_input_cb, - NULL) == -EIO) - return -EINPROGRESS; + return __connman_agent_request_passphrase_input(service, + request_input_cb, NULL); } reply_pending(service, -err); } @@ -5286,7 +5506,7 @@ static int service_register(struct connman_service *service) NULL, service, NULL); iter = g_hash_table_lookup(service_hash, service->identifier); - if (iter != NULL) { + if (iter != NULL && g_sequence_get_length(service_list) > 1) { g_sequence_sort_changed(iter, service_compare, NULL); service_schedule_changed(); } @@ -5587,7 +5807,7 @@ void __connman_service_update_ordering(void) GSequenceIter *iter; iter = g_sequence_get_begin_iter(service_list); - if (iter != NULL) + if (iter != NULL && g_sequence_get_length(service_list) > 1) g_sequence_sort_changed(iter, service_compare, NULL); } @@ -5689,7 +5909,7 @@ static void update_from_network(struct connman_service *service, service->network = connman_network_ref(network); iter = g_hash_table_lookup(service_hash, service->identifier); - if (iter != NULL) { + if (iter != NULL && g_sequence_get_length(service_list) > 1) { g_sequence_sort_changed(iter, service_compare, NULL); service_schedule_changed(); } @@ -5785,7 +6005,7 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne if (service->favorite == TRUE) { device = connman_network_get_device(service->network); - if (device && __connman_device_scanning(device) == FALSE) + if (device && connman_device_get_scanning(device) == FALSE) __connman_service_auto_connect(); } @@ -5855,7 +6075,7 @@ roaming: sorting: if (need_sort == TRUE) { iter = g_hash_table_lookup(service_hash, service->identifier); - if (iter != NULL) { + if (iter != NULL && g_sequence_get_length(service_list) > 1) { g_sequence_sort_changed(iter, service_compare, NULL); service_schedule_changed(); }