service: Try preferred technologies first, then normal autoconnect
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Thu, 5 Apr 2012 19:38:43 +0000 (22:38 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Wed, 11 Apr 2012 12:26:06 +0000 (15:26 +0300)
When autoconnecting, try first with the list of preferred
technologies. If none can be connected or there are no preferred
technologies, do a normal autoconnect.

When autoconnecting preferred services, skip any non-favorite and
online ones in the list instead of ending the autoconnect procedure.

src/service.c

index 446cba5..bf1eb26 100644 (file)
@@ -3059,48 +3059,79 @@ static GSequence* preferred_tech_list_get(GSequence *list)
        return tech_data.preferred_list;
 }
 
-void __connman_service_auto_connect(void)
+static connman_bool_t auto_connect_service(GSequenceIter* iter,
+               connman_bool_t preferred)
 {
        struct connman_service *service = NULL;
-       GSequenceIter *iter;
-
-       DBG("");
-
-       if (__connman_session_mode() == TRUE) {
-               DBG("Session mode enabled: auto connect disabled");
-               return;
-       }
-
-       iter = g_sequence_get_begin_iter(service_list);
 
        while (g_sequence_iter_is_end(iter) == FALSE) {
                service = g_sequence_get(iter);
 
                if (service->pending != NULL)
-                       return;
+                       return TRUE;
 
                if (is_connecting(service) == TRUE)
-                       return;
+                       return TRUE;
 
-               if (service->favorite == FALSE)
-                       return;
+               if (service->favorite == FALSE) {
+                       if (preferred == TRUE)
+                               goto next_service;
+                       return FALSE;
+               }
 
-               if (is_connected(service) == TRUE)
-                       return;
+               if (is_connected(service) == TRUE) {
+                       if (preferred == TRUE && service->state !=
+                                       CONNMAN_SERVICE_STATE_ONLINE)
+                               goto next_service;
+                       return TRUE;
+               }
 
                if (is_ignore(service) == FALSE && service->state ==
-                                               CONNMAN_SERVICE_STATE_IDLE)
+                               CONNMAN_SERVICE_STATE_IDLE)
                        break;
 
+       next_service:
                service = NULL;
 
                iter = g_sequence_iter_next(iter);
        }
 
        if (service != NULL) {
+
+               DBG("service %p %s %s", service, service->name,
+                               (preferred == TRUE)? "preferred": "auto");
+
                service->userconnect = FALSE;
                __connman_service_connect(service);
+               return TRUE;
        }
+       return FALSE;
+}
+
+void __connman_service_auto_connect(void)
+{
+       GSequenceIter *iter = NULL;
+       GSequence *preferred_tech;
+
+       DBG("");
+
+       if (__connman_session_mode() == TRUE) {
+               DBG("Session mode enabled: auto connect disabled");
+               return;
+       }
+
+       preferred_tech = preferred_tech_list_get(service_list);
+       if (preferred_tech != NULL)
+               iter = g_sequence_get_begin_iter(preferred_tech);
+
+       if (iter == NULL || auto_connect_service(iter, TRUE) == FALSE)
+               iter = g_sequence_get_begin_iter(service_list);
+
+       if (iter != NULL)
+               auto_connect_service(iter, FALSE);
+
+       if (preferred_tech != NULL)
+               g_sequence_free(preferred_tech);
 }
 
 static void remove_timeout(struct connman_service *service)