};
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);
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)
provider->host = g_strdup(host);
provider->domain = g_strdup(domain);
+ g_free(provider->name);
provider->name = g_strdup(name);
provider->type = g_strdup(type);
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,
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);
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;