[Spice-devel] [PATCH spice-streaming-agent] RFC: Handle endian in protocol
Frediano Ziglio
fziglio at redhat.com
Fri Mar 9 13:33:04 UTC 2018
Use overloaded function to handle endianness without
having to specify bit length every time.
Signed-off-by: Frediano Ziglio <fziglio at 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
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,
--
2.14.3
More information about the Spice-devel
mailing list