Track and report VPN providers states
authorSamuel Ortiz <sameo@linux.intel.com>
Mon, 2 Aug 2010 18:52:35 +0000 (20:52 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Mon, 2 Aug 2010 18:52:35 +0000 (20:52 +0200)
include/provider.h
plugins/openconnect.c
src/provider.c

index 94efc34..ba4ff7d 100644 (file)
@@ -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);
index c860f27..9232781 100644 (file)
 
 #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);
index 23fccfc..827f57e 100644 (file)
@@ -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;