diff --git a/pinos/client/context.c b/pinos/client/context.c index 2dc38f4d2..380fcaea5 100644 --- a/pinos/client/context.c +++ b/pinos/client/context.c @@ -26,6 +26,7 @@ #include "pinos/client/pinos.h" #include "pinos/client/context.h" +#include "pinos/client/protocol-native.h" #include "pinos/client/connection.h" #include "pinos/client/subscribe.h" @@ -93,146 +94,6 @@ context_set_state (PinosContext *context, } } -typedef void (*MarshallFunc) (void *object, void *data, size_t size); - -static void -core_interface_client_update (void *object, - const SpaDict *props) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageClientUpdate m = { props }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_CLIENT_UPDATE, - &m); - pinos_connection_flush (impl->connection); -} - -static void -core_interface_sync (void *object, - uint32_t seq) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageSync m = { seq }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_SYNC, - &m); - pinos_connection_flush (impl->connection); -} - -static void -core_interface_get_registry (void *object, - uint32_t seq, - uint32_t new_id) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageGetRegistry m = { seq, new_id }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_GET_REGISTRY, - &m); - pinos_connection_flush (impl->connection); -} - -static void -core_interface_create_node (void *object, - uint32_t seq, - const char *factory_name, - const char *name, - const SpaDict *props, - uint32_t new_id) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageCreateNode m = { seq, factory_name, name, props, new_id }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_CREATE_NODE, - &m); - pinos_connection_flush (impl->connection); -} - -static void -core_interface_create_client_node (void *object, - uint32_t seq, - const char *name, - const SpaDict *props, - uint32_t new_id) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageCreateClientNode m = { seq, name, props, new_id }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_CREATE_CLIENT_NODE, - &m); - pinos_connection_flush (impl->connection); -} - -static const PinosCoreInterface core_interface = { - &core_interface_client_update, - &core_interface_sync, - &core_interface_get_registry, - &core_interface_create_node, - &core_interface_create_client_node -}; - -static void -core_marshall_info (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageCoreInfo *m = data; - pinos_core_notify_info (proxy, m->info); -} - -static void -core_marshall_done (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageNotifyDone *m = data; - pinos_core_notify_done (proxy, m->seq); -} - -static void -core_marshall_error (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageError *m = data; - pinos_core_notify_error (proxy, m->id, m->res, m->error); -} - -static void -core_marshall_remove_id (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageRemoveId *m = data; - pinos_core_notify_remove_id (proxy, m->id); -} - -static const MarshallFunc core_marshall[] = { - [PINOS_MESSAGE_CORE_INFO] = &core_marshall_info, - [PINOS_MESSAGE_NOTIFY_DONE] = &core_marshall_done, - [PINOS_MESSAGE_ERROR] = &core_marshall_error, - [PINOS_MESSAGE_REMOVE_ID] = &core_marshall_remove_id, -}; - static void core_event_info (void *object, PinosCoreInfo *info) @@ -304,20 +165,6 @@ static const PinosCoreEvent core_events = { &core_event_remove_id }; -static void -module_marshall_info (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageModuleInfo *m = data; - pinos_module_notify_info (proxy, m->info); -} - -static const MarshallFunc module_marshall[] = { - [PINOS_MESSAGE_MODULE_INFO] = &module_marshall_info, -}; - static void module_event_info (void *object, PinosModuleInfo *info) @@ -346,31 +193,6 @@ static const PinosModuleEvent module_events = { &module_event_info, }; -static void -node_marshall_done (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageCreateNodeDone *m = data; - pinos_node_notify_done (proxy, m->seq); -} - -static void -node_marshall_info (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageNodeInfo *m = data; - pinos_node_notify_info (proxy, m->info); -} - -static const MarshallFunc node_marshall[] = { - [PINOS_MESSAGE_CREATE_NODE_DONE] = &node_marshall_done, - [PINOS_MESSAGE_NODE_INFO] = &node_marshall_info, -}; - static void node_event_done (void *object, uint32_t seq) @@ -406,252 +228,6 @@ static const PinosNodeEvent node_events = { &node_event_info }; -static void -client_node_interface_update (void *object, - uint32_t change_mask, - unsigned int max_input_ports, - unsigned int max_output_ports, - const SpaProps *props) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageNodeUpdate m = { change_mask, max_input_ports, max_output_ports, props }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_NODE_UPDATE, - &m); - pinos_connection_flush (impl->connection); -} - -static void -client_node_interface_port_update (void *object, - SpaDirection direction, - uint32_t port_id, - uint32_t change_mask, - unsigned int n_possible_formats, - SpaFormat **possible_formats, - SpaFormat *format, - const SpaProps *props, - const SpaPortInfo *info) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessagePortUpdate m = { direction, port_id, change_mask, n_possible_formats, - possible_formats, format, props, info }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_PORT_UPDATE, - &m); - pinos_connection_flush (impl->connection); -} - -static void -client_node_interface_state_change (void *object, - SpaNodeState state) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageNodeStateChange m = { state }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_NODE_STATE_CHANGE, - &m); - pinos_connection_flush (impl->connection); -} - -static void -client_node_interface_event (void *object, - SpaNodeEvent *event) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageNodeEvent m = { event }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_NODE_EVENT, - &m); - pinos_connection_flush (impl->connection); -} - -static void -client_node_interface_destroy (void *object, - uint32_t seq) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageDestroy m = { seq }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_DESTROY, - &m); - pinos_connection_flush (impl->connection); -} - -const PinosClientNodeInterface client_node_interface = { - &client_node_interface_update, - &client_node_interface_port_update, - &client_node_interface_state_change, - &client_node_interface_event, - &client_node_interface_destroy -}; - -static void -client_node_mashall_done (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageCreateClientNodeDone *m = data; - pinos_client_node_notify_done (proxy, m->seq, m->datafd); -} - -static void -client_node_mashall_event (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageNodeEvent *m = data; - pinos_client_node_notify_event (proxy, m->event); -} - -static void -client_node_mashall_add_port (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageAddPort *m = data; - pinos_client_node_notify_add_port (proxy, m->seq, m->direction, m->port_id); -} - -static void -client_node_mashall_remove_port (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageRemovePort *m = data; - pinos_client_node_notify_remove_port (proxy, m->seq, m->direction, m->port_id); -} - -static void -client_node_mashall_set_format (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageSetFormat *m = data; - pinos_client_node_notify_set_format (proxy, m->seq, m->direction, m->port_id, - m->flags, m->format); -} - -static void -client_node_mashall_set_property (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageSetProperty *m = data; - pinos_client_node_notify_set_property (proxy, m->seq, m->id, m->size, m->value); -} - -static void -client_node_mashall_add_mem (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageAddMem *m = data; - pinos_client_node_notify_add_mem (proxy, - m->direction, - m->port_id, - m->mem_id, - m->type, - m->memfd, - m->flags, - m->offset, - m->size); -} - -static void -client_node_mashall_use_buffers (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageUseBuffers *m = data; - pinos_client_node_notify_use_buffers (proxy, - m->seq, - m->direction, - m->port_id, - m->n_buffers, - m->buffers); -} - -static void -client_node_mashall_node_command (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageNodeCommand *m = data; - pinos_client_node_notify_node_command (proxy, m->seq, m->command); -} - -static void -client_node_mashall_port_command (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessagePortCommand *m = data; - pinos_client_node_notify_port_command (proxy, m->port_id, m->command); -} - -static void -client_node_mashall_transport (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageTransportUpdate *m = data; - pinos_client_node_notify_transport (proxy, m->memfd, m->offset, m->size); -} - -const MarshallFunc client_node_marshall[] = { - [PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE] = &client_node_mashall_done, - [PINOS_MESSAGE_NODE_EVENT] = &client_node_mashall_event, - [PINOS_MESSAGE_ADD_PORT] = &client_node_mashall_add_port, - [PINOS_MESSAGE_REMOVE_PORT] = &client_node_mashall_remove_port, - [PINOS_MESSAGE_SET_FORMAT] = &client_node_mashall_set_format, - [PINOS_MESSAGE_SET_PROPERTY] = &client_node_mashall_set_property, - [PINOS_MESSAGE_ADD_MEM] = &client_node_mashall_add_mem, - [PINOS_MESSAGE_USE_BUFFERS] = &client_node_mashall_use_buffers, - [PINOS_MESSAGE_NODE_COMMAND] = &client_node_mashall_node_command, - [PINOS_MESSAGE_PORT_COMMAND] = &client_node_mashall_port_command, - [PINOS_MESSAGE_TRANSPORT_UPDATE] = &client_node_mashall_transport -}; - -static void -client_marshall_info (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageClientInfo *m = data; - pinos_client_notify_info (proxy, m->info); -} - -static const MarshallFunc client_marshall[] = { - [PINOS_MESSAGE_CLIENT_INFO] = &client_marshall_info, -}; - static void client_event_info (void *object, PinosClientInfo *info) @@ -680,20 +256,6 @@ static const PinosClientEvent client_events = { &client_event_info }; -static void -link_marshall_info (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageLinkInfo *m = data; - pinos_link_notify_info (proxy, m->info); -} - -static const MarshallFunc link_marshall[] = { - [PINOS_MESSAGE_LINK_INFO] = &link_marshall_info, -}; - static void link_event_info (void *object, PinosLinkInfo *info) @@ -722,31 +284,6 @@ static const PinosLinkEvent link_events = { &link_event_info }; -static void -registry_marshall_global (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageNotifyGlobal *m = data; - pinos_registry_notify_global (proxy, m->id, m->type); -} - -static void -registry_marshall_global_remove (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - PinosMessageNotifyGlobalRemove *m = data; - pinos_registry_notify_global_remove (proxy, m->id); -} - -static const MarshallFunc registry_marshall[] = { - [PINOS_MESSAGE_NOTIFY_GLOBAL] = ®istry_marshall_global, - [PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE] = ®istry_marshall_global_remove, -}; - static void registry_event_global (void *object, uint32_t id, @@ -766,7 +303,7 @@ registry_event_global (void *object, goto no_mem; proxy->event = &node_events; - proxy->marshall = &node_marshall; + proxy->marshall = &pinos_protocol_native_client_node_marshall; proxy->interface = NULL; } else if (!strcmp (type, PINOS_MODULE_URI)) { proxy = pinos_proxy_new (this, @@ -776,7 +313,7 @@ registry_event_global (void *object, goto no_mem; proxy->event = &module_events; - proxy->marshall = &module_marshall; + proxy->marshall = &pinos_protocol_native_client_module_marshall; proxy->interface = NULL; } else if (!strcmp (type, PINOS_CLIENT_URI)) { proxy = pinos_proxy_new (this, @@ -786,7 +323,7 @@ registry_event_global (void *object, goto no_mem; proxy->event = &client_events; - proxy->marshall = &client_marshall; + proxy->marshall = &pinos_protocol_native_client_client_marshall; proxy->interface = NULL; } else if (!strcmp (type, PINOS_LINK_URI)) { proxy = pinos_proxy_new (this, @@ -796,7 +333,7 @@ registry_event_global (void *object, goto no_mem; proxy->event = &link_events; - proxy->marshall = &link_marshall; + proxy->marshall = &pinos_protocol_native_client_link_marshall; proxy->interface = NULL; } if (proxy) @@ -830,26 +367,6 @@ static const PinosRegistryEvent registry_events = { ®istry_event_global_remove }; -static void -registry_bind (void *object, - uint32_t id, - uint32_t new_id) -{ - PinosProxy *proxy = object; - PinosContextImpl *impl = SPA_CONTAINER_OF (proxy->context, PinosContextImpl, this); - PinosMessageBind m = { id, new_id }; - - pinos_connection_add_message (impl->connection, - proxy->id, - PINOS_MESSAGE_BIND, - &m); - pinos_connection_flush (impl->connection); -} - -static const PinosRegistryInterface registry_interface = { - ®istry_bind -}; - static void on_context_data (SpaSource *source, int fd, @@ -875,7 +392,7 @@ on_context_data (SpaSource *source, while (pinos_connection_get_next (conn, &type, &id, &size)) { void *p = alloca (size); PinosProxy *proxy; - const MarshallFunc *marshall; + const PinosMarshallFunc *marshall; if (!pinos_connection_parse_message (conn, p)) { pinos_log_error ("context %p: failed to parse message", this); @@ -1066,6 +583,8 @@ pinos_context_connect_fd (PinosContext *context, if (impl->connection == NULL) goto error_close; + context->protocol_private = impl->connection; + impl->fd = fd; pinos_loop_add_io (context->loop, @@ -1082,8 +601,8 @@ pinos_context_connect_fd (PinosContext *context, goto no_proxy; context->core_proxy->event = &core_events; - context->core_proxy->interface = &core_interface; - context->core_proxy->marshall = &core_marshall; + context->core_proxy->interface = &pinos_protocol_native_client_core_interface; + context->core_proxy->marshall = &pinos_protocol_native_client_core_marshall; pinos_core_do_client_update (context->core_proxy, &context->properties->dict); @@ -1095,8 +614,8 @@ pinos_context_connect_fd (PinosContext *context, goto no_registry; context->registry_proxy->event = ®istry_events; - context->registry_proxy->interface = ®istry_interface; - context->registry_proxy->marshall = ®istry_marshall; + context->registry_proxy->interface = &pinos_protocol_native_client_registry_interface; + context->registry_proxy->marshall = &pinos_protocol_native_client_registry_marshall; pinos_core_do_get_registry (context->core_proxy, 0, @@ -1138,6 +657,7 @@ pinos_context_disconnect (PinosContext *context) if (impl->connection) pinos_connection_destroy (impl->connection); impl->connection = NULL; + context->protocol_private = NULL; if (impl->fd != -1) close (impl->fd); diff --git a/pinos/client/context.h b/pinos/client/context.h index 6af1bb608..9f2f09ef0 100644 --- a/pinos/client/context.h +++ b/pinos/client/context.h @@ -73,6 +73,8 @@ struct _PinosContext { SpaList stream_list; SpaList proxy_list; + void *protocol_private; + PinosContextState state; char *error; PINOS_SIGNAL (state_changed, (PinosListener *listener, diff --git a/pinos/client/meson.build b/pinos/client/meson.build index eba876bc1..58bfae82a 100644 --- a/pinos/client/meson.build +++ b/pinos/client/meson.build @@ -8,6 +8,7 @@ pinos_headers = [ 'mem.h', 'pinos.h', 'properties.h', + 'protocol-native.h', 'proxy.h', 'rtkit.h', 'stream.h', @@ -27,6 +28,7 @@ pinos_sources = [ 'mapper.c', 'mem.c', 'properties.c', + 'protocol-native.c', 'proxy.c', 'serialize.c', 'stream.c', diff --git a/pinos/client/protocol-native.c b/pinos/client/protocol-native.c new file mode 100644 index 000000000..256ce2c84 --- /dev/null +++ b/pinos/client/protocol-native.c @@ -0,0 +1,508 @@ +/* Pinos + * Copyright (C) 2017 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include "pinos/client/pinos.h" + +#include "pinos/client/protocol-native.h" +#include "pinos/client/interfaces.h" +#include "pinos/client/connection.h" + +static void +core_interface_client_update (void *object, + const SpaDict *props) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageClientUpdate m = { props }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_CLIENT_UPDATE, + &m); + pinos_connection_flush (connection); +} + +static void +core_interface_sync (void *object, + uint32_t seq) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageSync m = { seq }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_SYNC, + &m); + pinos_connection_flush (connection); +} + +static void +core_interface_get_registry (void *object, + uint32_t seq, + uint32_t new_id) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageGetRegistry m = { seq, new_id }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_GET_REGISTRY, + &m); + pinos_connection_flush (connection); +} + +static void +core_interface_create_node (void *object, + uint32_t seq, + const char *factory_name, + const char *name, + const SpaDict *props, + uint32_t new_id) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageCreateNode m = { seq, factory_name, name, props, new_id }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_CREATE_NODE, + &m); + pinos_connection_flush (connection); +} + +static void +core_interface_create_client_node (void *object, + uint32_t seq, + const char *name, + const SpaDict *props, + uint32_t new_id) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageCreateClientNode m = { seq, name, props, new_id }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_CREATE_CLIENT_NODE, + &m); + pinos_connection_flush (connection); +} + +static void +core_marshall_info (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageCoreInfo *m = data; + pinos_core_notify_info (proxy, m->info); +} + +static void +core_marshall_done (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageNotifyDone *m = data; + pinos_core_notify_done (proxy, m->seq); +} + +static void +core_marshall_error (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageError *m = data; + pinos_core_notify_error (proxy, m->id, m->res, m->error); +} + +static void +core_marshall_remove_id (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageRemoveId *m = data; + pinos_core_notify_remove_id (proxy, m->id); +} + +static void +module_marshall_info (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageModuleInfo *m = data; + pinos_module_notify_info (proxy, m->info); +} + +static void +node_marshall_done (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageCreateNodeDone *m = data; + pinos_node_notify_done (proxy, m->seq); +} + +static void +node_marshall_info (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageNodeInfo *m = data; + pinos_node_notify_info (proxy, m->info); +} + +static void +client_node_interface_update (void *object, + uint32_t change_mask, + unsigned int max_input_ports, + unsigned int max_output_ports, + const SpaProps *props) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageNodeUpdate m = { change_mask, max_input_ports, max_output_ports, props }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_NODE_UPDATE, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_interface_port_update (void *object, + SpaDirection direction, + uint32_t port_id, + uint32_t change_mask, + unsigned int n_possible_formats, + SpaFormat **possible_formats, + SpaFormat *format, + const SpaProps *props, + const SpaPortInfo *info) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessagePortUpdate m = { direction, port_id, change_mask, n_possible_formats, + possible_formats, format, props, info }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_PORT_UPDATE, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_interface_state_change (void *object, + SpaNodeState state) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageNodeStateChange m = { state }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_NODE_STATE_CHANGE, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_interface_event (void *object, + SpaNodeEvent *event) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageNodeEvent m = { event }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_NODE_EVENT, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_interface_destroy (void *object, + uint32_t seq) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageDestroy m = { seq }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_DESTROY, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_mashall_done (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageCreateClientNodeDone *m = data; + pinos_client_node_notify_done (proxy, m->seq, m->datafd); +} + +static void +client_node_mashall_event (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageNodeEvent *m = data; + pinos_client_node_notify_event (proxy, m->event); +} + +static void +client_node_mashall_add_port (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageAddPort *m = data; + pinos_client_node_notify_add_port (proxy, m->seq, m->direction, m->port_id); +} + +static void +client_node_mashall_remove_port (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageRemovePort *m = data; + pinos_client_node_notify_remove_port (proxy, m->seq, m->direction, m->port_id); +} + +static void +client_node_mashall_set_format (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageSetFormat *m = data; + pinos_client_node_notify_set_format (proxy, m->seq, m->direction, m->port_id, + m->flags, m->format); +} + +static void +client_node_mashall_set_property (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageSetProperty *m = data; + pinos_client_node_notify_set_property (proxy, m->seq, m->id, m->size, m->value); +} + +static void +client_node_mashall_add_mem (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageAddMem *m = data; + pinos_client_node_notify_add_mem (proxy, + m->direction, + m->port_id, + m->mem_id, + m->type, + m->memfd, + m->flags, + m->offset, + m->size); +} + +static void +client_node_mashall_use_buffers (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageUseBuffers *m = data; + pinos_client_node_notify_use_buffers (proxy, + m->seq, + m->direction, + m->port_id, + m->n_buffers, + m->buffers); +} + +static void +client_node_mashall_node_command (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageNodeCommand *m = data; + pinos_client_node_notify_node_command (proxy, m->seq, m->command); +} + +static void +client_node_mashall_port_command (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessagePortCommand *m = data; + pinos_client_node_notify_port_command (proxy, m->port_id, m->command); +} + +static void +client_node_mashall_transport (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageTransportUpdate *m = data; + pinos_client_node_notify_transport (proxy, m->memfd, m->offset, m->size); +} + +static void +client_marshall_info (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageClientInfo *m = data; + pinos_client_notify_info (proxy, m->info); +} + +static void +link_marshall_info (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageLinkInfo *m = data; + pinos_link_notify_info (proxy, m->info); +} + +static void +registry_marshall_global (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageNotifyGlobal *m = data; + pinos_registry_notify_global (proxy, m->id, m->type); +} + +static void +registry_marshall_global_remove (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + PinosMessageNotifyGlobalRemove *m = data; + pinos_registry_notify_global_remove (proxy, m->id); +} + +static void +registry_bind (void *object, + uint32_t id, + uint32_t new_id) +{ + PinosProxy *proxy = object; + PinosConnection *connection = proxy->context->protocol_private; + PinosMessageBind m = { id, new_id }; + + pinos_connection_add_message (connection, + proxy->id, + PINOS_MESSAGE_BIND, + &m); + pinos_connection_flush (connection); +} + +const PinosCoreInterface pinos_protocol_native_client_core_interface = { + &core_interface_client_update, + &core_interface_sync, + &core_interface_get_registry, + &core_interface_create_node, + &core_interface_create_client_node +}; + +const PinosRegistryInterface pinos_protocol_native_client_registry_interface = { + ®istry_bind +}; + +const PinosClientNodeInterface pinos_protocol_native_client_client_node_interface = { + &client_node_interface_update, + &client_node_interface_port_update, + &client_node_interface_state_change, + &client_node_interface_event, + &client_node_interface_destroy +}; + +const PinosMarshallFunc pinos_protocol_native_client_core_marshall[] = { + [PINOS_MESSAGE_CORE_INFO] = &core_marshall_info, + [PINOS_MESSAGE_NOTIFY_DONE] = &core_marshall_done, + [PINOS_MESSAGE_ERROR] = &core_marshall_error, + [PINOS_MESSAGE_REMOVE_ID] = &core_marshall_remove_id, +}; + +const PinosMarshallFunc pinos_protocol_native_client_module_marshall[] = { + [PINOS_MESSAGE_MODULE_INFO] = &module_marshall_info, +}; + +const PinosMarshallFunc pinos_protocol_native_client_node_marshall[] = { + [PINOS_MESSAGE_CREATE_NODE_DONE] = &node_marshall_done, + [PINOS_MESSAGE_NODE_INFO] = &node_marshall_info, +}; + +const PinosMarshallFunc pinos_protocol_native_client_client_node_marshall[] = { + [PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE] = &client_node_mashall_done, + [PINOS_MESSAGE_NODE_EVENT] = &client_node_mashall_event, + [PINOS_MESSAGE_ADD_PORT] = &client_node_mashall_add_port, + [PINOS_MESSAGE_REMOVE_PORT] = &client_node_mashall_remove_port, + [PINOS_MESSAGE_SET_FORMAT] = &client_node_mashall_set_format, + [PINOS_MESSAGE_SET_PROPERTY] = &client_node_mashall_set_property, + [PINOS_MESSAGE_ADD_MEM] = &client_node_mashall_add_mem, + [PINOS_MESSAGE_USE_BUFFERS] = &client_node_mashall_use_buffers, + [PINOS_MESSAGE_NODE_COMMAND] = &client_node_mashall_node_command, + [PINOS_MESSAGE_PORT_COMMAND] = &client_node_mashall_port_command, + [PINOS_MESSAGE_TRANSPORT_UPDATE] = &client_node_mashall_transport +}; + +const PinosMarshallFunc pinos_protocol_native_client_client_marshall[] = { + [PINOS_MESSAGE_CLIENT_INFO] = &client_marshall_info, +}; + +const PinosMarshallFunc pinos_protocol_native_client_link_marshall[] = { + [PINOS_MESSAGE_LINK_INFO] = &link_marshall_info, +}; + +const PinosMarshallFunc pinos_protocol_native_client_registry_marshall[] = { + [PINOS_MESSAGE_NOTIFY_GLOBAL] = ®istry_marshall_global, + [PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE] = ®istry_marshall_global_remove, +}; diff --git a/pinos/client/protocol-native.h b/pinos/client/protocol-native.h new file mode 100644 index 000000000..ad94f1a4d --- /dev/null +++ b/pinos/client/protocol-native.h @@ -0,0 +1,34 @@ +/* Pinos + * Copyright (C) 2017 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "pinos/client/pinos.h" + +typedef void (*PinosMarshallFunc) (void *object, void *data, size_t size); + +extern const PinosCoreInterface pinos_protocol_native_client_core_interface; +extern const PinosRegistryInterface pinos_protocol_native_client_registry_interface; +extern const PinosClientNodeInterface pinos_protocol_native_client_client_node_interface; + +extern const PinosMarshallFunc pinos_protocol_native_client_core_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_client_module_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_client_node_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_client_client_node_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_client_client_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_client_link_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_client_registry_marshall[]; diff --git a/pinos/client/stream.c b/pinos/client/stream.c index 5bcbacd05..834f06ea2 100644 --- a/pinos/client/stream.c +++ b/pinos/client/stream.c @@ -27,6 +27,7 @@ #include "spa/lib/debug.h" #include "pinos/client/pinos.h" +#include "pinos/client/protocol-native.h" #include "pinos/client/array.h" #include "pinos/client/connection.h" #include "pinos/client/context.h" @@ -928,11 +929,6 @@ static const PinosClientNodeEvent client_node_events = { &client_node_transport }; -typedef void (*MarshallFunc) (void *object, void *data, size_t size); - -extern const PinosClientNodeInterface client_node_interface; -extern const MarshallFunc client_node_marshall[]; - static void on_node_proxy_destroy (PinosListener *listener, PinosProxy *proxy) @@ -1002,9 +998,9 @@ pinos_stream_connect (PinosStream *stream, on_node_proxy_destroy); impl->node_proxy->user_data = stream; - impl->node_proxy->interface = &client_node_interface; impl->node_proxy->event = &client_node_events; - impl->node_proxy->marshall = &client_node_marshall; + impl->node_proxy->interface = &pinos_protocol_native_client_client_node_interface; + impl->node_proxy->marshall = &pinos_protocol_native_client_client_node_marshall; pinos_core_do_create_client_node (stream->context->core_proxy, ++impl->seq, diff --git a/pinos/modules/module-protocol-native.c b/pinos/modules/module-protocol-native.c index 47ae4d911..65a805319 100644 --- a/pinos/modules/module-protocol-native.c +++ b/pinos/modules/module-protocol-native.c @@ -34,6 +34,7 @@ #include "pinos/client/interfaces.h" #include "pinos/server/core.h" +#include "pinos/server/protocol-native.h" #include "pinos/server/node.h" #include "pinos/server/module.h" #include "pinos/server/client-node.h" @@ -95,586 +96,37 @@ client_destroy (PinosProtocolNativeClient *this) free (this); } -typedef void (*MarshallFunc) (void *object, void *data, size_t size); - -static void -core_event_info (void *object, - PinosCoreInfo *info) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageCoreInfo m = { info }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_CORE_INFO, - &m); - pinos_connection_flush (client->connection); -} - -static void -core_event_done (void *object, - uint32_t seq) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageNotifyDone m = { seq }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_NOTIFY_DONE, - &m); - pinos_connection_flush (client->connection); -} - -static void -core_event_error (void *object, - uint32_t id, - SpaResult res, - const char *error, ...) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - char buffer[128]; - PinosMessageError m = { id, res, buffer }; - va_list ap; - - va_start (ap, error); - vsnprintf (buffer, sizeof (buffer), error, ap); - va_end (ap); - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_ERROR, - &m); - pinos_connection_flush (client->connection); -} - -static void -core_event_remove_id (void *object, - uint32_t id) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageRemoveId m = { id }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_REMOVE_ID, - &m); - pinos_connection_flush (client->connection); -} - -static void -core_marshall_client_update (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageClientUpdate *m = data; - pinos_core_do_client_update (resource, m->props); -} - -static void -core_marshall_sync (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageSync *m = data; - pinos_core_do_sync (resource, m->seq); -} - -static void -core_marshall_get_registry (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageGetRegistry *m = data; - pinos_core_do_get_registry (resource, m->seq, m->new_id); -} - -static void -core_marshall_create_node (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageCreateNode *m = data; - pinos_core_do_create_node (resource, - m->seq, - m->factory_name, - m->name, - m->props, - m->new_id); -} - -static void -core_marshall_create_client_node (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageCreateClientNode *m = data; - pinos_core_do_create_client_node (resource, - m->seq, - m->name, - m->props, - m->new_id); -} - -static void -registry_event_global (void *object, - uint32_t id, - const char *type) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageNotifyGlobal m = { id, type }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_NOTIFY_GLOBAL, - &m); - pinos_connection_flush (client->connection); -} - -static void -registry_event_global_remove (void *object, - uint32_t id) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageNotifyGlobalRemove m = { id }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE, - &m); - pinos_connection_flush (client->connection); -} - -static void -registry_marshall_bind (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageBind *m = data; - pinos_registry_do_bind (resource, - m->id, - m->new_id); -} - -static void -module_event_info (void *object, - PinosModuleInfo *info) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageModuleInfo m = { info }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_MODULE_INFO, - &m); - pinos_connection_flush (client->connection); -} - -static void -node_event_done (void *object, - uint32_t seq) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageCreateNodeDone m = { seq }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_CREATE_NODE_DONE, - &m); - pinos_connection_flush (client->connection); -} - -static void -node_event_info (void *object, - PinosNodeInfo *info) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageNodeInfo m = { info }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_NODE_INFO, - &m); - pinos_connection_flush (client->connection); -} - -static void -client_event_info (void *object, - PinosClientInfo *info) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageClientInfo m = { info }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_CLIENT_INFO, - &m); - pinos_connection_flush (client->connection); -} - -static void -client_node_event_done (void *object, - uint32_t seq, - int datafd) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageCreateClientNodeDone m = { seq, datafd }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE, - &m); - pinos_connection_flush (client->connection); -} - -static void -client_node_event_event (void *object, - SpaNodeEvent *event) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageNodeEvent m = { event }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_NODE_EVENT, - &m); - pinos_connection_flush (client->connection); -} - -static void -client_node_event_add_port (void *object, - uint32_t seq, - SpaDirection direction, - uint32_t port_id) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageAddPort m = { seq, direction, port_id }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_ADD_PORT, - &m); - pinos_connection_flush (client->connection); -} -static void -client_node_event_remove_port (void *object, - uint32_t seq, - SpaDirection direction, - uint32_t port_id) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageRemovePort m = { seq, direction, port_id }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_REMOVE_PORT, - &m); - pinos_connection_flush (client->connection); -} -static void -client_node_event_set_format (void *object, - uint32_t seq, - SpaDirection direction, - uint32_t port_id, - SpaPortFormatFlags flags, - const SpaFormat *format) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageSetFormat m = { seq, direction, port_id, flags, format }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_SET_FORMAT, - &m); - pinos_connection_flush (client->connection); -} - -static void -client_node_event_set_property (void *object, - uint32_t seq, - uint32_t id, - size_t size, - void *value) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageSetProperty m = { seq, id, size, value }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_SET_PROPERTY, - &m); - pinos_connection_flush (client->connection); -} -static void -client_node_event_add_mem (void *object, - SpaDirection direction, - uint32_t port_id, - uint32_t mem_id, - SpaDataType type, - int memfd, - uint32_t flags, - off_t offset, - size_t size) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageAddMem m = { direction, port_id, mem_id, type, memfd, flags, offset, size }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_ADD_MEM, - &m); - pinos_connection_flush (client->connection); -} -static void -client_node_event_use_buffers (void *object, - uint32_t seq, - SpaDirection direction, - uint32_t port_id, - unsigned int n_buffers, - PinosClientNodeBuffer *buffers) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageUseBuffers m = { seq, direction, port_id, n_buffers, buffers }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_USE_BUFFERS, - &m); - pinos_connection_flush (client->connection); -} -static void -client_node_event_node_command (void *object, - uint32_t seq, - SpaNodeCommand *command) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageNodeCommand m = { seq, command }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_NODE_COMMAND, - &m); - pinos_connection_flush (client->connection); -} -static void -client_node_event_port_command (void *object, - uint32_t port_id, - SpaNodeCommand *command) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessagePortCommand m = { port_id, command }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_PORT_COMMAND, - &m); - pinos_connection_flush (client->connection); -} - -static void -client_node_event_transport (void *object, - int memfd, - off_t offset, - size_t size) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageTransportUpdate m = { memfd, offset, size }; - - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_TRANSPORT_UPDATE, - &m); - pinos_connection_flush (client->connection); -} - -static void -client_node_marshall_update (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageNodeUpdate *m = data; - pinos_client_node_do_update (resource, - m->change_mask, - m->max_input_ports, - m->max_output_ports, - m->props); -} - -static void -client_node_marshall_port_update (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessagePortUpdate *m = data; - pinos_client_node_do_port_update (resource, - m->direction, - m->port_id, - m->change_mask, - m->n_possible_formats, - m->possible_formats, - m->format, - m->props, - m->info); -} - -static void -client_node_marshall_state_change (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageNodeStateChange *m = data; - pinos_client_node_do_state_change (resource, m->state); -} - -static void -client_node_marshall_event (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageNodeEvent *m = data; - pinos_client_node_do_event (resource, m->event); -} - -static void -client_node_marshall_destroy (void *object, - void *data, - size_t size) -{ - PinosResource *resource = object; - PinosMessageDestroy *m = data; - pinos_client_node_do_destroy (resource, m->seq); -} - -static void -link_event_info (void *object, - PinosLinkInfo *info) -{ - PinosResource *resource = object; - PinosProtocolNativeClient *client = resource->client->protocol_private; - PinosMessageLinkInfo m; - - m.info = info; - pinos_connection_add_message (client->connection, - resource->id, - PINOS_MESSAGE_LINK_INFO, - &m); - pinos_connection_flush (client->connection); -} - static void on_resource_added (PinosListener *listener, PinosClient *client, PinosResource *resource) { if (resource->type == resource->core->uri.core) { - static const PinosCoreEvent core_event = { - &core_event_info, - &core_event_done, - &core_event_error, - &core_event_remove_id - }; - static const MarshallFunc core_marshall[] = { - [PINOS_MESSAGE_CLIENT_UPDATE] = &core_marshall_client_update, - [PINOS_MESSAGE_SYNC] = &core_marshall_sync, - [PINOS_MESSAGE_GET_REGISTRY] = &core_marshall_get_registry, - [PINOS_MESSAGE_CREATE_NODE] = &core_marshall_create_node, - [PINOS_MESSAGE_CREATE_CLIENT_NODE] = &core_marshall_create_client_node - }; - resource->event = &core_event; - resource->marshall = &core_marshall; + resource->event = &pinos_protocol_native_server_core_event; + resource->marshall = &pinos_protocol_native_server_core_marshall; } else if (resource->type == resource->core->uri.registry) { - static const PinosRegistryEvent registry_event = { - ®istry_event_global, - ®istry_event_global_remove, - }; - static const MarshallFunc registry_marshall[] = { - [PINOS_MESSAGE_BIND] = ®istry_marshall_bind, - }; - resource->event = ®istry_event; - resource->marshall = ®istry_marshall; + resource->event = &pinos_protocol_native_server_registry_event; + resource->marshall = &pinos_protocol_native_server_registry_marshall; } else if (resource->type == resource->core->uri.module) { - static const PinosModuleEvent module_event = { - &module_event_info, - }; - resource->event = &module_event; + resource->event = &pinos_protocol_native_server_module_event; resource->marshall = NULL; } else if (resource->type == resource->core->uri.node) { - static const PinosNodeEvent node_event = { - &node_event_done, - &node_event_info, - }; - resource->event = &node_event; + resource->event = &pinos_protocol_native_server_node_event; resource->marshall = NULL; } else if (resource->type == resource->core->uri.client) { - static const PinosClientEvent client_event = { - &client_event_info, - }; - resource->event = &client_event; + resource->event = &pinos_protocol_native_server_client_event; resource->marshall = NULL; } else if (resource->type == resource->core->uri.client_node) { - static const PinosClientNodeEvent client_node_events = { - &client_node_event_done, - &client_node_event_event, - &client_node_event_add_port, - &client_node_event_remove_port, - &client_node_event_set_format, - &client_node_event_set_property, - &client_node_event_add_mem, - &client_node_event_use_buffers, - &client_node_event_node_command, - &client_node_event_port_command, - &client_node_event_transport, - }; - static const MarshallFunc client_node_marshall[] = { - [PINOS_MESSAGE_NODE_UPDATE] = &client_node_marshall_update, - [PINOS_MESSAGE_PORT_UPDATE] = &client_node_marshall_port_update, - [PINOS_MESSAGE_NODE_STATE_CHANGE] = &client_node_marshall_state_change, - [PINOS_MESSAGE_NODE_EVENT] = &client_node_marshall_event, - [PINOS_MESSAGE_DESTROY] = &client_node_marshall_destroy, - }; - resource->event = &client_node_events; - resource->marshall = &client_node_marshall; + resource->event = &pinos_protocol_native_server_client_node_events; + resource->marshall = &pinos_protocol_native_server_client_node_marshall; } else if (resource->type == resource->core->uri.link) { - static const PinosLinkEvent link_event = { - &link_event_info, - }; - resource->event = &link_event; + resource->event = &pinos_protocol_native_server_link_event; resource->marshall = NULL; } } @@ -701,7 +153,7 @@ connection_data (SpaSource *source, while (pinos_connection_get_next (conn, &type, &id, &size)) { PinosResource *resource; void *message = alloca (size); - const MarshallFunc *marshall; + const PinosMarshallFunc *marshall; pinos_log_debug ("protocol-native %p: got message %d from %u", client->impl, type, id); @@ -763,7 +215,7 @@ client_new (PinosProtocolNative *impl, if (client == NULL) goto no_client; - client->protocol_private = this; + client->protocol_private = this->connection; this->client = client; diff --git a/pinos/server/meson.build b/pinos/server/meson.build index d1cd97c9e..0f4ef7e1a 100644 --- a/pinos/server/meson.build +++ b/pinos/server/meson.build @@ -11,6 +11,7 @@ pinoscore_headers = [ 'node.h', 'node-factory.h', 'port.h', + 'protocol-native.h', 'resource.h', 'work-queue.h', ] @@ -28,6 +29,7 @@ pinoscore_sources = [ 'node.c', 'node-factory.c', 'port.c', + 'protocol-native.c', 'resource.c', 'work-queue.c', ] diff --git a/pinos/server/protocol-native.c b/pinos/server/protocol-native.c new file mode 100644 index 000000000..8556d9262 --- /dev/null +++ b/pinos/server/protocol-native.c @@ -0,0 +1,585 @@ +/* Pinos + * Copyright (C) 2017 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "pinos/client/interfaces.h" +#include "pinos/server/resource.h" +#include "pinos/server/protocol-native.h" + +static void +core_event_info (void *object, + PinosCoreInfo *info) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageCoreInfo m = { info }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_CORE_INFO, + &m); + pinos_connection_flush (connection); +} + +static void +core_event_done (void *object, + uint32_t seq) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageNotifyDone m = { seq }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_NOTIFY_DONE, + &m); + pinos_connection_flush (connection); +} + +static void +core_event_error (void *object, + uint32_t id, + SpaResult res, + const char *error, ...) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + char buffer[128]; + PinosMessageError m = { id, res, buffer }; + va_list ap; + + va_start (ap, error); + vsnprintf (buffer, sizeof (buffer), error, ap); + va_end (ap); + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_ERROR, + &m); + pinos_connection_flush (connection); +} + +static void +core_event_remove_id (void *object, + uint32_t id) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageRemoveId m = { id }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_REMOVE_ID, + &m); + pinos_connection_flush (connection); +} + +static void +core_marshall_client_update (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageClientUpdate *m = data; + pinos_core_do_client_update (resource, m->props); +} + +static void +core_marshall_sync (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageSync *m = data; + pinos_core_do_sync (resource, m->seq); +} + +static void +core_marshall_get_registry (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageGetRegistry *m = data; + pinos_core_do_get_registry (resource, m->seq, m->new_id); +} + +static void +core_marshall_create_node (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageCreateNode *m = data; + pinos_core_do_create_node (resource, + m->seq, + m->factory_name, + m->name, + m->props, + m->new_id); +} + +static void +core_marshall_create_client_node (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageCreateClientNode *m = data; + pinos_core_do_create_client_node (resource, + m->seq, + m->name, + m->props, + m->new_id); +} + +static void +registry_event_global (void *object, + uint32_t id, + const char *type) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageNotifyGlobal m = { id, type }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_NOTIFY_GLOBAL, + &m); + pinos_connection_flush (connection); +} + +static void +registry_event_global_remove (void *object, + uint32_t id) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageNotifyGlobalRemove m = { id }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE, + &m); + pinos_connection_flush (connection); +} + +static void +registry_marshall_bind (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageBind *m = data; + pinos_registry_do_bind (resource, + m->id, + m->new_id); +} + +static void +module_event_info (void *object, + PinosModuleInfo *info) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageModuleInfo m = { info }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_MODULE_INFO, + &m); + pinos_connection_flush (connection); +} + +static void +node_event_done (void *object, + uint32_t seq) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageCreateNodeDone m = { seq }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_CREATE_NODE_DONE, + &m); + pinos_connection_flush (connection); +} + +static void +node_event_info (void *object, + PinosNodeInfo *info) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageNodeInfo m = { info }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_NODE_INFO, + &m); + pinos_connection_flush (connection); +} + +static void +client_event_info (void *object, + PinosClientInfo *info) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageClientInfo m = { info }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_CLIENT_INFO, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_done (void *object, + uint32_t seq, + int datafd) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageCreateClientNodeDone m = { seq, datafd }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_event (void *object, + SpaNodeEvent *event) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageNodeEvent m = { event }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_NODE_EVENT, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_add_port (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageAddPort m = { seq, direction, port_id }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_ADD_PORT, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_remove_port (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageRemovePort m = { seq, direction, port_id }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_REMOVE_PORT, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_set_format (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id, + SpaPortFormatFlags flags, + const SpaFormat *format) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageSetFormat m = { seq, direction, port_id, flags, format }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_SET_FORMAT, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_set_property (void *object, + uint32_t seq, + uint32_t id, + size_t size, + void *value) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageSetProperty m = { seq, id, size, value }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_SET_PROPERTY, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_add_mem (void *object, + SpaDirection direction, + uint32_t port_id, + uint32_t mem_id, + SpaDataType type, + int memfd, + uint32_t flags, + off_t offset, + size_t size) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageAddMem m = { direction, port_id, mem_id, type, memfd, flags, offset, size }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_ADD_MEM, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_use_buffers (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id, + unsigned int n_buffers, + PinosClientNodeBuffer *buffers) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageUseBuffers m = { seq, direction, port_id, n_buffers, buffers }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_USE_BUFFERS, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_node_command (void *object, + uint32_t seq, + SpaNodeCommand *command) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageNodeCommand m = { seq, command }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_NODE_COMMAND, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_port_command (void *object, + uint32_t port_id, + SpaNodeCommand *command) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessagePortCommand m = { port_id, command }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_PORT_COMMAND, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_event_transport (void *object, + int memfd, + off_t offset, + size_t size) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageTransportUpdate m = { memfd, offset, size }; + + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_TRANSPORT_UPDATE, + &m); + pinos_connection_flush (connection); +} + +static void +client_node_marshall_update (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageNodeUpdate *m = data; + pinos_client_node_do_update (resource, + m->change_mask, + m->max_input_ports, + m->max_output_ports, + m->props); +} + +static void +client_node_marshall_port_update (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessagePortUpdate *m = data; + pinos_client_node_do_port_update (resource, + m->direction, + m->port_id, + m->change_mask, + m->n_possible_formats, + m->possible_formats, + m->format, + m->props, + m->info); +} + +static void +client_node_marshall_state_change (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageNodeStateChange *m = data; + pinos_client_node_do_state_change (resource, m->state); +} + +static void +client_node_marshall_event (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageNodeEvent *m = data; + pinos_client_node_do_event (resource, m->event); +} + +static void +client_node_marshall_destroy (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageDestroy *m = data; + pinos_client_node_do_destroy (resource, m->seq); +} + +static void +link_event_info (void *object, + PinosLinkInfo *info) +{ + PinosResource *resource = object; + PinosConnection *connection = resource->client->protocol_private; + PinosMessageLinkInfo m; + + m.info = info; + pinos_connection_add_message (connection, + resource->id, + PINOS_MESSAGE_LINK_INFO, + &m); + pinos_connection_flush (connection); +} + +const PinosCoreEvent pinos_protocol_native_server_core_event = { + &core_event_info, + &core_event_done, + &core_event_error, + &core_event_remove_id +}; + +const PinosMarshallFunc pinos_protocol_native_server_core_marshall[] = { + [PINOS_MESSAGE_CLIENT_UPDATE] = &core_marshall_client_update, + [PINOS_MESSAGE_SYNC] = &core_marshall_sync, + [PINOS_MESSAGE_GET_REGISTRY] = &core_marshall_get_registry, + [PINOS_MESSAGE_CREATE_NODE] = &core_marshall_create_node, + [PINOS_MESSAGE_CREATE_CLIENT_NODE] = &core_marshall_create_client_node +}; + +const PinosRegistryEvent pinos_protocol_native_server_registry_event = { + ®istry_event_global, + ®istry_event_global_remove, +}; + +const PinosMarshallFunc pinos_protocol_native_server_registry_marshall[] = { + [PINOS_MESSAGE_BIND] = ®istry_marshall_bind, +}; + +const PinosModuleEvent pinos_protocol_native_server_module_event = { + &module_event_info, +}; + +const PinosNodeEvent pinos_protocol_native_server_node_event = { + &node_event_done, + &node_event_info, +}; + +const PinosClientEvent pinos_protocol_native_server_client_event = { + &client_event_info, +}; + +const PinosClientNodeEvent pinos_protocol_native_server_client_node_events = { + &client_node_event_done, + &client_node_event_event, + &client_node_event_add_port, + &client_node_event_remove_port, + &client_node_event_set_format, + &client_node_event_set_property, + &client_node_event_add_mem, + &client_node_event_use_buffers, + &client_node_event_node_command, + &client_node_event_port_command, + &client_node_event_transport, +}; + +const PinosMarshallFunc pinos_protocol_native_server_client_node_marshall[] = { + [PINOS_MESSAGE_NODE_UPDATE] = &client_node_marshall_update, + [PINOS_MESSAGE_PORT_UPDATE] = &client_node_marshall_port_update, + [PINOS_MESSAGE_NODE_STATE_CHANGE] = &client_node_marshall_state_change, + [PINOS_MESSAGE_NODE_EVENT] = &client_node_marshall_event, + [PINOS_MESSAGE_DESTROY] = &client_node_marshall_destroy, +}; + +const PinosLinkEvent pinos_protocol_native_server_link_event = { + &link_event_info, +}; diff --git a/pinos/server/protocol-native.h b/pinos/server/protocol-native.h new file mode 100644 index 000000000..4c30ba2ad --- /dev/null +++ b/pinos/server/protocol-native.h @@ -0,0 +1,34 @@ +/* Pinos + * Copyright (C) 2017 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "pinos/client/pinos.h" + +typedef void (*PinosMarshallFunc) (void *object, void *data, size_t size); + +extern const PinosCoreEvent pinos_protocol_native_server_core_event; +extern const PinosRegistryEvent pinos_protocol_native_server_registry_event; +extern const PinosModuleEvent pinos_protocol_native_server_module_event; +extern const PinosNodeEvent pinos_protocol_native_server_node_event; +extern const PinosClientEvent pinos_protocol_native_server_client_event; +extern const PinosClientNodeEvent pinos_protocol_native_server_client_node_events; +extern const PinosLinkEvent pinos_protocol_native_server_link_event; + +extern const PinosMarshallFunc pinos_protocol_native_server_core_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_server_registry_marshall[]; +extern const PinosMarshallFunc pinos_protocol_native_server_client_node_marshall[];