1 // Copyright 2019 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 #ifndef CAST_COMMON_CHANNEL_MESSAGE_UTIL_H_
6 #define CAST_COMMON_CHANNEL_MESSAGE_UTIL_H_
7 
8 #include <string>
9 
10 #include "absl/strings/string_view.h"
11 #include "cast/common/channel/proto/cast_channel.pb.h"
12 
13 namespace openscreen {
14 namespace cast {
15 
16 // Reserved message namespaces for internal messages.
17 static constexpr char kCastInternalNamespacePrefix[] =
18     "urn:x-cast:com.google.cast.";
19 static constexpr char kTransportNamespacePrefix[] =
20     "urn:x-cast:com.google.cast.tp.";
21 static constexpr char kAuthNamespace[] =
22     "urn:x-cast:com.google.cast.tp.deviceauth";
23 static constexpr char kHeartbeatNamespace[] =
24     "urn:x-cast:com.google.cast.tp.heartbeat";
25 static constexpr char kConnectionNamespace[] =
26     "urn:x-cast:com.google.cast.tp.connection";
27 static constexpr char kReceiverNamespace[] =
28     "urn:x-cast:com.google.cast.receiver";
29 static constexpr char kBroadcastNamespace[] =
30     "urn:x-cast:com.google.cast.broadcast";
31 static constexpr char kMediaNamespace[] = "urn:x-cast:com.google.cast.media";
32 
33 // Sender and receiver IDs to use for platform messages.
34 static constexpr char kPlatformSenderId[] = "sender-0";
35 static constexpr char kPlatformReceiverId[] = "receiver-0";
36 
37 static constexpr char kBroadcastId[] = "*";
38 
39 static constexpr ::cast::channel::CastMessage_ProtocolVersion
40     kDefaultOutgoingMessageVersion =
41         ::cast::channel::CastMessage_ProtocolVersion_CASTV2_1_0;
42 
43 // JSON message key strings.
44 static constexpr char kMessageKeyType[] = "type";
45 static constexpr char kMessageKeyProtocolVersion[] = "protocolVersion";
46 static constexpr char kMessageKeyProtocolVersionList[] = "protocolVersionList";
47 static constexpr char kMessageKeyReasonCode[] = "reasonCode";
48 static constexpr char kMessageKeyAppId[] = "appId";
49 static constexpr char kMessageKeyRequestId[] = "requestId";
50 static constexpr char kMessageKeyResponseType[] = "responseType";
51 static constexpr char kMessageKeyTransportId[] = "transportId";
52 static constexpr char kMessageKeySessionId[] = "sessionId";
53 
54 // JSON message field values.
55 static constexpr char kMessageTypeConnect[] = "CONNECT";
56 static constexpr char kMessageTypeClose[] = "CLOSE";
57 static constexpr char kMessageTypeConnected[] = "CONNECTED";
58 static constexpr char kMessageValueAppAvailable[] = "APP_AVAILABLE";
59 static constexpr char kMessageValueAppUnavailable[] = "APP_UNAVAILABLE";
60 
61 // JSON message key strings specific to CONNECT messages.
62 static constexpr char kMessageKeyBrowserVersion[] = "browserVersion";
63 static constexpr char kMessageKeyConnType[] = "connType";
64 static constexpr char kMessageKeyConnectionType[] = "connectionType";
65 static constexpr char kMessageKeyUserAgent[] = "userAgent";
66 static constexpr char kMessageKeyOrigin[] = "origin";
67 static constexpr char kMessageKeyPlatform[] = "platform";
68 static constexpr char kMessageKeySdkType[] = "skdType";
69 static constexpr char kMessageKeySenderInfo[] = "senderInfo";
70 static constexpr char kMessageKeyVersion[] = "version";
71 
72 // JSON message key strings specific to application control messages.
73 static constexpr char kMessageKeyAvailability[] = "availability";
74 static constexpr char kMessageKeyAppParams[] = "appParams";
75 static constexpr char kMessageKeyApplications[] = "applications";
76 static constexpr char kMessageKeyControlType[] = "controlType";
77 static constexpr char kMessageKeyDisplayName[] = "displayName";
78 static constexpr char kMessageKeyIsIdleScreen[] = "isIdleScreen";
79 static constexpr char kMessageKeyLaunchedFromCloud[] = "launchedFromCloud";
80 static constexpr char kMessageKeyLevel[] = "level";
81 static constexpr char kMessageKeyMuted[] = "muted";
82 static constexpr char kMessageKeyName[] = "name";
83 static constexpr char kMessageKeyNamespaces[] = "namespaces";
84 static constexpr char kMessageKeyReason[] = "reason";
85 static constexpr char kMessageKeyStatus[] = "status";
86 static constexpr char kMessageKeyStepInterval[] = "stepInterval";
87 static constexpr char kMessageKeyUniversalAppId[] = "universalAppId";
88 static constexpr char kMessageKeyUserEq[] = "userEq";
89 static constexpr char kMessageKeyVolume[] = "volume";
90 
91 // JSON message field value strings specific to application control messages.
92 static constexpr char kMessageValueAttenuation[] = "attenuation";
93 static constexpr char kMessageValueBadParameter[] = "BAD_PARAMETER";
94 static constexpr char kMessageValueInvalidSessionId[] = "INVALID_SESSION_ID";
95 static constexpr char kMessageValueInvalidCommand[] = "INVALID_COMMAND";
96 static constexpr char kMessageValueNotFound[] = "NOT_FOUND";
97 static constexpr char kMessageValueSystemError[] = "SYSTEM_ERROR";
98 
99 // TODO(crbug.com/openscreen/111): Add validation that each message type is
100 // received on the correct namespace.  This will probably involve creating a
101 // data structure for mapping between type and namespace.
102 enum class CastMessageType {
103   // Heartbeat messages.
104   kPing,
105   kPong,
106 
107   // RPC control/status messages used by Media Remoting. These occur at high
108   // frequency, up to dozens per second at times, and should not be logged.
109   kRpc,
110 
111   kGetAppAvailability,
112   kGetStatus,
113 
114   // Virtual connection request.
115   kConnect,
116 
117   // Close virtual connection.
118   kCloseConnection,
119 
120   // Application broadcast / precache.
121   kBroadcast,
122 
123   // Session launch request.
124   kLaunch,
125 
126   // Session stop request.
127   kStop,
128 
129   kReceiverStatus,
130   kMediaStatus,
131 
132   // Error from receiver.
133   kLaunchError,
134 
135   kOffer,
136   kAnswer,
137   kCapabilitiesResponse,
138   kStatusResponse,
139 
140   // The following values are part of the protocol but are not currently used.
141   kMultizoneStatus,
142   kInvalidPlayerState,
143   kLoadFailed,
144   kLoadCancelled,
145   kInvalidRequest,
146   kPresentation,
147   kGetCapabilities,
148 
149   kOther,  // Add new types above |kOther|.
150   kMaxValue = kOther,
151 };
152 
153 enum class AppAvailabilityResult {
154   kAvailable,
155   kUnavailable,
156   kUnknown,
157 };
158 
159 std::string ToString(AppAvailabilityResult availability);
160 
161 // TODO(crbug.com/openscreen/111): When this and/or other enums need the
162 // string->enum mapping, import EnumTable from Chromium's
163 // //components/cast_channel/enum_table.h.
CastMessageTypeToString(CastMessageType type)164 inline constexpr const char* CastMessageTypeToString(CastMessageType type) {
165   switch (type) {
166     case CastMessageType::kPing:
167       return "PING";
168     case CastMessageType::kPong:
169       return "PONG";
170     case CastMessageType::kRpc:
171       return "RPC";
172     case CastMessageType::kGetAppAvailability:
173       return "GET_APP_AVAILABILITY";
174     case CastMessageType::kGetStatus:
175       return "GET_STATUS";
176     case CastMessageType::kConnect:
177       return "CONNECT";
178     case CastMessageType::kCloseConnection:
179       return "CLOSE";
180     case CastMessageType::kBroadcast:
181       return "APPLICATION_BROADCAST";
182     case CastMessageType::kLaunch:
183       return "LAUNCH";
184     case CastMessageType::kStop:
185       return "STOP";
186     case CastMessageType::kReceiverStatus:
187       return "RECEIVER_STATUS";
188     case CastMessageType::kMediaStatus:
189       return "MEDIA_STATUS";
190     case CastMessageType::kLaunchError:
191       return "LAUNCH_ERROR";
192     case CastMessageType::kOffer:
193       return "OFFER";
194     case CastMessageType::kAnswer:
195       return "ANSWER";
196     case CastMessageType::kCapabilitiesResponse:
197       return "CAPABILITIES_RESPONSE";
198     case CastMessageType::kStatusResponse:
199       return "STATUS_RESPONSE";
200     case CastMessageType::kMultizoneStatus:
201       return "MULTIZONE_STATUS";
202     case CastMessageType::kInvalidPlayerState:
203       return "INVALID_PLAYER_STATE";
204     case CastMessageType::kLoadFailed:
205       return "LOAD_FAILED";
206     case CastMessageType::kLoadCancelled:
207       return "LOAD_CANCELLED";
208     case CastMessageType::kInvalidRequest:
209       return "INVALID_REQUEST";
210     case CastMessageType::kPresentation:
211       return "PRESENTATION";
212     case CastMessageType::kGetCapabilities:
213       return "GET_CAPABILITIES";
214     case CastMessageType::kOther:
215     default:
216       return "OTHER";
217   }
218 }
219 
IsAuthMessage(const::cast::channel::CastMessage & message)220 inline bool IsAuthMessage(const ::cast::channel::CastMessage& message) {
221   return message.namespace_() == kAuthNamespace;
222 }
223 
IsTransportNamespace(absl::string_view namespace_)224 inline bool IsTransportNamespace(absl::string_view namespace_) {
225   return (namespace_.size() > (sizeof(kTransportNamespacePrefix) - 1)) &&
226          (namespace_.find_first_of(kTransportNamespacePrefix) == 0);
227 }
228 
229 ::cast::channel::CastMessage MakeSimpleUTF8Message(
230     const std::string& namespace_,
231     std::string payload);
232 
233 ::cast::channel::CastMessage MakeConnectMessage(
234     const std::string& source_id,
235     const std::string& destination_id);
236 ::cast::channel::CastMessage MakeCloseMessage(
237     const std::string& source_id,
238     const std::string& destination_id);
239 
240 // Returns a session/transport ID string that is unique within this application
241 // instance, having the format "prefix-12345". For example, calling this with a
242 // |prefix| of "sender" will result in a string like "sender-12345".
243 std::string MakeUniqueSessionId(const char* prefix);
244 
245 }  // namespace cast
246 }  // namespace openscreen
247 
248 #endif  // CAST_COMMON_CHANNEL_MESSAGE_UTIL_H_
249