From: Daniel Wagner <daniel.wag...@bmw-carit.de>

When a session is activated we check if there is already a service
connected which matches the configuration. Also whenever a service
state changes we check if we either have to remove or add a service
to a session.
---
 src/service.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/src/service.c b/src/service.c
index 3d65cae..48fb5c4 100644
--- a/src/service.c
+++ b/src/service.c
@@ -128,6 +128,8 @@ struct connman_service {
 };
 
 struct session_info {
+       struct connman_session *session;
+       struct connman_service *service;
        struct connman_session_config *config;
 };
 
@@ -1433,6 +1435,54 @@ static void default_changed(void)
        __connman_notifier_default_changed(service);
 }
 
+static bool is_session_connected(struct connman_session_config *config,
+                               struct connman_service *service)
+
+{
+       switch (service->state) {
+       case CONNMAN_SERVICE_STATE_UNKNOWN:
+                 case CONNMAN_SERVICE_STATE_IDLE:
+       case CONNMAN_SERVICE_STATE_ASSOCIATION:
+       case CONNMAN_SERVICE_STATE_CONFIGURATION:
+       case CONNMAN_SERVICE_STATE_DISCONNECT:
+       case CONNMAN_SERVICE_STATE_FAILURE:
+                         break;
+       case CONNMAN_SERVICE_STATE_READY:
+               if (config->type == CONNMAN_SESSION_TYPE_INTERNET)
+                       return false;
+       case CONNMAN_SERVICE_STATE_ONLINE:
+               return true;
+       }
+
+       return false;
+}
+
+static void session_update_state(struct connman_service *service)
+{
+       GHashTableIter iter;
+       gpointer key, value;
+
+       g_hash_table_iter_init(&iter, session_hash);
+       while (g_hash_table_iter_next(&iter, &key, &value)) {
+               struct connman_session *session = key;
+               struct session_info *info = value;
+               bool connected;
+
+               connected = is_session_connected(info->config, service);
+
+               if (info->service == service) {
+                       if (!connected)
+                               __connman_session_remove_service(session,
+                                                               service);
+
+               } else if (connected) {
+                       __connman_session_add_service(session,
+                                                       service);
+                       info->service = service;
+               }
+       }
+}
+
 static void state_changed(struct connman_service *service)
 {
        const char *str;
@@ -1443,6 +1493,8 @@ static void state_changed(struct connman_service *service)
        if (!str)
                return;
 
+       session_update_state(service);
+
        if (!allow_property_changed(service))
                return;
 
@@ -3483,6 +3535,61 @@ static bool is_ignore(struct connman_service *service)
 static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
 static int active_count = 0;
 
+static bool session_match_type(struct connman_session_config *config,
+                               struct connman_service *service)
+{
+       GSList *list;
+
+       for (list = config->allowed_bearers; list; list = list->next) {
+               enum connman_service_type type = GPOINTER_TO_INT(list->data);
+
+               if (type == service->type)
+                       return true;
+       }
+
+       return false;
+}
+
+static void add_service_to_session(struct connman_session *session)
+{
+       struct session_info *info;
+       GList *list;
+
+       info = g_hash_table_lookup(session_hash, session);
+       if (!info)
+               return;
+
+       for (list = service_list; list; list = list->next) {
+               struct connman_service *service = list->data;
+
+               if (!is_session_connected(info->config, service))
+                       continue;
+
+               if (!session_match_type(info->config, service))
+                       continue;
+
+               __connman_session_add_service(session, service);
+               info->service = service;
+
+               return;
+       }
+}
+
+static void remove_service_from_session(struct connman_session *session)
+{
+       struct session_info *info;
+
+       info = g_hash_table_lookup(session_hash, session);
+       if (!info)
+               return;
+
+       if (!info->service)
+               return;
+
+       __connman_session_remove_service(session, info->service);
+       info->service = NULL;
+}
+
 void __connman_service_set_active_session(struct connman_session *session,
                        struct connman_session_config *config, bool enable)
 {
@@ -3499,9 +3606,11 @@ void __connman_service_set_active_session(struct 
connman_session *session,
                info->config = config;
 
                g_hash_table_replace(session_hash, session, info);
+               add_service_to_session(session);
        } else {
                active_count--;
 
+               remove_service_from_session(session);
                g_hash_table_remove(session_hash, session);
        }
 
-- 
1.8.5.3

_______________________________________________
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to