};
struct connman_provider {
- gint refcount;
+ int refcount;
struct connman_service *vpn_service;
int index;
char *identifier;
&provider->type);
}
+static int connman_provider_load(struct connman_provider *provider)
+{
+ gsize idx = 0;
+ GKeyFile *keyfile;
+ gchar **settings;
+ gchar *key, *value;
+ gsize length;
+
+ DBG("provider %p", provider);
+
+ keyfile = __connman_storage_load_provider(provider->identifier);
+ if (keyfile == NULL)
+ return -ENOENT;
+
+ settings = g_key_file_get_keys(keyfile, provider->identifier, &length,
+ NULL);
+ if (settings == NULL) {
+ g_key_file_free(keyfile);
+ return -ENOENT;
+ }
+
+ while (idx < length) {
+ key = settings[idx];
+ DBG("found key %s", key);
+ if (key != NULL) {
+ value = g_key_file_get_string(keyfile,
+ provider->identifier,
+ key, NULL);
+ connman_provider_set_string(provider, key, value);
+ g_free(value);
+ }
+ idx += 1;
+ }
+ g_strfreev(settings);
+
+ g_key_file_free(keyfile);
+ return 0;
+}
+
+static int connman_provider_save(struct connman_provider *provider)
+{
+ GKeyFile *keyfile;
+
+ DBG("provider %p", provider);
+
+ keyfile = g_key_file_new();
+ if (keyfile == NULL)
+ return -ENOMEM;
+
+ g_key_file_set_string(keyfile, provider->identifier,
+ "Name", provider->name);
+ g_key_file_set_string(keyfile, provider->identifier,
+ "Type", provider->type);
+ g_key_file_set_string(keyfile, provider->identifier,
+ "Host", provider->host);
+ g_key_file_set_string(keyfile, provider->identifier,
+ "VPN.Domain", provider->domain);
+
+ if (provider->driver != NULL && provider->driver->save != NULL)
+ provider->driver->save(provider, keyfile);
+
+ __connman_storage_save_provider(keyfile, provider->identifier);
+ g_key_file_free(keyfile);
+
+ return 0;
+}
+
static struct connman_provider *connman_provider_lookup(const char *identifier)
{
struct connman_provider *provider = NULL;
static int provider_register(struct connman_provider *provider)
{
+ connman_provider_load(provider);
return provider_probe(provider);
}
struct connman_provider *connman_provider_ref(struct connman_provider *provider)
{
- DBG("provider %p", provider);
+ DBG("provider %p refcount %d", provider, provider->refcount + 1);
- g_atomic_int_inc(&provider->refcount);
+ __sync_fetch_and_add(&provider->refcount, 1);
return provider;
}
void connman_provider_unref(struct connman_provider *provider)
{
- DBG("provider %p", provider);
+ DBG("provider %p refcount %d", provider, provider->refcount - 1);
- if (g_atomic_int_dec_and_test(&provider->refcount) == FALSE)
+ if (__sync_fetch_and_sub(&provider->refcount, 1) != 1)
return;
provider_remove(provider);
{
DBG("state %d", state);
- __connman_service_indicate_state(provider->vpn_service, state,
+ __connman_service_ipconfig_indicate_state(provider->vpn_service, state,
CONNMAN_IPCONFIG_TYPE_IPV4);
- return __connman_service_indicate_state(provider->vpn_service, state,
- CONNMAN_IPCONFIG_TYPE_IPV6);
+ return __connman_service_ipconfig_indicate_state(provider->vpn_service,
+ state, CONNMAN_IPCONFIG_TYPE_IPV6);
}
int __connman_provider_disconnect(struct connman_provider *provider)
enum connman_provider_error error)
{
enum connman_service_error service_error;
+ const char *path;
+ int ret;
switch (error) {
case CONNMAN_PROVIDER_ERROR_LOGIN_FAILED:
break;
}
- return __connman_service_indicate_error(provider->vpn_service,
+ ret = __connman_service_indicate_error(provider->vpn_service,
service_error);
+ path = __connman_service_get_path(provider->vpn_service);
+ __connman_provider_remove(path);
+
+ return ret;
}
static void unregister_provider(gpointer data)
{
struct connman_provider *provider;
DBusMessageIter iter, array;
- const char *type = NULL, *name = NULL, *service_path = NULL;
+ const char *type = NULL, *name = NULL, *service_path;
const char *host = NULL, *domain = NULL;
char *ident;
- gboolean created = FALSE;
int err;
dbus_message_iter_init(msg, &iter);
dbus_message_iter_next(&array);
}
- if (host == NULL || domain == NULL) {
- err = -EINVAL;
- goto failed;
- }
+ if (host == NULL || domain == NULL)
+ return -EINVAL;
DBG("Type %s name %s", type, name);
- if (type == NULL || name == NULL) {
- err = -EOPNOTSUPP;
- goto failed;
- }
+ if (type == NULL || name == NULL)
+ return -EOPNOTSUPP;
ident = g_strdup_printf("%s_%s", host, domain);
provider_dbus_ident(ident);
DBG("ident %s", ident);
provider = connman_provider_lookup(ident);
-
if (provider == NULL) {
- created = TRUE;
provider = connman_provider_get(ident);
- if (provider) {
- provider->host = g_strdup(host);
- provider->domain = g_strdup(domain);
- provider->name = g_strdup(name);
- provider->type = g_strdup(type);
+ if (provider == NULL) {
+ DBG("can not create provider");
+ g_free(ident);
+ return -EOPNOTSUPP;
}
+ provider->host = g_strdup(host);
+ provider->domain = g_strdup(domain);
+ g_free(provider->name);
+ provider->name = g_strdup(name);
+ provider->type = g_strdup(type);
+
provider_register(provider);
}
- if (provider == NULL) {
- DBG("can not create provider");
- err = -EOPNOTSUPP;
- goto failed;
- }
dbus_message_iter_init(msg, &iter);
dbus_message_iter_recurse(&iter, &array);
g_free(ident);
- if (provider->vpn_service == NULL)
+ if (provider->vpn_service == NULL) {
provider->vpn_service =
__connman_service_create_from_provider(provider);
- if (provider->vpn_service == NULL) {
- err = -EOPNOTSUPP;
- goto failed;
- }
+ if (provider->vpn_service == NULL) {
+ err = -EOPNOTSUPP;
+ goto unref;
+ }
- err = __connman_service_connect(provider->vpn_service);
- if (err < 0 && err != -EINPROGRESS)
- goto failed;
+ err = __connman_service_connect(provider->vpn_service);
+ if (err < 0 && err != -EINPROGRESS)
+ goto failed;
+ } else
+ DBG("provider already connected");
+ connman_provider_save(provider);
service_path = __connman_service_get_path(provider->vpn_service);
g_dbus_send_reply(connection, msg,
DBUS_TYPE_OBJECT_PATH, &service_path,
return 0;
failed:
- if (provider != NULL && created == TRUE) {
- DBG("can not connect delete provider");
- connman_provider_unref(provider);
+ __connman_service_put(provider->vpn_service);
+ provider->vpn_service = NULL;
- if (provider->vpn_service != NULL) {
- __connman_service_put(provider->vpn_service);
- provider->vpn_service = NULL;
- }
- }
+unref:
+ DBG("can not connect, delete provider");
+
+ connman_provider_unref(provider);
return err;
}
} else if (g_str_equal(key, "Name") == TRUE) {
g_free(provider->name);
provider->name = g_strdup(value);
- }
-
- g_hash_table_replace(provider->setting_strings,
+ } else if (g_str_equal(key, "Host") == TRUE) {
+ g_free(provider->host);
+ provider->host = g_strdup(value);
+ } else if (g_str_equal(key, "VPN.Domain") == TRUE) {
+ g_free(provider->domain);
+ provider->domain = g_strdup(value);
+ } else
+ g_hash_table_replace(provider->setting_strings,
g_strdup(key), g_strdup(value));
return 0;
}
return provider->type;
else if (g_str_equal(key, "Name") == TRUE)
return provider->name;
+ else if (g_str_equal(key, "Host") == TRUE)
+ return provider->host;
+ else if (g_str_equal(key, "VPN.Domain") == TRUE)
+ return provider->domain;
return g_hash_table_lookup(provider->setting_strings, key);
}
for (i = 0; nameservers_array[i] != NULL; i++) {
__connman_service_nameserver_append(provider->vpn_service,
- nameservers_array[i]);
+ nameservers_array[i], FALSE);
}
g_strfreev(nameservers_array);
const char *connman_provider_get_driver_name(struct connman_provider *provider)
{
+ if (provider->driver == NULL)
+ return NULL;
+
return provider->driver->name;
}
+const char *connman_provider_get_save_group(struct connman_provider *provider)
+{
+ return provider->identifier;
+}
+
static gint compare_priority(gconstpointer a, gconstpointer b)
{
return 0;