diff --git a/src/extensions/protocol-native.h b/src/extensions/protocol-native.h index 3a690662b..5f7182126 100644 --- a/src/extensions/protocol-native.h +++ b/src/extensions/protocol-native.h @@ -35,8 +35,18 @@ extern "C" { #define PW_TYPE_INFO_PROTOCOL_Native PW_TYPE_INFO_PROTOCOL_BASE "Native" +struct pw_protocol_native_message { + uint32_t id; + uint32_t opcode; + void *data; + uint32_t size; + uint32_t n_fds; + int *fds; + int seq; +}; + struct pw_protocol_native_demarshal { - int (*func) (void *object, void *data, size_t size); + int (*func) (void *object, const struct pw_protocol_native_message *msg); uint32_t permissions; }; @@ -46,7 +56,7 @@ struct pw_protocol_native_ext { uint32_t version; struct spa_pod_builder * (*begin_proxy) (struct pw_proxy *proxy, - uint8_t opcode, int *res); + uint8_t opcode, struct pw_protocol_native_message **msg); uint32_t (*add_proxy_fd) (struct pw_proxy *proxy, int fd); int (*get_proxy_fd) (struct pw_proxy *proxy, uint32_t index); @@ -55,7 +65,7 @@ struct pw_protocol_native_ext { struct spa_pod_builder *builder); struct spa_pod_builder * (*begin_resource) (struct pw_resource *resource, - uint8_t opcode, int *res); + uint8_t opcode, struct pw_protocol_native_message **msg); uint32_t (*add_resource_fd) (struct pw_resource *resource, int fd); int (*get_resource_fd) (struct pw_resource *resource, uint32_t index); diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index af4f70f69..81f238c65 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -216,14 +216,14 @@ static int client_node_marshal_event_method(void *object, struct spa_event *even return pw_protocol_native_end_proxy(proxy, b); } -static int client_node_demarshal_add_mem(void *object, void *data, size_t size) +static int client_node_demarshal_add_mem(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t mem_id, type, memfd_idx, flags; int memfd; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&mem_id), SPA_POD_Id(&type), @@ -240,14 +240,14 @@ static int client_node_demarshal_add_mem(void *object, void *data, size_t size) return 0; } -static int client_node_demarshal_transport(void *object, void *data, size_t size) +static int client_node_demarshal_transport(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t node_id, ridx, widx; int readfd, writefd; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&node_id), SPA_POD_Int(&ridx), @@ -265,14 +265,14 @@ static int client_node_demarshal_transport(void *object, void *data, size_t size return 0; } -static int client_node_demarshal_set_param(void *object, void *data, size_t size) +static int client_node_demarshal_set_param(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t id, flags; const struct spa_pod *param = NULL; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Id(&id), SPA_POD_Int(&flags), @@ -283,13 +283,13 @@ static int client_node_demarshal_set_param(void *object, void *data, size_t size return 0; } -static int client_node_demarshal_event_event(void *object, void *data, size_t size) +static int client_node_demarshal_event_event(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; const struct spa_event *event; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_PodObject(&event)) < 0) return -EINVAL; @@ -298,13 +298,13 @@ static int client_node_demarshal_event_event(void *object, void *data, size_t si return 0; } -static int client_node_demarshal_command(void *object, void *data, size_t size) +static int client_node_demarshal_command(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; const struct spa_command *command; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_PodObject(&command)) < 0) return -EINVAL; @@ -313,7 +313,7 @@ static int client_node_demarshal_command(void *object, void *data, size_t size) return 0; } -static int client_node_demarshal_add_port(void *object, void *data, size_t size) +static int client_node_demarshal_add_port(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -322,7 +322,7 @@ static int client_node_demarshal_add_port(void *object, void *data, size_t size) struct spa_dict props; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0) return -EINVAL; @@ -351,13 +351,13 @@ static int client_node_demarshal_add_port(void *object, void *data, size_t size) return 0; } -static int client_node_demarshal_remove_port(void *object, void *data, size_t size) +static int client_node_demarshal_remove_port(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; int32_t direction, port_id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&direction), SPA_POD_Int(&port_id)) < 0) @@ -367,14 +367,14 @@ static int client_node_demarshal_remove_port(void *object, void *data, size_t si return 0; } -static int client_node_demarshal_port_set_param(void *object, void *data, size_t size) +static int client_node_demarshal_port_set_param(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t direction, port_id, id, flags; const struct spa_pod *param = NULL; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&direction), SPA_POD_Int(&port_id), @@ -388,7 +388,7 @@ static int client_node_demarshal_port_set_param(void *object, void *data, size_t return 0; } -static int client_node_demarshal_port_use_buffers(void *object, void *data, size_t size) +static int client_node_demarshal_port_use_buffers(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -397,7 +397,7 @@ static int client_node_demarshal_port_use_buffers(void *object, void *data, size struct pw_client_node_buffer *buffers; uint32_t i, j; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&direction), @@ -453,13 +453,13 @@ static int client_node_demarshal_port_use_buffers(void *object, void *data, size return 0; } -static int client_node_demarshal_port_set_io(void *object, void *data, size_t size) +static int client_node_demarshal_port_set_io(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t direction, port_id, mix_id, id, memid, off, sz; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&direction), SPA_POD_Int(&port_id), @@ -477,14 +477,14 @@ static int client_node_demarshal_port_set_io(void *object, void *data, size_t si return 0; } -static int client_node_demarshal_set_activation(void *object, void *data, size_t size) +static int client_node_demarshal_set_activation(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t node_id, sigidx, memid, off, sz; int signalfd; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&node_id), SPA_POD_Int(&sigidx), @@ -505,13 +505,13 @@ static int client_node_demarshal_set_activation(void *object, void *data, size_t return 0; } -static int client_node_demarshal_set_io(void *object, void *data, size_t size) +static int client_node_demarshal_set_io(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t id, memid, off, sz; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Id(&id), SPA_POD_Int(&memid), @@ -530,10 +530,11 @@ client_node_marshal_add_mem(void *object, uint32_t type, int memfd, uint32_t flags) { + struct pw_protocol_native_message *msg; struct pw_resource *resource = object; struct spa_pod_builder *b; - b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM, NULL); + b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM, &msg); spa_pod_builder_add_struct(b, SPA_POD_Int(mem_id), @@ -546,10 +547,11 @@ client_node_marshal_add_mem(void *object, static int client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd) { + struct pw_protocol_native_message *msg; struct pw_resource *resource = object; struct spa_pod_builder *b; - b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT, NULL); + b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT, &msg); spa_pod_builder_add_struct(b, SPA_POD_Int(node_id), @@ -751,10 +753,11 @@ client_node_marshal_set_activation(void *object, uint32_t offset, uint32_t size) { + struct pw_protocol_native_message *msg; struct pw_resource *resource = object; struct spa_pod_builder *b; - b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION, NULL); + b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION, &msg); spa_pod_builder_add_struct(b, SPA_POD_Int(node_id), @@ -785,13 +788,13 @@ client_node_marshal_set_io(void *object, return pw_protocol_native_end_resource(resource, b); } -static int client_node_demarshal_get_node(void *object, void *data, size_t size) +static int client_node_demarshal_get_node(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; int32_t version, new_id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&version), SPA_POD_Int(&new_id)) < 0) @@ -801,7 +804,7 @@ static int client_node_demarshal_get_node(void *object, void *data, size_t size) version, new_id); } -static int client_node_demarshal_update(void *object, void *data, size_t size) +static int client_node_demarshal_update(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -813,7 +816,7 @@ static int client_node_demarshal_update(void *object, void *data, size_t size) struct spa_dict props; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&change_mask), @@ -881,7 +884,7 @@ static int client_node_demarshal_update(void *object, void *data, size_t size) return 0; } -static int client_node_demarshal_port_update(void *object, void *data, size_t size) +static int client_node_demarshal_port_update(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -892,7 +895,7 @@ static int client_node_demarshal_port_update(void *object, void *data, size_t si struct spa_pod *ipod; struct spa_dict props; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&direction), @@ -965,13 +968,13 @@ static int client_node_demarshal_port_update(void *object, void *data, size_t si return 0; } -static int client_node_demarshal_set_active(void *object, void *data, size_t size) +static int client_node_demarshal_set_active(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; int active; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Bool(&active)) < 0) return -EINVAL; @@ -980,13 +983,13 @@ static int client_node_demarshal_set_active(void *object, void *data, size_t siz return 0; } -static int client_node_demarshal_event_method(void *object, void *data, size_t size) +static int client_node_demarshal_event_method(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; struct spa_event *event; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_PodObject(&event)) < 0) return -EINVAL; diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index 08472903f..61c89b24d 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -114,9 +114,7 @@ process_messages(struct client_data *data) struct pw_protocol_native_connection *conn = data->connection; struct pw_client *client = data->client; struct pw_core *core = client->core; - uint8_t opcode; - uint32_t id, size; - void *message; + const struct pw_protocol_native_message *msg; struct pw_resource *resource; core->current_client = client; @@ -127,50 +125,49 @@ process_messages(struct client_data *data) const struct pw_protocol_native_demarshal *demarshal; const struct pw_protocol_marshal *marshal; uint32_t permissions, required; - int seq = 0; - if (!pw_protocol_native_connection_get_next(conn, &opcode, &id, &message, &size, &seq)) + if (pw_protocol_native_connection_get_next(conn, &msg) != 1) break; - client->recv_seq = seq; + client->recv_seq = msg->seq; pw_log_trace("protocol-native %p: got message %d from %u", client->protocol, - opcode, id); + msg->opcode, msg->id); if (debug_messages) { - fprintf(stderr, "<<<<<<<<< in: %d %d %d\n", id, opcode, size); - spa_debug_pod(0, NULL, (struct spa_pod *)message); + fprintf(stderr, "<<<<<<<<< in: %d %d %d\n", msg->id, msg->opcode, msg->size); + spa_debug_pod(0, NULL, (struct spa_pod *)msg->data); } - resource = pw_client_find_resource(client, id); + resource = pw_client_find_resource(client, msg->id); if (resource == NULL) { pw_log_error("protocol-native %p: unknown resource %u", - client->protocol, id); + client->protocol, msg->id); pw_resource_error(client->core_resource, - -EINVAL, "unknown resource %u", id); + -EINVAL, "unknown resource %u", msg->id); continue; } marshal = pw_resource_get_marshal(resource); - if (marshal == NULL || opcode >= marshal->n_methods) + if (marshal == NULL || msg->opcode >= marshal->n_methods) goto invalid_method; demarshal = marshal->method_demarshal; - if (!demarshal[opcode].func) + if (!demarshal[msg->opcode].func) goto invalid_message; permissions = pw_resource_get_permissions(resource); - required = demarshal[opcode].permissions | PW_PERM_X; + required = demarshal[msg->opcode].permissions | PW_PERM_X; if ((required & permissions) != required) { pw_log_error("protocol-native %p: method %u on %u requires %08x, have %08x", - client->protocol, opcode, id, required, permissions); + client->protocol, msg->opcode, msg->id, required, permissions); pw_resource_error(resource, - -EACCES, "no permission to call method %u ", opcode, id); + -EACCES, "no permission to call method %u ", msg->opcode, msg->id); continue; } - if (demarshal[opcode].func(resource, message, size) < 0) + if (demarshal[msg->opcode].func(resource, msg) < 0) goto invalid_message; } done: @@ -179,15 +176,15 @@ process_messages(struct client_data *data) invalid_method: pw_log_error("protocol-native %p: invalid method %u on resource %u", - client->protocol, opcode, id); - pw_resource_error(resource, -EINVAL, "invalid method %u", opcode); + client->protocol, msg->opcode, msg->id); + pw_resource_error(resource, -EINVAL, "invalid method %u", msg->opcode); pw_client_destroy(client); goto done; invalid_message: pw_log_error("protocol-native %p: invalid message received %u %u", - client->protocol, id, opcode); - pw_resource_error(resource, -EINVAL, "invalid message %u", opcode); - spa_debug_pod(0, NULL, (struct spa_pod *)message); + client->protocol, msg->id, msg->opcode); + pw_resource_error(resource, -EINVAL, "invalid message %u", msg->opcode); + spa_debug_pod(0, NULL, (struct spa_pod *)msg->data); pw_client_destroy(client); goto done; } @@ -478,51 +475,49 @@ on_remote_data(void *data, int fd, enum spa_io mask) } if (mask & SPA_IO_IN) { - uint8_t opcode; - uint32_t id, size; - void *message; - int seq; + const struct pw_protocol_native_message *msg; while (!impl->disconnecting - && pw_protocol_native_connection_get_next(conn, - &opcode, &id, &message, &size, &seq)) { + && pw_protocol_native_connection_get_next(conn, &msg) == 1) { struct pw_proxy *proxy; const struct pw_protocol_native_demarshal *demarshal; const struct pw_protocol_marshal *marshal; pw_log_trace("protocol-native %p: got message %d from %u seq:%d", - this, opcode, id, seq); + this, msg->opcode, msg->id, msg->seq); - this->recv_seq = seq; + this->recv_seq = msg->seq; if (debug_messages) { - fprintf(stderr, "<<<<<<<<< in: %d %d %d %d\n", id, opcode, size, seq); - spa_debug_pod(0, NULL, (struct spa_pod *)message); + fprintf(stderr, "<<<<<<<<< in: %d %d %d %d\n", + msg->id, msg->opcode, msg->size, msg->seq); + spa_debug_pod(0, NULL, (struct spa_pod *)msg->data); } - proxy = pw_remote_find_proxy(this, id); + proxy = pw_remote_find_proxy(this, msg->id); if (proxy == NULL) { - pw_log_error("protocol-native %p: could not find proxy %u", this, id); + pw_log_error("protocol-native %p: could not find proxy %u", this, msg->id); continue; } marshal = pw_proxy_get_marshal(proxy); - if (marshal == NULL || opcode >= marshal->n_events) { - pw_log_error("protocol-native %p: invalid method %u for %u (%d %d)", this, opcode, - id, opcode, marshal ? marshal->n_events : (uint32_t)-1); + if (marshal == NULL || msg->opcode >= marshal->n_events) { + pw_log_error("protocol-native %p: invalid method %u for %u (%d)", + this, msg->opcode, msg->id, + marshal ? marshal->n_events : (uint32_t)-1); continue; } demarshal = marshal->event_demarshal; - if (!demarshal[opcode].func) { - pw_log_error("protocol-native %p: function %d not implemented on %u", this, - opcode, id); + if (!demarshal[msg->opcode].func) { + pw_log_error("protocol-native %p: function %d not implemented on %u", + this, msg->opcode, msg->id); continue; } - if (demarshal[opcode].func(proxy, message, size) < 0) { - pw_log_error ("protocol-native %p: invalid message received %u for %u", this, - opcode, id); + if (demarshal[msg->opcode].func(proxy, msg) < 0) { + pw_log_error ("protocol-native %p: invalid message received %u for %u", + this, msg->opcode, msg->id); continue; } } @@ -762,10 +757,10 @@ const static struct pw_protocol_implementaton protocol_impl = { }; static struct spa_pod_builder * -impl_ext_begin_proxy(struct pw_proxy *proxy, uint8_t opcode, int *res) +impl_ext_begin_proxy(struct pw_proxy *proxy, uint8_t opcode, struct pw_protocol_native_message **msg) { struct client *impl = SPA_CONTAINER_OF(proxy->remote->conn, struct client, this); - return pw_protocol_native_connection_begin(impl->connection, proxy->id, opcode, res); + return pw_protocol_native_connection_begin(impl->connection, proxy->id, opcode, msg); } static uint32_t impl_ext_add_proxy_fd(struct pw_proxy *proxy, int fd) @@ -789,10 +784,11 @@ static int impl_ext_end_proxy(struct pw_proxy *proxy, } static struct spa_pod_builder * -impl_ext_begin_resource(struct pw_resource *resource, uint8_t opcode, int *res) +impl_ext_begin_resource(struct pw_resource *resource, + uint8_t opcode, struct pw_protocol_native_message **msg) { struct client_data *data = resource->client->user_data; - return pw_protocol_native_connection_begin(data->connection, resource->id, opcode, res); + return pw_protocol_native_connection_begin(data->connection, resource->id, opcode, msg); } static uint32_t impl_ext_add_resource_fd(struct pw_resource *resource, int fd) @@ -815,14 +811,14 @@ static int impl_ext_end_resource(struct pw_resource *resource, } const static struct pw_protocol_native_ext protocol_ext_impl = { PW_VERSION_PROTOCOL_NATIVE_EXT, - impl_ext_begin_proxy, - impl_ext_add_proxy_fd, - impl_ext_get_proxy_fd, - impl_ext_end_proxy, - impl_ext_begin_resource, - impl_ext_add_resource_fd, - impl_ext_get_resource_fd, - impl_ext_end_resource, + .begin_proxy = impl_ext_begin_proxy, + .add_proxy_fd = impl_ext_add_proxy_fd, + .get_proxy_fd = impl_ext_get_proxy_fd, + .end_proxy = impl_ext_end_proxy, + .begin_resource = impl_ext_begin_resource, + .add_resource_fd = impl_ext_add_resource_fd, + .get_resource_fd = impl_ext_get_resource_fd, + .end_resource = impl_ext_end_resource, }; static void module_destroy(void *data) diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c index c3eaaff86..902d3793a 100644 --- a/src/modules/module-protocol-native/connection.c +++ b/src/modules/module-protocol-native/connection.c @@ -52,9 +52,10 @@ struct buffer { int fds[MAX_FDS]; uint32_t n_fds; + uint32_t seq; size_t offset; - void *data; - size_t size; + size_t fds_offset; + struct pw_protocol_native_message msg; bool update; }; @@ -64,10 +65,6 @@ struct impl { struct pw_core *core; struct buffer in, out; - - uint32_t dest_id; - uint8_t opcode; - uint32_t seq; struct spa_pod_builder builder; }; @@ -84,11 +81,12 @@ struct impl { int pw_protocol_native_connection_get_fd(struct pw_protocol_native_connection *conn, uint32_t index) { struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); + struct buffer *buf = &impl->in; - if (index >= impl->in.n_fds) + if (index >= buf->msg.n_fds) return -1; - return impl->in.fds[index]; + return buf->msg.fds[index]; } /** Add an fd to a connection @@ -102,21 +100,23 @@ int pw_protocol_native_connection_get_fd(struct pw_protocol_native_connection *c uint32_t pw_protocol_native_connection_add_fd(struct pw_protocol_native_connection *conn, int fd) { struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); + struct buffer *buf = &impl->out; uint32_t index, i; - for (i = 0; i < impl->out.n_fds; i++) { - if (impl->out.fds[i] == fd) + for (i = 0; i < buf->msg.n_fds; i++) { + if (buf->msg.fds[i] == fd) return i; } - index = impl->out.n_fds; - if (index >= MAX_FDS) { + index = buf->msg.n_fds; + if (index + buf->n_fds >= MAX_FDS) { pw_log_error("connection %p: too many fds", conn); return -1; } - impl->out.fds[index] = fd; - impl->out.n_fds++; + buf->msg.fds[index] = fd; + buf->msg.n_fds++; + pw_log_debug("connection %p: add fd %d at index %d", conn, fd, index); return index; } @@ -139,7 +139,7 @@ static void *connection_ensure_size(struct pw_protocol_native_connection *conn, return (uint8_t *) buf->buffer_data + buf->buffer_size; } -static bool refill_buffer(struct pw_protocol_native_connection *conn, struct buffer *buf) +static int refill_buffer(struct pw_protocol_native_connection *conn, struct buffer *buf) { ssize_t len; struct cmsghdr *cmsg; @@ -163,7 +163,7 @@ static bool refill_buffer(struct pw_protocol_native_connection *conn, struct buf continue; if (errno != EAGAIN || errno != EWOULDBLOCK) goto recv_error; - return false; + return -EAGAIN; } break; } @@ -183,20 +183,20 @@ static bool refill_buffer(struct pw_protocol_native_connection *conn, struct buf pw_log_trace("connection %p: %d read %zd bytes and %d fds", conn, conn->fd, len, n_fds); - return true; + return 0; /* ERRORS */ recv_error: pw_log_error("could not recvmsg on fd %d: %s", conn->fd, strerror(errno)); - return false; + return -errno; } static void clear_buffer(struct buffer *buf) { buf->n_fds = 0; - buf->offset = 0; - buf->size = 0; buf->buffer_size = 0; + buf->offset = 0; + buf->fds_offset = 0; } /** Make a new connection object for the given socket @@ -262,6 +262,44 @@ void pw_protocol_native_connection_destroy(struct pw_protocol_native_connection free(impl); } +static int prepare_packet(struct pw_protocol_native_connection *conn, struct buffer *buf) +{ + uint8_t *data; + size_t size, len; + uint32_t *p; + + data = buf->buffer_data + buf->offset; + size = buf->buffer_size - buf->offset; + + if (size < HDR_SIZE) + return HDR_SIZE; + + p = (uint32_t *) data; + data += HDR_SIZE; + size -= HDR_SIZE; + + buf->msg.id = p[0]; + buf->msg.opcode = p[1] >> 24; + len = p[1] & 0xffffff; + buf->msg.seq = p[2]; + buf->msg.n_fds = p[3]; + buf->msg.fds = &buf->fds[buf->fds_offset]; + + if (size < len) + return len; + + buf->msg.size = len; + buf->msg.data = data; + + buf->offset += HDR_SIZE + len; + buf->fds_offset += buf->msg.n_fds; + + if (buf->offset >= buf->buffer_size) + clear_buffer(buf); + + return 0; +} + /** Move to the next packet in the connection * * \param conn the connection @@ -276,74 +314,28 @@ void pw_protocol_native_connection_destroy(struct pw_protocol_native_connection * * \memberof pw_protocol_native_connection */ -bool +int pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *conn, - uint8_t *opcode, - uint32_t *dest_id, - void **dt, - uint32_t *sz, - int *seq) + const struct pw_protocol_native_message **msg) { struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); - size_t len, size; - uint8_t *data; + size_t len; + int res; struct buffer *buf; - uint32_t *p; buf = &impl->in; - /* move to next packet */ - buf->offset += buf->size; + while (1) { + if ((len = prepare_packet(conn, buf)) == 0) + break; - again: - if (buf->update) { - if (!refill_buffer(conn, buf)) - return false; - buf->update = false; - } - - /* now read packet */ - data = buf->buffer_data; - size = buf->buffer_size; - - if (buf->offset >= size) { - clear_buffer(buf); - buf->update = true; - goto again; - } - - data += buf->offset; - size -= buf->offset; - - if (size < HDR_SIZE) { - if (connection_ensure_size(conn, buf, HDR_SIZE) == NULL) - return false; - buf->update = true; - goto again; - } - p = (uint32_t *) data; - data += HDR_SIZE; - size -= HDR_SIZE; - - *dest_id = p[0]; - *opcode = p[1] >> 24; - len = p[1] & 0xffffff; - *seq = p[2]; - - if (len > size) { if (connection_ensure_size(conn, buf, len) == NULL) - return false; - buf->update = true; - goto again; + return -ENOMEM; + if ((res = refill_buffer(conn, buf)) < 0) + return res; } - buf->size = len; - buf->data = data; - buf->offset += HDR_SIZE; - - *dt = buf->data; - *sz = buf->size; - - return true; + *msg = &buf->msg; + return 1; } static inline void *begin_write(struct pw_protocol_native_connection *conn, uint32_t size) @@ -376,16 +368,22 @@ static const struct spa_pod_builder_callbacks builder_callbacks = { struct spa_pod_builder * pw_protocol_native_connection_begin(struct pw_protocol_native_connection *conn, - uint32_t id, uint8_t opcode, int *res) + uint32_t id, uint8_t opcode, + struct pw_protocol_native_message **msg) { struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); - impl->dest_id = id; - impl->opcode = opcode; + struct buffer *buf = &impl->out; + + buf->msg.id = id; + buf->msg.opcode = opcode; impl->builder = SPA_POD_BUILDER_INIT(NULL, 0); impl->builder.callbacks = &builder_callbacks; impl->builder.callbacks_data = impl; - if (res) - *res = SPA_RESULT_RETURN_ASYNC(impl->seq); + buf->msg.n_fds = 0; + buf->msg.fds = &buf->fds[buf->n_fds]; + buf->msg.seq = buf->seq; + if (msg) + *msg = &buf->msg; return &impl->builder; } @@ -396,29 +394,31 @@ pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn, struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); uint32_t *p, size = builder->state.offset; struct buffer *buf = &impl->out; - uint32_t seq; + int res; if ((p = connection_ensure_size(conn, buf, HDR_SIZE + size)) == NULL) return -ENOMEM; - seq = impl->seq; - impl->seq = (impl->seq + 1) & SPA_ASYNC_SEQ_MASK; - - p[0] = impl->dest_id; - p[1] = (impl->opcode << 24) | (size & 0xffffff); - p[2] = seq; + p[0] = buf->msg.id; + p[1] = (buf->msg.opcode << 24) | (size & 0xffffff); + p[2] = buf->msg.seq; + p[3] = buf->msg.n_fds; buf->buffer_size += HDR_SIZE + size; + buf->n_fds += buf->msg.n_fds; if (debug_messages) { - fprintf(stderr, ">>>>>>>>> out: %d %d %d\n", impl->dest_id, impl->opcode, size); + fprintf(stderr, ">>>>>>>>> out: %d %d %d\n", buf->msg.id, buf->msg.opcode, size); spa_debug_pod(0, NULL, SPA_MEMBER(p, HDR_SIZE, struct spa_pod)); } + buf->seq = (buf->seq + 1) & SPA_ASYNC_SEQ_MASK; + res = SPA_RESULT_RETURN_ASYNC(buf->msg.seq); + spa_hook_list_call(&conn->listener_list, struct pw_protocol_native_connection_events, need_flush, 0); - return SPA_RESULT_RETURN_ASYNC(seq); + return res; } /** Flush the connection object diff --git a/src/modules/module-protocol-native/connection.h b/src/modules/module-protocol-native/connection.h index 14cfd1d76..039e35502 100644 --- a/src/modules/module-protocol-native/connection.h +++ b/src/modules/module-protocol-native/connection.h @@ -32,6 +32,8 @@ extern "C" { #include #include +#include + struct pw_protocol_native_connection_events { #define PW_VERSION_PROTOCOL_NATIVE_CONNECTION_EVENTS 0 uint32_t version; @@ -71,19 +73,17 @@ pw_protocol_native_connection_new(struct pw_core *core, int fd); void pw_protocol_native_connection_destroy(struct pw_protocol_native_connection *conn); -bool +int pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *conn, - uint8_t *opcode, - uint32_t *dest_id, - void **data, uint32_t *size, int *seq); + const struct pw_protocol_native_message **msg); uint32_t pw_protocol_native_connection_add_fd(struct pw_protocol_native_connection *conn, int fd); - int pw_protocol_native_connection_get_fd(struct pw_protocol_native_connection *conn, uint32_t index); struct spa_pod_builder * pw_protocol_native_connection_begin(struct pw_protocol_native_connection *conn, - uint32_t id, uint8_t opcode, int *res); + uint32_t id, uint8_t opcode, + struct pw_protocol_native_message **msg); int pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn, diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index ef98dd793..59b4b3a35 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -47,14 +47,15 @@ static int core_method_marshal_hello(void *object, uint32_t version) static int core_method_marshal_sync(void *object, uint32_t id, int seq) { + struct pw_protocol_native_message *msg; struct pw_proxy *proxy = object; struct spa_pod_builder *b; - b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC, &seq); + b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC, &msg); spa_pod_builder_add_struct(b, SPA_POD_Int(id), - SPA_POD_Int(seq)); + SPA_POD_Int(SPA_RESULT_RETURN_ASYNC(msg->seq))); return pw_protocol_native_end_proxy(proxy, b); } @@ -173,7 +174,7 @@ core_method_marshal_destroy(void *object, uint32_t id) return pw_protocol_native_end_proxy(proxy, b); } -static int core_event_demarshal_info(void *object, void *data, size_t size) +static int core_event_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_dict props; @@ -182,7 +183,7 @@ static int core_event_demarshal_info(void *object, void *data, size_t size) struct spa_pod_parser prs; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0) return -EINVAL; if (spa_pod_parser_get(&prs, @@ -213,13 +214,13 @@ static int core_event_demarshal_info(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_core_proxy_events, info, 0, &info); } -static int core_event_demarshal_done(void *object, void *data, size_t size) +static int core_event_demarshal_done(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t id, seq; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Int(&seq)) < 0) @@ -228,13 +229,13 @@ static int core_event_demarshal_done(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_core_proxy_events, done, 0, id, seq); } -static int core_event_demarshal_ping(void *object, void *data, size_t size) +static int core_event_demarshal_ping(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t id, seq; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Int(&seq)) < 0) @@ -243,7 +244,7 @@ static int core_event_demarshal_ping(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_core_proxy_events, ping, 0, id, seq); } -static int core_event_demarshal_error(void *object, void *data, size_t size) +static int core_event_demarshal_error(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -251,7 +252,7 @@ static int core_event_demarshal_error(void *object, void *data, size_t size) int seq; const char *error; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Int(&seq), @@ -262,13 +263,13 @@ static int core_event_demarshal_error(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_core_proxy_events, error, 0, id, seq, res, error); } -static int core_event_demarshal_remove_id(void *object, void *data, size_t size) +static int core_event_demarshal_remove_id(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id)) < 0) return -EINVAL; @@ -317,12 +318,13 @@ static void core_event_marshal_ping(void *object, uint32_t id, int seq) { struct pw_resource *resource = object; struct spa_pod_builder *b; + struct pw_protocol_native_message *msg; - b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_PING, &seq); + b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_PING, &msg); spa_pod_builder_add_struct(b, SPA_POD_Int(id), - SPA_POD_Int(seq)); + SPA_POD_Int(SPA_RESULT_RETURN_ASYNC(msg->seq))); pw_protocol_native_end_resource(resource, b); } @@ -356,13 +358,13 @@ static void core_event_marshal_remove_id(void *object, uint32_t id) pw_protocol_native_end_resource(resource, b); } -static int core_method_demarshal_hello(void *object, void *data, size_t size) +static int core_method_demarshal_hello(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t version; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&version)) < 0) return -EINVAL; @@ -370,13 +372,13 @@ static int core_method_demarshal_hello(void *object, void *data, size_t size) return pw_resource_do(resource, struct pw_core_proxy_methods, hello, 0, version); } -static int core_method_demarshal_sync(void *object, void *data, size_t size) +static int core_method_demarshal_sync(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id, seq; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Int(&seq)) < 0) @@ -385,13 +387,13 @@ static int core_method_demarshal_sync(void *object, void *data, size_t size) return pw_resource_do(resource, struct pw_core_proxy_methods, sync, 0, id, seq); } -static int core_method_demarshal_pong(void *object, void *data, size_t size) +static int core_method_demarshal_pong(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id, seq; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Int(&seq)) < 0) @@ -400,7 +402,7 @@ static int core_method_demarshal_pong(void *object, void *data, size_t size) return pw_resource_do(resource, struct pw_core_proxy_methods, pong, 0, id, seq); } -static int core_method_demarshal_error(void *object, void *data, size_t size) +static int core_method_demarshal_error(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -408,7 +410,7 @@ static int core_method_demarshal_error(void *object, void *data, size_t size) int seq; const char *error; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Int(&seq), @@ -419,13 +421,13 @@ static int core_method_demarshal_error(void *object, void *data, size_t size) return pw_resource_do(resource, struct pw_core_proxy_methods, error, 0, id, seq, res, error); } -static int core_method_demarshal_get_registry(void *object, void *data, size_t size) +static int core_method_demarshal_get_registry(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; int32_t version, new_id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&version), SPA_POD_Int(&new_id)) < 0) @@ -434,7 +436,7 @@ static int core_method_demarshal_get_registry(void *object, void *data, size_t s return pw_resource_do(resource, struct pw_core_proxy_methods, get_registry, 0, version, new_id); } -static int core_method_demarshal_create_object(void *object, void *data, size_t size) +static int core_method_demarshal_create_object(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -443,7 +445,7 @@ static int core_method_demarshal_create_object(void *object, void *data, size_t const char *factory_name; struct spa_dict props; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_String(&factory_name), @@ -475,13 +477,13 @@ static int core_method_demarshal_create_object(void *object, void *data, size_t &props, new_id); } -static int core_method_demarshal_destroy(void *object, void *data, size_t size) +static int core_method_demarshal_destroy(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id)) < 0) return -EINVAL; @@ -524,13 +526,13 @@ static void registry_marshal_global_remove(void *object, uint32_t id) pw_protocol_native_end_resource(resource, b); } -static int registry_demarshal_bind(void *object, void *data, size_t size) +static int registry_demarshal_bind(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id, version, type, new_id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Id(&type), @@ -541,13 +543,13 @@ static int registry_demarshal_bind(void *object, void *data, size_t size) return pw_resource_do(resource, struct pw_registry_proxy_methods, bind, 0, id, type, version, new_id); } -static int registry_demarshal_destroy(void *object, void *data, size_t size) +static int registry_demarshal_destroy(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id)) < 0) return -EINVAL; @@ -577,7 +579,7 @@ static void module_marshal_info(void *object, const struct pw_module_info *info) pw_protocol_native_end_resource(resource, b); } -static int module_demarshal_info(void *object, void *data, size_t size) +static int module_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -586,7 +588,7 @@ static int module_demarshal_info(void *object, void *data, size_t size) struct pw_module_info info; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), @@ -633,7 +635,7 @@ static void device_marshal_info(void *object, const struct pw_device_info *info) pw_protocol_native_end_resource(resource, b); } -static int device_demarshal_info(void *object, void *data, size_t size) +static int device_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -642,7 +644,7 @@ static int device_demarshal_info(void *object, void *data, size_t size) struct pw_device_info info; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), @@ -700,7 +702,7 @@ static void device_marshal_param(void *object, int seq, uint32_t id, uint32_t in pw_protocol_native_end_resource(resource, b); } -static int device_demarshal_param(void *object, void *data, size_t size) +static int device_demarshal_param(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -708,7 +710,7 @@ static int device_demarshal_param(void *object, void *data, size_t size) int seq; struct spa_pod *param; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&seq), SPA_POD_Id(&id), @@ -724,13 +726,14 @@ static int device_demarshal_param(void *object, void *data, size_t size) static int device_marshal_enum_params(void *object, int seq, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { + struct pw_protocol_native_message *msg; struct pw_proxy *proxy = object; struct spa_pod_builder *b; - b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, &seq); + b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, &msg); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), + SPA_POD_Int(SPA_RESULT_RETURN_ASYNC(msg->seq)), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(num), @@ -739,7 +742,7 @@ static int device_marshal_enum_params(void *object, int seq, return pw_protocol_native_end_proxy(proxy, b); } -static int device_demarshal_enum_params(void *object, void *data, size_t size) +static int device_demarshal_enum_params(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -747,7 +750,7 @@ static int device_demarshal_enum_params(void *object, void *data, size_t size) int seq; struct spa_pod *filter; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&seq), SPA_POD_Id(&id), @@ -775,14 +778,14 @@ static int device_marshal_set_param(void *object, uint32_t id, uint32_t flags, return pw_protocol_native_end_proxy(proxy, b); } -static int device_demarshal_set_param(void *object, void *data, size_t size) +static int device_demarshal_set_param(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id, flags; struct spa_pod *param; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Id(&id), SPA_POD_Int(&flags), @@ -814,7 +817,7 @@ static void factory_marshal_info(void *object, const struct pw_factory_info *inf pw_protocol_native_end_resource(resource, b); } -static int factory_demarshal_info(void *object, void *data, size_t size) +static int factory_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -823,7 +826,7 @@ static int factory_demarshal_info(void *object, void *data, size_t size) struct pw_factory_info info; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), @@ -876,7 +879,7 @@ static void node_marshal_info(void *object, const struct pw_node_info *info) pw_protocol_native_end_resource(resource, b); } -static int node_demarshal_info(void *object, void *data, size_t size) +static int node_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -885,7 +888,7 @@ static int node_demarshal_info(void *object, void *data, size_t size) struct pw_node_info info; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), @@ -949,7 +952,7 @@ static void node_marshal_param(void *object, int seq, uint32_t id, pw_protocol_native_end_resource(resource, b); } -static int node_demarshal_param(void *object, void *data, size_t size) +static int node_demarshal_param(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -957,7 +960,7 @@ static int node_demarshal_param(void *object, void *data, size_t size) int seq; struct spa_pod *param; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&seq), SPA_POD_Id(&id), @@ -983,14 +986,14 @@ static int node_marshal_subscribe_params(void *object, uint32_t *ids, uint32_t n return pw_protocol_native_end_proxy(proxy, b); } -static int node_demarshal_subscribe_params(void *object, void *data, size_t size) +static int node_demarshal_subscribe_params(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t csize, ctype, n_ids; uint32_t *ids; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; @@ -1005,13 +1008,14 @@ static int node_demarshal_subscribe_params(void *object, void *data, size_t size static int node_marshal_enum_params(void *object, int seq, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { + struct pw_protocol_native_message *msg; struct pw_proxy *proxy = object; struct spa_pod_builder *b; - b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, &seq); + b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, &msg); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), + SPA_POD_Int(SPA_RESULT_RETURN_ASYNC(msg->seq)), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(num), @@ -1020,7 +1024,7 @@ static int node_marshal_enum_params(void *object, int seq, uint32_t id, return pw_protocol_native_end_proxy(proxy, b); } -static int node_demarshal_enum_params(void *object, void *data, size_t size) +static int node_demarshal_enum_params(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -1028,7 +1032,7 @@ static int node_demarshal_enum_params(void *object, void *data, size_t size) int seq; struct spa_pod *filter; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&seq), SPA_POD_Id(&id), @@ -1056,14 +1060,14 @@ static int node_marshal_set_param(void *object, uint32_t id, uint32_t flags, return pw_protocol_native_end_proxy(proxy, b); } -static int node_demarshal_set_param(void *object, void *data, size_t size) +static int node_demarshal_set_param(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id, flags; struct spa_pod *param; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Id(&id), SPA_POD_Int(&flags), @@ -1084,13 +1088,13 @@ static int node_marshal_send_command(void *object, const struct spa_command *com return pw_protocol_native_end_proxy(proxy, b); } -static int node_demarshal_send_command(void *object, void *data, size_t size) +static int node_demarshal_send_command(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; struct spa_command *command; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Pod(&command)) < 0) return -EINVAL; @@ -1119,7 +1123,7 @@ static void port_marshal_info(void *object, const struct pw_port_info *info) pw_protocol_native_end_resource(resource, b); } -static int port_demarshal_info(void *object, void *data, size_t size) +static int port_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -1128,7 +1132,7 @@ static int port_demarshal_info(void *object, void *data, size_t size) struct pw_port_info info; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), @@ -1185,7 +1189,7 @@ static void port_marshal_param(void *object, int seq, uint32_t id, pw_protocol_native_end_resource(resource, b); } -static int port_demarshal_param(void *object, void *data, size_t size) +static int port_demarshal_param(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -1193,7 +1197,7 @@ static int port_demarshal_param(void *object, void *data, size_t size) int seq; struct spa_pod *param; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&seq), SPA_POD_Id(&id), @@ -1219,14 +1223,14 @@ static int port_marshal_subscribe_params(void *object, uint32_t *ids, uint32_t n return pw_protocol_native_end_proxy(proxy, b); } -static int port_demarshal_subscribe_params(void *object, void *data, size_t size) +static int port_demarshal_subscribe_params(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t csize, ctype, n_ids; uint32_t *ids; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; @@ -1241,13 +1245,14 @@ static int port_demarshal_subscribe_params(void *object, void *data, size_t size static int port_marshal_enum_params(void *object, int seq, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { + struct pw_protocol_native_message *msg; struct pw_proxy *proxy = object; struct spa_pod_builder *b; - b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, &seq); + b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, &msg); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), + SPA_POD_Int(SPA_RESULT_RETURN_ASYNC(msg->seq)), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(num), @@ -1256,7 +1261,7 @@ static int port_marshal_enum_params(void *object, int seq, uint32_t id, return pw_protocol_native_end_proxy(proxy, b); } -static int port_demarshal_enum_params(void *object, void *data, size_t size) +static int port_demarshal_enum_params(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -1264,7 +1269,7 @@ static int port_demarshal_enum_params(void *object, void *data, size_t size) int seq; struct spa_pod *filter; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&seq), SPA_POD_Id(&id), @@ -1296,7 +1301,7 @@ static void client_marshal_info(void *object, const struct pw_client_info *info) pw_protocol_native_end_resource(resource, b); } -static int client_demarshal_info(void *object, void *data, size_t size) +static int client_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -1305,7 +1310,7 @@ static int client_demarshal_info(void *object, void *data, size_t size) struct pw_client_info info; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), @@ -1360,7 +1365,7 @@ static void client_marshal_permissions(void *object, uint32_t index, uint32_t n_ pw_protocol_native_end_resource(resource, b); } -static int client_demarshal_permissions(void *object, void *data, size_t size) +static int client_demarshal_permissions(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct pw_permission *permissions; @@ -1368,7 +1373,7 @@ static int client_demarshal_permissions(void *object, void *data, size_t size) struct spa_pod_frame f[2]; uint32_t i, index, n_permissions; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&index), NULL) < 0) @@ -1402,14 +1407,14 @@ static int client_marshal_error(void *object, uint32_t id, int res, const char * return pw_protocol_native_end_proxy(proxy, b); } -static int client_demarshal_error(void *object, void *data, size_t size) +static int client_demarshal_error(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t id, res; const char *error; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id), SPA_POD_Int(&res), @@ -1448,7 +1453,7 @@ static int client_marshal_update_properties(void *object, const struct spa_dict return pw_protocol_native_end_proxy(proxy, b); } -static int client_demarshal_update_properties(void *object, void *data, size_t size) +static int client_demarshal_update_properties(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_dict props; @@ -1456,7 +1461,7 @@ static int client_demarshal_update_properties(void *object, void *data, size_t s struct spa_pod_frame f[2]; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_push_struct(&prs, &f[1]) < 0 || spa_pod_parser_get(&prs, @@ -1474,13 +1479,13 @@ static int client_demarshal_update_properties(void *object, void *data, size_t s &props); } -static int client_demarshal_get_permissions(void *object, void *data, size_t size) +static int client_demarshal_get_permissions(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct spa_pod_parser prs; uint32_t index, num; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&index), SPA_POD_Int(&num)) < 0) @@ -1510,7 +1515,7 @@ static int client_marshal_update_permissions(void *object, uint32_t n_permission return pw_protocol_native_end_proxy(proxy, b); } -static int client_demarshal_update_permissions(void *object, void *data, size_t size) +static int client_demarshal_update_permissions(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct pw_permission *permissions; @@ -1518,7 +1523,7 @@ static int client_demarshal_update_permissions(void *object, void *data, size_t struct spa_pod_frame f[1]; uint32_t i, n_permissions; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&n_permissions), NULL) < 0) @@ -1561,7 +1566,7 @@ static void link_marshal_info(void *object, const struct pw_link_info *info) pw_protocol_native_end_resource(resource, b); } -static int link_demarshal_info(void *object, void *data, size_t size) +static int link_demarshal_info(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -1570,7 +1575,7 @@ static int link_demarshal_info(void *object, void *data, size_t size) struct pw_link_info info = { 0, }; uint32_t i; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), @@ -1600,7 +1605,7 @@ static int link_demarshal_info(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_link_proxy_events, info, 0, &info); } -static int registry_demarshal_global(void *object, void *data, size_t size) +static int registry_demarshal_global(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -1608,7 +1613,7 @@ static int registry_demarshal_global(void *object, void *data, size_t size) uint32_t id, parent_id, permissions, type, version, i; struct spa_dict props; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&id), @@ -1636,13 +1641,13 @@ static int registry_demarshal_global(void *object, void *data, size_t size) props.n_items > 0 ? &props : NULL); } -static int registry_demarshal_global_remove(void *object, void *data, size_t size) +static int registry_demarshal_global_remove(void *object, const struct pw_protocol_native_message *msg) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; uint32_t id; - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id)) < 0) return -EINVAL; diff --git a/src/modules/module-protocol-native/test-connection.c b/src/modules/module-protocol-native/test-connection.c index 2f76d69a7..7113aaf1b 100644 --- a/src/modules/module-protocol-native/test-connection.c +++ b/src/modules/module-protocol-native/test-connection.c @@ -30,14 +30,12 @@ static void test_create(struct pw_protocol_native_connection *conn) { - uint8_t opcode; - uint32_t dest_id, size; - void *data; - int res, seq; + const struct pw_protocol_native_message *msg; + int res; - res = pw_protocol_native_connection_get_next(conn, - &opcode, &dest_id, &data, &size, &seq); - spa_assert(res == false); + res = pw_protocol_native_connection_get_next(conn, &msg); + spa_assert(res != 1); + spa_assert(msg != NULL); res = pw_protocol_native_connection_get_fd(conn, 0); spa_assert(res == -1); @@ -51,12 +49,15 @@ static void test_create(struct pw_protocol_native_connection *conn) static void write_message(struct pw_protocol_native_connection *conn, int fd) { + struct pw_protocol_native_message *msg; struct spa_pod_builder *b; int seq = -1, res; - b = pw_protocol_native_connection_begin(conn, 1, 5, &seq); + b = pw_protocol_native_connection_begin(conn, 1, 5, &msg); spa_assert(b != NULL); - spa_assert(seq != -1); + spa_assert(msg->seq != -1); + + seq = SPA_RESULT_RETURN_ASYNC(msg->seq); spa_pod_builder_add_struct(b, SPA_POD_Int(42), @@ -70,23 +71,20 @@ static void write_message(struct pw_protocol_native_connection *conn, int fd) static int read_message(struct pw_protocol_native_connection *conn) { struct spa_pod_parser prs; - uint8_t opcode; - uint32_t dest_id, size; - void *data; - int res, seq, fd; + const struct pw_protocol_native_message *msg; + int res, fd; uint32_t v_int, v_id, fdidx; - res = pw_protocol_native_connection_get_next(conn, - &opcode, &dest_id, &data, &size, &seq); - if (!res) + res = pw_protocol_native_connection_get_next(conn, &msg); + if (res != 1) return -1; - spa_assert(opcode == 5); - spa_assert(dest_id == 1); - spa_assert(data != NULL); - spa_assert(size > 0); + spa_assert(msg->opcode == 5); + spa_assert(msg->id == 1); + spa_assert(msg->data != NULL); + spa_assert(msg->size > 0); - spa_pod_parser_init(&prs, data, size); + spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&v_int), SPA_POD_Id(&v_id), @@ -94,7 +92,7 @@ static int read_message(struct pw_protocol_native_connection *conn) spa_assert_not_reached(); fd = pw_protocol_native_connection_get_fd(conn, fdidx); - pw_log_debug("got fd %d", fd); + pw_log_debug("got fd %d %d", fdidx, fd); spa_assert(fd != -1); return 0; }