1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #include "cast/streaming/sender_message.h"
6*3f982cf4SFabien Sanglard
7*3f982cf4SFabien Sanglard #include <utility>
8*3f982cf4SFabien Sanglard
9*3f982cf4SFabien Sanglard #include "absl/strings/ascii.h"
10*3f982cf4SFabien Sanglard #include "cast/streaming/message_fields.h"
11*3f982cf4SFabien Sanglard #include "util/base64.h"
12*3f982cf4SFabien Sanglard #include "util/enum_name_table.h"
13*3f982cf4SFabien Sanglard #include "util/json/json_helpers.h"
14*3f982cf4SFabien Sanglard #include "util/json/json_serialization.h"
15*3f982cf4SFabien Sanglard
16*3f982cf4SFabien Sanglard namespace openscreen {
17*3f982cf4SFabien Sanglard namespace cast {
18*3f982cf4SFabien Sanglard
19*3f982cf4SFabien Sanglard namespace {
20*3f982cf4SFabien Sanglard
21*3f982cf4SFabien Sanglard EnumNameTable<SenderMessage::Type, 4> kMessageTypeNames{
22*3f982cf4SFabien Sanglard {{kMessageTypeOffer, SenderMessage::Type::kOffer},
23*3f982cf4SFabien Sanglard {"GET_CAPABILITIES", SenderMessage::Type::kGetCapabilities},
24*3f982cf4SFabien Sanglard {"RPC", SenderMessage::Type::kRpc}}};
25*3f982cf4SFabien Sanglard
GetMessageType(const Json::Value & root)26*3f982cf4SFabien Sanglard SenderMessage::Type GetMessageType(const Json::Value& root) {
27*3f982cf4SFabien Sanglard std::string type;
28*3f982cf4SFabien Sanglard if (!json::TryParseString(root[kMessageType], &type)) {
29*3f982cf4SFabien Sanglard return SenderMessage::Type::kUnknown;
30*3f982cf4SFabien Sanglard }
31*3f982cf4SFabien Sanglard
32*3f982cf4SFabien Sanglard absl::AsciiStrToUpper(&type);
33*3f982cf4SFabien Sanglard ErrorOr<SenderMessage::Type> parsed = GetEnum(kMessageTypeNames, type);
34*3f982cf4SFabien Sanglard
35*3f982cf4SFabien Sanglard return parsed.value(SenderMessage::Type::kUnknown);
36*3f982cf4SFabien Sanglard }
37*3f982cf4SFabien Sanglard
38*3f982cf4SFabien Sanglard } // namespace
39*3f982cf4SFabien Sanglard
40*3f982cf4SFabien Sanglard // static
Parse(const Json::Value & value)41*3f982cf4SFabien Sanglard ErrorOr<SenderMessage> SenderMessage::Parse(const Json::Value& value) {
42*3f982cf4SFabien Sanglard if (!value) {
43*3f982cf4SFabien Sanglard return Error(Error::Code::kParameterInvalid, "Empty JSON");
44*3f982cf4SFabien Sanglard }
45*3f982cf4SFabien Sanglard
46*3f982cf4SFabien Sanglard SenderMessage message;
47*3f982cf4SFabien Sanglard if (!json::TryParseInt(value[kSequenceNumber], &(message.sequence_number))) {
48*3f982cf4SFabien Sanglard message.sequence_number = -1;
49*3f982cf4SFabien Sanglard }
50*3f982cf4SFabien Sanglard
51*3f982cf4SFabien Sanglard message.type = GetMessageType(value);
52*3f982cf4SFabien Sanglard switch (message.type) {
53*3f982cf4SFabien Sanglard case Type::kOffer: {
54*3f982cf4SFabien Sanglard Offer offer;
55*3f982cf4SFabien Sanglard if (Offer::TryParse(value[kOfferMessageBody], &offer).ok()) {
56*3f982cf4SFabien Sanglard message.body = std::move(offer);
57*3f982cf4SFabien Sanglard message.valid = true;
58*3f982cf4SFabien Sanglard }
59*3f982cf4SFabien Sanglard } break;
60*3f982cf4SFabien Sanglard
61*3f982cf4SFabien Sanglard case Type::kRpc: {
62*3f982cf4SFabien Sanglard std::string rpc_body;
63*3f982cf4SFabien Sanglard std::vector<uint8_t> rpc;
64*3f982cf4SFabien Sanglard if (json::TryParseString(value[kRpcMessageBody], &rpc_body) &&
65*3f982cf4SFabien Sanglard base64::Decode(rpc_body, &rpc)) {
66*3f982cf4SFabien Sanglard message.body = rpc;
67*3f982cf4SFabien Sanglard message.valid = true;
68*3f982cf4SFabien Sanglard }
69*3f982cf4SFabien Sanglard } break;
70*3f982cf4SFabien Sanglard
71*3f982cf4SFabien Sanglard case Type::kGetCapabilities:
72*3f982cf4SFabien Sanglard message.valid = true;
73*3f982cf4SFabien Sanglard break;
74*3f982cf4SFabien Sanglard
75*3f982cf4SFabien Sanglard default:
76*3f982cf4SFabien Sanglard break;
77*3f982cf4SFabien Sanglard }
78*3f982cf4SFabien Sanglard
79*3f982cf4SFabien Sanglard return message;
80*3f982cf4SFabien Sanglard }
81*3f982cf4SFabien Sanglard
ToJson() const82*3f982cf4SFabien Sanglard ErrorOr<Json::Value> SenderMessage::ToJson() const {
83*3f982cf4SFabien Sanglard OSP_CHECK(type != SenderMessage::Type::kUnknown)
84*3f982cf4SFabien Sanglard << "Trying to send an unknown message is a developer error";
85*3f982cf4SFabien Sanglard
86*3f982cf4SFabien Sanglard Json::Value root;
87*3f982cf4SFabien Sanglard ErrorOr<const char*> message_type = GetEnumName(kMessageTypeNames, type);
88*3f982cf4SFabien Sanglard root[kMessageType] = message_type.value();
89*3f982cf4SFabien Sanglard if (sequence_number >= 0) {
90*3f982cf4SFabien Sanglard root[kSequenceNumber] = sequence_number;
91*3f982cf4SFabien Sanglard }
92*3f982cf4SFabien Sanglard
93*3f982cf4SFabien Sanglard switch (type) {
94*3f982cf4SFabien Sanglard case SenderMessage::Type::kOffer:
95*3f982cf4SFabien Sanglard root[kOfferMessageBody] = absl::get<Offer>(body).ToJson();
96*3f982cf4SFabien Sanglard break;
97*3f982cf4SFabien Sanglard
98*3f982cf4SFabien Sanglard case SenderMessage::Type::kRpc:
99*3f982cf4SFabien Sanglard root[kRpcMessageBody] =
100*3f982cf4SFabien Sanglard base64::Encode(absl::get<std::vector<uint8_t>>(body));
101*3f982cf4SFabien Sanglard break;
102*3f982cf4SFabien Sanglard
103*3f982cf4SFabien Sanglard case SenderMessage::Type::kGetCapabilities:
104*3f982cf4SFabien Sanglard break;
105*3f982cf4SFabien Sanglard
106*3f982cf4SFabien Sanglard default:
107*3f982cf4SFabien Sanglard OSP_NOTREACHED();
108*3f982cf4SFabien Sanglard }
109*3f982cf4SFabien Sanglard return root;
110*3f982cf4SFabien Sanglard }
111*3f982cf4SFabien Sanglard
112*3f982cf4SFabien Sanglard } // namespace cast
113*3f982cf4SFabien Sanglard } // namespace openscreen
114