예제 #1
0
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);
}
예제 #2
0
int connman_session_config_update(struct connman_session *session)
{
    struct session_info *info = session->info;
    GSList *allowed_bearers;
    int err;

    DBG("session %p", session);

    /*
     * We update all configuration even though only one entry
     * might have changed. We can still optimize this later.
     */

    if (session->id_type != session->policy_config->id_type) {
        cleanup_firewall_session(session);
        err = init_firewall_session(session);
        if (err < 0) {
            connman_session_destroy(session);
            return err;
        }

        session->id_type = session->policy_config->id_type;
    }

    apply_policy_on_bearers(
        session->policy_config->allowed_bearers,
        session->user_allowed_bearers,
        &allowed_bearers);

    if (session->active)
        set_active_session(session, false);

    session->active = false;
    session_deactivate(session);

    g_slist_free(info->config.allowed_bearers);
    info->config.allowed_bearers = allowed_bearers;

    session_activate(session);

    info->config.type = apply_policy_on_type(
                            session->policy_config->type,
                            info->config.type);

    info->config.roaming_policy = session->policy_config->roaming_policy;

    info->config.ecall = session->policy_config->ecall;
    if (info->config.ecall)
        ecall_session = session;

    info->config.priority = session->policy_config->priority;

    session_notify(session);

    return 0;
}
예제 #3
0
    static void update_session_state(struct connman_session *session)
{
    enum connman_service_state service_state;
    enum connman_session_state state = CONNMAN_SESSION_STATE_DISCONNECTED;

    if (session->service) {
        service_state = __connman_service_get_state(session->service);
        state = service_to_session_state(service_state);
        session->info->state = state;
    }
    session->info->state = state;

    DBG("session %p state %s", session, state2string(state));

    update_routing_table(session);
    update_nat_rules(session);
    session_notify(session);
}
예제 #4
0
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);

            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 {
            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);
}
예제 #5
0
파일: session.c 프로젝트: leinomii/connman
static void session_changed(struct connman_session *session,
				enum connman_session_trigger trigger)
{
	struct session_info *info = session->info;
	struct session_info *info_last = session->info_last;
	GSequenceIter *service_iter = NULL, *service_iter_last = NULL;
	GSequence *service_list_last;
	GHashTable *service_hash_last;

	/*
	 * TODO: This only a placeholder for the 'real' algorithm to
	 * play a bit around. So we are going to improve it step by step.
	 */

	DBG("session %p trigger %s reason %s", session, trigger2string(trigger),
						reason2string(info->reason));

	if (info->entry != NULL) {
		enum connman_session_state state;

		state = service_to_session_state(info->entry->state);

		if (is_type_matching_state(&state, info->config.type) == TRUE)
			info->state = state;
	}

	switch (trigger) {
	case CONNMAN_SESSION_TRIGGER_UNKNOWN:
		DBG("ignore session changed event");
		return;
	case CONNMAN_SESSION_TRIGGER_SETTING:
		if (info->config.allowed_bearers != info_last->config.allowed_bearers) {

			service_hash_last = session->service_hash;
			service_list_last = session->service_list;

			populate_service_list(session);

			if (info->entry != NULL) {
				service_iter_last = g_hash_table_lookup(
							service_hash_last,
							info->entry->service);
				service_iter = g_hash_table_lookup(
							session->service_hash,
							info->entry->service);
			}

			if (service_iter == NULL && service_iter_last != NULL) {
				/*
				 * The currently selected service is
				 * not part of this session anymore.
				 */
				deselect_and_disconnect(session);
			}

			g_hash_table_remove_all(service_hash_last);
			g_sequence_free(service_list_last);
		}

		if (info->config.type != info_last->config.type) {
			if (info->state >= CONNMAN_SESSION_STATE_CONNECTED &&
					is_type_matching_state(&info->state,
							info->config.type) == FALSE)
				deselect_and_disconnect(session);
		}

		if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED) {
			select_and_connect(session,
					CONNMAN_SESSION_REASON_FREE_RIDE);
		}

		break;
	case CONNMAN_SESSION_TRIGGER_ECALL:
		/*
		 * For the time beeing we fallback to normal connect
		 * strategy.
		 */
	case CONNMAN_SESSION_TRIGGER_CONNECT:
		if (info->state >= CONNMAN_SESSION_STATE_CONNECTED) {
			if (info->entry->reason == CONNMAN_SESSION_REASON_CONNECT)
				break;
			info->entry->reason = CONNMAN_SESSION_REASON_CONNECT;
			__connman_service_session_inc(info->entry->service);
			break;
		}

		if (info->entry != NULL &&
				is_connecting(info->entry->state) == TRUE) {
			break;
		}

		select_and_connect(session,
				CONNMAN_SESSION_REASON_CONNECT);

		break;
	case CONNMAN_SESSION_TRIGGER_DISCONNECT:
		deselect_and_disconnect(session);

		break;
	case CONNMAN_SESSION_TRIGGER_SERVICE:
		if (info->entry != NULL &&
			(is_connecting(info->entry->state) == TRUE ||
				is_connected(info->entry->state) == TRUE)) {
			break;
		}

		deselect_and_disconnect(session);

		if (info->reason == CONNMAN_SESSION_REASON_FREE_RIDE) {
			select_and_connect(session, info->reason);
		}

		break;
	}

	session_notify(session);
}
예제 #6
0
파일: session.c 프로젝트: igaw/connman
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);
}