summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2017-01-25 09:51:01 +0000
committerFrediano Ziglio <fziglio@redhat.com>2017-01-25 09:53:22 +0000
commitb7536a5580702ac64f83f0a0ea13eea3f42424be (patch)
tree207482aea8bdcc294db7372e8c027a3114e076f2
parent8643276af8ac39f35ade93011b01fee793adaaaa (diff)
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac1
-rw-r--r--src/stream-send.c99
3 files changed, 100 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 272542f..3a13c55 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,6 +8,7 @@ common_sources = \
src_spice_stream_send_CFLAGS = \
$(SPICE_CFLAGS) \
+ $(GLIB2_CFLAGS) \
-I$(srcdir)/src \
$(NULL)
diff --git a/configure.ac b/configure.ac
index e44c667..e8dd6b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,6 +17,7 @@ AC_DEFINE(_GNU_SOURCE, [1], [Enable GNU extensions])
PKG_PROG_PKG_CONFIG
PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.8])
+PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.28])
# If no CFLAGS are set, set some sane default CFLAGS
if test "$ac_test_CFLAGS" != set; then
diff --git a/src/stream-send.c b/src/stream-send.c
index 27504c0..fee9961 100644
--- a/src/stream-send.c
+++ b/src/stream-send.c
@@ -22,10 +22,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
+#include <poll.h>
+#include <assert.h>
+#include <glib.h>
#include <spice/stream-device.h>
#include <spice/enums.h>
@@ -65,6 +69,82 @@ write_all(int fd, const void *buf, size_t len)
return written;
}
+static bool got_start = false;
+static bool got_stop = false;
+
+static void
+on_message(StreamDevType type, const uint8_t *data, size_t size)
+{
+ assert(type == STREAM_TYPE_STREAM_START);
+ assert(size >= sizeof(StreamMsgStart));
+
+ const StreamMsgStart *start = (const StreamMsgStart *) data;
+ if (start->num_codecs) {
+ printf("got start\n");
+ got_start = true;
+ } else {
+ printf("got stop\n");
+ got_stop = true;
+ }
+}
+
+static void
+on_data(void)
+{
+ static unsigned hdr_pos = 0;
+ static StreamDevHeader hdr;
+ static unsigned data_pos = 0;
+ static uint8_t data[128];
+
+ // read header
+ while (hdr_pos < sizeof(hdr)) {
+ int n = read(device_fd, ((uint8_t *) &hdr) + hdr_pos, sizeof(hdr) - hdr_pos);
+ if (n == -1 && errno == EINTR)
+ continue;
+ if (n == -1)
+ err(1, "read");
+ hdr_pos += n;
+ if (hdr_pos >= sizeof(hdr)) {
+ assert(hdr.protocol_version == STREAM_DEVICE_PROTOCOL);
+ hdr.type = GUINT16_FROM_LE(hdr.type);
+ hdr.size = GUINT32_FROM_LE(hdr.size);
+ data_pos = 0;
+ }
+ }
+
+ // read data
+ assert(hdr.size < sizeof(data));
+ while (data_pos < hdr.size) {
+ int n = read(device_fd, data + data_pos, hdr.size - data_pos);
+ if (n == -1 && errno == EINTR)
+ continue;
+ if (n == -1)
+ err(1, "read");
+ data_pos += n;
+ }
+
+ hdr_pos = 0;
+ on_message((StreamDevType) hdr.type, data, data_pos);
+}
+
+static int
+wait_read(int fd, int timeout)
+{
+ for (;;) {
+ struct pollfd poll_fd = { fd, POLLIN, 0 };
+ switch (poll(&poll_fd, 1, timeout)) {
+ case -1:
+ if (errno == EINTR)
+ continue;
+ err(1, "poll");
+ break;
+ case 0:
+ return 0;
+ }
+ return 1;
+ }
+}
+
int main(int argc, char *argv[])
{
int c;
@@ -107,7 +187,16 @@ int main(int argc, char *argv[])
if (!f_in) {
err(1, "open %s", fn);
}
-
+
+ // we must wait for beginning
+again:
+ while (!got_start) {
+ wait_read(device_fd, -1);
+ on_data();
+ }
+ got_start = got_stop = false;
+ rewind(f_in);
+
StreamDevHeader hdr;
hdr.protocol_version = STREAM_DEVICE_PROTOCOL;
hdr.padding = 0;
@@ -134,6 +223,14 @@ int main(int argc, char *argv[])
write_all(device_fd, &hdr, sizeof(hdr));
write_all(device_fd, buffer, l);
sleep(1);
+ // TODO check for request from host
+ if (wait_read(device_fd, 0)) {
+ on_data();
+ if (got_stop) {
+ got_start = got_stop = false;
+ goto again;
+ }
+ }
}
fclose(f_in);