summaryrefslogtreecommitdiff
path: root/src/provider.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/provider.c')
-rw-r--r--src/provider.c324
1 files changed, 37 insertions, 287 deletions
diff --git a/src/provider.c b/src/provider.c
index 66fb6281..f0e63381 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -39,61 +39,44 @@ struct connman_provider {
struct connman_element element;
struct connman_service *vpn_service;
char *identifier;
- char *path;
- enum connman_provider_state state;
- enum connman_provider_error error;
char *name;
char *type;
char *dns;
char *domain;
- DBusMessage *pending;
- guint timeout;
struct connman_provider_driver *driver;
void *driver_data;
};
-static const char *state2string(enum connman_provider_state state)
-{
- switch (state) {
- case CONNMAN_PROVIDER_STATE_UNKNOWN:
- break;
- case CONNMAN_PROVIDER_STATE_IDLE:
- return "idle";
- case CONNMAN_PROVIDER_STATE_CONNECT:
- return "connect";
- case CONNMAN_PROVIDER_STATE_READY:
- return "ready";
- case CONNMAN_PROVIDER_STATE_DISCONNECT:
- return "disconnect";
- case CONNMAN_PROVIDER_STATE_FAILURE:
- return "failure";
- }
- return NULL;
-}
-
-static const char *error2string(enum connman_provider_error error)
+void __connman_provider_append_properties(struct connman_provider *provider,
+ DBusMessageIter *iter)
{
- switch (error) {
- case CONNMAN_PROVIDER_ERROR_UNKNOWN:
- break;
- case CONNMAN_PROVIDER_ERROR_CONNECT_FAILED:
- return "connect-failed";
- }
+ dbus_bool_t required;
- return NULL;
+ if (provider->name != NULL)
+ connman_dbus_dict_append_basic(iter, "Name",
+ DBUS_TYPE_STRING, &provider->name);
+
+ if (provider->type != NULL)
+ connman_dbus_dict_append_basic(iter, "Type", DBUS_TYPE_STRING,
+ &provider->type);
+
+ required = TRUE;
+ connman_dbus_dict_append_basic(iter, "PassphraseRequired",
+ DBUS_TYPE_BOOLEAN, &required);
}
static void append_path(gpointer key, gpointer value, gpointer user_data)
{
struct connman_provider *provider = value;
DBusMessageIter *iter = user_data;
+ const char *service_path;
- DBG("add provider path");
- if (provider->path == NULL)
+ service_path = __connman_service_get_path(provider->vpn_service);
+ if (service_path == NULL)
return;
dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
- &provider->path);
+ &service_path);
}
void __connman_provider_list(DBusMessageIter *iter, void *user_data)
@@ -194,59 +177,17 @@ static int provider_probe(struct connman_provider *provider)
return 0;
}
-static void state_changed(struct connman_provider *provider)
-{
- const char *str;
-
- str = state2string(provider->state);
- if (str == NULL)
- return;
-
- connman_dbus_property_changed_basic(provider->path,
- CONNMAN_PROVIDER_INTERFACE, "State",
- DBUS_TYPE_STRING, &str);
-}
-
-static void reply_pending(struct connman_provider *provider, int error)
-{
- if (provider->timeout > 0) {
- g_source_remove(provider->timeout);
- provider->timeout = 0;
- }
-
- if (provider->pending != NULL) {
- if (error > 0) {
- DBusMessage *reply;
-
- reply = __connman_error_failed(provider->pending,
- error);
- if (reply != NULL)
- g_dbus_send_message(connection, reply);
- } else
- g_dbus_send_reply(connection, provider->pending,
- DBUS_TYPE_INVALID);
-
- dbus_message_unref(provider->pending);
- provider->pending = NULL;
- }
-}
-
-static int connman_provider_disconnect(struct connman_provider *provider)
+int __connman_provider_disconnect(struct connman_provider *provider)
{
int err;
DBG("provider %p", provider);
- reply_pending(provider, ECONNABORTED);
-
if (provider->driver != NULL && provider->driver->disconnect != NULL)
err = provider->driver->disconnect(provider);
else
return -EOPNOTSUPP;
- __connman_provider_indicate_state(provider,
- CONNMAN_PROVIDER_STATE_DISCONNECT);
-
__connman_service_indicate_state(provider->vpn_service,
CONNMAN_SERVICE_STATE_DISCONNECT);
if (err < 0) {
@@ -259,114 +200,12 @@ static int connman_provider_disconnect(struct connman_provider *provider)
return 0;
}
-int __connman_provider_indicate_state(struct connman_provider *provider,
- enum connman_provider_state state)
-{
- DBG("provider %p state %d", provider, state);
-
- if (provider == NULL)
- return -EINVAL;
-
- if (provider->state == state)
- return -EALREADY;
-
- if (provider->state == CONNMAN_PROVIDER_STATE_FAILURE &&
- state == CONNMAN_PROVIDER_STATE_IDLE)
- return -EINVAL;
-
- if (provider->state == CONNMAN_PROVIDER_STATE_IDLE &&
- state == CONNMAN_PROVIDER_STATE_DISCONNECT)
- return -EINVAL;
-
- if (state == CONNMAN_PROVIDER_STATE_IDLE &&
- provider->state != CONNMAN_PROVIDER_STATE_DISCONNECT) {
- provider->state = CONNMAN_PROVIDER_STATE_DISCONNECT;
- state_changed(provider);
-
- connman_provider_disconnect(provider);
- }
-
- provider->state = state;
- state_changed(provider);
-
- if (state == CONNMAN_PROVIDER_STATE_READY)
- reply_pending(provider, 0);
-
- if (state == CONNMAN_PROVIDER_STATE_FAILURE)
- reply_pending(provider, EIO);
- else
- provider->error = CONNMAN_PROVIDER_ERROR_UNKNOWN;
-
- return 0;
-}
-
-int __connman_provider_indicate_error(struct connman_provider *provider,
- enum connman_provider_error error)
-{
- DBG("provider %p error %d", provider, error);
-
- if (provider == NULL)
- return -EINVAL;
-
- provider->error = error;
-
- return __connman_provider_indicate_state(provider,
- CONNMAN_PROVIDER_STATE_FAILURE);
-}
-
-static gboolean connect_timeout(gpointer user_data)
-{
- struct connman_provider *provider = user_data;
-
- DBG("provider %p", provider);
-
- provider->timeout = 0;
-
- if (provider->pending != NULL) {
- DBusMessage *reply;
-
- reply = __connman_error_operation_timeout(provider->pending);
- if (reply != NULL)
- g_dbus_send_message(connection, reply);
-
- dbus_message_unref(provider->pending);
- provider->pending = NULL;
- }
-
- __connman_provider_indicate_error(provider,
- CONNMAN_PROVIDER_ERROR_CONNECT_FAILED);
-
- return FALSE;
-}
-
-static connman_bool_t is_connecting(struct connman_provider *provider)
-{
- switch (provider->state) {
- case CONNMAN_PROVIDER_STATE_UNKNOWN:
- case CONNMAN_PROVIDER_STATE_IDLE:
- case CONNMAN_PROVIDER_STATE_FAILURE:
- case CONNMAN_PROVIDER_STATE_DISCONNECT:
- case CONNMAN_PROVIDER_STATE_READY:
- break;
- case CONNMAN_PROVIDER_STATE_CONNECT:
- return TRUE;
- }
-
- return FALSE;
-}
-
-static int connman_provider_connect(struct connman_provider *provider)
+int __connman_provider_connect(struct connman_provider *provider)
{
int err;
DBG("provider %p", provider);
- if (provider->state == CONNMAN_PROVIDER_STATE_READY)
- return -EISCONN;
-
- if (is_connecting(provider) == TRUE)
- return -EALREADY;
-
g_free(provider->element.ipv4.address);
g_free(provider->element.ipv4.netmask);
g_free(provider->element.ipv4.gateway);
@@ -388,11 +227,8 @@ static int connman_provider_connect(struct connman_provider *provider)
if (err != -EINPROGRESS)
return err;
- provider->timeout = g_timeout_add_seconds(60,
- connect_timeout, provider);
-
- __connman_provider_indicate_state(provider,
- CONNMAN_PROVIDER_STATE_CONNECT);
+ __connman_service_indicate_state(provider->vpn_service,
+ CONNMAN_SERVICE_STATE_ASSOCIATION);
return -EINPROGRESS;
}
@@ -416,63 +252,6 @@ int __connman_provider_remove(const char *path)
return 0;
}
-static DBusMessage *get_properties(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- struct connman_provider *provider = user_data;
- DBusMessage *reply;
- DBusMessageIter array, dict;
- dbus_bool_t required;
- const char *str;
-
- DBG("provider %p", provider);
-
- reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
- return NULL;
-
- dbus_message_iter_init_append(reply, &array);
-
- connman_dbus_dict_open(&array, &dict);
-
- if (provider->name != NULL)
- connman_dbus_dict_append_basic(&dict, "Name",
- DBUS_TYPE_STRING, &provider->name);
-
- if (str != NULL)
- connman_dbus_dict_append_basic(&dict, "Type",
- DBUS_TYPE_STRING,
- &provider->type);
-
- str = state2string(provider->state);
- if (str != NULL)
- connman_dbus_dict_append_basic(&dict, "State",
- DBUS_TYPE_STRING, &str);
-
- str = error2string(provider->error);
- if (str != NULL)
- connman_dbus_dict_append_basic(&dict, "Error",
- DBUS_TYPE_STRING, &str);
-
- required = TRUE;
- connman_dbus_dict_append_basic(&dict, "PassphraseRequired",
- DBUS_TYPE_BOOLEAN, &required);
-
- connman_dbus_dict_close(&array, &dict);
-
- return reply;
-}
-
-static GDBusMethodTable provider_methods[] = {
- { "GetProperties", "", "a{sv}", get_properties },
- { },
-};
-
-static GDBusSignalTable provider_signals[] = {
- { "PropertyChanged", "sv" },
- { },
-};
-
int connman_provider_set_connected(struct connman_provider *provider,
connman_bool_t connected)
{
@@ -518,15 +297,10 @@ int connman_provider_set_connected(struct connman_provider *provider,
}
}
- __connman_provider_indicate_state(provider,
- CONNMAN_PROVIDER_STATE_READY);
__connman_service_indicate_state(provider->vpn_service,
CONNMAN_SERVICE_STATE_READY);
} else {
- reply_pending(provider, ECONNABORTED);
connman_element_unregister_children(&provider->element);
- __connman_provider_indicate_state(provider,
- CONNMAN_PROVIDER_STATE_DISCONNECT);
__connman_service_indicate_state(provider->vpn_service,
CONNMAN_SERVICE_STATE_DISCONNECT);
}
@@ -537,19 +311,9 @@ int connman_provider_set_connected(struct connman_provider *provider,
static void provider_free(gpointer user_data)
{
struct connman_provider *provider = user_data;
- char *path = provider->path;
DBG("provider %p", provider);
- reply_pending(provider, ENOENT);
- provider->path = NULL;
-
- if (path != NULL) {
- g_dbus_unregister_interface(connection, path,
- CONNMAN_PROVIDER_INTERFACE);
- g_free(path);
- }
-
g_free(provider->name);
g_free(provider->type);
g_free(provider->domain);
@@ -564,7 +328,7 @@ static void unregister_provider(gpointer data)
DBG("provider %p", provider);
- connman_provider_disconnect(provider);
+ __connman_provider_disconnect(provider);
connman_element_unregister(&provider->element);
connman_provider_unref(provider);
@@ -583,8 +347,6 @@ static void __connman_provider_initialize(struct connman_provider *provider)
{
DBG("provider %p", provider);
- provider->state = CONNMAN_PROVIDER_STATE_UNKNOWN;
-
__connman_element_initialize(&provider->element);
provider->element.private = provider;
@@ -601,8 +363,6 @@ static void __connman_provider_initialize(struct connman_provider *provider)
provider->dns = NULL;
provider->domain = NULL;
provider->identifier = NULL;
- provider->path = NULL;
- provider->pending = NULL;
}
static struct connman_provider *connman_provider_new(void)
@@ -621,22 +381,8 @@ static struct connman_provider *connman_provider_new(void)
static int provider_register(struct connman_provider *provider)
{
- const char *path = "/provider";
-
DBG("provider %p", provider);
- if (provider->path != NULL)
- return -EALREADY;
-
- provider->path = g_strdup_printf("%s/%s", path, provider->identifier);
-
- DBG("path %s", provider->path);
-
- g_dbus_register_interface(connection, provider->path,
- CONNMAN_PROVIDER_INTERFACE,
- provider_methods, provider_signals,
- NULL, provider, NULL);
-
return 0;
}
@@ -673,9 +419,6 @@ static struct connman_provider *connman_provider_create(const char *name)
if (provider == NULL)
return NULL;
- if (provider->path != NULL)
- return provider;
-
provider_register(provider);
return provider;
@@ -685,7 +428,7 @@ int __connman_provider_create_and_connect(DBusMessage *msg)
{
struct connman_provider *provider;
DBusMessageIter iter, array;
- const char *type = NULL, *name = NULL;
+ const char *type = NULL, *name = NULL, *service_path = NULL;
char *ident;
gboolean created = FALSE;
int err;
@@ -776,23 +519,30 @@ int __connman_provider_create_and_connect(DBusMessage *msg)
if (created == TRUE)
provider_probe(provider);
- err = connman_provider_connect(provider);
+ provider->vpn_service =
+ __connman_service_create_from_provider(provider);
+ if (provider->vpn_service == NULL) {
+ err = -EOPNOTSUPP;
+ goto failed;
+ }
+
+ err = __connman_service_connect(provider->vpn_service);
if (err < 0 && err != -EINPROGRESS)
goto failed;
+ service_path = __connman_service_get_path(provider->vpn_service);
g_dbus_send_reply(connection, msg,
- DBUS_TYPE_OBJECT_PATH, &provider->path,
+ DBUS_TYPE_OBJECT_PATH, &service_path,
DBUS_TYPE_INVALID);
-
- provider->vpn_service =
- __connman_service_create_from_provider(provider);
-
return 0;
failed:
if (provider != NULL && created == TRUE) {
DBG("can not connect delete provider");
connman_provider_unref(provider);
+
+ if (provider->vpn_service != NULL)
+ __connman_service_put(provider->vpn_service);
}
return err;