Commit 8fc0e526 authored by Kevin Pouget's avatar Kevin Pouget Committed by Frediano Ziglio

spice-streaming-agent: handle capability negotiation

This patch completes the initial skeleton for capability negotiation.

It populates the outgoing message (CapabilitiesOutMessage) with a bit
array listing, for each known capability, if it is supported or not.

Likewise, it unpacks the capability message received from the server
(InCapabilitiesMessage) and calls the function
`server_capabilities_received` with a vector containing the
capabilities supported by the server.
Signed-off-by: Kevin Pouget's avatarKevin Pouget <kpouget@redhat.com>
Acked-by: Frediano Ziglio's avatarFrediano Ziglio <fziglio@redhat.com>
parent 65dd4f4a
Pipeline #124837 passed with stage
in 2 minutes and 53 seconds
......@@ -39,6 +39,8 @@
#include <vector>
#include <string>
#include <common/utils.h>
using namespace spice::streaming_agent;
class FormatMessage : public OutboundMessage<StreamMsgFormat, FormatMessage, STREAM_TYPE_FORMAT>
......@@ -81,14 +83,27 @@ public:
class CapabilitiesOutMessage : public OutboundMessage<StreamMsgCapabilities, CapabilitiesOutMessage, STREAM_TYPE_CAPABILITIES>
{
public:
CapabilitiesOutMessage(const std::vector<bool> &capabilities) : OutboundMessage() {}
static size_t size()
{
return sizeof(PayloadType);
uint8_t caps[AgentCapabilitiesBytes];
return sizeof(PayloadType) + sizeof(caps);
}
void write_message_body(StreamPort &stream_port)
void write_message_body(StreamPort &stream_port, const std::vector<bool> &capabilities)
{
// No body for capabilities message
uint8_t caps[AgentCapabilitiesBytes] = {};
size_t i = 0;
for (auto cap: capabilities) {
if (cap) {
set_bitmap(i, caps);
}
i++;
}
stream_port.write(caps, sizeof(caps));
}
};
......@@ -149,13 +164,31 @@ static bool have_something_to_read(StreamPort &stream_port, bool blocking)
return false;
}
static void server_capabilities_received(StreamPort &stream_port,
std::vector<bool> &server_capabilities)
{
#if 0 /* No capability defined at the moment */
/* Check here if the server supports the capability */
if (server_capabilities[STREAM_CAP_...]) {
...
}
#endif
}
static void read_command_from_device(StreamPort &stream_port)
{
InboundMessage in_message = stream_port.receive();
switch (in_message.header.type) {
case STREAM_TYPE_CAPABILITIES: {
stream_port.send<CapabilitiesOutMessage>();
InCapabilitiesMessage msg = in_message.get_payload<InCapabilitiesMessage>();
std::vector<bool> agent_capabilities(STREAM_CAP_END, false);
server_capabilities_received(stream_port, msg.capabilities);
// populate here the `agent_capabilities` vector
// agent_capabilities[STREAM_CAP_...] = true;
stream_port.send<CapabilitiesOutMessage>(agent_capabilities);
return;
}
case STREAM_TYPE_NOTIFY_ERROR: {
......
......@@ -14,6 +14,7 @@
#include <unistd.h>
#include <stdexcept>
#include <common/utils.h>
namespace spice {
namespace streaming_agent {
......@@ -52,8 +53,24 @@ StartStopMessage InboundMessage::get_payload<StartStopMessage>()
template<>
InCapabilitiesMessage InboundMessage::get_payload<InCapabilitiesMessage>()
{
// no capabilities yet
return InCapabilitiesMessage();
size_t msg_len = header.size;
if (msg_len > STREAM_MSG_CAPABILITIES_MAX_BYTES) {
throw std::runtime_error("Received Capabilities message is too long (" +
std::to_string(header.size) + " > " +
std::to_string(STREAM_MSG_CAPABILITIES_MAX_BYTES) + ")");
}
StreamMsgCapabilities *server_caps = (StreamMsgCapabilities *) data.get();
struct InCapabilitiesMessage msg;
size_t caps_len = std::min(msg_len*8, (size_t) STREAM_CAP_END);
for (size_t cap = 0; cap < caps_len; ++cap) {
msg.capabilities.push_back((bool) test_bitmap(cap, server_caps->capabilities));
}
for (size_t cap = caps_len; cap < (size_t) STREAM_CAP_END; ++cap) {
msg.capabilities.push_back(false);
}
return msg;
}
template<>
......
......@@ -16,6 +16,7 @@
#include <memory>
#include <mutex>
#include <set>
#include <vector>
namespace spice {
......@@ -47,7 +48,12 @@ struct StartStopMessage
std::set<SpiceVideoCodecType> client_codecs;
};
struct InCapabilitiesMessage {};
const size_t AgentCapabilitiesBytes = (STREAM_CAP_END + 7) / 8;
struct InCapabilitiesMessage
{
std::vector<bool> capabilities;
};
struct NotifyErrorMessage
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment