#include <netdb.h>
#include <gdbus.h>
+#include <connman/storage.h>
+
#include "connman.h"
#define CONNECT_TIMEOUT 120
char *phase2;
DBusMessage *pending;
guint timeout;
- struct connman_location *location;
struct connman_stats stats;
struct connman_stats stats_roaming;
GHashTable *counter_table;
static int service_load(struct connman_service *service)
{
- const char *ident = "default";
GKeyFile *keyfile;
GError *error = NULL;
- gchar *pathname, *data = NULL;
gsize length;
gchar *str;
connman_bool_t autoconnect;
DBG("service %p", service);
- if (ident == NULL)
- return -EINVAL;
-
- pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
- if (pathname == NULL)
- return -ENOMEM;
-
- keyfile = g_key_file_new();
-
- if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE) {
- g_free(pathname);
- return -ENOENT;
- }
-
- g_free(pathname);
-
- if (g_key_file_load_from_data(keyfile, data, length,
- 0, NULL) == FALSE) {
- g_free(data);
- return -EILSEQ;
- }
-
- g_free(data);
+ keyfile = connman_storage_load_service(service->identifier);
+ if (keyfile == NULL)
+ return -EIO;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
static int service_save(struct connman_service *service)
{
- const char *ident = "default";
GKeyFile *keyfile;
- gchar *pathname, *data = NULL;
- gsize length;
gchar *str;
+ guint freq;
const char *cst_str = NULL;
int err = 0;
DBG("service %p", service);
- if (ident == NULL)
- return -EINVAL;
-
- pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
- if (pathname == NULL)
- return -ENOMEM;
-
- keyfile = g_key_file_new();
-
- if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
- goto update;
-
- if (length > 0) {
- if (g_key_file_load_from_data(keyfile, data, length,
- 0, NULL) == FALSE)
- goto done;
- }
-
- g_free(data);
+ keyfile = __connman_storage_open_service(service->identifier);
+ if (keyfile == NULL)
+ return -EIO;
-update:
if (service->name != NULL)
g_key_file_set_string(keyfile, service->identifier,
"Name", service->name);
g_string_free(str, TRUE);
}
+
+ freq = connman_network_get_frequency(service->network);
+ g_key_file_set_integer(keyfile, service->identifier,
+ "Frequency", freq);
}
/* fall through */
g_key_file_remove_key(keyfile, service->identifier,
"Proxy.URL", NULL);
- data = g_key_file_to_data(keyfile, &length, NULL);
-
- if (g_file_set_contents(pathname, data, length, NULL) == FALSE)
- connman_error("Failed to store service information");
-
done:
- g_free(data);
+ __connman_storage_save_service(keyfile, service->identifier);
g_key_file_free(keyfile);
- g_free(pathname);
-
return err;
}
goto done;
}
- if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) {
- if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION ||
- state_b == CONNMAN_SERVICE_STATE_ONLINE ||
- state_b == CONNMAN_SERVICE_STATE_READY)
- result = state_b;
- else
- result = state_a;
+ if (state_a == CONNMAN_SERVICE_STATE_ONLINE) {
+ result = state_a;
goto done;
}
- if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) {
- if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION ||
- state_a == CONNMAN_SERVICE_STATE_ONLINE ||
- state_a == CONNMAN_SERVICE_STATE_READY)
- result = state_a;
- else
- result = state_b;
+ if (state_b == CONNMAN_SERVICE_STATE_ONLINE) {
+ result = state_b;
goto done;
}
- if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) {
- if (state_b == CONNMAN_SERVICE_STATE_ONLINE ||
- state_b == CONNMAN_SERVICE_STATE_READY)
- result = state_b;
- else
- result = state_a;
+ if (state_a == CONNMAN_SERVICE_STATE_READY) {
+ result = state_a;
goto done;
}
- if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) {
- if (state_a == CONNMAN_SERVICE_STATE_ONLINE ||
- state_a == CONNMAN_SERVICE_STATE_READY)
- result = state_a;
- else
- result = state_b;
+ if (state_b == CONNMAN_SERVICE_STATE_READY) {
+ result = state_b;
goto done;
}
- if (state_a == CONNMAN_SERVICE_STATE_READY) {
- if (state_b == CONNMAN_SERVICE_STATE_ONLINE ||
- state_b == CONNMAN_SERVICE_STATE_DISCONNECT)
- result = state_b;
- else
- result = state_a;
+ if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) {
+ result = state_a;
goto done;
}
- if (state_b == CONNMAN_SERVICE_STATE_READY) {
- if (state_a == CONNMAN_SERVICE_STATE_ONLINE ||
- state_a == CONNMAN_SERVICE_STATE_DISCONNECT)
- result = state_a;
- else
- result = state_b;
+ if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) {
+ result = state_b;
goto done;
}
- if (state_a == CONNMAN_SERVICE_STATE_ONLINE) {
- if (state_b == CONNMAN_SERVICE_STATE_DISCONNECT)
- result = state_b;
- else
- result = state_a;
+ if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) {
+ result = state_a;
goto done;
}
- if (state_b == CONNMAN_SERVICE_STATE_ONLINE) {
- if (state_a == CONNMAN_SERVICE_STATE_DISCONNECT)
- result = state_a;
- else
- result = state_b;
+ if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) {
+ result = state_b;
goto done;
}
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &str);
- str = "wps";
- if (service->wps == TRUE)
- dbus_message_iter_append_basic(iter,
- DBUS_TYPE_STRING, &str);
+ /*
+ * Some access points incorrectly advertise WPS even when they
+ * are configured as open or no security, so filter
+ * appropriately.
+ */
+ if (service->wps == TRUE) {
+ switch (service->security) {
+ case CONNMAN_SERVICE_SECURITY_PSK:
+ case CONNMAN_SERVICE_SECURITY_WPA:
+ case CONNMAN_SERVICE_SECURITY_RSN:
+ str = "wps";
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str);
+ break;
+ case CONNMAN_SERVICE_SECURITY_UNKNOWN:
+ case CONNMAN_SERVICE_SECURITY_NONE:
+ case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_8021X:
+ break;
+ }
+ }
}
static void append_ethernet(DBusMessageIter *iter, void *user_data)
return __connman_device_get_reconnect(device);
}
-static void request_input_cb (struct connman_service *service,
- const char *identity, const char *passphrase,
- void *user_data)
-{
- DBG ("RequestInput return, %p", service);
-
- if (identity == NULL && passphrase == NULL && service->wps == FALSE)
- return;
-
- if (identity != NULL)
- __connman_service_set_agent_identity(service, identity);
-
- if (passphrase != NULL) {
- switch (service->security) {
- case CONNMAN_SERVICE_SECURITY_WEP:
- case CONNMAN_SERVICE_SECURITY_PSK:
- __connman_service_set_passphrase(service, passphrase);
- break;
- case CONNMAN_SERVICE_SECURITY_8021X:
- __connman_service_set_agent_passphrase(service,
- passphrase);
- break;
- case CONNMAN_SERVICE_SECURITY_UNKNOWN:
- case CONNMAN_SERVICE_SECURITY_NONE:
- case CONNMAN_SERVICE_SECURITY_WPA:
- case CONNMAN_SERVICE_SECURITY_RSN:
- DBG("service security '%s' not handled",
- security2string(service->security));
- break;
- }
- }
-
- __connman_service_connect(service);
-
- /* Never cache agent provided credentials */
- __connman_service_set_agent_identity(service, NULL);
- __connman_service_set_agent_passphrase(service, NULL);
-}
-
static DBusMessage *connect_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
return __connman_error_not_supported(msg);
target = find_service(path);
- if (target == NULL || target->favorite == FALSE || target == service)
+ if (target == NULL || target->favorite == FALSE || target == service ||
+ target->type == CONNMAN_SERVICE_TYPE_VPN)
return __connman_error_invalid_service(msg);
target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
__connman_notifier_service_remove(service);
stats_stop(service);
- service_save(service);
service->path = NULL;
service->ipconfig_ipv6 = NULL;
}
- if (service->location != NULL)
- connman_location_unref(service->location);
-
g_strfreev(service->nameservers);
g_strfreev(service->nameservers_config);
g_strfreev(service->domains);
service_initialize(service);
- service->location = __connman_location_create(service);
-
return service;
}
-struct connman_location *__connman_service_get_location(struct connman_service *service)
-{
- return service->location;
-}
-
/**
* connman_service_ref:
* @service: service structure
}
}
+static void request_input_cb (struct connman_service *service,
+ const char *identity, const char *passphrase,
+ void *user_data)
+{
+ DBG ("RequestInput return, %p", service);
+
+ if (identity == NULL && passphrase == NULL && service->wps == FALSE) {
+ service_complete(service);
+ services_changed(FALSE);
+ __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN);
+ return;
+ }
+
+ if (identity != NULL)
+ __connman_service_set_agent_identity(service, identity);
+
+ if (passphrase != NULL) {
+ switch (service->security) {
+ case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_PSK:
+ __connman_service_set_passphrase(service, passphrase);
+ break;
+ case CONNMAN_SERVICE_SECURITY_8021X:
+ __connman_service_set_agent_passphrase(service,
+ passphrase);
+ break;
+ case CONNMAN_SERVICE_SECURITY_UNKNOWN:
+ case CONNMAN_SERVICE_SECURITY_NONE:
+ case CONNMAN_SERVICE_SECURITY_WPA:
+ case CONNMAN_SERVICE_SECURITY_RSN:
+ DBG("service security '%s' not handled",
+ security2string(service->security));
+ break;
+ }
+ }
+
+ __connman_service_connect(service);
+
+ /* Never cache agent provided credentials */
+ __connman_service_set_agent_identity(service, NULL);
+ __connman_service_set_agent_passphrase(service, NULL);
+}
+
static int service_indicate_state(struct connman_service *service)
{
enum connman_service_state old_state, new_state;
def_service->provider != NULL)
__connman_provider_disconnect(def_service->provider);
- __connman_location_finish(service);
-
default_changed();
+ __connman_wispr_stop(service);
+
__connman_wpad_stop(service);
update_nameservers(service);
default_changed();
- __connman_location_detect(service);
-
return 0;
}
*/
if (service->proxy != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
- return;
+ goto done;
if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
(service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
service->pac != NULL))
- return;
+ goto done;
if (__connman_wpad_start(service) < 0) {
service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
__connman_notifier_proxy_changed(service);
}
+
+ return;
+
+done:
+ __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
}
int __connman_service_ipconfig_indicate_state(struct connman_service *service,
{
struct connman_ipconfig *ipconfig = NULL;
enum connman_service_state old_state;
+ int ret;
if (service == NULL)
return -EINVAL;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
check_proxy_setup(service);
+ else
+ __connman_wispr_start(service, type);
break;
case CONNMAN_SERVICE_STATE_ONLINE:
break;
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
service->state_ipv6 = new_state;
- return service_indicate_state(service);
+ ret = service_indicate_state(service);
+
+ /*
+ * If the ipconfig method is OFF, then we set the state to IDLE
+ * so that it will not affect the combined state in the future.
+ */
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+ enum connman_ipconfig_method method;
+ method = __connman_ipconfig_get_method(service->ipconfig_ipv4);
+ if (method == CONNMAN_IPCONFIG_METHOD_OFF ||
+ method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) {
+ service->state_ipv4 = CONNMAN_SERVICE_STATE_IDLE;
+ ret = service_indicate_state(service);
+ }
+
+ } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
+ enum connman_ipconfig_method method;
+ method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
+ if (method == CONNMAN_IPCONFIG_METHOD_OFF ||
+ method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) {
+ service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
+ ret = service_indicate_state(service);
+ }
+ }
+
+ return ret;
}
int __connman_service_request_login(struct connman_service *service)
if (service->userconnect == TRUE) {
if (err == -ENOKEY) {
- if (__connman_agent_request_input(service,
+ if (__connman_agent_request_passphrase_input(service,
request_input_cb,
NULL) == -EIO)
return -EINPROGRESS;
if (service->ipconfig_ipv4 == NULL)
return;
- keyfile = __connman_storage_open_profile("default");
+ keyfile = __connman_storage_load_global();
if (keyfile == NULL)
return;
if (service->ipconfig_ipv6 == NULL)
return;
- keyfile = __connman_storage_open_profile("default");
+ keyfile = connman_storage_load_service(service->identifier);
if (keyfile == NULL)
return;
return;
setup_ip6config(service, index);
+
__connman_service_read_ip6config(service);
}
DBG("network %p", network);
+ if (network == NULL)
+ return NULL;
+
ident = __connman_network_get_ident(network);
if (ident == NULL)
return NULL;
DBG("network %p", network);
+ if (network == NULL)
+ return NULL;
+
ident = __connman_network_get_ident(network);
if (ident == NULL)
return NULL;