[spice-streaming-agent] RFC: Handle endian in protocol

Submitted by Frediano Ziglio on March 9, 2018, 1:33 p.m.

Details

Message ID 20180309133304.32241-1-fziglio@redhat.com
State New
Headers show
Series "RFC: Handle endian in protocol" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

Frediano Ziglio March 9, 2018, 1:33 p.m.
Use overloaded function to handle endianness without
having to specify bit length every time.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
---
This patch can wait other series, not really important at the moment
---
 src/Makefile.am               |  1 +
 src/byteswap.hpp              | 55 +++++++++++++++++++++++++++++++++++++++++++
 src/spice-streaming-agent.cpp | 50 +++++++++++++++++++--------------------
 3 files changed, 80 insertions(+), 26 deletions(-)
 create mode 100644 src/byteswap.hpp

Patch hide | download patch | download mbox

diff --git a/src/Makefile.am b/src/Makefile.am
index 606f51a..a7b2198 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -50,6 +50,7 @@  spice_streaming_agent_LDADD = \
 
 spice_streaming_agent_SOURCES = \
 	spice-streaming-agent.cpp \
+	byteswap.hpp \
 	concrete-agent.cpp \
 	concrete-agent.hpp \
 	mjpeg-fallback.cpp \
diff --git a/src/byteswap.hpp b/src/byteswap.hpp
new file mode 100644
index 0000000..bd466f6
--- /dev/null
+++ b/src/byteswap.hpp
@@ -0,0 +1,55 @@ 
+#ifndef SPICE_STREAMING_AGENT_BYTESWAP_HPP
+#define SPICE_STREAMING_AGENT_BYTESWAP_HPP
+
+#include <cstdint>
+#include <spice/macros.h>
+
+#if SPICE_ENDIAN == SPICE_ENDIAN_LITTLE
+#  define SPICE_STREAMING_AGENT_BYTESWAP(len, val) (val)
+#else
+#  define SPICE_STREAMING_AGENT_BYTESWAP(len, val) SPICE_BYTESWAP ## len(val)
+#endif
+
+inline void put_uint_le(uint8_t &out, uint8_t val)
+{
+    out = val;
+}
+
+inline void put_uint_le(uint16_t &out, uint16_t val)
+{
+    out = SPICE_STREAMING_AGENT_BYTESWAP(16, val);
+}
+
+inline void put_uint_le(uint32_t &out, uint32_t val)
+{
+    out = SPICE_STREAMING_AGENT_BYTESWAP(32, val);
+}
+
+inline void put_uint_le(uint64_t &out, uint64_t val)
+{
+    out = SPICE_STREAMING_AGENT_BYTESWAP(64, val);
+}
+
+inline uint8_t get_uint_le(const uint8_t &in)
+{
+    return in;
+}
+
+inline uint16_t get_uint_le(const uint16_t &in)
+{
+    return SPICE_STREAMING_AGENT_BYTESWAP(16, in);
+}
+
+inline uint32_t get_uint_le(const uint32_t &in)
+{
+    return SPICE_STREAMING_AGENT_BYTESWAP(32, in);
+}
+
+inline uint64_t get_uint_le(const uint64_t &in)
+{
+    return SPICE_STREAMING_AGENT_BYTESWAP(64, in);
+}
+
+#undef SPICE_STREAMING_AGENT_BYTESWAP
+
+#endif // SPICE_STREAMING_AGENT_BYTESWAP_HPP
diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp
index 777e330..ed4784e 100644
--- a/src/spice-streaming-agent.cpp
+++ b/src/spice-streaming-agent.cpp
@@ -7,6 +7,7 @@ 
 #include "concrete-agent.hpp"
 #include "hexdump.h"
 #include "mjpeg-fallback.hpp"
+#include "byteswap.hpp"
 
 #include <spice/stream-device.h>
 #include <spice/enums.h>
@@ -126,12 +127,9 @@  static void handle_stream_capabilities(uint32_t len)
 
     read_all(caps, len);
     // we currently do not support extensions so just reply so
-    StreamDevHeader hdr = {
-        STREAM_DEVICE_PROTOCOL,
-        0,
-        STREAM_TYPE_CAPABILITIES,
-        0
-    };
+    StreamDevHeader hdr{ };
+    put_uint_le(hdr.protocol_version, STREAM_DEVICE_PROTOCOL);
+    put_uint_le(hdr.type, STREAM_TYPE_CAPABILITIES);
     if (write_all(streamfd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
         throw std::runtime_error("error writing capabilities");
     }
@@ -155,7 +153,7 @@  static void handle_stream_error(size_t len)
     ((uint8_t *) &msg)[len_to_read] = '\0';
 
     syslog(LOG_ERR, "Received NotifyError message from the server: %d - %s\n",
-        msg.error_code, msg.msg);
+        get_uint_le(msg.error_code), msg.msg);
 
     if (len_to_read < len) {
         throw std::runtime_error("Received NotifyError message size " + std::to_string(len) +
@@ -179,15 +177,18 @@  static void read_command_from_device(void)
                                  " (expected is " + std::to_string(STREAM_DEVICE_PROTOCOL) + ")");
     }
 
-    switch (hdr.type) {
+    auto type = get_uint_le(hdr.type);
+    auto size = get_uint_le(hdr.size);
+
+    switch (type) {
     case STREAM_TYPE_CAPABILITIES:
-        return handle_stream_capabilities(hdr.size);
+        return handle_stream_capabilities(size);
     case STREAM_TYPE_NOTIFY_ERROR:
-        return handle_stream_error(hdr.size);
+        return handle_stream_error(size);
     case STREAM_TYPE_START_STOP:
-        return handle_stream_start_stop(hdr.size);
+        return handle_stream_start_stop(size);
     }
-    throw std::runtime_error("UNKNOWN msg of type " + std::to_string(hdr.type));
+    throw std::runtime_error("UNKNOWN msg of type " + std::to_string(type));
 }
 
 static int read_command(bool blocking)
@@ -229,17 +230,15 @@  write_all(int fd, const void *buf, const size_t len)
 
 static int spice_stream_send_format(unsigned w, unsigned h, unsigned c)
 {
-
-    SpiceStreamFormatMessage msg;
+    SpiceStreamFormatMessage msg{};
     const size_t msgsize = sizeof(msg);
     const size_t hdrsize  = sizeof(msg.hdr);
-    memset(&msg, 0, msgsize);
-    msg.hdr.protocol_version = STREAM_DEVICE_PROTOCOL;
-    msg.hdr.type = STREAM_TYPE_FORMAT;
-    msg.hdr.size = msgsize - hdrsize; /* includes only the body? */
-    msg.msg.width = w;
-    msg.msg.height = h;
-    msg.msg.codec = c;
+    put_uint_le(msg.hdr.protocol_version, STREAM_DEVICE_PROTOCOL);
+    put_uint_le(msg.hdr.type, STREAM_TYPE_FORMAT);
+    put_uint_le(msg.hdr.size, msgsize - hdrsize);
+    put_uint_le(msg.msg.width, w);
+    put_uint_le(msg.msg.height, h);
+    put_uint_le(msg.msg.codec, c);
     syslog(LOG_DEBUG, "writing format\n");
     std::lock_guard<std::mutex> stream_guard(stream_mtx);
     if (write_all(streamfd, &msg, msgsize) != msgsize) {
@@ -250,14 +249,13 @@  static int spice_stream_send_format(unsigned w, unsigned h, unsigned c)
 
 static int spice_stream_send_frame(const void *buf, const unsigned size)
 {
-    SpiceStreamDataMessage msg;
+    SpiceStreamDataMessage msg{};
     const size_t msgsize = sizeof(msg);
     ssize_t n;
 
-    memset(&msg, 0, msgsize);
-    msg.hdr.protocol_version = STREAM_DEVICE_PROTOCOL;
-    msg.hdr.type = STREAM_TYPE_DATA;
-    msg.hdr.size = size; /* includes only the body? */
+    put_uint_le(msg.hdr.protocol_version, STREAM_DEVICE_PROTOCOL);
+    put_uint_le(msg.hdr.type, STREAM_TYPE_DATA);
+    put_uint_le(msg.hdr.size, size);
     std::lock_guard<std::mutex> stream_guard(stream_mtx);
     n = write_all(streamfd, &msg, msgsize);
     syslog(LOG_DEBUG,