diff options
author | Wim Taymans <wtaymans@redhat.com> | 2016-07-25 10:46:29 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2016-07-25 10:46:29 +0200 |
commit | d374f50d28f7078a11108ee1a034a1d7bf7de23c (patch) | |
tree | 6e79aa8fa3d56d3fe76a1d634533ac5c633a5731 | |
parent | 907bd7bfd71f13a67337195abaac25f205a39068 (diff) |
channel: remove the channelrework2
Remove the channel, the functionality is now in the client-node.
-rw-r--r-- | pinos/Makefile.am | 1 | ||||
-rw-r--r-- | pinos/client/stream.c | 2 | ||||
-rw-r--r-- | pinos/dbus/org.pinos.xml | 71 | ||||
-rw-r--r-- | pinos/server/channel.c | 729 | ||||
-rw-r--r-- | pinos/server/channel.h | 73 | ||||
-rw-r--r-- | pinos/server/client-node.c | 26 | ||||
-rw-r--r-- | pinos/server/daemon.c | 127 | ||||
-rw-r--r-- | pinos/server/link.c | 27 | ||||
-rw-r--r-- | pinos/server/port.c | 60 | ||||
-rw-r--r-- | pinos/server/port.h | 7 |
10 files changed, 67 insertions, 1056 deletions
diff --git a/pinos/Makefile.am b/pinos/Makefile.am index 03210c4f..ef1f434c 100644 --- a/pinos/Makefile.am +++ b/pinos/Makefile.am @@ -205,7 +205,6 @@ lib_LTLIBRARIES += libpinoscore-@PINOS_MAJORMINOR@.la # Pure core stuff libpinoscore_@PINOS_MAJORMINOR@_la_SOURCES = \ - server/channel.c server/channel.h \ server/client.c server/client.h \ server/client-node.c server/client-node.h \ server/daemon.c server/daemon.h \ diff --git a/pinos/client/stream.c b/pinos/client/stream.c index 4386ceea..815f025b 100644 --- a/pinos/client/stream.c +++ b/pinos/client/stream.c @@ -786,7 +786,7 @@ do_connect (PinosStream *stream) g_variant_builder_add (&b, "u", 0); g_variant_builder_add (&b, "s", g_bytes_get_data (priv->possible_formats, NULL)); g_variant_builder_add_value (&b, pinos_properties_to_variant (priv->properties)); - g_variant_builder_add (&b, "s", priv->path); + g_variant_builder_add (&b, "s", priv->path == NULL ? "" : priv->path); g_variant_builder_close (&b); ports = g_variant_builder_end (&b); diff --git a/pinos/dbus/org.pinos.xml b/pinos/dbus/org.pinos.xml index fe4076ec..eed21e28 100644 --- a/pinos/dbus/org.pinos.xml +++ b/pinos/dbus/org.pinos.xml @@ -23,27 +23,6 @@ <!-- Properties: Extra properties of the daemon --> <property name='Properties' type='a{sv}' access='read' /> - <!-- CreateChannel: - @node: the Node1 object path or / for default - @direction: the direction of the channel - 0 = input channel - 1 = output channel - @possible_formats: the possible formats that can be accepted - @properties: extra properties - @channel: the Channel object path - @fd: a file descriptor for data transfer - - Create a new channel to communicate with @node with given @possible_formats - --> - <method name='CreateChannel'> - <arg type='s' name='node' direction='in'/> - <arg type='u' name='direction' direction='in'/> - <arg type='s' name='possible_formats' direction='in'/> - <arg type='a{sv}' name='properties' direction='in'/> - <arg type='o' name='channel' direction='out'/> - <arg type='h' name='fd' direction='out'/> - </method> - <!-- CreateNode: @factory_name: the factory name to use for the node @name: the name of the node @@ -59,6 +38,14 @@ <arg type='o' name='node' direction='out'/> </method> + <!-- CreateClientNode: + @name: the name of the node + @Properties: extra properties + @ports: the port descriptions + @node: the Node1 object path + + Create a new Node with given name and properties and ports. + --> <method name='CreateClientNode'> <arg type='s' name='name' direction='in' /> <arg type='a{sv}' name='properties' direction='in'/> @@ -83,54 +70,12 @@ <property name='Sender' type='s' access='read' /> <!-- Name: Properties of the client --> <property name='Properties' type='a{sv}' access='read' /> - </interface> - - <!-- - org.pinos.Channel: - @short_description: Interface for input/output channel - - This interface is used to control the input/output of a - node and start/stop the media transport. - --> - <interface name='org.pinos.Channel1'> - <!-- Owner: the owner node of this channel --> - <property name='Owner' type='o' access='read' /> - <!-- type: type of the channel - 0 = input channel - 1 = output channel - --> - <property name='Direction' type='u' access='read' /> - - <property name='Node' type='o' access='read' /> - - <!-- Properties: extra channel properties --> - <property name='Properties' type='a{sv}' access='read' /> - - <!-- state: state of the channel - -1 = the channel is in error - 0 = the channel is idle - 1 = the channel is starting - 2 = the channel is streaming - --> - <property name='State' type='u' access='read' /> - <!-- PossibleFormats: - all possible formats of the channel. This is filtered - against the accepted_formats when creating the channel. - --> - <property name='PossibleFormats' type='s' access='read' /> - <!-- Format: the current streaming format --> - <property name='Format' type='s' access='read' /> - <!-- Remove: - Remove the channel - --> - <method name='Remove'/> </interface> - <!-- org.pinos.Node1: @short_description: A processing node diff --git a/pinos/server/channel.c b/pinos/server/channel.c deleted file mode 100644 index 9c94d312..00000000 --- a/pinos/server/channel.c +++ /dev/null @@ -1,729 +0,0 @@ -/* Pinos - * Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com> - * - * 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 <string.h> -#include <sys/socket.h> -#include <errno.h> - -#include <gio/gunixfdlist.h> - -#include "pinos/client/pinos.h" -#include "pinos/client/enumtypes.h" -#include "pinos/client/private.h" - -#include "pinos/server/daemon.h" -#include "pinos/server/channel.h" -#include "pinos/server/utils.h" - -#include "pinos/dbus/org-pinos.h" - - -#define MAX_BUFFER_SIZE 1024 -#define MAX_FDS 16 - -struct _PinosChannelPrivate -{ - PinosDaemon *daemon; - PinosChannel1 *iface; - - gchar *object_path; - gchar *client_path; - PinosPort *port; - PinosDirection direction; - - GBytes *possible_formats; - PinosProperties *properties; - PinosChannelState state; - GBytes *format; - - gulong send_id; - int fd; - GSource *socket_source; - GSocket *sockets[2]; - - PinosBuffer recv_buffer; - - guint8 recv_data[MAX_BUFFER_SIZE]; - int recv_fds[MAX_FDS]; - - guint8 send_data[MAX_BUFFER_SIZE]; - int send_fds[MAX_FDS]; - - GSocket *socket; -}; - -#define PINOS_CHANNEL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_CHANNEL, PinosChannelPrivate)) - -G_DEFINE_TYPE (PinosChannel, pinos_channel, G_TYPE_OBJECT); - -enum -{ - PROP_0, - PROP_DAEMON, - PROP_PORT, - PROP_OBJECT_PATH, - PROP_CLIENT_PATH, - PROP_DIRECTION, - PROP_POSSIBLE_FORMATS, - PROP_PROPERTIES, - PROP_FORMAT, - PROP_STATE, -}; - -enum -{ - SIGNAL_REMOVE, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static void -pinos_channel_get_property (GObject *_object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - PinosChannel *channel = PINOS_CHANNEL (_object); - PinosChannelPrivate *priv = channel->priv; - - switch (prop_id) { - case PROP_DAEMON: - g_value_set_object (value, priv->daemon); - break; - - case PROP_PORT: - g_value_set_object (value, priv->port); - break; - - case PROP_OBJECT_PATH: - g_value_set_string (value, priv->object_path); - break; - - case PROP_CLIENT_PATH: - g_value_set_string (value, priv->client_path); - break; - - case PROP_DIRECTION: - g_value_set_enum (value, priv->direction); - break; - - case PROP_POSSIBLE_FORMATS: - g_value_set_boxed (value, priv->possible_formats); - break; - - case PROP_PROPERTIES: - g_value_set_boxed (value, priv->properties); - break; - - case PROP_FORMAT: - g_value_set_boxed (value, priv->format); - break; - - case PROP_STATE: - g_value_set_uint (value, priv->state); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (channel, prop_id, pspec); - break; - } -} - -static void -pinos_channel_set_property (GObject *_object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - PinosChannel *channel = PINOS_CHANNEL (_object); - PinosChannelPrivate *priv = channel->priv; - - switch (prop_id) { - case PROP_DAEMON: - priv->daemon = g_value_dup_object (value); - break; - - case PROP_PORT: - priv->port = g_value_dup_object (value); - break; - - case PROP_OBJECT_PATH: - priv->object_path = g_value_dup_string (value); - break; - - case PROP_CLIENT_PATH: - priv->client_path = g_value_dup_string (value); - g_object_set (priv->iface, "client", priv->client_path, NULL); - break; - - case PROP_DIRECTION: - priv->direction = g_value_get_enum (value); - g_object_set (priv->iface, "direction", priv->direction, NULL); - break; - - case PROP_POSSIBLE_FORMATS: - if (priv->possible_formats) - g_bytes_unref (priv->possible_formats); - priv->possible_formats = g_value_dup_boxed (value); - g_object_set (priv->iface, "possible-formats", - g_bytes_get_data (priv->possible_formats, NULL), NULL); - break; - - case PROP_PROPERTIES: - if (priv->properties) - pinos_properties_free (priv->properties); - priv->properties = g_value_dup_boxed (value); - g_object_set (priv->iface, "properties", priv->properties ? - pinos_properties_to_variant (priv->properties) : NULL, NULL); - break; - - case PROP_FORMAT: - if (priv->format) - g_bytes_unref (priv->format); - priv->format = g_value_dup_boxed (value); - g_object_set (priv->iface, "format", priv->format ? - g_bytes_get_data (priv->format, NULL) : NULL, NULL); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (channel, prop_id, pspec); - break; - } -} - -static void -clear_formats (PinosChannel *channel) -{ - PinosChannelPrivate *priv = channel->priv; - - g_debug ("channel %p: clear format", channel); - - g_clear_pointer (&priv->format, g_bytes_unref); -} - -static void -stop_transfer (PinosChannel *channel) -{ - PinosChannelPrivate *priv = channel->priv; - - g_debug ("channel %p: stop transfer", channel); - - pinos_port_deactivate (priv->port); - clear_formats (channel); - priv->state = PINOS_CHANNEL_STATE_STOPPED; -} - -static gboolean -handle_remove (PinosChannel1 *interface, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - PinosChannel *channel = user_data; - - g_debug ("channel %p: handle remove", channel); - stop_transfer (channel); - - g_signal_emit (channel, signals[SIGNAL_REMOVE], 0, NULL); - - g_dbus_method_invocation_return_value (invocation, NULL); - - return TRUE; -} - -static gboolean -on_send_buffer (PinosPort *port, - PinosBuffer *buffer, - GError **error, - gpointer user_data) -{ - PinosChannel *channel = user_data; - PinosChannelPrivate *priv = channel->priv; - gboolean res; - - if (priv->state == PINOS_CHANNEL_STATE_STREAMING) - res = pinos_io_write_buffer (priv->fd, buffer, error); - else - res = TRUE; - - return res; -} - -static gboolean -parse_buffer (PinosChannel *channel, - PinosBuffer *pbuf) -{ - PinosBufferIter it; - PinosChannelPrivate *priv = channel->priv; - - pinos_buffer_iter_init (&it, pbuf); - while (pinos_buffer_iter_next (&it)) { - PinosPacketType type = pinos_buffer_iter_get_type (&it); - - switch (type) { - case PINOS_PACKET_TYPE_FORMAT_CHANGE: - { - PinosPacketFormatChange p; - GBytes *format, *req_format; - GError *error = NULL; - const gchar *format_str; - - if (!pinos_buffer_iter_parse_format_change (&it, &p)) - break; - - req_format = g_bytes_new_static (p.format, strlen (p.format) + 1); - format = pinos_format_filter (priv->possible_formats, req_format, &error); - g_bytes_unref (req_format); - - if (format == NULL) - break; - - format_str = g_bytes_get_data (format, NULL); - - g_debug ("channel %p: format change %s", channel, format_str); - g_object_set (priv->port, "possible-formats", format, NULL); - g_object_set (priv->iface, "format", format_str, NULL); - break; - } - case PINOS_PACKET_TYPE_START: - { - GBytes *format; - PinosBufferBuilder builder; - PinosPacketFormatChange fc; - PinosBuffer obuf; - guint8 buffer[1024]; - GError *error = NULL; - - pinos_port_activate (priv->port); - g_object_get (priv->port, "format", &format, NULL); - if (format == NULL) - break; - - fc.id = 0; - fc.format = g_bytes_get_data (format, NULL); - - g_debug ("channel %p: we are now streaming in format \"%s\"", channel, fc.format); - - priv->state = PINOS_CHANNEL_STATE_STREAMING; - pinos_buffer_builder_init_into (&builder, buffer, 1024, NULL, 0); - pinos_buffer_builder_add_format_change (&builder, &fc); - pinos_buffer_builder_add_empty (&builder, PINOS_PACKET_TYPE_STREAMING); - pinos_buffer_builder_end (&builder, &obuf); - g_object_set (priv->iface, "state", priv->state, NULL); - - if (!pinos_io_write_buffer (priv->fd, &obuf, &error)) { - g_warning ("channel %p: error writing buffer: %s", channel, error->message); - g_clear_error (&error); - } - - break; - } - case PINOS_PACKET_TYPE_STOP: - { - break; - } - case PINOS_PACKET_TYPE_REUSE_MEM: - { - break; - } - default: - g_warning ("unhandled packet %d", type); - break; - } - } - pinos_buffer_iter_end (&it); - - return TRUE; -} - -static gboolean -on_socket_condition (GSocket *socket, - GIOCondition condition, - gpointer user_data) -{ - PinosChannel *channel = user_data; - PinosChannelPrivate *priv = channel->priv; - - switch (condition) { - case G_IO_IN: - { - PinosBuffer *buffer = &priv->recv_buffer; - GError *error = NULL; - - if (!pinos_io_read_buffer (priv->fd, - buffer, - priv->recv_data, - MAX_BUFFER_SIZE, - priv->recv_fds, - MAX_FDS, - &error)) { - g_warning ("channel %p: failed to read buffer: %s", channel, error->message); - g_clear_error (&error); - return TRUE; - } - - parse_buffer (channel, buffer); - - if (!pinos_port_receive_buffer (priv->port, buffer, &error)) { - g_warning ("channel %p: port %p failed to receive buffer: %s", channel, priv->port, error->message); - g_clear_error (&error); - } - g_assert (pinos_buffer_unref (buffer) == FALSE); - break; - } - - case G_IO_OUT: - g_warning ("can do IO OUT\n"); - break; - - default: - break; - } - return TRUE; -} - -static void -handle_socket (PinosChannel *channel, GSocket *socket) -{ - PinosChannelPrivate *priv = channel->priv; - GMainContext *context = g_main_context_get_thread_default(); - - g_debug ("channel %p: handle socket in context %p", channel, context); - priv->fd = g_socket_get_fd (socket); - priv->socket_source = g_socket_create_source (socket, G_IO_IN, NULL); - g_source_set_callback (priv->socket_source, (GSourceFunc) on_socket_condition, channel, NULL); - g_source_attach (priv->socket_source, context); -} - -static void -unhandle_socket (PinosChannel *channel) -{ - PinosChannelPrivate *priv = channel->priv; - - g_debug ("channel %p: unhandle socket", channel); - if (priv->socket_source) { - g_source_destroy (priv->socket_source); - g_clear_pointer (&priv->socket_source, g_source_unref); - priv->fd = -1; - } -} - -/** - * pinos_channel_get_socket_pair: - * @channel: a #PinosChannel - * @error: a #GError - * - * Create or return a previously create socket pair for @channel. The - * Socket for the other end is returned. - * - * Returns: a #GSocket that can be used to send/receive buffers to channel. - */ -GSocket * -pinos_channel_get_socket_pair (PinosChannel *channel, - GError **error) -{ - PinosChannelPrivate *priv; - - g_return_val_if_fail (PINOS_IS_CHANNEL (channel), FALSE); - priv = channel->priv; - - if (priv->sockets[1] == NULL) { - int fd[2]; - - if (socketpair (AF_UNIX, SOCK_STREAM, 0, fd) != 0) - goto no_sockets; - - priv->sockets[0] = g_socket_new_from_fd (fd[0], error); - if (priv->sockets[0] == NULL) - goto create_failed; - - priv->sockets[1] = g_socket_new_from_fd (fd[1], error); - if (priv->sockets[1] == NULL) - goto create_failed; - - handle_socket (channel, priv->sockets[0]); - } - return g_object_ref (priv->sockets[1]); - - /* ERRORS */ -no_sockets: - { - g_set_error (error, - G_IO_ERROR, - g_io_error_from_errno (errno), - "could not create socketpair: %s", strerror (errno)); - return NULL; - } -create_failed: - { - g_clear_object (&priv->sockets[0]); - g_clear_object (&priv->sockets[1]); - return NULL; - } -} - -static void -channel_register_object (PinosChannel *channel) -{ - PinosChannelPrivate *priv = channel->priv; - PinosObjectSkeleton *skel; - gchar *name; - - priv->send_id = pinos_port_add_send_buffer_cb (priv->port, - on_send_buffer, - channel, - NULL); - - name = g_strdup_printf ("%s/channel", priv->client_path); - skel = pinos_object_skeleton_new (name); - g_free (name); - - pinos_object_skeleton_set_channel1 (skel, priv->iface); - - g_free (priv->object_path); - priv->object_path = pinos_daemon_export_uniquely (priv->daemon, G_DBUS_OBJECT_SKELETON (skel)); - g_object_unref (skel); - - g_debug ("channel %p: register object %s", channel, priv->object_path); -} - -static void -channel_unregister_object (PinosChannel *channel) -{ - PinosChannelPrivate *priv = channel->priv; - - pinos_port_remove_send_buffer_cb (priv->port, priv->send_id); - - g_debug ("channel %p: unregister object", channel); - pinos_daemon_unexport (priv->daemon, priv->object_path); -} - -static void -pinos_channel_dispose (GObject * object) -{ - PinosChannel *channel = PINOS_CHANNEL (object); - PinosChannelPrivate *priv = channel->priv; - - g_debug ("channel %p: dispose", channel); - pinos_port_deactivate (priv->port); - clear_formats (channel); - unhandle_socket (channel); - channel_unregister_object (channel); - - G_OBJECT_CLASS (pinos_channel_parent_class)->dispose (object); -} - -static void -pinos_channel_finalize (GObject * object) -{ - PinosChannel *channel = PINOS_CHANNEL (object); - PinosChannelPrivate *priv = channel->priv; - - g_debug ("channel %p: finalize", channel); - if (priv->possible_formats) - g_bytes_unref (priv->possible_formats); - if (priv->properties) - pinos_properties_free (priv->properties); - g_clear_object (&priv->port); - g_clear_object (&priv->daemon); - g_clear_object (&priv->iface); - g_free (priv->client_path); - g_free (priv->object_path); - - G_OBJECT_CLASS (pinos_channel_parent_class)->finalize (object); -} - -static void -pinos_channel_constructed (GObject * object) -{ - PinosChannel *channel = PINOS_CHANNEL (object); - - g_debug ("channel %p: constructed", channel); - channel_register_object (channel); - - G_OBJECT_CLASS (pinos_channel_parent_class)->constructed (object); -} - -static void -pinos_channel_class_init (PinosChannelClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (PinosChannelPrivate)); - - gobject_class->constructed = pinos_channel_constructed; - gobject_class->dispose = pinos_channel_dispose; - gobject_class->finalize = pinos_channel_finalize; - gobject_class->set_property = pinos_channel_set_property; - gobject_class->get_property = pinos_channel_get_property; - - g_object_class_install_property (gobject_class, - PROP_DAEMON, - g_param_spec_object ("daemon", - "Daemon", - "The Daemon", - PINOS_TYPE_DAEMON, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_PORT, - g_param_spec_object ("port", - "Port", - "The Port", - PINOS_TYPE_PORT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_OBJECT_PATH, - g_param_spec_string ("object-path", - "Object Path", - "The object path", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_CLIENT_PATH, - g_param_spec_string ("client-path", - "Client Path", - "The client object path", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_DIRECTION, - g_param_spec_enum ("direction", - "Direction", - "The direction of the port", - PINOS_TYPE_DIRECTION, - PINOS_DIRECTION_INVALID, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_POSSIBLE_FORMATS, - g_param_spec_boxed ("possible-formats", - "Possible Formats", - "The possbile formats of the stream", - G_TYPE_BYTES, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_PROPERTIES, - g_param_spec_boxed ("properties", - "Properties", - "Extra properties of the stream", - PINOS_TYPE_PROPERTIES, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_FORMAT, - g_param_spec_boxed ("format", - "Format", - "The format of the stream", - G_TYPE_BYTES, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - signals[SIGNAL_REMOVE] = g_signal_new ("remove", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, - 0, - G_TYPE_NONE); -} - -static void -pinos_channel_init (PinosChannel * channel) -{ - PinosChannelPrivate *priv = channel->priv = PINOS_CHANNEL_GET_PRIVATE (channel); - - priv->iface = pinos_channel1_skeleton_new (); - g_signal_connect (priv->iface, "handle-remove", (GCallback) handle_remove, channel); - - priv->state = PINOS_CHANNEL_STATE_STOPPED; - g_object_set (priv->iface, "state", priv->state, NULL); - - priv->direction = PINOS_DIRECTION_INVALID; - - g_debug ("channel %p: new", channel); -} - -/** - * pinos_channel_remove: - * @channel: a #PinosChannel - * - * Remove @channel. This will stop the transfer on the channel and - * free the resources allocated by @channel. - */ -void -pinos_channel_remove (PinosChannel *channel) -{ - g_debug ("channel %p: remove", channel); - stop_transfer (channel); - - g_signal_emit (channel, signals[SIGNAL_REMOVE], 0, NULL); -} - -const gchar * -pinos_channel_get_client_path (PinosChannel *channel) -{ - PinosChannelPrivate *priv; - - g_return_val_if_fail (PINOS_IS_CHANNEL (channel), NULL); - priv = channel->priv; - - return priv->client_path; -} - -/** - * pinos_channel_get_object_path: - * @channel: a #PinosChannel - * - * Get the object patch of @channel - * - * Returns: the object path of @source. - */ -const gchar * -pinos_channel_get_object_path (PinosChannel *channel) -{ - PinosChannelPrivate *priv; - - g_return_val_if_fail (PINOS_IS_CHANNEL (channel), NULL); - priv = channel->priv; - - return priv->object_path; -} diff --git a/pinos/server/channel.h b/pinos/server/channel.h deleted file mode 100644 index 4a7bad28..00000000 --- a/pinos/server/channel.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Pinos - * Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com> - * - * 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. - */ - -#ifndef __PINOS_CHANNEL_H__ -#define __PINOS_CHANNEL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define PINOS_TYPE_CHANNEL (pinos_channel_get_type ()) -#define PINOS_IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_CHANNEL)) -#define PINOS_IS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_CHANNEL)) -#define PINOS_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_CHANNEL, PinosChannelClass)) -#define PINOS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_CHANNEL, PinosChannel)) -#define PINOS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_CHANNEL, PinosChannelClass)) -#define PINOS_CHANNEL_CAST(obj) ((PinosChannel*)(obj)) -#define PINOS_CHANNEL_CLASS_CAST(klass) ((PinosChannelClass*)(klass)) - -typedef struct _PinosChannel PinosChannel; -typedef struct _PinosChannelClass PinosChannelClass; -typedef struct _PinosChannelPrivate PinosChannelPrivate; - -/** - * PinosChannel: - * - * Pinos source channel object class. - */ -struct _PinosChannel { - GObject object; - - PinosChannelPrivate *priv; -}; - -/** - * PinosChannelClass: - * - * Pinos source channel object class. - */ -struct _PinosChannelClass { - GObjectClass parent_class; -}; - -/* normal GObject stuff */ -GType pinos_channel_get_type (void); - -void pinos_channel_remove (PinosChannel *channel); - -const gchar * pinos_channel_get_client_path (PinosChannel *channel); -const gchar * pinos_channel_get_object_path (PinosChannel *channel); - -GSocket * pinos_channel_get_socket_pair (PinosChannel *channel, - GError **error); - -G_END_DECLS - -#endif /* __PINOS_CHANNEL_H__ */ diff --git a/pinos/server/client-node.c b/pinos/server/client-node.c index 3423dadf..0be3954c 100644 --- a/pinos/server/client-node.c +++ b/pinos/server/client-node.c @@ -68,7 +68,7 @@ enum LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +//static guint signals[LAST_SIGNAL] = { 0 }; static void pinos_client_node_get_property (GObject *_object, @@ -175,6 +175,26 @@ parse_buffer (PinosClientNode *cnode, } case PINOS_PACKET_TYPE_STOP: { + PinosBufferBuilder builder; + PinosBuffer obuf; + guint8 buffer[1024]; + GError *error = NULL; + GList *ports, *walk; + + pinos_buffer_builder_init_into (&builder, buffer, 1024, NULL, 0); + + ports = pinos_node_get_ports (node); + for (walk = ports; walk; walk = g_list_next (walk)) { + port = walk->data; + pinos_port_deactivate (port); + } + pinos_buffer_builder_add_empty (&builder, PINOS_PACKET_TYPE_STOPPED); + pinos_buffer_builder_end (&builder, &obuf); + + if (!pinos_io_write_buffer (priv->fd, &obuf, &error)) { + g_warning ("client-node %p: error writing buffer: %s", node, error->message); + g_clear_error (&error); + } break; } case PINOS_PACKET_TYPE_REUSE_MEM: @@ -359,7 +379,6 @@ static void pinos_client_node_dispose (GObject * object) { PinosClientNode *node = PINOS_CLIENT_NODE (object); - PinosClientNodePrivate *priv = node->priv; g_debug ("client-node %p: dispose", node); unhandle_socket (node); @@ -371,7 +390,6 @@ static void pinos_client_node_finalize (GObject * object) { PinosClientNode *node = PINOS_CLIENT_NODE (object); - PinosClientNodePrivate *priv = node->priv; g_debug ("client-node %p: finalize", node); @@ -409,7 +427,7 @@ pinos_client_node_class_init (PinosClientNodeClass * klass) static void pinos_client_node_init (PinosClientNode * node) { - PinosClientNodePrivate *priv = node->priv = PINOS_CLIENT_NODE_GET_PRIVATE (node); + node->priv = PINOS_CLIENT_NODE_GET_PRIVATE (node); g_debug ("client-node %p: new", node); } diff --git a/pinos/server/daemon.c b/pinos/server/daemon.c index a22748a3..d5c961a5 100644 --- a/pinos/server/daemon.c +++ b/pinos/server/daemon.c @@ -30,7 +30,6 @@ #include "pinos/server/node.h" #include "pinos/server/client-node.h" #include "pinos/server/client.h" -#include "pinos/server/channel.h" #include "pinos/server/link.h" #include "pinos/dbus/org-pinos.h" @@ -107,117 +106,6 @@ sender_get_client (PinosDaemon *daemon, } static void -handle_remove_channel (PinosChannel *channel, - gpointer user_data) -{ - PinosClient *client = user_data; - - g_debug ("client %p: remove channel %p", client, channel); - pinos_client_remove_object (client, G_OBJECT (channel)); -} - -static gboolean -handle_create_channel (PinosDaemon1 *interface, - GDBusMethodInvocation *invocation, - const gchar *arg_node, - PinosDirection direction, - const gchar *arg_possible_formats, - GVariant *arg_properties, - gpointer user_data) -{ - PinosDaemon *daemon = user_data; - const gchar *sender, *object_path; - PinosProperties *props; - PinosClient *client; - PinosPort *port; - PinosChannel *channel; - GBytes *formats; - GError *error = NULL; - GUnixFDList *fdlist; - GSocket *socket; - gint fdidx; - - sender = g_dbus_method_invocation_get_sender (invocation); - - g_debug ("daemon %p: %s create channel", daemon, sender); - - formats = g_bytes_new (arg_possible_formats, strlen (arg_possible_formats) + 1); - props = pinos_properties_from_variant (arg_properties); - - port = pinos_daemon_find_port (daemon, - direction, - arg_node, - props, - formats, - &error); - if (port == NULL) - goto no_port; - - g_debug ("daemon %p: matched port %p", daemon, port); - - client = sender_get_client (daemon, sender); - - channel = pinos_port_create_channel (port, - pinos_client_get_object_path (client), - formats, - props, - &error); - pinos_properties_free (props); - g_bytes_unref (formats); - - if (channel == NULL) - goto no_channel; - - pinos_client_add_object (client, G_OBJECT (channel)); - - g_signal_connect (channel, - "remove", - (GCallback) handle_remove_channel, - client); - - socket = pinos_channel_get_socket_pair (channel, &error); - if (socket == NULL) - goto no_socket; - - object_path = pinos_channel_get_object_path (channel); - g_debug ("daemon %p: add channel %p, %s", daemon, channel, object_path); - - fdlist = g_unix_fd_list_new (); - fdidx = g_unix_fd_list_append (fdlist, g_socket_get_fd (socket), NULL); - - g_dbus_method_invocation_return_value_with_unix_fd_list (invocation, - g_variant_new ("(oh)", object_path, fdidx), fdlist); - g_object_unref (fdlist); - - return TRUE; - - /* ERRORS */ -no_port: - { - g_debug ("daemon %p: could not find port %s, %s", daemon, arg_node, error->message); - pinos_properties_free (props); - g_bytes_unref (formats); - goto exit_error; - } -no_channel: - { - g_debug ("daemon %p: could not create channel %s", daemon, error->message); - goto exit_error; - } -no_socket: - { - g_debug ("daemon %p: could not create channel %s", daemon, error->message); - goto exit_error; - } -exit_error: - { - g_dbus_method_invocation_return_gerror (invocation, error); - g_clear_error (&error); - return TRUE; - } -} - -static void handle_remove_node (PinosNode *node, gpointer user_data) { @@ -356,8 +244,13 @@ handle_create_client_node (PinosDaemon1 *interface, pprops, formats, &error); - if (target == NULL) + if (target == NULL) { + g_warning ("daemon %p: can't find port target: %s", daemon, error->message); + g_clear_error (&error); continue; + } + + pinos_client_add_object (client, G_OBJECT (target)); link = pinos_link_new (daemon, port, target, NULL); pinos_client_add_object (client, G_OBJECT (link)); @@ -653,7 +546,7 @@ pinos_daemon_find_port (PinosDaemon *daemon, have_name = name ? strlen (name) > 0 : FALSE; - g_debug ("name %s, format %s", name, (gchar*)g_bytes_get_data (format_filter, NULL)); + g_debug ("name %s, format %s, %d", name, (gchar*)g_bytes_get_data (format_filter, NULL), have_name); for (nodes = priv->nodes; nodes; nodes = g_list_next (nodes)) { PinosNode *n = nodes->data; @@ -662,7 +555,10 @@ pinos_daemon_find_port (PinosDaemon *daemon, g_debug ("node path %s", pinos_node_get_object_path (n)); /* we found the node */ - if (have_name && g_str_has_suffix (pinos_node_get_object_path (n), name)) { + if (have_name) { + if (!g_str_has_suffix (pinos_node_get_object_path (n), name)) + continue; + g_debug ("name \"%s\" matches node %p", name, n); node_found = TRUE; } @@ -842,7 +738,6 @@ pinos_daemon_init (PinosDaemon * daemon) priv->iface = pinos_daemon1_skeleton_new (); g_signal_connect (priv->iface, "handle-create-node", (GCallback) handle_create_node, daemon); g_signal_connect (priv->iface, "handle-create-client-node", (GCallback) handle_create_client_node, daemon); - g_signal_connect (priv->iface, "handle-create-channel", (GCallback) handle_create_channel, daemon); g_signal_connect (priv->iface, "handle-link-nodes", (GCallback) handle_link_nodes, daemon); priv->server_manager = g_dbus_object_manager_server_new (PINOS_DBUS_OBJECT_PREFIX); diff --git a/pinos/server/link.c b/pinos/server/link.c index 0bcef848..7f58addc 100644 --- a/pinos/server/link.c +++ b/pinos/server/link.c @@ -39,6 +39,8 @@ struct _PinosLinkPrivate gchar *object_path; + gulong input_id, output_id; + gboolean active; PinosPort *output; PinosPort *input; GBytes *possible_formats; @@ -203,10 +205,14 @@ on_activate (PinosPort *port, gpointer user_data) PinosLink *link = user_data; PinosLinkPrivate *priv = link->priv; + if (priv->active) + return TRUE; + if (priv->input == port) pinos_port_activate (priv->output); else pinos_port_activate (priv->input); + priv->active = TRUE; return TRUE; } @@ -217,10 +223,14 @@ on_deactivate (PinosPort *port, gpointer user_data) PinosLink *link = user_data; PinosLinkPrivate *priv = link->priv; + if (!priv->active) + return TRUE; + if (priv->input == port) pinos_port_deactivate (priv->output); else pinos_port_deactivate (priv->input); + priv->active = FALSE; return TRUE; } @@ -232,18 +242,20 @@ pinos_link_constructed (GObject * object) PinosLinkPrivate *priv = link->priv; GBytes *formats; - pinos_port_add_send_buffer_cb (priv->output, + priv->output_id = pinos_port_add_send_buffer_cb (priv->output, on_output_send, link, NULL); - pinos_port_add_send_buffer_cb (priv->input, + priv->input_id = pinos_port_add_send_buffer_cb (priv->input, on_input_send, link, NULL); g_object_get (priv->input, "possible-formats", &formats, NULL); g_object_set (priv->output, "possible-formats", formats, NULL); + g_object_get (priv->output, "format", &formats, NULL); + g_object_set (priv->input, "format", formats, NULL); g_signal_connect (priv->input, "activate", (GCallback) on_activate, link); g_signal_connect (priv->input, "deactivate", (GCallback) on_deactivate, link); @@ -260,8 +272,19 @@ static void pinos_link_dispose (GObject * object) { PinosLink *link = PINOS_LINK (object); + PinosLinkPrivate *priv = link->priv; g_debug ("link %p: dispose", link); + + pinos_port_remove_send_buffer_cb (priv->input, priv->input_id); + pinos_port_remove_send_buffer_cb (priv->output, priv->output_id); + if (priv->active) { + priv->active = FALSE; + pinos_port_deactivate (priv->input); + pinos_port_deactivate (priv->output); + } + g_clear_object (&priv->input); + g_clear_object (&priv->output); link_unregister_object (link); G_OBJECT_CLASS (pinos_link_parent_class)->dispose (object); diff --git a/pinos/server/port.c b/pinos/server/port.c index 738a96f0..a725ec82 100644 --- a/pinos/server/port.c +++ b/pinos/server/port.c @@ -625,66 +625,6 @@ parse_control_buffer (PinosPort *port, PinosBuffer *buffer) } } -/** - * pinos_port_create_channel: - * @port: a #PinosPort - * @client_path: the client path - * @format_filter: a #GBytes - * @props: #PinosProperties - * @prefix: a prefix - * @error: a #GError or %NULL - * - * Create a new #PinosChannel for @port. - * - * Returns: a new #PinosChannel or %NULL, in wich case @error will contain - * more information about the error. - */ -PinosChannel * -pinos_port_create_channel (PinosPort *port, - const gchar *client_path, - GBytes *format_filter, - PinosProperties *props, - GError **error) -{ - PinosPortPrivate *priv; - PinosChannel *channel; - GBytes *possible_formats; - - g_return_val_if_fail (PINOS_IS_PORT (port), NULL); - priv = port->priv; - - possible_formats = pinos_port_filter_formats (port, format_filter, error); - if (possible_formats == NULL) - return NULL; - - g_debug ("port %p: make channel with formats %s", port, - (gchar *) g_bytes_get_data (possible_formats, NULL)); - - channel = g_object_new (PINOS_TYPE_CHANNEL, "daemon", priv->daemon, - "port", port, - "client-path", client_path, - "direction", priv->direction, - "possible-formats", possible_formats, - "properties", props, - NULL); - g_bytes_unref (possible_formats); - - if (channel == NULL) - goto no_channel; - - return channel; - - /* ERRORS */ -no_channel: - { - if (error) - *error = g_error_new (G_IO_ERROR, - G_IO_ERROR_FAILED, - "Could not create channel"); - return NULL; - } -} - void pinos_port_activate (PinosPort *port) { diff --git a/pinos/server/port.h b/pinos/server/port.h index fda644d3..27c2898b 100644 --- a/pinos/server/port.h +++ b/pinos/server/port.h @@ -30,7 +30,6 @@ typedef struct _PinosPortPrivate PinosPortPrivate; #include <pinos/client/introspect.h> #include <pinos/client/buffer.h> -#include <pinos/server/channel.h> #include <pinos/server/daemon.h> #define PINOS_TYPE_PORT (pinos_port_get_type ()) @@ -95,12 +94,6 @@ GBytes * pinos_port_get_format (PinosPort *port); void pinos_port_activate (PinosPort *port); void pinos_port_deactivate (PinosPort *port); -PinosChannel * pinos_port_create_channel (PinosPort *port, - const gchar *client_path, - GBytes *format_filter, - PinosProperties *props, - GError **error); - gboolean pinos_port_send_buffer (PinosPort *port, PinosBuffer *buffer, GError **error); |