Blame SOURCES/0006-stream-device-Add-device-to-handle-streaming.patch

7bbc9c
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
7bbc9c
From: Frediano Ziglio <fziglio@redhat.com>
7bbc9c
Date: Sat, 21 Jan 2017 11:24:58 +0000
7bbc9c
Subject: [spice-server] stream-device: Add device to handle streaming
7bbc9c
7bbc9c
Add a stub device in guest.
7bbc9c
The aim of this device is to make it possible for the guest to send a
7bbc9c
stream through a DisplayChannel (in the sense of protocol channel).
7bbc9c
This stub allows the guest to send some data and you can see some debug
7bbc9c
lines of data arrived on host logs.
7bbc9c
7bbc9c
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
7bbc9c
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
7bbc9c
---
7bbc9c
 server/Makefile.am     |   1 +
7bbc9c
 server/char-device.h   |   1 +
7bbc9c
 server/reds.c          |   2 +
7bbc9c
 server/stream-device.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++
7bbc9c
 4 files changed, 134 insertions(+)
7bbc9c
 create mode 100644 server/stream-device.c
7bbc9c
7bbc9c
diff --git a/server/Makefile.am b/server/Makefile.am
7bbc9c
index 5d5590af9..f08ddf883 100644
7bbc9c
--- a/server/Makefile.am
7bbc9c
+++ b/server/Makefile.am
7bbc9c
@@ -166,6 +166,7 @@ libserver_la_SOURCES =				\
7bbc9c
 	stat.h					\
7bbc9c
 	stream.c				\
7bbc9c
 	stream.h				\
7bbc9c
+	stream-device.c				\
7bbc9c
 	sw-canvas.c				\
7bbc9c
 	tree.c					\
7bbc9c
 	tree.h					\
7bbc9c
diff --git a/server/char-device.h b/server/char-device.h
7bbc9c
index dccd576da..54a1ef939 100644
7bbc9c
--- a/server/char-device.h
7bbc9c
+++ b/server/char-device.h
7bbc9c
@@ -236,6 +236,7 @@ RedCharDevice *spicevmc_device_connect(RedsState *reds,
7bbc9c
                                        uint8_t channel_type);
7bbc9c
 void spicevmc_device_disconnect(RedsState *reds,
7bbc9c
                                 SpiceCharDeviceInstance *char_device);
7bbc9c
+RedCharDevice *stream_device_connect(RedsState *reds, SpiceCharDeviceInstance *sin);
7bbc9c
 
7bbc9c
 SpiceCharDeviceInterface *spice_char_device_get_interface(SpiceCharDeviceInstance *instance);
7bbc9c
 
7bbc9c
diff --git a/server/reds.c b/server/reds.c
7bbc9c
index 99b1fd76b..b24f61ab2 100644
7bbc9c
--- a/server/reds.c
7bbc9c
+++ b/server/reds.c
7bbc9c
@@ -3223,6 +3223,8 @@ static int spice_server_char_device_add_interface(SpiceServer *reds,
7bbc9c
     else if (strcmp(char_device->subtype, SUBTYPE_PORT) == 0) {
7bbc9c
         if (strcmp(char_device->portname, "org.spice-space.webdav.0") == 0) {
7bbc9c
             dev_state = spicevmc_device_connect(reds, char_device, SPICE_CHANNEL_WEBDAV);
7bbc9c
+        } else if (strcmp(char_device->portname, "com.redhat.stream.0") == 0) {
7bbc9c
+            dev_state = stream_device_connect(reds, char_device);
7bbc9c
         } else {
7bbc9c
             dev_state = spicevmc_device_connect(reds, char_device, SPICE_CHANNEL_PORT);
7bbc9c
         }
7bbc9c
diff --git a/server/stream-device.c b/server/stream-device.c
7bbc9c
new file mode 100644
7bbc9c
index 000000000..f3a147b80
7bbc9c
--- /dev/null
7bbc9c
+++ b/server/stream-device.c
7bbc9c
@@ -0,0 +1,130 @@
7bbc9c
+/* spice-server character device to handle a video stream
7bbc9c
+
7bbc9c
+   Copyright (C) 2017 Red Hat, Inc.
7bbc9c
+
7bbc9c
+   This library is free software; you can redistribute it and/or
7bbc9c
+   modify it under the terms of the GNU Lesser General Public
7bbc9c
+   License as published by the Free Software Foundation; either
7bbc9c
+   version 2.1 of the License, or (at your option) any later version.
7bbc9c
+
7bbc9c
+   This library is distributed in the hope that it will be useful,
7bbc9c
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
7bbc9c
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
7bbc9c
+   Lesser General Public License for more details.
7bbc9c
+
7bbc9c
+   You should have received a copy of the GNU Lesser General Public
7bbc9c
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
7bbc9c
+*/
7bbc9c
+#ifdef HAVE_CONFIG_H
7bbc9c
+#include <config.h>
7bbc9c
+#endif
7bbc9c
+
7bbc9c
+#include "char-device.h"
7bbc9c
+
7bbc9c
+#define TYPE_STREAM_DEVICE stream_device_get_type()
7bbc9c
+
7bbc9c
+#define STREAM_DEVICE(obj) \
7bbc9c
+    (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_STREAM_DEVICE, StreamDevice))
7bbc9c
+#define STREAM_DEVICE_CLASS(klass) \
7bbc9c
+    (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_STREAM_DEVICE, StreamDeviceClass))
7bbc9c
+#define STREAM_DEVICE_GET_CLASS(obj) \
7bbc9c
+    (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_STREAM_DEVICE, StreamDeviceClass))
7bbc9c
+
7bbc9c
+typedef struct StreamDevice StreamDevice;
7bbc9c
+typedef struct StreamDeviceClass StreamDeviceClass;
7bbc9c
+
7bbc9c
+struct StreamDevice {
7bbc9c
+    RedCharDevice parent;
7bbc9c
+};
7bbc9c
+
7bbc9c
+struct StreamDeviceClass {
7bbc9c
+    RedCharDeviceClass parent_class;
7bbc9c
+};
7bbc9c
+
7bbc9c
+static GType stream_device_get_type(void) G_GNUC_CONST;
7bbc9c
+static StreamDevice *stream_device_new(SpiceCharDeviceInstance *sin, RedsState *reds);
7bbc9c
+
7bbc9c
+G_DEFINE_TYPE(StreamDevice, stream_device, RED_TYPE_CHAR_DEVICE)
7bbc9c
+
7bbc9c
+static RedPipeItem *
7bbc9c
+stream_device_read_msg_from_dev(RedCharDevice *self, SpiceCharDeviceInstance *sin)
7bbc9c
+{
7bbc9c
+    SpiceCharDeviceInterface *sif;
7bbc9c
+    int n;
7bbc9c
+
7bbc9c
+    sif = spice_char_device_get_interface(sin);
7bbc9c
+
7bbc9c
+    do {
7bbc9c
+        uint8_t buf[256];
7bbc9c
+        n = sif->read(sin, buf, sizeof(buf));
7bbc9c
+        spice_debug("read %d bytes from device", n);
7bbc9c
+    } while (n > 0);
7bbc9c
+
7bbc9c
+    return NULL;
7bbc9c
+}
7bbc9c
+
7bbc9c
+static void
7bbc9c
+stream_device_send_msg_to_client(RedCharDevice *self, RedPipeItem *msg, RedClient *client)
7bbc9c
+{
7bbc9c
+}
7bbc9c
+
7bbc9c
+static void
7bbc9c
+stream_device_send_tokens_to_client(RedCharDevice *self, RedClient *client, uint32_t tokens)
7bbc9c
+{
7bbc9c
+    spice_printerr("Not implemented!");
7bbc9c
+}
7bbc9c
+
7bbc9c
+static void
7bbc9c
+stream_device_remove_client(RedCharDevice *self, RedClient *client)
7bbc9c
+{
7bbc9c
+}
7bbc9c
+
7bbc9c
+RedCharDevice *
7bbc9c
+stream_device_connect(RedsState *reds, SpiceCharDeviceInstance *sin)
7bbc9c
+{
7bbc9c
+    SpiceCharDeviceInterface *sif;
7bbc9c
+
7bbc9c
+    StreamDevice *dev = stream_device_new(sin, reds);
7bbc9c
+
7bbc9c
+    sif = spice_char_device_get_interface(sin);
7bbc9c
+    if (sif->state) {
7bbc9c
+        sif->state(sin, 1);
7bbc9c
+    }
7bbc9c
+
7bbc9c
+    return RED_CHAR_DEVICE(dev);
7bbc9c
+}
7bbc9c
+
7bbc9c
+static void
7bbc9c
+stream_device_dispose(GObject *object)
7bbc9c
+{
7bbc9c
+}
7bbc9c
+
7bbc9c
+static void
7bbc9c
+stream_device_class_init(StreamDeviceClass *klass)
7bbc9c
+{
7bbc9c
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
7bbc9c
+    RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass);
7bbc9c
+
7bbc9c
+    object_class->dispose = stream_device_dispose;
7bbc9c
+
7bbc9c
+    char_dev_class->read_one_msg_from_device = stream_device_read_msg_from_dev;
7bbc9c
+    char_dev_class->send_msg_to_client = stream_device_send_msg_to_client;
7bbc9c
+    char_dev_class->send_tokens_to_client = stream_device_send_tokens_to_client;
7bbc9c
+    char_dev_class->remove_client = stream_device_remove_client;
7bbc9c
+}
7bbc9c
+
7bbc9c
+static void
7bbc9c
+stream_device_init(StreamDevice *self)
7bbc9c
+{
7bbc9c
+}
7bbc9c
+
7bbc9c
+static StreamDevice *
7bbc9c
+stream_device_new(SpiceCharDeviceInstance *sin, RedsState *reds)
7bbc9c
+{
7bbc9c
+    return g_object_new(TYPE_STREAM_DEVICE,
7bbc9c
+                        "sin", sin,
7bbc9c
+                        "spice-server", reds,
7bbc9c
+                        "client-tokens-interval", 0ULL,
7bbc9c
+                        "self-tokens", ~0ULL,
7bbc9c
+                        NULL);
7bbc9c
+}