[PATCH v3 02/10] session: Mark session active or inactive
From: Daniel Wagner Free-ride mode is implicit always enabled (see documentation) we only need to track when a user requests a connection. This can be expressed by a boolean. Remove the reason enum and rename the connect and disconnect functions. Instead storing the user's connect request, we just track if the session is active or not. So we move the boolean flag to the session and get rid for the two trigger functions. Note we don't have to deactive the session in session_disconnect() because this will be done in cleanup_session() function which is hash table destroy callback. --- src/session.c | 84 +++ 1 file changed, 21 insertions(+), 63 deletions(-) diff --git a/src/session.c b/src/session.c index e4a8b49..4c273cb 100644 --- a/src/session.c +++ b/src/session.c @@ -39,12 +39,6 @@ static GSList *policy_list; static uint32_t session_mark = 256; static struct firewall_context *global_firewall = NULL; -enum connman_session_reason { - CONNMAN_SESSION_REASON_UNKNOWN = 0, - CONNMAN_SESSION_REASON_CONNECT = 1, - CONNMAN_SESSION_REASON_FREE_RIDE= 2, -}; - enum connman_session_state { CONNMAN_SESSION_STATE_DISCONNECTED = 0, CONNMAN_SESSION_STATE_CONNECTED = 1, @@ -54,7 +48,6 @@ enum connman_session_state { struct session_info { struct connman_session_config config; enum connman_session_state state; - enum connman_session_reason reason; }; struct connman_session { @@ -65,6 +58,7 @@ struct connman_session { struct connman_session_policy *policy; + bool active; bool append_all; struct session_info *info; struct session_info *info_last; @@ -83,20 +77,6 @@ struct connman_session { char *gateway; }; -static const char *reason2string(enum connman_session_reason reason) -{ - switch (reason) { - case CONNMAN_SESSION_REASON_UNKNOWN: - return "unknown"; - case CONNMAN_SESSION_REASON_CONNECT: - return "connect"; - case CONNMAN_SESSION_REASON_FREE_RIDE: - return "free-ride"; - } - - return NULL; -} - static const char *state2string(enum connman_session_state state) { switch (state) { @@ -441,11 +421,9 @@ static void free_session(struct connman_session *session) static void cleanup_session_final(struct connman_session *session) { - struct session_info *info = session->info; - DBG("remove %s", session->session_path); - if (info->reason == CONNMAN_SESSION_REASON_CONNECT) + if (session->active) __connman_service_set_active_session(false, session->info->config.allowed_bearers); @@ -952,36 +930,6 @@ static void ipconfig_ipv6_changed(struct connman_session *session) session->service); } -static void deselect_and_disconnect(struct connman_session *session) -{ - struct session_info *info = session->info; - - if (info->reason == CONNMAN_SESSION_REASON_CONNECT) - __connman_service_set_active_session(false, - info->config.allowed_bearers); - - info->reason = CONNMAN_SESSION_REASON_FREE_RIDE; - info->state = CONNMAN_SESSION_STATE_DISCONNECTED; -} - -static void select_and_connect(struct connman_session *session, - enum connman_session_reason reason) -{ - struct session_info *info = session->info; - - DBG("session %p reason %s", session, reason2string(reason)); - - if (info->reason != reason && - reason == CONNMAN_SESSION_REASON_CONNECT) { - __connman_service_set_active_session(true, - info->config.allowed_bearers); - - __connman_service_auto_connect(); - } - - info->reason = reason; -} - int connman_session_config_update(struct connman_session *session) { struct session_info *info = session->info; @@ -1013,14 +961,14 @@ int connman_session_config_update(struct connman_session *session) if (err < 0) return err; - if (info->reason == CONNMAN_SESSION_REASON_CONNECT) + if (session->active) __connman_service_set_active_session(false, info->config.allowed_bearers); g_slist_free(info->config.allowed_bearers); info->config.allowed_bearers = allowed_bearers; - if (info->reason == CONNMAN_SESSION_REASON_CONNECT) + if (session->active) __connman_service_set_active_session(true, info->config.allowed_bearers); @@ -1055,7 +1003,13 @@ static DBusMessage *connect_session(DBusConnection *conn, session->ecall = true; } - select_and_connect(session, CONNMAN_SESSION_REASON_CONNECT); + if (!session->active) { +
[PATCH v3 06/10] session: Add functions to de/assign service to a session
From: Daniel Wagner Service will now be able to add or remove a service from a session. --- src/connman.h | 5 src/session.c | 84 ++- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/connman.h b/src/connman.h index 74ff797..2b30d5b 100644 --- a/src/connman.h +++ b/src/connman.h @@ -831,6 +831,11 @@ int __connman_rtnl_send(const void *buf, size_t len); bool __connman_session_mode(); void __connman_session_set_mode(bool enable); +void __connman_session_add_service(struct connman_session *session, + struct connman_service *service); +void __connman_session_remove_service(struct connman_session *session, + struct connman_service *service); + int __connman_session_create(DBusMessage *msg); int __connman_session_destroy(DBusMessage *msg); diff --git a/src/session.c b/src/session.c index 7ed5d08..d32a9a8 100644 --- a/src/session.c +++ b/src/session.c @@ -1571,6 +1571,67 @@ int __connman_session_destroy(DBusMessage *msg) return 0; } + +static enum connman_session_state service_to_session_state( + enum connman_service_state state) +{ + switch (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: + return CONNMAN_SESSION_STATE_CONNECTED; + case CONNMAN_SERVICE_STATE_ONLINE: + return CONNMAN_SESSION_STATE_ONLINE; + } + + return CONNMAN_SESSION_STATE_DISCONNECTED; +} + +static void update_session_state(struct connman_session *session) +{ + enum connman_service_state service_state; + enum connman_session_state state; + + if (session->service) { + service_state = __connman_service_get_state(session->service); + state = service_to_session_state(service_state); + session->info->state = state; + } else { + session->info->state = CONNMAN_SESSION_STATE_DISCONNECTED; + } + + DBG("session %p state %s", session, state2string(state)); + + update_routing_table(session); + session_notify(session); +} + +void __connman_session_add_service(struct connman_session *session, + struct connman_service *service) +{ + DBG("session %p service %p", session, service); + + session->service = service; + update_session_state(session); +} + +void __connman_session_remove_service(struct connman_session *session, + struct connman_service *service) +{ + DBG("session %p service %p", session, service); + + if (session->service != service) + return; + + session->service = NULL; + update_session_state(session); +} + static void service_state_changed(struct connman_service *service, enum connman_service_state state) { @@ -1583,30 +1644,29 @@ static void ipconfig_changed(struct connman_service *service, GHashTableIter iter; gpointer key, value; struct connman_session *session; - struct session_info *info; enum connman_ipconfig_type type; DBG("service %p ipconfig %p", service, ipconfig); - type = __connman_ipconfig_get_config_type(ipconfig); - g_hash_table_iter_init(&iter, session_hash); while (g_hash_table_iter_next(&iter, &key, &value)) { session = value; - info = session->info; - if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED) + if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED) continue; - if (session->service && session->service == service) { - update_routing_table(session); + if (session->service != service) + continue; - if (type == CONNMAN_IPCONFIG_TYPE_IPV4) - ipconfig_ipv4_changed(session); - else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) - ipconfig_ipv6_changed(session); - } + type = __connman_ipconfig_get_config_type(ipconfig); + + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + ipconfig_ipv4_changed(session); + else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + ipconfig_ipv6_changed(session); + + update_session_state(session); } } -- 1.8.5.3 ___ connman mailing list connman@connman.net https://lists.connman.net/mail
[PATCH v3 10/10] service: Enter session mode when config files are found
From: Daniel Wagner This is just a hack to explain what I mean. Instead introducing a new main.conf flag we allow a policy plugin to enable session mode permemanantly. I don't we have to add this feature to session_policy_local.c. I have for my stuff my own plugin (called session_policy_pold.c and pold stands for policy daemon). We reactive the SessionMode D-Bus flag and allow to be set via a policy plugin. What do you think? --- include/session.h | 1 + plugins/session_policy_local.c | 5 + src/connman.h | 2 ++ src/service.c | 8 src/session.c | 5 + 5 files changed, 21 insertions(+) diff --git a/include/session.h b/include/session.h index 2be999f..6a74497 100644 --- a/include/session.h +++ b/include/session.h @@ -83,6 +83,7 @@ struct connman_session_policy { int connman_session_policy_register(struct connman_session_policy *config); void connman_session_policy_unregister(struct connman_session_policy *config); +void connman_session_set_mode(bool enable); int connman_session_config_update(struct connman_session *session); void connman_session_destroy(struct connman_session *session); diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index eaeaf79..3d947f9 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -667,6 +667,7 @@ static int read_policies(void) GDir *dir; const gchar *filename; struct policy_file *file; + bool found = false; DBG(""); @@ -685,10 +686,14 @@ static int read_policies(void) } g_hash_table_replace(file_hash, g_strdup(filename), file); + found = true; } g_dir_close(dir); + if (found) + connman_session_set_mode(true); + return 0; } diff --git a/src/connman.h b/src/connman.h index 2b30d5b..7c31aa3 100644 --- a/src/connman.h +++ b/src/connman.h @@ -780,6 +780,8 @@ void __connman_service_notify(struct connman_service *service, int __connman_service_counter_register(const char *counter); void __connman_service_counter_unregister(const char *counter); +void __connman_service_set_session_mode(bool enable); + #include typedef void (* service_iterate_cb) (struct connman_service *service, diff --git a/src/service.c b/src/service.c index b79dc05..39f92bf 100644 --- a/src/service.c +++ b/src/service.c @@ -3843,6 +3843,14 @@ void __connman_service_auto_connect(enum connman_service_connect_reason reason) GUINT_TO_POINTER(reason)); } +void __connman_service_set_session_mode(bool enable) +{ + if (enable) + active_count++; + else + active_count--; +} + static gboolean run_vpn_auto_connect(gpointer data) { GList *list; bool need_split = false; diff --git a/src/session.c b/src/session.c index d32a9a8..2648c31 100644 --- a/src/session.c +++ b/src/session.c @@ -1686,6 +1686,11 @@ static int session_nfacct_flush_cb(unsigned int error, void *user_data) return -error; } +void connman_session_set_mode(bool enable) +{ + __connman_service_set_session_mode(enable); +} + int __connman_session_init(void) { int err; -- 1.8.5.3 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH v3 08/10] service: Disconnect service on last session deactivation
From: Daniel Wagner Since we know if a service was connected by a user or by a session we can use this information and disconnect the service if there is no user asking for it. --- src/service.c | 29 + 1 file changed, 29 insertions(+) diff --git a/src/service.c b/src/service.c index 48fb5c4..d852c38 100644 --- a/src/service.c +++ b/src/service.c @@ -3575,9 +3575,35 @@ static void add_service_to_session(struct connman_session *session) } } +static void disconnect_service_on_last_session(struct connman_service *service) +{ + GHashTableIter iter; + gpointer key, value; + + DBG("service %p reason %s", service, + reason2string(service->connect_reason)); + + if (!is_connected(service)) + return; + + if(service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_SESSION) + return; + + g_hash_table_iter_init(&iter, session_hash); + while (g_hash_table_iter_next(&iter, &key, &value)) { + struct session_info *info = value; + + if (info->service == service) + return; + } + + __connman_service_disconnect(service); +} + static void remove_service_from_session(struct connman_session *session) { struct session_info *info; + struct connman_service *service; info = g_hash_table_lookup(session_hash, session); if (!info) @@ -3587,7 +3613,10 @@ static void remove_service_from_session(struct connman_session *session) return; __connman_session_remove_service(session, info->service); + service = info->service; info->service = NULL; + + disconnect_service_on_last_session(service); } void __connman_service_set_active_session(struct connman_session *session, -- 1.8.5.3 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH v3 09/10] service: Add session auto connect support
From: Daniel Wagner Session are allowed to auto connect. This is done by checking the reason code. But before that we check if session are active. If yes we disable the normal auto connect mode and only allow sessions to establish new connections. --- src/service.c | 24 ++-- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/service.c b/src/service.c index d852c38..b79dc05 100644 --- a/src/service.c +++ b/src/service.c @@ -3738,7 +3738,8 @@ static bool auto_connect_service(GList *services, bool autoconnecting = false; GList *list; - DBG("preferred %d sessions %d", preferred, active_count); + DBG("preferred %d sessions %d reason %s", preferred, active_count, + reason2string(reason)); ignore[CONNMAN_SERVICE_TYPE_VPN] = true; @@ -3777,14 +3778,25 @@ static bool auto_connect_service(GList *services, CONNMAN_SERVICE_STATE_IDLE) continue; - if (autoconnecting && !active_sessions[service->type]) { - DBG("service %p type %s has no users", service, - __connman_service_type2string(service->type)); - continue; + if (active_count) { + DBG("session mode"); + + switch (reason) { + case CONNMAN_SERVICE_CONNECT_REASON_NONE: + case CONNMAN_SERVICE_CONNECT_REASON_USER: + case CONNMAN_SERVICE_CONNECT_REASON_AUTO: + /* disable normal auto connect for now */ + continue; + case CONNMAN_SERVICE_CONNECT_REASON_SESSION: + if (!active_sessions[service->type]) + /* no sessions is asking for this type */ + continue; + break; + } } DBG("service %p %s %s", service, service->name, - (preferred) ? "preferred" : "auto"); + (preferred) ? "preferred" : reason2string(reason)); __connman_service_connect(service, reason); -- 1.8.5.3 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH v3 03/10] service: Add connect reason to __connman_service_connect()
From: Daniel Wagner The caller indicates by providing a connect reason 'who' initiated the connection. For this we remove the userconnect bool from struct connman_service and set the __connect_service_connect() and __connman_service_disconnect(). --- src/config.c | 6 +++-- src/connman.h | 12 +++--- src/network.c | 4 ++-- src/service.c | 72 +-- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/src/config.c b/src/config.c index 19d8b92..feee6b2 100644 --- a/src/config.c +++ b/src/config.c @@ -1044,7 +1044,8 @@ static gboolean remove_virtual_config(gpointer user_data) { struct connect_virtual *virtual = user_data; - __connman_service_connect(virtual->service); + __connman_service_connect(virtual->service, + CONNMAN_SERVICE_CONNECT_REASON_AUTO); g_hash_table_remove(config_table, virtual->vfile); g_free(virtual); @@ -1241,7 +1242,8 @@ static void provision_service(gpointer key, gpointer value, provision_service_wifi(key, config, service, network, ssid, ssid_len); } else - __connman_service_connect(service); + __connman_service_connect(service, + CONNMAN_SERVICE_CONNECT_REASON_AUTO); __connman_service_mark_dirty(); diff --git a/src/connman.h b/src/connman.h index bf209cc..80afab3 100644 --- a/src/connman.h +++ b/src/connman.h @@ -672,8 +672,6 @@ int __connman_service_set_immutable(struct connman_service *service, bool immutable); int __connman_service_set_ignore(struct connman_service *service, bool ignore); -void __connman_service_set_userconnect(struct connman_service *service, - bool userconnect); void __connman_service_set_search_domains(struct connman_service *service, char **domains); void __connman_service_update_search_domains(struct connman_service *service, @@ -695,7 +693,15 @@ int __connman_service_indicate_error(struct connman_service *service, int __connman_service_clear_error(struct connman_service *service); int __connman_service_indicate_default(struct connman_service *service); -int __connman_service_connect(struct connman_service *service); +enum connman_service_connect_reason { + CONNMAN_SERVICE_CONNECT_REASON_NONE = 0, + CONNMAN_SERVICE_CONNECT_REASON_AUTO = 1, + CONNMAN_SERVICE_CONNECT_REASON_USER = 2, + CONNMAN_SERVICE_CONNECT_REASON_SESSION = 3, +}; + +int __connman_service_connect(struct connman_service *service, + enum connman_service_connect_reason reason); int __connman_service_disconnect(struct connman_service *service); int __connman_service_disconnect_all(void); void __connman_service_set_active_session(bool enable, GSList *list); diff --git a/src/network.c b/src/network.c index 36366f4..d7b5d0c 100644 --- a/src/network.c +++ b/src/network.c @@ -1469,9 +1469,9 @@ int connman_network_connect_hidden(struct connman_network *network, goto out; } else { __connman_service_set_hidden(service); - __connman_service_set_userconnect(service, true); __connman_service_set_hidden_data(service, user_data); - return __connman_service_connect(service); + return __connman_service_connect(service, + CONNMAN_SERVICE_CONNECT_REASON_USER); } out: diff --git a/src/service.c b/src/service.c index 4bc70c0..63054b7 100644 --- a/src/service.c +++ b/src/service.c @@ -73,13 +73,13 @@ struct connman_service { enum connman_service_state state_ipv4; enum connman_service_state state_ipv6; enum connman_service_error error; + enum connman_service_connect_reason connect_reason; uint8_t strength; bool favorite; bool immutable; bool hidden; bool ignore; bool autoconnect; - bool userconnect; GTimeVal modified; unsigned int order; char *name; @@ -162,6 +162,23 @@ static struct connman_service *find_service(const char *path) return data.service; } +static const char *reason2string(enum connman_service_connect_reason reason) +{ + + switch (reason) { + case CONNMAN_SERVICE_CONNECT_REASON_NONE: + return "none"; + case CONNMAN_SERVICE_CONNECT_REASON_USER: + return "user"; + case CONNMAN_SERVICE_CONNECT_REASON_AUTO: + return "auto"; + case CONNMAN_SERVICE_CONNECT_REASON_SESSION: + return "session"; + } + + return "unknown"; +} + const char *__connman_service_type2string(enum connman_service_type type) {
[PATCH v3 04/10] service: Add connect reason to __connman_serice_auto_connect()
From: Daniel Wagner --- src/config.c | 2 +- src/connman.h | 2 +- src/device.c | 4 ++-- src/service.c | 30 +- src/session.c | 2 +- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/config.c b/src/config.c index feee6b2..22321bf 100644 --- a/src/config.c +++ b/src/config.c @@ -1258,7 +1258,7 @@ static void provision_service(gpointer key, gpointer value, g_timeout_add(0, remove_virtual_config, virtual); } else - __connman_service_auto_connect(); + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); } int __connman_config_provision_service(struct connman_service *service) diff --git a/src/connman.h b/src/connman.h index 80afab3..87c5835 100644 --- a/src/connman.h +++ b/src/connman.h @@ -705,7 +705,7 @@ int __connman_service_connect(struct connman_service *service, int __connman_service_disconnect(struct connman_service *service); int __connman_service_disconnect_all(void); void __connman_service_set_active_session(bool enable, GSList *list); -void __connman_service_auto_connect(void); +void __connman_service_auto_connect(enum connman_service_connect_reason reason); bool __connman_service_remove(struct connman_service *service); bool __connman_service_is_provider_pending(struct connman_service *service); void __connman_service_set_provider_pending(struct connman_service *service, diff --git a/src/device.c b/src/device.c index e112d27..508733c 100644 --- a/src/device.c +++ b/src/device.c @@ -669,7 +669,7 @@ int connman_device_reconnect_service(struct connman_device *device) { DBG("device %p", device); - __connman_service_auto_connect(); + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); return 0; } @@ -758,7 +758,7 @@ int connman_device_set_scanning(struct connman_device *device, __connman_technology_scan_stopped(device); - __connman_service_auto_connect(); + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); return 0; } diff --git a/src/service.c b/src/service.c index 63054b7..0f294ee 100644 --- a/src/service.c +++ b/src/service.c @@ -3091,7 +3091,7 @@ int __connman_service_reset_ipconfig(struct connman_service *service, *new_state = service->state_ipv4; else *new_state = service->state_ipv6; - __connman_service_auto_connect(); + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); } DBG("err %d ipconfig %p type %d method %d state %s", err, @@ -3146,7 +3146,7 @@ static DBusMessage *set_property(DBusConnection *conn, autoconnect_changed(service); if (autoconnect) - __connman_service_auto_connect(); + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); service_save(service); } else if (g_str_equal(name, "Nameservers.Configuration")) { @@ -3569,7 +3569,9 @@ static GList *preferred_tech_list_get(void) return tech_data.preferred_list; } -static bool auto_connect_service(GList *services, bool preferred) +static bool auto_connect_service(GList *services, + enum connman_service_connect_reason reason, + bool preferred) { struct connman_service *service = NULL; bool ignore[MAX_CONNMAN_SERVICE_TYPES] = { }; @@ -3624,8 +3626,7 @@ static bool auto_connect_service(GList *services, bool preferred) DBG("service %p %s %s", service, service->name, (preferred) ? "preferred" : "auto"); - __connman_service_connect(service, - CONNMAN_SERVICE_CONNECT_REASON_AUTO); + __connman_service_connect(service, reason); if (!active_count) return true; @@ -3638,6 +3639,7 @@ static bool auto_connect_service(GList *services, bool preferred) static gboolean run_auto_connect(gpointer data) { + enum connman_service_connect_reason reason = GPOINTER_TO_UINT(data); bool autoconnecting = false; GList *preferred_tech; @@ -3647,24 +3649,26 @@ static gboolean run_auto_connect(gpointer data) preferred_tech = preferred_tech_list_get(); if (preferred_tech) { - autoconnecting = auto_connect_service(preferred_tech, true); + autoconnecting = auto_connect_service(preferred_tech, reason, + true); g_list_free(preferred_tech); } if (!autoconnecting || active_count) - auto_connect_service(service_list, false); + auto_connect_service(service_list, reason, false); return FALSE; } -void __connman_service_auto_connect(void) +void __connman_se
[PATCH v3 00/10] Reimplementation of session selection implementation
From: Daniel Wagner Hi, As result of your disucssion I completely rewrote the series. The main changes is that the session's configuration are tracked in service.c and that we track the connection request reason. With this information inside service.c, the auto connect algorithm can decide which service to add or remove from a session. #1 session: Remove service selection implementation Just git rid of all the implementation #2 session: Mark session active or inactive Another small cleanup and preperation for the stuff which is added in the following patches. #3 service: Add connect reason to __connman_service_connect() #4 service: Add connect reason to __connman_serice_auto_connect() In these two patches the connection reason code is added to the services. #5 service: Store config per session With this change the service.c file is aware of all activated sessions and their configuration. #6 session: Add functions to de/assign service to a session #7 service: Assign services to sessions These patches brings back one important feature. A free-ride session is now updated again, that is it gets serivces added or removed. #8 sevice: Disconnect service on last session deactivation Since we know who established a connection, we can also tear down after the last 'user' (session) is gone. If the connection was established via the Service API then we don't take it down. #9 service: Add session auto connect support The auto connect algorithm now can do decision part which service should be connected. I consider this version as starting point towards a smarter version. It is very simple and still gets the basic stuff correct. Which is if a session request a conneciton a matching service will be connected. #10 service: Enter session mode when config files are found This patch is just for dicussions. Without it the normal auto connect mode will race with the session connect mode on ConnMan's startup (before sessions are created). cheers, daniel Daniel Wagner (10): session: Remove service selection implementation session: Mark session active or inactive service: Add connect reason to __connman_service_connect() service: Add connect reason to __connman_serice_auto_connect() service: Store config per session session: Add functions to de/assign service to a session service: Assign services to sessions service: Disconnect service on last session deactivation service: Add session auto connect support service: Enter session mode when config files are found include/session.h | 1 + plugins/session_policy_local.c | 5 + src/config.c | 8 +- src/connman.h | 27 +- src/device.c | 4 +- src/network.c | 4 +- src/service.c | 310 +++--- src/session.c | 729 ++--- 8 files changed, 395 insertions(+), 693 deletions(-) -- 1.8.5.3 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH v3 07/10] service: Assign services to sessions
From: Daniel Wagner 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_servic
[PATCH v3 05/10] service: Store config per session
From: Daniel Wagner Currently, service has no idea which session needs to be updated after the auto connect algorithm has choosen a service. Updated means that service will add and remove services to a session. First step in this support this, we start storing the bearer list per session in service. Also pass in the complete configuration, because we need later to know the ConnectionType or RoamingPolicy information anyway. --- src/connman.h | 6 +- src/service.c | 42 +++--- src/session.c | 31 +++ 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/connman.h b/src/connman.h index 87c5835..74ff797 100644 --- a/src/connman.h +++ b/src/connman.h @@ -700,11 +700,15 @@ enum connman_service_connect_reason { CONNMAN_SERVICE_CONNECT_REASON_SESSION = 3, }; +struct connman_session; +struct connman_session_config; + int __connman_service_connect(struct connman_service *service, enum connman_service_connect_reason reason); int __connman_service_disconnect(struct connman_service *service); int __connman_service_disconnect_all(void); -void __connman_service_set_active_session(bool enable, GSList *list); +void __connman_service_set_active_session(struct connman_session *session, + struct connman_session_config *config, bool enable); void __connman_service_auto_connect(enum connman_service_connect_reason reason); bool __connman_service_remove(struct connman_service *service); bool __connman_service_is_provider_pending(struct connman_service *service); diff --git a/src/service.c b/src/service.c index 0f294ee..3d65cae 100644 --- a/src/service.c +++ b/src/service.c @@ -43,6 +43,7 @@ static DBusConnection *connection = NULL; static GList *service_list = NULL; static GHashTable *service_hash = NULL; +static GHashTable *session_hash = NULL; static GSList *counter_list = NULL; static unsigned int autoconnect_timeout = 0; static unsigned int vpn_autoconnect_timeout = 0; @@ -126,6 +127,10 @@ struct connman_service { char *config_entry; }; +struct session_info { + struct connman_session_config *config; +}; + static bool allow_property_changed(struct connman_service *service); static struct connman_ipconfig *create_ip4config(struct connman_service *service, @@ -139,6 +144,13 @@ struct find_data { struct connman_service *service; }; +static void session_free(gpointer data) +{ + struct session_info *info = data; + + g_free(info); +} + static void compare_path(gpointer value, gpointer user_data) { struct connman_service *service = value; @@ -3471,17 +3483,29 @@ static bool is_ignore(struct connman_service *service) static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {}; static int active_count = 0; -void __connman_service_set_active_session(bool enable, GSList *list) +void __connman_service_set_active_session(struct connman_session *session, + struct connman_session_config *config, bool enable) { - if (!list) + struct session_info *info; + GSList *list; + + if (!config) return; - if (enable) + if (enable) { active_count++; - else + + info = g_new0(struct session_info, 1); + info->config = config; + + g_hash_table_replace(session_hash, session, info); + } else { active_count--; - while (list != NULL) { + g_hash_table_remove(session_hash, session); + } + + for (list = config->allowed_bearers; list; list = list->next) { enum connman_service_type type = GPOINTER_TO_INT(list->data); switch (type) { @@ -3502,8 +3526,6 @@ void __connman_service_set_active_session(bool enable, GSList *list) case CONNMAN_SERVICE_TYPE_GADGET: break; } - - list = g_slist_next(list); } DBG("eth %d wifi %d bt %d cellular %d sessions %d", @@ -6987,6 +7009,9 @@ int __connman_service_init(void) service_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, service_free); + session_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, session_free); + services_notify = g_new0(struct _services_notify, 1); services_notify->remove = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); @@ -7019,6 +7044,9 @@ void __connman_service_cleanup(void) g_hash_table_destroy(service_hash); service_hash = NULL; + g_hash_table_destroy(session_hash); + session_hash = NULL; + g_slist_free(counter_list); counter_list = NULL; diff --git a/src/session.c b/src/session.c index 72ed5c9..7ed5d08 100644 --- a/src/session.
[PATCH v3 01/10] session: Remove service selection implementation
From: Daniel Wagner The current implemention is decoupled from what service.c is doing. For example session.c needs to guess via the service state which session original wanted a connection. Let's start over with a new approach. First step is to remove the current implemantation. --- src/session.c | 573 +- 1 file changed, 10 insertions(+), 563 deletions(-) diff --git a/src/session.c b/src/session.c index 5985a59..e4a8b49 100644 --- a/src/session.c +++ b/src/session.c @@ -39,15 +39,6 @@ static GSList *policy_list; static uint32_t session_mark = 256; static struct firewall_context *global_firewall = NULL; -enum connman_session_trigger { - CONNMAN_SESSION_TRIGGER_UNKNOWN = 0, - CONNMAN_SESSION_TRIGGER_SETTING = 1, - CONNMAN_SESSION_TRIGGER_CONNECT = 2, - CONNMAN_SESSION_TRIGGER_DISCONNECT = 3, - CONNMAN_SESSION_TRIGGER_SERVICE = 4, - CONNMAN_SESSION_TRIGGER_ECALL = 5, -}; - enum connman_session_reason { CONNMAN_SESSION_REASON_UNKNOWN = 0, CONNMAN_SESSION_REASON_CONNECT = 1, @@ -90,31 +81,8 @@ struct connman_session { uint32_t mark; int index; char *gateway; - - GList *service_list; - GHashTable *service_hash; }; -static const char *trigger2string(enum connman_session_trigger trigger) -{ - switch (trigger) { - case CONNMAN_SESSION_TRIGGER_UNKNOWN: - break; - case CONNMAN_SESSION_TRIGGER_SETTING: - return "setting"; - case CONNMAN_SESSION_TRIGGER_CONNECT: - return "connect"; - case CONNMAN_SESSION_TRIGGER_DISCONNECT: - return "disconnect"; - case CONNMAN_SESSION_TRIGGER_SERVICE: - return "service"; - case CONNMAN_SESSION_TRIGGER_ECALL: - return "ecall"; - } - - return NULL; -} - static const char *reason2string(enum connman_session_reason reason) { switch (reason) { @@ -482,9 +450,6 @@ static void cleanup_session_final(struct connman_session *session) session->info->config.allowed_bearers); g_slist_free(session->user_allowed_bearers); - if (session->service_hash) - g_hash_table_destroy(session->service_hash); - g_list_free(session->service_list); free_session(session); } @@ -921,30 +886,6 @@ static void append_notify(DBusMessageIter *dict, session->append_all = false; } -static bool is_type_matching_state(enum connman_session_state *state, - enum connman_session_type type) -{ - switch (type) { - case CONNMAN_SESSION_TYPE_UNKNOWN: - return false; - case CONNMAN_SESSION_TYPE_ANY: - return true; - case CONNMAN_SESSION_TYPE_LOCAL: - if (*state >= CONNMAN_SESSION_STATE_CONNECTED) { - *state = CONNMAN_SESSION_STATE_CONNECTED; - return true; - } - - break; - case CONNMAN_SESSION_TYPE_INTERNET: - if (*state == CONNMAN_SESSION_STATE_ONLINE) - return true; - break; - } - - return false; -} - static bool compute_notifiable_changes(struct connman_session *session) { struct session_info *info_last = session->info_last; @@ -1011,200 +952,6 @@ static void ipconfig_ipv6_changed(struct connman_session *session) session->service); } -static bool service_type_match(struct connman_session *session, - struct connman_service *service) -{ - struct session_info *info = session->info; - GSList *list; - - for (list = info->config.allowed_bearers; - list; list = list->next) { - enum connman_service_type bearer = GPOINTER_TO_INT(list->data); - enum connman_service_type service_type; - - if (bearer == CONNMAN_SERVICE_TYPE_UNKNOWN) - return true; - - service_type = connman_service_get_type(service); - if (bearer == service_type) - return true; - } - - return false; -} - -static bool service_match(struct connman_session *session, - struct connman_service *service) -{ - if (!service_type_match(session, service)) - return false; - - return true; -} - -static int service_type_weight(enum connman_service_type type) -{ - /* -* The session doesn't care which service -* to use. Nevertheless we have to sort them -* according their type. The ordering is -* -* 1. Ethernet -* 2. Bluetooth -* 3. WiFi -* 4. Cellular -*/ - - switch (type) { - c
[PATCH] ntp: Only accept NTP packets from the defined time server
--- src/ntp.c | 9 + 1 file changed, 9 insertions(+) diff --git a/src/ntp.c b/src/ntp.c index 57205f8..63eac03 100644 --- a/src/ntp.c +++ b/src/ntp.c @@ -117,6 +117,7 @@ static struct timespec mtx_time; static int transmit_fd = 0; static char *timeserver = NULL; +static struct sockaddr_in timeserver_addr; static gint poll_id = 0; static gint timeout_id = 0; static guint retries = 0; @@ -345,6 +346,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, gpointer user_data) { unsigned char buf[128]; + struct sockaddr_in sender_addr; struct msghdr msg; struct iovec iov; struct cmsghdr *cmsg; @@ -370,11 +372,17 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, msg.msg_iovlen = 1; msg.msg_control = aux; msg.msg_controllen = sizeof(aux); + msg.msg_name = &sender_addr; + msg.msg_namelen = sizeof(sender_addr); len = recvmsg(fd, &msg, MSG_DONTWAIT); if (len < 0) return TRUE; + if (timeserver_addr.sin_addr.s_addr != sender_addr.sin_addr.s_addr) + /* only accept messages from the timeserver */ + return TRUE; + tv = NULL; clock_gettime(CLOCK_MONOTONIC, &mrx_time); @@ -468,6 +476,7 @@ int __connman_ntp_start(char *server) g_free(timeserver); timeserver = g_strdup(server); + timeserver_addr.sin_addr.s_addr = inet_addr(server); start_ntp(timeserver); -- 1.8.3.1 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Angstrom connman version 1.4 ?
I'm on beagleboneblack using Angstrom linux distribution and using opkg list | grep connman i see that the last version avaiable is connman - 1.4-r18.0.15 - A daemon for managing internet connections within embedded devices but why on connman.net the last version is 1.21 ? connman 1.21 has the Gadget tecnology implementation right? Thanks, and sorry for the silliness of the question. ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: Angstrom connman version 1.4 ?
Hi, On Tue, 2014-02-04 at 13:11 +0100, andrea pola wrote: > I'm on beagleboneblack using Angstrom linux distribution and using > opkg list | grep connman > > i see that the last version avaiable is connman - 1.4-r18.0.15 - A > daemon for managing internet connections within embedded devices > but why on connman.net the last version is 1.21 ? We've been busy cranking out new versions since July 2012, I suppose :-). For new features and bugfixes since 1.4 see the release notes at https://01.org/connman/blogs > connman 1.21 has the Gadget tecnology implementation right? ConnMan 1.17 has the gadget technology properly implemented for tethering. HTH, Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] wispr: Handle wispr redirect properly
Return true if agent invocation is successful after receiving a valid wispr redirect message. Otherwise wispr_portal_web_result() will proceed based on HTTP status code. --- src/wispr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wispr.c b/src/wispr.c index 32cf75a..733debd 100644 --- a/src/wispr.c +++ b/src/wispr.c @@ -646,6 +646,8 @@ static bool wispr_manage_message(GWebResult *result, wispr_portal_request_wispr_login, wp_context) != -EINPROGRESS) wispr_portal_error(wp_context); + else + return true; break; case 120: /* Falling down */ -- 1.8.5.3 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH] ntp: Only accept NTP packets from the defined time server
On Tue, 2014-02-04 at 13:03 +0200, Jukka Rissanen wrote: > --- > src/ntp.c | 9 + > 1 file changed, 9 insertions(+) Applied, thanks! Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH] wispr: Handle wispr redirect properly
On Tue, 2014-02-04 at 15:06 +0200, Hannu Mallat wrote: > Return true if agent invocation is successful after receiving > a valid wispr redirect message. Otherwise wispr_portal_web_result() > will proceed based on HTTP status code. Applied, thanks! Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: Angstrom connman version 1.4 ?
Ok thanks, i've downloaded last version from https://www.kernel.org/pub/linux/network/connman/ and i try to ./configure but i've got errors for dbus version unsatisfied configure: error: D-Bus >= 1.4 is required I've made a opkg list and i see that dbus is 1.6 but libdbus not. Connman configure is checking for libdbus right? I need to download it manually,compile ad install right? 2014-02-04 Patrik Flykt : > > Hi, > > On Tue, 2014-02-04 at 13:11 +0100, andrea pola wrote: > > I'm on beagleboneblack using Angstrom linux distribution and using > > opkg list | grep connman > > > > i see that the last version avaiable is connman - 1.4-r18.0.15 - A > > daemon for managing internet connections within embedded devices > > but why on connman.net the last version is 1.21 ? > > We've been busy cranking out new versions since July 2012, I > suppose :-). For new features and bugfixes since 1.4 see the release > notes at https://01.org/connman/blogs > > > connman 1.21 has the Gadget tecnology implementation right? > > ConnMan 1.17 has the gadget technology properly implemented for > tethering. > > HTH, > > Patrik > > > ___ > connman mailing list > connman@connman.net > https://lists.connman.net/mailman/listinfo/connman > ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman