1 // Copyright 2013 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 "chrome/browser/extensions/api/cast_channel/cast_message_util.h" 6 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 "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" 12 #include "chrome/common/extensions/api/cast_channel.h" 13 14 namespace { 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"; 20 } // namespace 21 22 namespace extensions { 23 namespace api { 24 namespace cast_channel { 25 26 bool MessageInfoToCastMessage(const MessageInfo& message, 27 CastMessage* message_proto) { 28 DCHECK(message_proto); 29 message_proto->set_protocol_version(CastMessage_ProtocolVersion_CASTV2_1_0); 30 message_proto->set_source_id(message.source_id); 31 message_proto->set_destination_id(message.destination_id); 32 message_proto->set_namespace_(message.namespace_); 33 // Determine the type of the base::Value and set the message payload 34 // appropriately. 35 std::string data; 36 base::BinaryValue* real_value; 37 switch (message.data->GetType()) { 38 // JS string 39 case base::Value::TYPE_STRING: 40 if (message.data->GetAsString(&data)) { 41 message_proto->set_payload_type(CastMessage_PayloadType_STRING); 42 message_proto->set_payload_utf8(data); 43 } 44 break; 45 // JS ArrayBuffer 46 case base::Value::TYPE_BINARY: 47 real_value = static_cast<base::BinaryValue*>(message.data.get()); 48 if (real_value->GetBuffer()) { 49 message_proto->set_payload_type(CastMessage_PayloadType_BINARY); 50 message_proto->set_payload_binary(real_value->GetBuffer(), 51 real_value->GetSize()); 52 } 53 break; 54 default: 55 // Unknown value type. message_proto will remain uninitialized because 56 // payload_type is unset. 57 break; 58 } 59 return message_proto->IsInitialized(); 60 } 61 62 bool CastMessageToMessageInfo(const CastMessage& message_proto, 63 MessageInfo* message) { 64 DCHECK(message); 65 message->source_id = message_proto.source_id(); 66 message->destination_id = message_proto.destination_id(); 67 message->namespace_ = message_proto.namespace_(); 68 // Determine the type of the payload and fill base::Value appropriately. 69 scoped_ptr<base::Value> value; 70 switch (message_proto.payload_type()) { 71 case CastMessage_PayloadType_STRING: 72 if (message_proto.has_payload_utf8()) 73 value.reset(new base::StringValue(message_proto.payload_utf8())); 74 break; 75 case CastMessage_PayloadType_BINARY: 76 if (message_proto.has_payload_binary()) 77 value.reset(base::BinaryValue::CreateWithCopiedBuffer( 78 message_proto.payload_binary().data(), 79 message_proto.payload_binary().size())); 80 break; 81 default: 82 // Unknown payload type. value will remain unset. 83 break; 84 } 85 if (value.get()) { 86 DCHECK(!message->data.get()); 87 message->data.reset(value.release()); 88 return true; 89 } else { 90 return false; 91 } 92 } 93 94 std::string CastMessageToString(const CastMessage& message_proto) { 95 std::string out("{"); 96 out += "namespace = " + message_proto.namespace_(); 97 out += ", sourceId = " + message_proto.source_id(); 98 out += ", destId = " + message_proto.destination_id(); 99 out += ", type = " + base::IntToString(message_proto.payload_type()); 100 out += ", str = \"" + message_proto.payload_utf8() + "\"}"; 101 return out; 102 } 103 104 std::string AuthMessageToString(const DeviceAuthMessage& message) { 105 std::string out("{"); 106 if (message.has_challenge()) { 107 out += "\n challenge = {},"; 108 } 109 if (message.has_response()) { 110 out += "\n response = {"; 111 out += "\n signature = " + message.response().signature(); 112 out += "\n, certificate = " + 113 message.response().client_auth_certificate(); 114 out += "\n }"; 115 } 116 if (message.has_error()) { 117 out += "\n error = {"; 118 out += base::IntToString(message.error().error_type()); 119 out += "}"; 120 } 121 out += "}"; 122 return out; 123 } 124 125 void CreateAuthChallengeMessage(CastMessage* message_proto) { 126 CHECK(message_proto); 127 DeviceAuthMessage auth_message; 128 auth_message.mutable_challenge(); 129 std::string auth_message_string; 130 auth_message.SerializeToString(&auth_message_string); 131 132 message_proto->set_protocol_version(CastMessage_ProtocolVersion_CASTV2_1_0); 133 message_proto->set_source_id(kPlatformSenderId); 134 message_proto->set_destination_id(kPlatformReceiverId); 135 message_proto->set_namespace_(kAuthNamespace); 136 message_proto->set_payload_type(CastMessage_PayloadType_BINARY); 137 message_proto->set_payload_binary(auth_message_string); 138 } 139 140 bool IsAuthMessage(const CastMessage& message) { 141 return message.namespace_() == kAuthNamespace; 142 } 143 144 } // namespace cast_channel 145 } // namespace api 146 } // namespace extensions 147