Beispiel #1
0
int __connman_session_create(DBusMessage *msg)
{
    const char *owner, *notify_path;
    char *session_path = NULL;
    DBusMessageIter iter, array;
    struct connman_session *session = NULL;
    struct creation_data *creation_data = NULL;
    bool user_allowed_bearers = false;
    bool user_connection_type = false;
    int err, i;
    char *str;

    owner = dbus_message_get_sender(msg);

    DBG("owner %s", owner);

    if (ecall_session && ecall_session->ecall) {
        /*
         * If there is an emergency call already going on,
         * ignore session creation attempt
         */
        err = -EBUSY;
        goto err;
    }

    creation_data = g_try_new0(struct creation_data, 1);
    if (!creation_data) {
        err = -ENOMEM;
        goto err;
    }

    creation_data->pending = dbus_message_ref(msg);

    dbus_message_iter_init(msg, &iter);
    dbus_message_iter_recurse(&iter, &array);

    while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
        DBusMessageIter entry, value;
        const char *key, *val;

        dbus_message_iter_recurse(&array, &entry);
        dbus_message_iter_get_basic(&entry, &key);

        dbus_message_iter_next(&entry);
        dbus_message_iter_recurse(&entry, &value);

        switch (dbus_message_iter_get_arg_type(&value)) {
        case DBUS_TYPE_ARRAY:
            if (g_str_equal(key, "AllowedBearers")) {
                err = parse_bearers(&value,
                                    &creation_data->allowed_bearers);
                if (err < 0)
                    goto err;

                user_allowed_bearers = true;
            } else {
                err = -EINVAL;
                goto err;
            }
            break;
        case DBUS_TYPE_STRING:
            if (g_str_equal(key, "ConnectionType")) {
                dbus_message_iter_get_basic(&value, &val);
                creation_data->type =
                    connman_session_parse_connection_type(val);

                user_connection_type = true;
            } else {
                err = -EINVAL;
                goto err;
            }
        }
        dbus_message_iter_next(&array);
    }

    /*
     * If the user hasn't provided a configuration, we set
     * the default configuration.
     *
     * For AllowedBearers this is '*', ...
     */
    if (!user_allowed_bearers) {
        add_default_bearer_types(&creation_data->allowed_bearers);
        if (!creation_data->allowed_bearers) {
            err = -ENOMEM;
            goto err;
        }
    }

    /* ... and for ConnectionType it is 'any'. */
    if (!user_connection_type)
        creation_data->type = CONNMAN_SESSION_TYPE_ANY;

    dbus_message_iter_next(&iter);
    dbus_message_iter_get_basic(&iter, &notify_path);

    if (!notify_path) {
        err = -EINVAL;
        goto err;
    }

    str = g_strdup(owner);
    for (i = 0; str[i] != '\0'; i++)
        if (str[i] == ':' || str[i] == '.')
            str[i] = '_';
    session_path = g_strdup_printf("/sessions/%s%s", str, notify_path);
    g_free(str);

    if (!session_path) {
        err = -ENOMEM;
        goto err;
    }

    session = g_hash_table_lookup(session_hash, session_path);
    if (session) {
        g_free(session_path);
        session = NULL;
        err = -EEXIST;
        goto err;
    }

    session = g_try_new0(struct connman_session, 1);
    if (!session) {
        g_free(session_path);
        err = -ENOMEM;
        goto err;
    }

    creation_data->session = session;
    session->session_path = session_path;

    session->info = g_try_new0(struct session_info, 1);
    if (!session->info) {
        err = -ENOMEM;
        goto err;
    }

    session->info_last = g_try_new0(struct session_info, 1);
    if (!session->info_last) {
        err = -ENOMEM;
        goto err;
    }

    session->owner = g_strdup(owner);
    session->notify_path = g_strdup(notify_path);
    session->notify_watch =
        g_dbus_add_disconnect_watch(connection, session->owner,
                                    owner_disconnect, session, NULL);

    err = create_policy_config(session, session_policy_config_cb,
                               creation_data);
    if (err < 0 && err != -EINPROGRESS)
        return err;

    return -EINPROGRESS;

err:
    connman_error("Failed to create session");

    free_session(session);

    cleanup_creation_data(creation_data);
    return err;
}
Beispiel #2
0
int __connman_session_create(DBusMessage *msg)
{
	const char *owner, *notify_path;
	char *session_path = NULL;
	DBusMessageIter iter, array;
	struct connman_session *session = NULL;
	struct user_config *user_config = NULL;
	connman_bool_t user_allowed_bearers = FALSE;
	connman_bool_t user_connection_type = FALSE;
	int err;

	owner = dbus_message_get_sender(msg);

	DBG("owner %s", owner);

	if (ecall_session != NULL && ecall_session->ecall == TRUE) {
		/*
		 * If there is an emergency call already going on,
		 * ignore session creation attempt
		 */
		err = -EBUSY;
		goto err;
	}

	user_config = g_try_new0(struct user_config, 1);
	if (user_config == NULL) {
		err = -ENOMEM;
		goto err;
	}

	user_config->pending = dbus_message_ref(msg);

	dbus_message_iter_init(msg, &iter);
	dbus_message_iter_recurse(&iter, &array);

	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry, value;
		const char *key, *val;

		dbus_message_iter_recurse(&array, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		switch (dbus_message_iter_get_arg_type(&value)) {
		case DBUS_TYPE_ARRAY:
			if (g_str_equal(key, "AllowedBearers") == TRUE) {
				err = parse_bearers(&value,
						&user_config->allowed_bearers);
				if (err < 0)
					goto err;

				user_allowed_bearers = TRUE;
			} else {
				err = -EINVAL;
				goto err;
			}
			break;
		case DBUS_TYPE_STRING:
			if (g_str_equal(key, "ConnectionType") == TRUE) {
				dbus_message_iter_get_basic(&value, &val);
				user_config->type =
					connman_session_parse_connection_type(val);

				user_connection_type = TRUE;
			} else {
				err = -EINVAL;
				goto err;
			}
		}
		dbus_message_iter_next(&array);
	}

	/*
	 * If the user hasn't provided a configuration, we set
	 * the default configuration.
	 *
	 * For AllowedBearers this is '*', ...
	 */
	if (user_allowed_bearers == FALSE) {
		user_config->allowed_bearers =
			g_slist_append(NULL,
				GINT_TO_POINTER(CONNMAN_SERVICE_TYPE_UNKNOWN));
		if (user_config->allowed_bearers == NULL) {
			err = -ENOMEM;
			goto err;
		}
	}

	/* ... and for ConnectionType it is 'any'. */
	if (user_connection_type == FALSE)
		user_config->type = CONNMAN_SESSION_TYPE_ANY;

	dbus_message_iter_next(&iter);
	dbus_message_iter_get_basic(&iter, &notify_path);

	if (notify_path == NULL) {
		err = -EINVAL;
		goto err;
	}

	session_path = g_strdup_printf("/sessions%s", notify_path);
	if (session_path == NULL) {
		err = -ENOMEM;
		goto err;
	}

	session = g_hash_table_lookup(session_hash, session_path);
	if (session != NULL) {
		g_free(session_path);
		session = NULL;
		err = -EEXIST;
		goto err;
	}

	session = g_try_new0(struct connman_session, 1);
	if (session == NULL) {
		g_free(session_path);
		err = -ENOMEM;
		goto err;
	}

	session->session_path = session_path;

	session->info = g_try_new0(struct session_info, 1);
	if (session->info == NULL) {
		err = -ENOMEM;
		goto err;
	}

	session->info_last = g_try_new0(struct session_info, 1);
	if (session->info_last == NULL) {
		err = -ENOMEM;
		goto err;
	}

	session->owner = g_strdup(owner);
	session->notify_path = g_strdup(notify_path);
	session->notify_watch =
		g_dbus_add_disconnect_watch(connection, session->owner,
					owner_disconnect, session, NULL);

	err = assign_policy_plugin(session);
	if (err < 0)
		goto err;

	err = create_policy_config(session, session_create_cb, user_config);
	if (err < 0 && err != -EINPROGRESS)
		return err;

	return -EINPROGRESS;

err:
	connman_error("Failed to create session");

	free_session(session);

	cleanup_user_config(user_config);
	return err;
}