static void handle_service_state_online(struct connman_service *service, enum connman_service_state state, struct connman_service_info *info) { 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 = value; bool connected; connected = is_session_connected(session, state); if (session->service == service) { if (!connected) { DBG("session %p remove service %p", session, service); info->sessions = g_slist_remove(info->sessions, session); session->service = NULL; update_session_state(session); } } else if (connected && session_match_service(session, service)) { DBG("session %p add service %p", session, service); info->sessions = g_slist_prepend(info->sessions, session); session->service = service; update_session_state(session); } } }
static void session_activate(struct connman_session *session) { GHashTableIter iter; gpointer key, value; if (!service_hash) return; g_hash_table_iter_init(&iter, service_hash); while (g_hash_table_iter_next(&iter, &key, &value)) { struct connman_service_info *info = value; enum connman_service_state state; state = __connman_service_get_state(info->service); if (is_session_connected(session, state) && session_match_service(session, info->service)) { DBG("session %p add service %p", session, info->service); info->sessions = g_slist_prepend(info->sessions, session); session->service = info->service; update_session_state(session); return; } } session_notify(session); }
static void cleanup_session(gpointer user_data) { struct connman_session *session = user_data; DBG("remove %s", session->session_path); cleanup_routing_table(session); cleanup_firewall_session(session); if (session->active) set_active_session(session, false); session_deactivate(session); update_session_state(session); g_slist_free(session->user_allowed_bearers); free_session(session); }
static void handle_service_state_offline(struct connman_service *service, struct connman_service_info *info) { GSList *list; for (list = info->sessions; list; list = list->next) { struct connman_session *session = list->data; if (session->service != service) { connman_warn("session %p should have session %p assigned", session, service); continue; } DBG("session %p remove service %p", session, service); session->service = NULL; update_session_state(session); } }
static DBusMessage *disconnect_session(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct connman_session *session = user_data; DBG("session %p", session); if (ecall_session) { if (ecall_session->ecall && ecall_session != session) return __connman_error_failed(msg, EBUSY); session->ecall = false; } if (session->active) { session->active = false; set_active_session(session, false); } session_deactivate(session); update_session_state(session); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); }
static void session_activate(struct connman_session *session) { GHashTableIter iter; gpointer key, value; if (!service_hash) return; if (policy && policy->get_service_for_session) { struct connman_service *service; struct connman_service_info *info; GSList *service_list = NULL; enum connman_service_state state = CONNMAN_SESSION_STATE_DISCONNECTED; g_hash_table_iter_init(&iter, service_hash); while (g_hash_table_iter_next(&iter, &key, &value)) { struct connman_service_info *info = value; state = connman_service_get_state(info->service); if (is_session_connected(session, state)) service_list = g_slist_prepend(service_list, info->service); } service_list = g_slist_reverse(service_list); service = policy->get_service_for_session(session, service_list); if (service) { info = g_hash_table_lookup(service_hash, service); DBG("session %p add service %p", session, info->service); info->sessions = g_slist_prepend(info->sessions, session); session->service = info->service; update_session_state(session); } g_slist_free(service_list); return; } g_hash_table_iter_init(&iter, service_hash); while (g_hash_table_iter_next(&iter, &key, &value)) { struct connman_service_info *info = value; enum connman_service_state state; state = connman_service_get_state(info->service); if (is_session_connected(session, state) && session_match_service(session, info->service)) { DBG("session %p add service %p", session, info->service); info->sessions = g_slist_prepend(info->sessions, session); session->service = info->service; update_session_state(session); return; } } session_notify(session); }
static DBusMessage *change_session(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct connman_session *session = user_data; struct session_info *info = session->info; DBusMessageIter iter, value; const char *name; const char *val; GSList *allowed_bearers; int err; DBG("session %p", session); if (!dbus_message_iter_init(msg, &iter)) return __connman_error_invalid_arguments(msg); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) return __connman_error_invalid_arguments(msg); dbus_message_iter_get_basic(&iter, &name); dbus_message_iter_next(&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) return __connman_error_invalid_arguments(msg); dbus_message_iter_recurse(&iter, &value); switch (dbus_message_iter_get_arg_type(&value)) { case DBUS_TYPE_ARRAY: if (g_str_equal(name, "AllowedBearers")) { err = parse_bearers(&value, &allowed_bearers); if (err < 0) return __connman_error_failed(msg, -err); if (session->active) set_active_session(session, false); session->active = false; session_deactivate(session); update_session_state(session); g_slist_free(info->config.allowed_bearers); session->user_allowed_bearers = allowed_bearers; apply_policy_on_bearers( session->policy_config->allowed_bearers, session->user_allowed_bearers, &info->config.allowed_bearers); session_activate(session); } else { goto err; } break; case DBUS_TYPE_STRING: if (g_str_equal(name, "ConnectionType")) { dbus_message_iter_get_basic(&value, &val); info->config.type = apply_policy_on_type( session->policy_config->type, connman_session_parse_connection_type(val)); } else if (g_str_equal(name, "AllowedInterface")) { dbus_message_iter_get_basic(&value, &val); if (session->active) set_active_session(session, false); session->active = false; session_deactivate(session); update_session_state(session); g_free(session->user_allowed_interface); /* empty string means allow any interface */ if (!g_strcmp0(val, "")) session->user_allowed_interface = NULL; else session->user_allowed_interface = g_strdup(val); info->config.allowed_interface = apply_policy_on_interface( session->policy_config->allowed_interface, session->user_allowed_interface); session_activate(session); } else { goto err; } break; case DBUS_TYPE_BOOLEAN: if (g_str_equal(name, "SourceIPRule")) { dbus_bool_t source_ip_rule; dbus_message_iter_get_basic(&value, &source_ip_rule); info->config.source_ip_rule = source_ip_rule; update_session_state(session); } else { goto err; } break; default: goto err; } session_notify(session); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); err: return __connman_error_invalid_arguments(msg); }