1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-16 00:00:02 +01:00
VILLASnode/lib/nodes/webrtc/signaling_message.cpp
Steffen Vogel 2d4783599f webrtc: signaling almost working
Signed-off-by: Steffen Vogel <post@steffenvogel.de>
2023-06-16 16:27:54 +02:00

185 lines
4.1 KiB
C++

/** WebRTC signaling messages.
*
* @author Steffen Vogel <svogel2@eonerc.rwth-aachen.de>
* @copyright 2014-2022, Institute for Automation of Complex Power Systems, EONERC
* @license Apache 2.0
*********************************************************************************/
#include <villas/exceptions.hpp>
#include <villas/nodes/webrtc/signaling_message.hpp>
using namespace villas;
using namespace villas::node;
using namespace villas::node::webrtc;
json_t * Connection::toJSON() const
{
return json_pack("{ s: i, s: s, s: s, s: s }",
"id", id,
"remote", remote.c_str(),
"user_agent", userAgent.c_str(),
"created", "" // TODO
);
}
Connection::Connection(json_t *j)
{
const char *rem, *ua, *ts;
int ret = json_unpack(j, "{ s: i, s: s, s: s, s: s }",
"id", &id,
"remote", &rem,
"user_agent", &ua,
"created", &ts
);
if (ret)
throw RuntimeError("Failed to decode signaling message");
remote = rem;
userAgent = ua;
// TODO: created
}
json_t * ControlMessage::toJSON() const
{
json_t *json_connections = json_array();
for (auto &c : connections) {
json_t *json_connection = c.toJSON();
json_array_append(json_connections, json_connection);
}
return json_pack("{ s: i, s: o }",
"connection_id", connectionID,
"connections", json_connections
);
}
ControlMessage::ControlMessage(json_t *j)
{
int ret;
json_t *json_connections;
ret = json_unpack(j, "{ s: i, s: o }",
"connection_id", &connectionID,
"connections", &json_connections
);
if (ret)
throw RuntimeError("Failed to decode signaling message");
if (!json_is_array(json_connections))
throw RuntimeError("Failed to decode signaling message");
json_t *json_connection;
size_t i;
json_array_foreach(json_connections, i, json_connection)
connections.emplace_back(json_connection);
}
json_t * SignalingMessage::toJSON() const
{
switch (type) {
case TYPE_CONTROL:
return json_pack("{ s: s, s: o }",
"type", "control",
"control", control->toJSON()
);
case TYPE_OFFER:
case TYPE_ANSWER:
return json_pack("{ s: s, s: o }",
"type", type == TYPE_OFFER ? "offer" : "answer",
"description", std::string(*description).c_str()
);
case TYPE_CANDIDATE:
return json_pack("{ s: s, s: o }",
"type", "candidate",
"candidate", std::string(*candidate).c_str()
);
}
return nullptr;
}
std::string SignalingMessage::toString() const
{
switch (type) {
case TYPE_ANSWER:
return fmt::format("type=answer, description={}", std::string(*description));
case TYPE_OFFER:
return fmt::format("type=offer, description={}", std::string(*description));
case TYPE_CANDIDATE:
return fmt::format("type=candidate, candidate={}", std::string(*candidate));
case TYPE_CONTROL:
return fmt::format("type=control, control={}", json_dumps(control->toJSON(), 0));
}
return "";
}
SignalingMessage::SignalingMessage(rtc::Description desc, bool answer) :
type(answer ? TYPE_ANSWER : TYPE_OFFER),
description(new rtc::Description(desc))
{ }
SignalingMessage::SignalingMessage(rtc::Candidate cand) :
type(TYPE_CANDIDATE),
candidate(new rtc::Candidate(cand))
{ }
SignalingMessage::~SignalingMessage()
{
if (description)
delete description;
if (candidate)
delete candidate;
if (control)
delete control;
}
SignalingMessage::SignalingMessage(json_t *j) :
control(nullptr),
description(nullptr),
candidate(nullptr)
{
json_t *json_control = nullptr;
const char *desc = nullptr;
const char *cand = nullptr;
const char *typ = nullptr;
int ret = json_unpack(j, "{ s: s, s?: s, s?: s, s?: o }",
"type", &typ,
"description", &desc,
"candidate", &cand,
"control", &json_control
);
if (ret)
throw RuntimeError("Failed to decode signaling message");
if (!strcmp(typ, "offer")) {
type = TYPE_OFFER;
description = new rtc::Description(desc);
}
else if (!strcmp(typ, "answer")) {
type = TYPE_ANSWER;
description = new rtc::Description(desc);
}
else if (!strcmp(typ, "candidate")) {
type = TYPE_CANDIDATE;
candidate = new rtc::Candidate(cand);
}
else if (!strcmp(typ, "control")) {
type = TYPE_CONTROL;
control = new ControlMessage(json_control);
}
}