summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2010-08-02 18:52:35 (GMT)
committerSamuel Ortiz <sameo@linux.intel.com>2010-08-02 18:52:35 (GMT)
commit2fc5b6e25c9633a75d60ac54214b9058242623d1 (patch)
treeaa6dd9b23d91040feda139d945b9d77156ccd9e4
parentcb39febef3587c749e5b818009204b61dd7c970a (diff)
downloadconnman-2fc5b6e25c9633a75d60ac54214b9058242623d1.zip
connman-2fc5b6e25c9633a75d60ac54214b9058242623d1.tar.gz
connman-2fc5b6e25c9633a75d60ac54214b9058242623d1.tar.bz2
Track and report VPN providers states
-rw-r--r--include/provider.h4
-rw-r--r--plugins/openconnect.c34
-rw-r--r--src/provider.c31
3 files changed, 61 insertions, 8 deletions
diff --git a/include/provider.h b/include/provider.h
index 94efc34..ba4ff7d 100644
--- a/include/provider.h
+++ b/include/provider.h
@@ -63,8 +63,8 @@ int connman_provider_set_string(struct connman_provider *provider,
const char *connman_provider_get_string(struct connman_provider *provider,
const char *key);
-int connman_provider_set_connected(struct connman_provider *provider,
- connman_bool_t connected);
+int connman_provider_set_state(struct connman_provider *provider,
+ enum connman_provider_state state);
void connman_provider_set_index(struct connman_provider *provider, int index);
int connman_provider_get_index(struct connman_provider *provider);
diff --git a/plugins/openconnect.c b/plugins/openconnect.c
index c860f27..9232781 100644
--- a/plugins/openconnect.c
+++ b/plugins/openconnect.c
@@ -52,10 +52,20 @@
#include "inet.h"
+enum oc_state {
+ OC_STATE_UNKNOWN = 0,
+ OC_STATE_IDLE = 1,
+ OC_STATE_CONNECT = 2,
+ OC_STATE_READY = 3,
+ OC_STATE_DISCONNECT = 4,
+ OC_STATE_FAILURE = 5,
+};
+
struct oc_data {
char *if_name;
unsigned flags;
unsigned int watch;
+ unsigned int state;
struct connman_task *task;
};
@@ -100,6 +110,7 @@ static void openconnect_died(struct connman_task *task, void *user_data)
{
struct connman_provider *provider = user_data;
struct oc_data *data = connman_provider_get_data(provider);
+ int state = data->state;
DBG("provider %p data %p", provider, data);
@@ -112,7 +123,13 @@ static void openconnect_died(struct connman_task *task, void *user_data)
g_free(data);
oc_exit:
- connman_provider_set_connected(provider, FALSE);
+ if (state != OC_STATE_READY && state != OC_STATE_DISCONNECT)
+ connman_provider_set_state(provider,
+ CONNMAN_PROVIDER_STATE_FAILURE);
+ else
+ connman_provider_set_state(provider,
+ CONNMAN_PROVIDER_STATE_IDLE);
+
connman_provider_set_index(provider, -1);
connman_provider_unref(provider);
connman_task_destroy(task);
@@ -124,8 +141,11 @@ static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
struct oc_data *data = connman_provider_get_data(provider);
if ((data->flags & IFF_UP) != (flags & IFF_UP)) {
- if (flags & IFF_UP)
- connman_provider_set_connected(provider, TRUE);
+ if (flags & IFF_UP) {
+ data->state = OC_STATE_READY;
+ connman_provider_set_state(provider,
+ CONNMAN_PROVIDER_STATE_READY);
+ }
}
data->flags = flags;
}
@@ -157,7 +177,8 @@ static void openconnect_task_notify(struct connman_task *task,
}
if (strcmp(reason, "connect")) {
- connman_provider_set_connected(provider, FALSE);
+ connman_provider_set_state(provider,
+ CONNMAN_PROVIDER_STATE_DISCONNECT);
return;
}
@@ -223,6 +244,7 @@ static int oc_connect(struct connman_provider *provider)
data->watch = 0;
data->flags = 0;
data->task = NULL;
+ data->state = OC_STATE_IDLE;
connman_provider_set_data(provider, data);
@@ -352,6 +374,9 @@ static int oc_connect(struct connman_provider *provider)
}
connman_provider_ref(provider);
+
+ data->state = OC_STATE_CONNECT;
+
return -EINPROGRESS;
exist_err:
@@ -380,6 +405,7 @@ static int oc_disconnect(struct connman_provider *provider)
connman_rtnl_remove_watch(data->watch);
data->watch = 0;
+ data->state = OC_STATE_DISCONNECT;
connman_task_stop(data->task);
connman_provider_unref(provider);
diff --git a/src/provider.c b/src/provider.c
index 23fccfc..827f57e 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -227,8 +227,8 @@ int __connman_provider_remove(const char *path)
return 0;
}
-int connman_provider_set_connected(struct connman_provider *provider,
- connman_bool_t connected)
+static int set_connected(struct connman_provider *provider,
+ connman_bool_t connected)
{
if (connected == TRUE) {
enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
@@ -283,6 +283,33 @@ int connman_provider_set_connected(struct connman_provider *provider,
return 0;
}
+int connman_provider_set_state(struct connman_provider *provider,
+ enum connman_provider_state state)
+{
+ if (provider == NULL || provider->vpn_service == NULL)
+ return -EINVAL;
+
+ switch (state) {
+ case CONNMAN_PROVIDER_STATE_UNKNOWN:
+ return -EINVAL;
+ case CONNMAN_PROVIDER_STATE_IDLE:
+ return set_connected(provider, FALSE);
+ case CONNMAN_PROVIDER_STATE_CONNECT:
+ return __connman_service_indicate_state(provider->vpn_service,
+ CONNMAN_SERVICE_STATE_ASSOCIATION);
+ case CONNMAN_PROVIDER_STATE_READY:
+ return set_connected(provider, TRUE);
+ case CONNMAN_PROVIDER_STATE_DISCONNECT:
+ return __connman_service_indicate_state(provider->vpn_service,
+ CONNMAN_SERVICE_STATE_DISCONNECT);
+ case CONNMAN_PROVIDER_STATE_FAILURE:
+ return __connman_service_indicate_state(provider->vpn_service,
+ CONNMAN_SERVICE_STATE_FAILURE);
+ }
+
+ return -EINVAL;
+}
+
static void provider_free(gpointer user_data)
{
struct connman_provider *provider = user_data;