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