Hi Marcel:
I have revised the patch and send it again.
Please use this patch and ignore my last two patches. ;-).
I have done some test on the patch and find that it can work fine.
I thought it carefully and believe the patch is a good option to implement auto 
connection.

>From 1f2e2ed95977a0879731064e9311a94006f04506 Mon Sep 17 00:00:00 2001
From: Martin Xu <[email protected]>
Date: Mon, 6 Jul 2009 04:54:02 -0400
Subject: [PATCH 4/4] add auto connect

---
 src/service.c |  108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 108 insertions(+), 0 deletions(-)

diff --git a/src/service.c b/src/service.c
index 4e445e0..9557b62 100644
--- a/src/service.c
+++ b/src/service.c
@@ -27,6 +27,8 @@
 
 #include "connman.h"
 
+#define AUTO_RETRY_PERIOD 5
+
 static DBusConnection *connection = NULL;
 
 static GSequence *service_list = NULL;
@@ -1206,6 +1208,106 @@ static enum connman_service_type 
convert_device_type(struct connman_device *devi
        return CONNMAN_SERVICE_TYPE_UNKNOWN;
 }
 
+struct try_data {
+       struct connman_service  *last_service;
+       GSequenceIter           *last_iter;
+       guint                   timeout;
+};
+
+static struct try_data auto_connect_data = {.last_iter = NULL,
+                                       .last_service = NULL,
+                                       .timeout = 0};
+
+static gboolean service_is_connecting(struct connman_service *service)
+{
+       if (service->state == CONNMAN_SERVICE_STATE_ASSOCIATION ||
+               service->state == CONNMAN_SERVICE_STATE_CONFIGURATION ||
+               service->state == CONNMAN_SERVICE_STATE_CARRIER)
+               return TRUE;
+       return FALSE;
+}
+
+static gboolean try_service(gpointer user_data)
+{
+       struct try_data *data = user_data;
+       struct connman_service *last_service = data->last_service;
+       struct connman_service *service;
+       GSequenceIter *last_iter = data->last_iter;
+       GSequenceIter *iter;
+       DBG("Last service %p", last_service);
+
+       if (last_service != NULL) {
+               if (last_service->state == CONNMAN_SERVICE_STATE_READY) {
+                       DBG("Auto connect to service: %s", last_service->name);
+                       return FALSE;
+               }
+               if (service_is_connecting(last_service)) {
+                       DBG("service: %s is connecting", last_service->name);
+                       return TRUE;
+               }
+       }
+
+       if (last_iter == NULL)
+               iter = g_sequence_get_begin_iter(service_list);
+       else
+               iter = g_sequence_iter_next(last_iter);
+
+       if (g_sequence_iter_is_end(iter)) {
+               DBG("Finish going through service sequence");
+               return FALSE;
+       }
+       service = g_sequence_get(iter);
+       while (service == NULL ||
+                service->state == CONNMAN_SERVICE_STATE_FAILURE) {
+               iter = g_sequence_iter_next(iter);
+               if (g_sequence_iter_is_end(iter)) {
+                       DBG("Finish going through service sequence");
+                       return FALSE;
+               }
+               service = g_sequence_get(iter);
+       }
+
+       if (!service->favorite) {
+               DBG("Finish going through favorite sequence");
+               return FALSE;
+       }
+
+       if (service->state == CONNMAN_SERVICE_STATE_READY) {
+               DBG("service: %s is connected, ignore others", service->name);
+               return FALSE;
+       }
+
+       data->last_service = service;
+       data->last_iter = iter;
+
+       if (!service_is_connecting(service)) {
+               DBG("connect service %s", service->name);
+               __connman_service_connect(service);
+       }
+
+       return TRUE;
+}
+
+static void  clear_auto_connect(void)
+{
+       DBG("");
+       auto_connect_data.last_service = NULL;
+       auto_connect_data.last_iter = NULL;
+       g_source_remove(auto_connect_data.timeout);
+       auto_connect_data.timeout = 0;
+}
+
+static void single_auto_connect(void)
+{
+       DBG("");
+       if (auto_connect_data.timeout != 0)
+               clear_auto_connect();
+
+       auto_connect_data.timeout =
+                       g_timeout_add_seconds(AUTO_RETRY_PERIOD,
+                                               try_service,
+                                               &auto_connect_data);
+}
 /**
  * connman_service_create_from_device:
  * @device: device structure
@@ -1243,6 +1345,9 @@ struct connman_service 
*__connman_service_create_from_device(struct connman_devi
 
 done:
        g_free(name);
+       
+       if (service->favorite)
+               single_auto_connect();
 
        return service;
 }
@@ -1431,6 +1536,9 @@ struct connman_service 
*__connman_service_create_from_network(struct connman_net
 
 done:
        g_free(name);
+       
+       if (service->favorite)
+               single_auto_connect();
 
        return service;
 }
-- 
1.6.1.3

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to