X-Git-Url: http://review.tizen.org/git/?p=framework%2Fconnectivity%2Fconnman.git;a=blobdiff_plain;f=src%2Fservice.c;h=a3a0160a07b51adf11716b1f121d5000842ddd9f;hp=5e1b51aacff9b47bcd9cea6df234284259c84566;hb=3ca789e446848eed6ca3c00af080cd737d115dcb;hpb=c329f0f22773df936ef31c539d8fd32c3a973659 diff --git a/src/service.c b/src/service.c index 5e1b51a..a3a0160 100644 --- a/src/service.c +++ b/src/service.c @@ -696,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) @@ -1143,48 +1148,26 @@ static void add_nameserver_route(int family, int index, char *nameserver, static void nameserver_add_routes(int index, char **nameservers, const char *gw) { - int i, ret, family; - struct addrinfo hints; - struct addrinfo *addr; + int i, family; for (i = 0; nameservers[i] != NULL; i++) { - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = AI_NUMERICHOST; - addr = NULL; - - ret = getaddrinfo(nameservers[i], NULL, &hints, &addr); - if (ret == EAI_NONAME) - family = AF_INET; /* use the IPv4 as a default */ - else if (ret != 0) + family = connman_inet_check_ipaddress(nameservers[i]); + if (family < 0) continue; - else - family = addr->ai_family; add_nameserver_route(family, index, nameservers[i], gw); - - freeaddrinfo(addr); } } static void nameserver_del_routes(int index, char **nameservers, enum connman_ipconfig_type type) { - int i, ret, family; - struct addrinfo hints; - struct addrinfo *addr; + int i, family; for (i = 0; nameservers[i] != NULL; i++) { - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = AI_NUMERICHOST; - addr = NULL; - - ret = getaddrinfo(nameservers[i], NULL, &hints, &addr); - if (ret == EAI_NONAME) - family = AF_INET; /* use the IPv4 as a default */ - else if (ret != 0) + family = connman_inet_check_ipaddress(nameservers[i]); + if (family < 0) continue; - else - family = addr->ai_family; switch (family) { case AF_INET: @@ -1198,8 +1181,6 @@ static void nameserver_del_routes(int index, char **nameservers, nameservers[i]); break; } - - freeaddrinfo(addr); } } @@ -2637,14 +2618,23 @@ void __connman_service_set_agent_identity(struct connman_service *service, service->agent_identity); } -static int check_passphrase(enum connman_service_security security, +static int check_passphrase(struct connman_service *service, + enum connman_service_security security, const char *passphrase) { guint i; gsize length; - if (passphrase == NULL) - return 0; + if (passphrase == NULL) { + /* + * This will prevent __connman_service_set_passphrase() to + * wipe the passphrase out in case of -ENOKEY error for a + * favorite service. */ + if (service->favorite == TRUE) + return 1; + else + return 0; + } length = strlen(passphrase); @@ -2693,7 +2683,7 @@ int __connman_service_set_passphrase(struct connman_service *service, if (service->immutable == TRUE || service->hidden == TRUE) return -EINVAL; - err = check_passphrase(service->security, passphrase); + err = check_passphrase(service, service->security, passphrase); if (err == 0) { g_free(service->passphrase); @@ -2709,6 +2699,14 @@ int __connman_service_set_passphrase(struct connman_service *service, return err; } +const char *__connman_service_get_passphrase(struct connman_service *service) +{ + if (service == NULL) + return NULL; + + return service->passphrase; +} + void __connman_service_set_agent_passphrase(struct connman_service *service, const char *agent_passphrase) { @@ -3036,10 +3034,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); @@ -3388,39 +3388,78 @@ static void remove_timeout(struct connman_service *service) } } -static void reply_pending(struct connman_service *service, int error) +void __connman_service_reply_dbus_pending(DBusMessage *pending, int error) { - remove_timeout(service); - - if (service->pending != NULL) { + if (pending != NULL) { if (error > 0) { DBusMessage *reply; - reply = __connman_error_failed(service->pending, - error); + reply = __connman_error_failed(pending, error); if (reply != NULL) g_dbus_send_message(connection, reply); } else { - const char *sender; + const char *sender, *path; - sender = dbus_message_get_interface(service->pending); + sender = dbus_message_get_interface(pending); + path = dbus_message_get_path(pending); - DBG("sender %s", sender); + DBG("sender %s path %s", sender, path); if (g_strcmp0(sender, CONNMAN_MANAGER_INTERFACE) == 0) - g_dbus_send_reply(connection, service->pending, - DBUS_TYPE_OBJECT_PATH, &service->path, + g_dbus_send_reply(connection, pending, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); else - g_dbus_send_reply(connection, service->pending, + g_dbus_send_reply(connection, pending, DBUS_TYPE_INVALID); } - dbus_message_unref(service->pending); + dbus_message_unref(pending); + } +} + +static void reply_pending(struct connman_service *service, int error) +{ + remove_timeout(service); + + if (service->pending != NULL) { + __connman_service_reply_dbus_pending(service->pending, error); service->pending = NULL; } } +static void check_pending_msg(struct connman_service *service) +{ + if (service->pending == NULL) + return; + + DBG("service %p pending msg %p already exists", service, + service->pending); + dbus_message_unref(service->pending); +} + +void __connman_service_set_hidden_data(struct connman_service *service, + gpointer user_data) +{ + DBusMessage *pending = user_data; + + DBG("service %p pending %p", service, pending); + + check_pending_msg(service); + + service->pending = pending; +} + +void __connman_service_return_error(struct connman_service *service, + int error, gpointer user_data) +{ + DBG("service %p error %d user_data %p", service, error, user_data); + + __connman_service_set_hidden_data(service, user_data); + + reply_pending(service, error); +} + static gboolean connect_timeout(gpointer user_data) { struct connman_service *service = user_data; @@ -4624,6 +4663,9 @@ static void request_input_cb (struct connman_service *service, done: if (err >= 0) { + /* We forget any previous error. */ + service->error = CONNMAN_SERVICE_ERROR_UNKNOWN; + __connman_service_connect(service); /* Never cache agent provided credentials */ @@ -5281,7 +5323,9 @@ static int service_connect(struct connman_service *service) service->network, "WiFi.UseWPS") == FALSE) return -ENOKEY; - } + } else if (service->error == + CONNMAN_SERVICE_ERROR_INVALID_KEY) + return -ENOKEY; break; case CONNMAN_SERVICE_SECURITY_8021X: if (service->eap == NULL) @@ -5495,17 +5539,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,