X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fservice.c;h=94ef7b66ecc8fb1b43d80befe98af5026c8f6b09;hb=0e9992014e61671dc81685b7ce87c2da39b877fc;hp=c9ee004c459f0b2966c11e463734bd3138f1abcf;hpb=e9070381b7fda94a771376783336c699165e1787;p=framework%2Fconnectivity%2Fconnman.git diff --git a/src/service.c b/src/service.c index c9ee004..94ef7b6 100644 --- a/src/service.c +++ b/src/service.c @@ -44,6 +44,7 @@ static GHashTable *service_hash = NULL; static GSList *counter_list = NULL; static unsigned int autoconnect_timeout = 0; static struct connman_service *current_default = NULL; +static connman_bool_t services_dirty = FALSE; struct connman_stats { connman_bool_t valid; @@ -678,6 +679,15 @@ static int service_save(struct connman_service *service) g_key_file_set_boolean(keyfile, service->identifier, "Hidden", TRUE); + if (service->config_file != NULL && strlen(service->config_file) > 0) + g_key_file_set_string(keyfile, service->identifier, + "Config.file", service->config_file); + + if (service->config_entry != NULL && + strlen(service->config_entry) > 0) + g_key_file_set_string(keyfile, service->identifier, + "Config.ident", service->config_entry); + done: __connman_storage_save_service(keyfile, service->identifier); @@ -686,6 +696,11 @@ done: return err; } +void __connman_service_save(struct connman_service *service) +{ + service_save(service); +} + static enum connman_service_state combine_state( enum connman_service_state state_a, enum connman_service_state state_b) @@ -3026,10 +3041,12 @@ static DBusMessage *set_property(DBusConnection *conn, const char *val; dbus_message_iter_get_basic(&entry, &val); dbus_message_iter_next(&entry); - if (str->len > 0) - g_string_append_printf(str, " %s", val); - else - g_string_append(str, val); + if (connman_inet_check_ipaddress(val) > 0) { + if (str->len > 0) + g_string_append_printf(str, " %s", val); + else + g_string_append(str, val); + } } remove_nameservers(service, NULL, service->nameservers_config); @@ -4366,15 +4383,22 @@ connman_bool_t __connman_service_wps_enabled(struct connman_service *service) return service->wps; } +void __connman_service_mark_dirty() + { + services_dirty = TRUE; + } + /** - * __connman_service_set_favorite: + * __connman_service_set_favorite_delayed: * @service: service structure * @favorite: favorite value + * @delay_ordering: do not order service sequence * * Change the favorite setting of service */ -int __connman_service_set_favorite(struct connman_service *service, - connman_bool_t favorite) +int __connman_service_set_favorite_delayed(struct connman_service *service, + connman_bool_t favorite, + gboolean delay_ordering) { GSequenceIter *iter; @@ -4388,20 +4412,39 @@ int __connman_service_set_favorite(struct connman_service *service, return -EALREADY; service->favorite = favorite; - service->order = __connman_service_get_order(service); + + if (delay_ordering == FALSE) + service->order = __connman_service_get_order(service); favorite_changed(service); - if (g_sequence_get_length(service_list) > 1) { - g_sequence_sort_changed(iter, service_compare, NULL); - service_schedule_changed(); - } + if (delay_ordering == FALSE) { - __connman_connection_update_gateway(); + if (g_sequence_get_length(service_list) > 1) { + g_sequence_sort_changed(iter, service_compare, NULL); + service_schedule_changed(); + } + + __connman_connection_update_gateway(); + } return 0; } +/** + * __connman_service_set_favorite: + * @service: service structure + * @favorite: favorite value + * + * Change the favorite setting of service + */ +int __connman_service_set_favorite(struct connman_service *service, + connman_bool_t favorite) +{ + return __connman_service_set_favorite_delayed(service, favorite, + FALSE); +} + int __connman_service_set_immutable(struct connman_service *service, connman_bool_t immutable) { @@ -5459,17 +5502,49 @@ static struct connman_service *lookup_by_identifier(const char *identifier) return NULL; } +struct provision_user_data { + const char *ident; + int ret; +}; + static void provision_changed(gpointer value, gpointer user_data) { struct connman_service *service = value; - char *path = user_data; + struct provision_user_data *data = user_data; + const char *path = data->ident; + int ret; - __connman_config_provision_service_ident(service, path); + ret = __connman_config_provision_service_ident(service, path, + service->config_file, service->config_entry); + if (ret > 0) + data->ret = ret; } -void __connman_service_provision_changed(const char *ident) +int __connman_service_provision_changed(const char *ident) { - g_sequence_foreach(service_list, provision_changed, (void *)ident); + struct provision_user_data data = { + .ident = ident, + .ret = 0 + }; + + g_sequence_foreach(service_list, provision_changed, (void *)&data); + + /* + * Because the provision_changed() might have set some services + * as favorite, we must sort the sequence now. + */ + if (services_dirty == TRUE) { + services_dirty = FALSE; + + if (g_sequence_get_length(service_list) > 1) { + g_sequence_sort(service_list, service_compare, NULL); + service_schedule_changed(); + } + + __connman_connection_update_gateway(); + } + + return data.ret; } void __connman_service_set_config(struct connman_service *service, @@ -6205,6 +6280,66 @@ __connman_service_create_from_provider(struct connman_provider *provider) return service; } +static void remove_unprovisioned_services() +{ + gchar **services; + GKeyFile *keyfile, *configkeyfile; + char *file, *section; + int i = 0; + + services = connman_storage_get_services(); + if (services == NULL) + return; + + for (;services[i] != NULL; i++) { + file = section = NULL; + keyfile = configkeyfile = NULL; + + keyfile = connman_storage_load_service(services[i]); + if (keyfile == NULL) + continue; + + file = g_key_file_get_string(keyfile, services[i], + "Config.file", NULL); + if (file == NULL) + goto next; + + section = g_key_file_get_string(keyfile, services[i], + "Config.ident", NULL); + if (section == NULL) + goto next; + + configkeyfile = __connman_storage_load_config(file); + if (configkeyfile == NULL) { + /* + * Config file is missing, remove the provisioned + * service. + */ + __connman_storage_remove_service(services[i]); + goto next; + } + + if (g_key_file_has_group(configkeyfile, section) == FALSE) + /* + * Config section is missing, remove the provisioned + * service. + */ + __connman_storage_remove_service(services[i]); + + next: + if (keyfile != NULL) + g_key_file_free(keyfile); + + if (configkeyfile != NULL) + g_key_file_free(configkeyfile); + + g_free(section); + g_free(file); + } + + g_strfreev(services); +} + int __connman_service_init(void) { DBG(""); @@ -6221,6 +6356,8 @@ int __connman_service_init(void) g_str_equal, g_free, NULL); services_notify->add = g_hash_table_new(g_str_hash, g_str_equal); + remove_unprovisioned_services(); + return 0; }