mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
protocol: add more methods on client
Add method to get and set permissions on a client Add method to send error to client.
This commit is contained in:
parent
bbf718cc98
commit
e026f55c97
6 changed files with 410 additions and 46 deletions
|
|
@ -1017,6 +1017,155 @@ static int client_demarshal_info(void *object, void *data, size_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void client_marshal_permissions(void *object, const struct spa_dict *dict)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
uint32_t i, n_items;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_PERMISSIONS);
|
||||
|
||||
n_items = dict ? dict->n_items : 0;
|
||||
|
||||
spa_pod_builder_add(b,
|
||||
"[",
|
||||
"i", n_items, NULL);
|
||||
|
||||
for (i = 0; i < n_items; i++) {
|
||||
spa_pod_builder_add(b,
|
||||
"s", dict->items[i].key,
|
||||
"s", dict->items[i].value, NULL);
|
||||
}
|
||||
spa_pod_builder_add(b, "]", NULL);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static int client_demarshal_permissions(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_dict props;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t i;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs, "[ i", &props.n_items, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
props.items = alloca(props.n_items * sizeof(struct spa_dict_item));
|
||||
for (i = 0; i < props.n_items; i++) {
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"s", &props.items[i].key,
|
||||
"s", &props.items[i].value,
|
||||
NULL) < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
pw_proxy_notify(proxy, struct pw_client_proxy_events, permissions, 0, &props);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_marshal_error(void *object, uint32_t id, int res, const char *error)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_ERROR);
|
||||
spa_pod_builder_add_struct(b,
|
||||
"i", id,
|
||||
"i", res,
|
||||
"s", error);
|
||||
pw_protocol_native_end_proxy(proxy, b);
|
||||
}
|
||||
|
||||
static int client_demarshal_error(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t id, res;
|
||||
const char *error;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"[ i", &id,
|
||||
"i", &res,
|
||||
"s", &error, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
pw_resource_do(resource, struct pw_client_proxy_methods, error, 0, id, res, error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_marshal_get_permissions(void *object)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_GET_PERMISSIONS);
|
||||
|
||||
spa_pod_builder_add_struct(b, "P", NULL);
|
||||
|
||||
pw_protocol_native_end_proxy(proxy, b);
|
||||
}
|
||||
|
||||
static int client_demarshal_get_permissions(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
void *ptr;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs, "[P]", &ptr, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
pw_resource_do(resource, struct pw_client_proxy_methods, get_permissions, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_marshal_update_permissions(void *object, const struct spa_dict *props)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
int i, n_items;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PERMISSIONS);
|
||||
|
||||
n_items = props ? props->n_items : 0;
|
||||
|
||||
spa_pod_builder_add(b, "[ i", n_items, NULL);
|
||||
|
||||
for (i = 0; i < n_items; i++) {
|
||||
spa_pod_builder_add(b,
|
||||
"s", props->items[i].key,
|
||||
"s", props->items[i].value, NULL);
|
||||
}
|
||||
spa_pod_builder_add(b, "]", NULL);
|
||||
|
||||
pw_protocol_native_end_proxy(proxy, b);
|
||||
}
|
||||
|
||||
static int client_demarshal_update_permissions(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_dict props;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t i;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs, "[ i", &props.n_items, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
props.items = alloca(props.n_items * sizeof(struct spa_dict_item));
|
||||
for (i = 0; i < props.n_items; i++) {
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"s", &props.items[i].key,
|
||||
"s", &props.items[i].value,
|
||||
NULL) < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
pw_resource_do(resource, struct pw_client_proxy_methods, update_permissions, 0, &props);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void link_marshal_info(void *object, struct pw_link_info *info)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
|
|
@ -1342,19 +1491,36 @@ static const struct pw_protocol_marshal pw_protocol_native_port_marshal = {
|
|||
PW_PORT_PROXY_EVENT_NUM,
|
||||
};
|
||||
|
||||
static const struct pw_client_proxy_methods pw_protocol_native_client_method_marshal = {
|
||||
PW_VERSION_CLIENT_PROXY_METHODS,
|
||||
&client_marshal_error,
|
||||
&client_marshal_get_permissions,
|
||||
&client_marshal_update_permissions,
|
||||
};
|
||||
|
||||
static const struct pw_protocol_native_demarshal pw_protocol_native_client_method_demarshal[] = {
|
||||
{ &client_demarshal_error, PW_PROTOCOL_NATIVE_PERM_W, },
|
||||
{ &client_demarshal_get_permissions, 0, },
|
||||
{ &client_demarshal_update_permissions, PW_PROTOCOL_NATIVE_PERM_W, },
|
||||
};
|
||||
|
||||
static const struct pw_client_proxy_events pw_protocol_native_client_event_marshal = {
|
||||
PW_VERSION_CLIENT_PROXY_EVENTS,
|
||||
&client_marshal_info,
|
||||
&client_marshal_permissions,
|
||||
};
|
||||
|
||||
static const struct pw_protocol_native_demarshal pw_protocol_native_client_event_demarshal[] = {
|
||||
{ &client_demarshal_info, 0, },
|
||||
{ &client_demarshal_permissions, 0, }
|
||||
};
|
||||
|
||||
static const struct pw_protocol_marshal pw_protocol_native_client_marshal = {
|
||||
PW_TYPE_INTERFACE_Client,
|
||||
PW_VERSION_CLIENT,
|
||||
NULL, NULL, 0,
|
||||
&pw_protocol_native_client_method_marshal,
|
||||
pw_protocol_native_client_method_demarshal,
|
||||
PW_CLIENT_PROXY_METHOD_NUM,
|
||||
&pw_protocol_native_client_event_marshal,
|
||||
pw_protocol_native_client_event_demarshal,
|
||||
PW_CLIENT_PROXY_EVENT_NUM,
|
||||
|
|
|
|||
|
|
@ -47,21 +47,42 @@ struct resource_data {
|
|||
|
||||
/** find a specific permission for a global or NULL when there is none */
|
||||
static struct permission *
|
||||
find_permission(struct pw_client *client, struct pw_global *global)
|
||||
find_permission(struct pw_client *client, uint32_t id)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||
struct permission *p;
|
||||
|
||||
if (!pw_array_check_index(&impl->permissions, global->id, struct permission))
|
||||
if (!pw_array_check_index(&impl->permissions, id, struct permission))
|
||||
return NULL;
|
||||
|
||||
p = pw_array_get_unchecked(&impl->permissions, global->id, struct permission);
|
||||
p = pw_array_get_unchecked(&impl->permissions, id, struct permission);
|
||||
if (p->permissions == -1)
|
||||
return NULL;
|
||||
else
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct permission *ensure_permissions(struct pw_client *client, uint32_t id)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||
struct permission *p;
|
||||
size_t len, i;
|
||||
|
||||
len = pw_array_get_len(&impl->permissions, struct permission);
|
||||
if (len <= id) {
|
||||
size_t diff = id - len + 1;
|
||||
|
||||
p = pw_array_add(&impl->permissions, diff * sizeof(struct permission));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < diff; i++)
|
||||
p[i].permissions = -1;
|
||||
}
|
||||
p = pw_array_get_unchecked(&impl->permissions, id, struct permission);
|
||||
return p;
|
||||
}
|
||||
|
||||
/** \endcond */
|
||||
|
||||
static uint32_t
|
||||
|
|
@ -71,13 +92,111 @@ client_permission_func(struct pw_global *global,
|
|||
struct impl *impl = data;
|
||||
struct permission *p;
|
||||
|
||||
p = find_permission(client, global);
|
||||
p = find_permission(client, global->id);
|
||||
if (p == NULL)
|
||||
return impl->permissions_default;
|
||||
else
|
||||
return p->permissions;
|
||||
}
|
||||
|
||||
static uint32_t parse_mask(const char *str)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
|
||||
while (*str != '\0') {
|
||||
switch (*str++) {
|
||||
case 'r':
|
||||
mask |= PW_PERM_R;
|
||||
break;
|
||||
case 'w':
|
||||
mask |= PW_PERM_W;
|
||||
break;
|
||||
case 'x':
|
||||
mask |= PW_PERM_X;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void client_error(void *object, uint32_t id, int res, const char *error)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct resource_data *data = pw_resource_get_user_data(resource);
|
||||
struct pw_client *client = data->client;
|
||||
pw_resource_error(client->core_resource, id, res, error);
|
||||
}
|
||||
|
||||
static void client_get_permissions(void *object)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct resource_data *data = pw_resource_get_user_data(resource);
|
||||
struct pw_client *client = data->client;
|
||||
}
|
||||
|
||||
static void client_update_permissions(void *object, const struct spa_dict *props)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct resource_data *data = pw_resource_get_user_data(resource);
|
||||
struct pw_client *client = data->client;
|
||||
struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||
const char *str;
|
||||
int i, len;
|
||||
|
||||
for (i = 0; i < props->n_items; i++) {
|
||||
str = props->items[i].value;
|
||||
|
||||
pw_log_debug("client %p: %s %s", client, props->items[i].key, str);
|
||||
|
||||
if (strcmp(props->items[i].key, PW_CORE_PROXY_PERMISSIONS_DEFAULT) == 0) {
|
||||
impl->permissions_default = parse_mask(str);
|
||||
pw_log_debug("client %p: set default permissions to %08x",
|
||||
client, impl->permissions_default);
|
||||
}
|
||||
else if (strcmp(props->items[i].key, PW_CORE_PROXY_PERMISSIONS_GLOBAL) == 0) {
|
||||
struct pw_global *global;
|
||||
uint32_t global_id, old_perm, new_perm;
|
||||
struct permission *p;
|
||||
|
||||
/* permissions.update=<global-id>:[r][w][x] */
|
||||
len = strcspn(str, ":");
|
||||
if (len == 0)
|
||||
continue;
|
||||
|
||||
global_id = atoi(str);
|
||||
global = pw_core_find_global(client->core, global_id);
|
||||
if (global == NULL) {
|
||||
pw_log_warn("client %p: invalid global %d", client, global_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
p = ensure_permissions(client, global_id);
|
||||
old_perm = p->permissions == -1 ? impl->permissions_default : p->permissions;
|
||||
new_perm = parse_mask(str + len);
|
||||
|
||||
pw_log_debug("client %p: %08x %08x", client, old_perm, new_perm);
|
||||
|
||||
p->permissions = new_perm;
|
||||
|
||||
if (PW_PERM_IS_R(old_perm) && !PW_PERM_IS_R(new_perm)) {
|
||||
pw_global_revoke(global, client);
|
||||
}
|
||||
else if (!PW_PERM_IS_R(old_perm) && PW_PERM_IS_R(new_perm)) {
|
||||
pw_global_grant(global, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (impl->permissions_default != 0)
|
||||
pw_client_set_busy(client, false);
|
||||
}
|
||||
|
||||
static const struct pw_client_proxy_methods client_methods = {
|
||||
PW_VERSION_CLIENT_PROXY_METHODS,
|
||||
.error = client_error,
|
||||
.get_permissions = client_get_permissions,
|
||||
.update_permissions = client_update_permissions
|
||||
};
|
||||
|
||||
static void client_unbind_func(void *data)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
|
|
@ -89,7 +208,6 @@ static const struct pw_resource_events resource_events = {
|
|||
.destroy = client_unbind_func,
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
|
|
@ -131,7 +249,7 @@ core_global_removed(void *data, struct pw_global *global)
|
|||
struct pw_client *client = &impl->this;
|
||||
struct permission *p;
|
||||
|
||||
p = find_permission(client, global);
|
||||
p = find_permission(client, global->id);
|
||||
pw_log_debug("client %p: global %d removed, %p", client, global->id, p);
|
||||
if (p != NULL)
|
||||
p->permissions = -1;
|
||||
|
|
@ -385,21 +503,10 @@ static int do_permissions(void *data, struct pw_global *global)
|
|||
struct pw_client *client = update->client;
|
||||
struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||
struct permission *p;
|
||||
size_t len, i;
|
||||
|
||||
len = pw_array_get_len(&impl->permissions, struct permission);
|
||||
if (len <= global->id) {
|
||||
size_t diff = global->id - len + 1;
|
||||
|
||||
p = pw_array_add(&impl->permissions, diff * sizeof(struct permission));
|
||||
p = ensure_permissions(client, global->id);
|
||||
if (p == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < diff; i++)
|
||||
p[i].permissions = -1;
|
||||
}
|
||||
|
||||
p = pw_array_get_unchecked(&impl->permissions, global->id, struct permission);
|
||||
if (p->permissions == -1)
|
||||
p->permissions = impl->permissions_default;
|
||||
else if (update->only_new)
|
||||
|
|
@ -411,26 +518,6 @@ static int do_permissions(void *data, struct pw_global *global)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t parse_mask(const char *str)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
|
||||
while (*str != '\0') {
|
||||
switch (*str++) {
|
||||
case 'r':
|
||||
mask |= PW_PERM_R;
|
||||
break;
|
||||
case 'w':
|
||||
mask |= PW_PERM_W;
|
||||
break;
|
||||
case 'x':
|
||||
mask |= PW_PERM_X;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
int pw_client_update_permissions(struct pw_client *client, const struct spa_dict *dict)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||
|
|
@ -500,3 +587,11 @@ void pw_client_set_busy(struct pw_client *client, bool busy)
|
|||
pw_client_events_busy_changed(client, busy);
|
||||
}
|
||||
}
|
||||
|
||||
void pw_client_set_permissions(struct pw_client *client, uint32_t permissions)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||
pw_log_debug("client %p: permissions %08x", client, permissions);
|
||||
impl->permissions_default = permissions;
|
||||
pw_client_set_busy(client, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ void pw_client_add_listener(struct pw_client *client,
|
|||
* started and no further processing is allowed to happen for the client */
|
||||
void pw_client_set_busy(struct pw_client *client, bool busy);
|
||||
|
||||
void pw_client_set_permissions(struct pw_client *client, uint32_t permissions);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -678,7 +678,8 @@ pw_factory_proxy_add_listener(struct pw_factory_proxy *factory,
|
|||
#define PW_VERSION_CLIENT 0
|
||||
|
||||
#define PW_CLIENT_PROXY_EVENT_INFO 0
|
||||
#define PW_CLIENT_PROXY_EVENT_NUM 1
|
||||
#define PW_CLIENT_PROXY_EVENT_PERMISSIONS 1
|
||||
#define PW_CLIENT_PROXY_EVENT_NUM 2
|
||||
|
||||
/** Client events */
|
||||
struct pw_client_proxy_events {
|
||||
|
|
@ -690,6 +691,14 @@ struct pw_client_proxy_events {
|
|||
* \param info info about the client
|
||||
*/
|
||||
void (*info) (void *object, struct pw_client_info *info);
|
||||
/**
|
||||
* Notify a client permission
|
||||
*
|
||||
* Event emited as a result of the get_permissions method.
|
||||
*
|
||||
* \param param the parameter
|
||||
*/
|
||||
void (*permissions) (void *object, const struct spa_dict *dict);
|
||||
};
|
||||
|
||||
/** Client */
|
||||
|
|
@ -703,7 +712,59 @@ pw_client_proxy_add_listener(struct pw_client_proxy *client,
|
|||
}
|
||||
|
||||
#define pw_client_resource_info(r,...) pw_resource_notify(r,struct pw_client_proxy_events,info,__VA_ARGS__)
|
||||
#define pw_client_resource_permissions(r,...) pw_resource_notify(r,struct pw_client_proxy_events,permissions,__VA_ARGS__)
|
||||
|
||||
#define PW_CLIENT_PROXY_METHOD_ERROR 0
|
||||
#define PW_CLIENT_PROXY_METHOD_GET_PERMISSIONS 1
|
||||
#define PW_CLIENT_PROXY_METHOD_UPDATE_PERMISSIONS 2
|
||||
#define PW_CLIENT_PROXY_METHOD_NUM 3
|
||||
|
||||
/** Client methods */
|
||||
struct pw_client_proxy_methods {
|
||||
#define PW_VERSION_CLIENT_PROXY_METHODS 0
|
||||
uint32_t version;
|
||||
|
||||
/**
|
||||
* Send an error to a client
|
||||
*
|
||||
* \param id the global id to report the error on
|
||||
* \param res an errno style error code
|
||||
* \param error an error string
|
||||
*/
|
||||
void (*error) (void *object, uint32_t id, int res, const char *error);
|
||||
/**
|
||||
* Get client permissions
|
||||
*
|
||||
* A permissions event will be emited with the permissions.
|
||||
*/
|
||||
void (*get_permissions) (void *object);
|
||||
|
||||
/**
|
||||
* Update client permissions
|
||||
*
|
||||
* \param dict list of permissions to update
|
||||
*/
|
||||
void (*update_permissions) (void *object, const struct spa_dict *dict);
|
||||
};
|
||||
|
||||
/** Client permissions */
|
||||
static inline void
|
||||
pw_client_proxy_error(struct pw_client_proxy *client, uint32_t id, int res, const char *error)
|
||||
{
|
||||
pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, error, id, res, error);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pw_client_proxy_get_permissions(struct pw_client_proxy *client)
|
||||
{
|
||||
pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, get_permissions);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pw_client_proxy_update_permissions(struct pw_client_proxy *client, const struct spa_dict *dict)
|
||||
{
|
||||
pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, update_permissions, dict);
|
||||
}
|
||||
|
||||
#define PW_VERSION_LINK 0
|
||||
|
||||
|
|
|
|||
|
|
@ -230,8 +230,9 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
if (current == NULL || spa_pod_compare(current, format) != 0) {
|
||||
pw_log_debug("link %p: output format change, renegotiate", this);
|
||||
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG)) {
|
||||
spa_debug_format(2, NULL, current);
|
||||
spa_debug_format(2, NULL, format);
|
||||
if (current)
|
||||
spa_debug_pod(2, NULL, current);
|
||||
spa_debug_pod(2, NULL, format);
|
||||
}
|
||||
pw_node_set_state(output->node, PW_NODE_STATE_SUSPENDED);
|
||||
out_state = PW_PORT_STATE_CONFIGURE;
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ static bool do_create_link(struct data *data, const char *cmd, char *args, char
|
|||
static bool do_export_node(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_node_params(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_port_params(struct data *data, const char *cmd, char *args, char **error);
|
||||
static bool do_permissions(struct data *data, const char *cmd, char *args, char **error);
|
||||
|
||||
static struct command command_list[] = {
|
||||
{ "help", "Show this help", do_help },
|
||||
|
|
@ -194,6 +195,7 @@ static struct command command_list[] = {
|
|||
{ "export-node", "Export a local node to the current remote. <node-id> [remote-var]", do_export_node },
|
||||
{ "node-params", "Enumerate params of a node <node-id> [<param-id-name>]", do_node_params },
|
||||
{ "port-params", "Enumerate params of a port <port-id> [<param-id-name>]", do_port_params },
|
||||
{ "permissions", "Set permissions for a client <client-id> <permissions>", do_permissions },
|
||||
};
|
||||
|
||||
static bool do_help(struct data *data, const char *cmd, char *args, char **error)
|
||||
|
|
@ -1133,10 +1135,10 @@ static bool do_port_params(struct data *data, const char *cmd, char *args, char
|
|||
asprintf(error, "%s <object-id> [<param-id-name>]", cmd);
|
||||
return false;
|
||||
}
|
||||
if (n == 2)
|
||||
if (n < 2)
|
||||
param_id = SPA_PARAM_List;
|
||||
else
|
||||
param_id = SPA_PARAM_List;
|
||||
param_id = atoi(a[1]);
|
||||
|
||||
id = atoi(a[0]);
|
||||
global = pw_map_lookup(&rd->globals, id);
|
||||
|
|
@ -1159,6 +1161,43 @@ static bool do_port_params(struct data *data, const char *cmd, char *args, char
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool do_permissions(struct data *data, const char *cmd, char *args, char **error)
|
||||
{
|
||||
struct remote_data *rd = data->current;
|
||||
char *a[2];
|
||||
int n;
|
||||
uint32_t id;
|
||||
struct global *global;
|
||||
struct spa_dict_item items[1];
|
||||
|
||||
n = pw_split_ip(args, WHITESPACE, 2, a);
|
||||
if (n < 2) {
|
||||
asprintf(error, "%s <client-id> <permission>", cmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
id = atoi(a[0]);
|
||||
global = pw_map_lookup(&rd->globals, id);
|
||||
if (global == NULL) {
|
||||
asprintf(error, "%s: unknown global %d", cmd, id);
|
||||
return false;
|
||||
}
|
||||
if (global->type != PW_TYPE_INTERFACE_Client) {
|
||||
asprintf(error, "object %d is not a client", atoi(a[0]));
|
||||
return false;
|
||||
}
|
||||
if (global->proxy == NULL) {
|
||||
if (!bind_global(rd, global, error))
|
||||
return false;
|
||||
}
|
||||
|
||||
items[0] = SPA_DICT_ITEM_INIT(PW_CORE_PROXY_PERMISSIONS_GLOBAL, a[1]);
|
||||
pw_client_proxy_update_permissions((struct pw_client_proxy*)global->proxy,
|
||||
&SPA_DICT_INIT(items, 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse(struct data *data, char *buf, size_t size, char **error)
|
||||
{
|
||||
char *a[2];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue