1 // Copyright 2014 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.
5 #include "extensions/browser/api/cast_channel/cast_message_util.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/values.h"
11 #include "extensions/common/api/cast_channel.h"
12 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
15 static const char kAuthNamespace
[] =
16 "urn:x-cast:com.google.cast.tp.deviceauth";
17 // Sender and receiver IDs to use for platform messages.
18 static const char kPlatformSenderId
[] = "sender-0";
19 static const char kPlatformReceiverId
[] = "receiver-0";
22 namespace extensions
{
24 namespace cast_channel
{
26 bool MessageInfoToCastMessage(const MessageInfo
& message
,
27 CastMessage
* message_proto
) {
28 DCHECK(message_proto
);
32 message_proto
->set_protocol_version(CastMessage_ProtocolVersion_CASTV2_1_0
);
33 message_proto
->set_source_id(message
.source_id
);
34 message_proto
->set_destination_id(message
.destination_id
);
35 message_proto
->set_namespace_(message
.namespace_
);
36 // Determine the type of the base::Value and set the message payload
39 base::BinaryValue
* real_value
;
40 switch (message
.data
->GetType()) {
42 case base::Value::TYPE_STRING
:
43 if (message
.data
->GetAsString(&data
)) {
44 message_proto
->set_payload_type(CastMessage_PayloadType_STRING
);
45 message_proto
->set_payload_utf8(data
);
49 case base::Value::TYPE_BINARY
:
50 real_value
= static_cast<base::BinaryValue
*>(message
.data
.get());
51 if (real_value
->GetBuffer()) {
52 message_proto
->set_payload_type(CastMessage_PayloadType_BINARY
);
53 message_proto
->set_payload_binary(real_value
->GetBuffer(),
54 real_value
->GetSize());
58 // Unknown value type. message_proto will remain uninitialized because
59 // payload_type is unset.
62 return message_proto
->IsInitialized();
65 bool IsCastMessageValid(const CastMessage
& message_proto
) {
66 if (message_proto
.namespace_().empty() || message_proto
.source_id().empty() ||
67 message_proto
.destination_id().empty()) {
70 return (message_proto
.payload_type() == CastMessage_PayloadType_STRING
&&
71 message_proto
.has_payload_utf8()) ||
72 (message_proto
.payload_type() == CastMessage_PayloadType_BINARY
&&
73 message_proto
.has_payload_binary());
76 bool CastMessageToMessageInfo(const CastMessage
& message_proto
,
77 MessageInfo
* message
) {
79 message
->source_id
= message_proto
.source_id();
80 message
->destination_id
= message_proto
.destination_id();
81 message
->namespace_
= message_proto
.namespace_();
82 // Determine the type of the payload and fill base::Value appropriately.
83 scoped_ptr
<base::Value
> value
;
84 switch (message_proto
.payload_type()) {
85 case CastMessage_PayloadType_STRING
:
86 if (message_proto
.has_payload_utf8())
87 value
.reset(new base::StringValue(message_proto
.payload_utf8()));
89 case CastMessage_PayloadType_BINARY
:
90 if (message_proto
.has_payload_binary())
91 value
.reset(base::BinaryValue::CreateWithCopiedBuffer(
92 message_proto
.payload_binary().data(),
93 message_proto
.payload_binary().size()));
96 // Unknown payload type. value will remain unset.
100 DCHECK(!message
->data
.get());
101 message
->data
.reset(value
.release());
108 std::string
CastMessageToString(const CastMessage
& message_proto
) {
109 std::string
out("{");
110 out
+= "namespace = " + message_proto
.namespace_();
111 out
+= ", sourceId = " + message_proto
.source_id();
112 out
+= ", destId = " + message_proto
.destination_id();
113 out
+= ", type = " + base::IntToString(message_proto
.payload_type());
114 out
+= ", str = \"" + message_proto
.payload_utf8() + "\"}";
118 std::string
AuthMessageToString(const DeviceAuthMessage
& message
) {
119 std::string
out("{");
120 if (message
.has_challenge()) {
121 out
+= "challenge: {}, ";
123 if (message
.has_response()) {
124 out
+= "response: {signature: (";
125 out
+= base::UintToString(message
.response().signature().length());
126 out
+= " bytes), certificate: (";
127 out
+= base::UintToString(
128 message
.response().client_auth_certificate().length());
131 if (message
.has_error()) {
133 out
+= base::IntToString(message
.error().error_type());
140 void CreateAuthChallengeMessage(CastMessage
* message_proto
) {
141 CHECK(message_proto
);
142 DeviceAuthMessage auth_message
;
143 auth_message
.mutable_challenge();
144 std::string auth_message_string
;
145 auth_message
.SerializeToString(&auth_message_string
);
147 message_proto
->set_protocol_version(CastMessage_ProtocolVersion_CASTV2_1_0
);
148 message_proto
->set_source_id(kPlatformSenderId
);
149 message_proto
->set_destination_id(kPlatformReceiverId
);
150 message_proto
->set_namespace_(kAuthNamespace
);
151 message_proto
->set_payload_type(CastMessage_PayloadType_BINARY
);
152 message_proto
->set_payload_binary(auth_message_string
);
155 bool IsAuthMessage(const CastMessage
& message
) {
156 return message
.namespace_() == kAuthNamespace
;
159 } // namespace cast_channel
161 } // namespace extensions