summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 21:38:46 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 21:38:46 +0000
commit88b460b939077577521fe6119a3682b17992eeae (patch)
tree97edbd2852b18015c524842a82d4459f5f21b2d6 /remoting
parent02de972eead4d567089d97635328ed520091389d (diff)
downloadchromium_src-88b460b939077577521fe6119a3682b17992eeae.zip
chromium_src-88b460b939077577521fe6119a3682b17992eeae.tar.gz
chromium_src-88b460b939077577521fe6119a3682b17992eeae.tar.bz2
Move ContentDescription class to a separate file.
BUG=None TEST=Compiles Review URL: http://codereview.chromium.org/7261011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90650 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/protocol/content_description.cc373
-rw-r--r--remoting/protocol/content_description.h66
-rw-r--r--remoting/protocol/jingle_session_manager.cc358
-rw-r--r--remoting/protocol/jingle_session_manager.h40
-rw-r--r--remoting/remoting.gyp2
5 files changed, 447 insertions, 392 deletions
diff --git a/remoting/protocol/content_description.cc b/remoting/protocol/content_description.cc
new file mode 100644
index 0000000..df289d8
--- /dev/null
+++ b/remoting/protocol/content_description.cc
@@ -0,0 +1,373 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/protocol/content_description.h"
+
+#include "base/base64.h"
+#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "remoting/base/constants.h"
+#include "remoting/proto/auth.pb.h"
+#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
+
+using buzz::QName;
+using buzz::XmlElement;
+
+namespace remoting {
+namespace protocol {
+
+namespace {
+
+const char kDefaultNs[] = "";
+
+const char kChromotingContentName[] = "chromoting";
+
+// Following constants are used to format session description in XML.
+const char kDescriptionTag[] = "description";
+const char kControlTag[] = "control";
+const char kEventTag[] = "event";
+const char kVideoTag[] = "video";
+const char kResolutionTag[] = "initial-resolution";
+const char kAuthenticationTag[] = "authentication";
+const char kCertificateTag[] = "certificate";
+const char kMasterKeyTag[] = "master-key";
+const char kAuthTokenTag[] = "auth-token";
+
+const char kTransportAttr[] = "transport";
+const char kVersionAttr[] = "version";
+const char kCodecAttr[] = "codec";
+const char kWidthAttr[] = "width";
+const char kHeightAttr[] = "height";
+
+const char kStreamTransport[] = "stream";
+const char kDatagramTransport[] = "datagram";
+const char kSrtpTransport[] = "srtp";
+const char kRtpDtlsTransport[] = "rtp-dtls";
+
+const char kVp8Codec[] = "vp8";
+const char kZipCodec[] = "zip";
+
+const char* GetTransportName(ChannelConfig::TransportType type) {
+ switch (type) {
+ case ChannelConfig::TRANSPORT_STREAM:
+ return kStreamTransport;
+ case ChannelConfig::TRANSPORT_DATAGRAM:
+ return kDatagramTransport;
+ case ChannelConfig::TRANSPORT_SRTP:
+ return kSrtpTransport;
+ case ChannelConfig::TRANSPORT_RTP_DTLS:
+ return kRtpDtlsTransport;
+ }
+ NOTREACHED();
+ return NULL;
+}
+
+const char* GetCodecName(ChannelConfig::Codec type) {
+ switch (type) {
+ case ChannelConfig::CODEC_VP8:
+ return kVp8Codec;
+ case ChannelConfig::CODEC_ZIP:
+ return kZipCodec;
+ default:
+ break;
+ }
+ NOTREACHED();
+ return NULL;
+}
+
+
+// Format a channel configuration tag for chromotocol session description,
+// e.g. for video channel:
+// <video transport="srtp" version="1" codec="vp8" />
+XmlElement* FormatChannelConfig(const ChannelConfig& config,
+ const std::string& tag_name) {
+ XmlElement* result = new XmlElement(
+ QName(kChromotingXmlNamespace, tag_name));
+
+ result->AddAttr(QName(kDefaultNs, kTransportAttr),
+ GetTransportName(config.transport));
+
+ result->AddAttr(QName(kDefaultNs, kVersionAttr),
+ base::IntToString(config.version));
+
+ if (config.codec != ChannelConfig::CODEC_UNDEFINED) {
+ result->AddAttr(QName(kDefaultNs, kCodecAttr),
+ GetCodecName(config.codec));
+ }
+
+ return result;
+}
+
+bool ParseTransportName(const std::string& value,
+ ChannelConfig::TransportType* transport) {
+ if (value == kStreamTransport) {
+ *transport = ChannelConfig::TRANSPORT_STREAM;
+ } else if (value == kDatagramTransport) {
+ *transport = ChannelConfig::TRANSPORT_DATAGRAM;
+ } else if (value == kSrtpTransport) {
+ *transport = ChannelConfig::TRANSPORT_SRTP;
+ } else if (value == kRtpDtlsTransport) {
+ *transport = ChannelConfig::TRANSPORT_RTP_DTLS;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool ParseCodecName(const std::string& value, ChannelConfig::Codec* codec) {
+ if (value == kVp8Codec) {
+ *codec = ChannelConfig::CODEC_VP8;
+ } else if (value == kZipCodec) {
+ *codec = ChannelConfig::CODEC_ZIP;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+// Returns false if the element is invalid.
+bool ParseChannelConfig(const XmlElement* element, bool codec_required,
+ ChannelConfig* config) {
+ if (!ParseTransportName(element->Attr(QName(kDefaultNs, kTransportAttr)),
+ &config->transport) ||
+ !base::StringToInt(element->Attr(QName(kDefaultNs, kVersionAttr)),
+ &config->version)) {
+ return false;
+ }
+
+ if (codec_required) {
+ if (!ParseCodecName(element->Attr(QName(kDefaultNs, kCodecAttr)),
+ &config->codec)) {
+ return false;
+ }
+ } else {
+ config->codec = ChannelConfig::CODEC_UNDEFINED;
+ }
+
+ return true;
+}
+
+} // namespace
+
+ContentDescription::ContentDescription(
+ const CandidateSessionConfig* candidate_config,
+ const std::string& auth_token,
+ const std::string& master_key,
+ scoped_refptr<net::X509Certificate> certificate)
+ : candidate_config_(candidate_config),
+ auth_token_(auth_token),
+ master_key_(master_key),
+ certificate_(certificate) {
+}
+
+ContentDescription::~ContentDescription() { }
+
+// ToXml() creates content description for chromoting session. The
+// description looks as follows:
+// <description xmlns="google:remoting">
+// <control transport="stream" version="1" />
+// <event transport="datagram" version="1" />
+// <video transport="srtp" codec="vp8" version="1" />
+// <initial-resolution width="800" height="600" />
+// <authentication>
+// <certificate>[BASE64 Encoded Certificate]</certificate>
+// <master-key>[master key encrypted with hosts
+// public key encoded with BASE64]</master-key>
+// <auth-token>...</auth-token> // IT2Me only.
+// </authentication>
+// </description>
+//
+XmlElement* ContentDescription::ToXml() const {
+ XmlElement* root = new XmlElement(
+ QName(kChromotingXmlNamespace, kDescriptionTag), true);
+
+ std::vector<ChannelConfig>::const_iterator it;
+
+ for (it = config()->control_configs().begin();
+ it != config()->control_configs().end(); ++it) {
+ root->AddElement(FormatChannelConfig(*it, kControlTag));
+ }
+
+ for (it = config()->event_configs().begin();
+ it != config()->event_configs().end(); ++it) {
+ root->AddElement(FormatChannelConfig(*it, kEventTag));
+ }
+
+ for (it = config()->video_configs().begin();
+ it != config()->video_configs().end(); ++it) {
+ root->AddElement(FormatChannelConfig(*it, kVideoTag));
+ }
+
+ XmlElement* resolution_tag = new XmlElement(
+ QName(kChromotingXmlNamespace, kResolutionTag));
+ resolution_tag->AddAttr(QName(kDefaultNs, kWidthAttr),
+ base::IntToString(
+ config()->initial_resolution().width));
+ resolution_tag->AddAttr(QName(kDefaultNs, kHeightAttr),
+ base::IntToString(
+ config()->initial_resolution().height));
+ root->AddElement(resolution_tag);
+
+ if (certificate() || !auth_token().empty()) {
+ XmlElement* authentication_tag = new XmlElement(
+ QName(kChromotingXmlNamespace, kAuthenticationTag));
+
+ if (certificate()) {
+ XmlElement* certificate_tag = new XmlElement(
+ QName(kChromotingXmlNamespace, kCertificateTag));
+
+ std::string der_cert;
+ if (!certificate()->GetDEREncoded(&der_cert)) {
+ LOG(DFATAL) << "Cannot obtain DER encoded certificate";
+ }
+
+ std::string base64_cert;
+ if (!base::Base64Encode(der_cert, &base64_cert)) {
+ LOG(DFATAL) << "Cannot perform base64 encode on certificate";
+ }
+
+ certificate_tag->SetBodyText(base64_cert);
+ authentication_tag->AddElement(certificate_tag);
+ }
+
+ if (!master_key().empty()) {
+ XmlElement* master_key_tag = new XmlElement(
+ QName(kChromotingXmlNamespace, kMasterKeyTag));
+
+ std::string master_key_base64;
+ if (!base::Base64Encode(master_key(), &master_key_base64)) {
+ LOG(DFATAL) << "Cannot perform base64 encode on master key";
+ }
+
+ master_key_tag->SetBodyText(master_key_base64);
+ authentication_tag->AddElement(master_key_tag);
+ }
+
+ if (!auth_token().empty()) {
+ XmlElement* auth_token_tag = new XmlElement(
+ QName(kChromotingXmlNamespace, kAuthTokenTag));
+ auth_token_tag->SetBodyText(auth_token());
+ authentication_tag->AddElement(auth_token_tag);
+ }
+
+ root->AddElement(authentication_tag);
+ }
+
+ return root;
+}
+
+// static
+cricket::ContentDescription* ContentDescription::ParseXml(
+ const XmlElement* element) {
+ if (element->Name() == QName(kChromotingXmlNamespace, kDescriptionTag)) {
+ scoped_ptr<CandidateSessionConfig> config(
+ CandidateSessionConfig::CreateEmpty());
+ const XmlElement* child = NULL;
+
+ // <control> tags.
+ QName control_tag(kChromotingXmlNamespace, kControlTag);
+ child = element->FirstNamed(control_tag);
+ while (child) {
+ ChannelConfig channel_config;
+ if (!ParseChannelConfig(child, false, &channel_config))
+ return NULL;
+ config->mutable_control_configs()->push_back(channel_config);
+ child = child->NextNamed(control_tag);
+ }
+
+ // <event> tags.
+ QName event_tag(kChromotingXmlNamespace, kEventTag);
+ child = element->FirstNamed(event_tag);
+ while (child) {
+ ChannelConfig channel_config;
+ if (!ParseChannelConfig(child, false, &channel_config))
+ return NULL;
+ config->mutable_event_configs()->push_back(channel_config);
+ child = child->NextNamed(event_tag);
+ }
+
+ // <video> tags.
+ QName video_tag(kChromotingXmlNamespace, kVideoTag);
+ child = element->FirstNamed(video_tag);
+ while (child) {
+ ChannelConfig channel_config;
+ if (!ParseChannelConfig(child, true, &channel_config))
+ return NULL;
+ config->mutable_video_configs()->push_back(channel_config);
+ child = child->NextNamed(video_tag);
+ }
+
+ // <initial-resolution> tag.
+ child = element->FirstNamed(QName(kChromotingXmlNamespace, kResolutionTag));
+ if (!child)
+ return NULL; // Resolution must always be specified.
+ int width;
+ int height;
+ if (!base::StringToInt(child->Attr(QName(kDefaultNs, kWidthAttr)),
+ &width) ||
+ !base::StringToInt(child->Attr(QName(kDefaultNs, kHeightAttr)),
+ &height)) {
+ return NULL;
+ }
+ ScreenResolution resolution(width, height);
+ if (!resolution.IsValid()) {
+ return NULL;
+ }
+
+ *config->mutable_initial_resolution() = resolution;
+
+ // Parse authentication information.
+ scoped_refptr<net::X509Certificate> certificate;
+ std::string auth_token;
+ std::string master_key;
+ child = element->FirstNamed(QName(kChromotingXmlNamespace,
+ kAuthenticationTag));
+ if (child) {
+ // Parse the certificate.
+ const XmlElement* cert_tag =
+ child->FirstNamed(QName(kChromotingXmlNamespace, kCertificateTag));
+ if (cert_tag) {
+ std::string base64_cert = cert_tag->BodyText();
+ std::string der_cert;
+ if (!base::Base64Decode(base64_cert, &der_cert)) {
+ LOG(ERROR) << "Failed to decode certificate received from the peer.";
+ return NULL;
+ }
+
+ certificate = net::X509Certificate::CreateFromBytes(der_cert.data(),
+ der_cert.length());
+ if (!certificate) {
+ LOG(ERROR) << "Failed to create platform-specific certificate handle";
+ return NULL;
+ }
+ }
+
+ // Parse master-key.
+ const XmlElement* master_key_tag =
+ child->FirstNamed(QName(kChromotingXmlNamespace, kMasterKeyTag));
+ if (master_key_tag) {
+ if (!base::Base64Decode(master_key_tag->BodyText(), &master_key)) {
+ LOG(ERROR) << "Failed to decode master-key received from the peer.";
+ return NULL;
+ }
+ master_key = master_key_tag->BodyText();
+ }
+
+ // Parse auth-token.
+ const XmlElement* auth_token_tag =
+ child->FirstNamed(QName(kChromotingXmlNamespace, kAuthTokenTag));
+ if (auth_token_tag) {
+ auth_token = auth_token_tag->BodyText();
+ }
+ }
+
+ return new ContentDescription(config.release(), auth_token, master_key,
+ certificate);
+ }
+ LOG(ERROR) << "Invalid description: " << element->Str();
+ return NULL;
+}
+
+} // namespace protocol
+} // namespace remoting
diff --git a/remoting/protocol/content_description.h b/remoting/protocol/content_description.h
new file mode 100644
index 0000000..3759838
--- /dev/null
+++ b/remoting/protocol/content_description.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_PROTOCOL_CONTENT_DESCRIPTION_H_
+#define REMOTING_PROTOCOL_CONTENT_DESCRIPTION_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "net/base/x509_certificate.h"
+#include "remoting/protocol/session_config.h"
+#include "third_party/libjingle/source/talk/p2p/base/sessiondescription.h"
+
+namespace buzz {
+class XmlElement;
+} // namespace buzz
+
+namespace remoting {
+namespace protocol {
+
+// ContentDescription used for chromoting sessions. It contains the information
+// from the content description stanza in the session intialization handshake.
+//
+// This class also provides a type abstraction so that the Chromotocol Session
+// interface does not need to depend on libjingle.
+class ContentDescription : public cricket::ContentDescription {
+ public:
+ explicit ContentDescription(const CandidateSessionConfig* config,
+ const std::string& auth_token,
+ const std::string& master_key,
+ scoped_refptr<net::X509Certificate> certificate);
+ virtual ~ContentDescription();
+
+ const CandidateSessionConfig* config() const {
+ return candidate_config_.get();
+ }
+
+ const std::string& auth_token() const { return auth_token_; }
+ const std::string& master_key() const { return master_key_; }
+ scoped_refptr<net::X509Certificate> certificate() const {
+ return certificate_;
+ }
+
+ buzz::XmlElement* ToXml() const;
+
+ static cricket::ContentDescription* ParseXml(const buzz::XmlElement* element);
+
+ private:
+ scoped_ptr<const CandidateSessionConfig> candidate_config_;
+
+ // This may contain the initiating, or the accepting token depending on
+ // context.
+ std::string auth_token_;
+
+ // Master key used for the session encrypted with the hosts key.
+ std::string master_key_;
+
+ scoped_refptr<net::X509Certificate> certificate_;
+};
+
+} // namespace protocol
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_CONTENT_DESCRIPTION_H_
diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc
index f665553..0c6e272 100644
--- a/remoting/protocol/jingle_session_manager.cc
+++ b/remoting/protocol/jingle_session_manager.cc
@@ -2,172 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <limits>
-
#include "remoting/protocol/jingle_session_manager.h"
-#include "base/base64.h"
+#include <limits>
+
#include "base/message_loop.h"
-#include "base/rand_util.h"
-#include "base/string_number_conversions.h"
#include "remoting/base/constants.h"
-#include "remoting/proto/auth.pb.h"
#include "third_party/libjingle/source/talk/p2p/base/constants.h"
#include "third_party/libjingle/source/talk/p2p/base/transport.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
-using buzz::QName;
using buzz::XmlElement;
namespace remoting {
namespace protocol {
-namespace {
-
-const char kDefaultNs[] = "";
-
-const char kChromotingContentName[] = "chromoting";
-
-// Following constants are used to format session description in XML.
-const char kDescriptionTag[] = "description";
-const char kControlTag[] = "control";
-const char kEventTag[] = "event";
-const char kVideoTag[] = "video";
-const char kResolutionTag[] = "initial-resolution";
-const char kAuthenticationTag[] = "authentication";
-const char kCertificateTag[] = "certificate";
-const char kMasterKeyTag[] = "master-key";
-const char kAuthTokenTag[] = "auth-token";
-
-const char kTransportAttr[] = "transport";
-const char kVersionAttr[] = "version";
-const char kCodecAttr[] = "codec";
-const char kWidthAttr[] = "width";
-const char kHeightAttr[] = "height";
-
-const char kStreamTransport[] = "stream";
-const char kDatagramTransport[] = "datagram";
-const char kSrtpTransport[] = "srtp";
-const char kRtpDtlsTransport[] = "rtp-dtls";
-
-const char kVp8Codec[] = "vp8";
-const char kZipCodec[] = "zip";
-
-const char* GetTransportName(ChannelConfig::TransportType type) {
- switch (type) {
- case ChannelConfig::TRANSPORT_STREAM:
- return kStreamTransport;
- case ChannelConfig::TRANSPORT_DATAGRAM:
- return kDatagramTransport;
- case ChannelConfig::TRANSPORT_SRTP:
- return kSrtpTransport;
- case ChannelConfig::TRANSPORT_RTP_DTLS:
- return kRtpDtlsTransport;
- }
- NOTREACHED();
- return NULL;
-}
-
-const char* GetCodecName(ChannelConfig::Codec type) {
- switch (type) {
- case ChannelConfig::CODEC_VP8:
- return kVp8Codec;
- case ChannelConfig::CODEC_ZIP:
- return kZipCodec;
- default:
- break;
- }
- NOTREACHED();
- return NULL;
-}
-
-
-// Format a channel configuration tag for chromotocol session description,
-// e.g. for video channel:
-// <video transport="srtp" version="1" codec="vp8" />
-XmlElement* FormatChannelConfig(const ChannelConfig& config,
- const std::string& tag_name) {
- XmlElement* result = new XmlElement(
- QName(kChromotingXmlNamespace, tag_name));
-
- result->AddAttr(QName(kDefaultNs, kTransportAttr),
- GetTransportName(config.transport));
-
- result->AddAttr(QName(kDefaultNs, kVersionAttr),
- base::IntToString(config.version));
-
- if (config.codec != ChannelConfig::CODEC_UNDEFINED) {
- result->AddAttr(QName(kDefaultNs, kCodecAttr),
- GetCodecName(config.codec));
- }
-
- return result;
-}
-
-bool ParseTransportName(const std::string& value,
- ChannelConfig::TransportType* transport) {
- if (value == kStreamTransport) {
- *transport = ChannelConfig::TRANSPORT_STREAM;
- } else if (value == kDatagramTransport) {
- *transport = ChannelConfig::TRANSPORT_DATAGRAM;
- } else if (value == kSrtpTransport) {
- *transport = ChannelConfig::TRANSPORT_SRTP;
- } else if (value == kRtpDtlsTransport) {
- *transport = ChannelConfig::TRANSPORT_RTP_DTLS;
- } else {
- return false;
- }
- return true;
-}
-
-bool ParseCodecName(const std::string& value, ChannelConfig::Codec* codec) {
- if (value == kVp8Codec) {
- *codec = ChannelConfig::CODEC_VP8;
- } else if (value == kZipCodec) {
- *codec = ChannelConfig::CODEC_ZIP;
- } else {
- return false;
- }
- return true;
-}
-
-// Returns false if the element is invalid.
-bool ParseChannelConfig(const XmlElement* element, bool codec_required,
- ChannelConfig* config) {
- if (!ParseTransportName(element->Attr(QName(kDefaultNs, kTransportAttr)),
- &config->transport) ||
- !base::StringToInt(element->Attr(QName(kDefaultNs, kVersionAttr)),
- &config->version)) {
- return false;
- }
-
- if (codec_required) {
- if (!ParseCodecName(element->Attr(QName(kDefaultNs, kCodecAttr)),
- &config->codec)) {
- return false;
- }
- } else {
- config->codec = ChannelConfig::CODEC_UNDEFINED;
- }
-
- return true;
-}
-
-} // namespace
-
-ContentDescription::ContentDescription(
- const CandidateSessionConfig* candidate_config,
- const std::string& auth_token,
- const std::string& master_key,
- scoped_refptr<net::X509Certificate> certificate)
- : candidate_config_(candidate_config),
- auth_token_(auth_token),
- master_key_(master_key),
- certificate_(certificate) {
-}
-
-ContentDescription::~ContentDescription() { }
-
JingleSessionManager::JingleSessionManager(MessageLoop* message_loop)
: message_loop_(message_loop),
cricket_session_manager_(NULL),
@@ -373,131 +222,10 @@ bool JingleSessionManager::ParseContent(
const XmlElement* element,
const cricket::ContentDescription** content,
cricket::ParseError* error) {
- if (element->Name() == QName(kChromotingXmlNamespace, kDescriptionTag)) {
- scoped_ptr<CandidateSessionConfig> config(
- CandidateSessionConfig::CreateEmpty());
- const XmlElement* child = NULL;
-
- // <control> tags.
- QName control_tag(kChromotingXmlNamespace, kControlTag);
- child = element->FirstNamed(control_tag);
- while (child) {
- ChannelConfig channel_config;
- if (!ParseChannelConfig(child, false, &channel_config))
- return false;
- config->mutable_control_configs()->push_back(channel_config);
- child = child->NextNamed(control_tag);
- }
-
- // <event> tags.
- QName event_tag(kChromotingXmlNamespace, kEventTag);
- child = element->FirstNamed(event_tag);
- while (child) {
- ChannelConfig channel_config;
- if (!ParseChannelConfig(child, false, &channel_config))
- return false;
- config->mutable_event_configs()->push_back(channel_config);
- child = child->NextNamed(event_tag);
- }
-
- // <video> tags.
- QName video_tag(kChromotingXmlNamespace, kVideoTag);
- child = element->FirstNamed(video_tag);
- while (child) {
- ChannelConfig channel_config;
- if (!ParseChannelConfig(child, true, &channel_config))
- return false;
- config->mutable_video_configs()->push_back(channel_config);
- child = child->NextNamed(video_tag);
- }
-
- // <initial-resolution> tag.
- child = element->FirstNamed(QName(kChromotingXmlNamespace, kResolutionTag));
- if (!child)
- return false; // Resolution must always be specified.
- int width;
- int height;
- if (!base::StringToInt(child->Attr(QName(kDefaultNs, kWidthAttr)),
- &width) ||
- !base::StringToInt(child->Attr(QName(kDefaultNs, kHeightAttr)),
- &height)) {
- return false;
- }
- ScreenResolution resolution(width, height);
- if (!resolution.IsValid()) {
- return false;
- }
-
- *config->mutable_initial_resolution() = resolution;
-
- // Parse authentication information.
- scoped_refptr<net::X509Certificate> certificate;
- std::string auth_token;
- std::string master_key;
- child = element->FirstNamed(QName(kChromotingXmlNamespace,
- kAuthenticationTag));
- if (child) {
- // Parse the certificate.
- const XmlElement* cert_tag =
- child->FirstNamed(QName(kChromotingXmlNamespace, kCertificateTag));
- if (cert_tag) {
- std::string base64_cert = cert_tag->BodyText();
- std::string der_cert;
- if (!base::Base64Decode(base64_cert, &der_cert)) {
- LOG(ERROR) << "Failed to decode certificate received from the peer.";
- return false;
- }
-
- certificate = net::X509Certificate::CreateFromBytes(der_cert.data(),
- der_cert.length());
- if (!certificate) {
- LOG(ERROR) << "Failed to create platform-specific certificate handle";
- return false;
- }
- }
-
- // Parse master-key.
- const XmlElement* master_key_tag =
- child->FirstNamed(QName(kChromotingXmlNamespace, kMasterKeyTag));
- if (master_key_tag) {
- if (!base::Base64Decode(master_key_tag->BodyText(), &master_key)) {
- LOG(ERROR) << "Failed to decode master-key received from the peer.";
- return false;
- }
- master_key = master_key_tag->BodyText();
- }
-
- // Parse auth-token.
- const XmlElement* auth_token_tag =
- child->FirstNamed(QName(kChromotingXmlNamespace, kAuthTokenTag));
- if (auth_token_tag) {
- auth_token = auth_token_tag->BodyText();
- }
- }
-
- *content = new ContentDescription(config.release(), auth_token, master_key,
- certificate);
- return true;
- }
- LOG(ERROR) << "Invalid description: " << element->Str();
- return false;
+ *content = ContentDescription::ParseXml(element);
+ return *content != NULL;
}
-// WriteContent creates content description for chromoting session. The
-// description looks as follows:
-// <description xmlns="google:remoting">
-// <control transport="stream" version="1" />
-// <event transport="datagram" version="1" />
-// <video transport="srtp" codec="vp8" version="1" />
-// <initial-resolution width="800" height="600" />
-// <authentication>
-// <certificate>[BASE64 Encoded Certificate]</certificate>
-// <master-key>[master key encrypted with hosts
-// public key encoded with BASE64]</master-key>
-// <auth-token>...</auth-token> // Me2Mom only.
-// </authentication>
-// </description>
-//
bool JingleSessionManager::WriteContent(
cricket::SignalingProtocol protocol,
const cricket::ContentDescription* content,
@@ -506,83 +234,7 @@ bool JingleSessionManager::WriteContent(
const ContentDescription* desc =
static_cast<const ContentDescription*>(content);
- XmlElement* root = new XmlElement(
- QName(kChromotingXmlNamespace, kDescriptionTag), true);
-
- const CandidateSessionConfig* config = desc->config();
- std::vector<ChannelConfig>::const_iterator it;
-
- for (it = config->control_configs().begin();
- it != config->control_configs().end(); ++it) {
- root->AddElement(FormatChannelConfig(*it, kControlTag));
- }
-
- for (it = config->event_configs().begin();
- it != config->event_configs().end(); ++it) {
- root->AddElement(FormatChannelConfig(*it, kEventTag));
- }
-
- for (it = config->video_configs().begin();
- it != config->video_configs().end(); ++it) {
- root->AddElement(FormatChannelConfig(*it, kVideoTag));
- }
-
- XmlElement* resolution_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kResolutionTag));
- resolution_tag->AddAttr(QName(kDefaultNs, kWidthAttr),
- base::IntToString(
- config->initial_resolution().width));
- resolution_tag->AddAttr(QName(kDefaultNs, kHeightAttr),
- base::IntToString(
- config->initial_resolution().height));
- root->AddElement(resolution_tag);
-
- if (desc->certificate() || !desc->auth_token().empty()) {
- XmlElement* authentication_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kAuthenticationTag));
-
- if (desc->certificate()) {
- XmlElement* certificate_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kCertificateTag));
-
- std::string der_cert;
- if (!desc->certificate()->GetDEREncoded(&der_cert)) {
- LOG(DFATAL) << "Cannot obtain DER encoded certificate";
- }
-
- std::string base64_cert;
- if (!base::Base64Encode(der_cert, &base64_cert)) {
- LOG(DFATAL) << "Cannot perform base64 encode on certificate";
- }
-
- certificate_tag->SetBodyText(base64_cert);
- authentication_tag->AddElement(certificate_tag);
- }
-
- if (!desc->master_key().empty()) {
- XmlElement* master_key_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kMasterKeyTag));
-
- std::string master_key_base64;
- if (!base::Base64Encode(desc->master_key(), &master_key_base64)) {
- LOG(DFATAL) << "Cannot perform base64 encode on master key";
- }
-
- master_key_tag->SetBodyText(master_key_base64);
- authentication_tag->AddElement(master_key_tag);
- }
-
- if (!desc->auth_token().empty()) {
- XmlElement* auth_token_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kAuthTokenTag));
- auth_token_tag->SetBodyText(desc->auth_token());
- authentication_tag->AddElement(auth_token_tag);
- }
-
- root->AddElement(authentication_tag);
- }
-
- *elem = root;
+ *elem = desc->ToXml();
return true;
}
diff --git a/remoting/protocol/jingle_session_manager.h b/remoting/protocol/jingle_session_manager.h
index b91087f..eb6ca8b 100644
--- a/remoting/protocol/jingle_session_manager.h
+++ b/remoting/protocol/jingle_session_manager.h
@@ -10,11 +10,11 @@
#include "base/memory/ref_counted.h"
#include "net/base/x509_certificate.h"
+#include "remoting/protocol/content_description.h"
#include "remoting/protocol/jingle_session.h"
#include "remoting/protocol/session_manager.h"
#include "third_party/libjingle/source/talk/p2p/base/session.h"
#include "third_party/libjingle/source/talk/p2p/base/sessionclient.h"
-#include "third_party/libjingle/source/talk/p2p/base/sessiondescription.h"
class MessageLoop;
@@ -27,45 +27,8 @@ class SessionManager;
} // namespace cricket
namespace remoting {
-
namespace protocol {
-// ContentDescription used for chromoting sessions. It contains the information
-// from the content description stanza in the session intialization handshake.
-//
-// This class also provides a type abstraction so that the Chromotocol Session
-// interface does not need to depend on libjingle.
-class ContentDescription : public cricket::ContentDescription {
- public:
- explicit ContentDescription(const CandidateSessionConfig* config,
- const std::string& auth_token,
- const std::string& master_key,
- scoped_refptr<net::X509Certificate> certificate);
- virtual ~ContentDescription();
-
- const CandidateSessionConfig* config() const {
- return candidate_config_.get();
- }
-
- const std::string& auth_token() const { return auth_token_; }
- const std::string& master_key() const { return master_key_; }
- scoped_refptr<net::X509Certificate> certificate() const {
- return certificate_;
- }
-
- private:
- scoped_ptr<const CandidateSessionConfig> candidate_config_;
-
- // This may contain the initiating, or the accepting token depending on
- // context.
- std::string auth_token_;
-
- // Master key used for the session encrypted with the hosts key.
- std::string master_key_;
-
- scoped_refptr<net::X509Certificate> certificate_;
-};
-
// This class implements SessionClient for Chromoting sessions. It acts as a
// server that accepts chromoting connections and can also make new connections
// to other hosts.
@@ -160,7 +123,6 @@ class JingleSessionManager
};
} // namespace protocol
-
} // namespace remoting
#endif // REMOTING_PROTOCOL_JINGLE_SESSION_MANAGER_H_
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index afb4a08..3561353 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -561,6 +561,8 @@
'protocol/connection_to_client.h',
'protocol/connection_to_host.cc',
'protocol/connection_to_host.h',
+ 'protocol/content_description.cc',
+ 'protocol/content_description.h',
'protocol/host_control_sender.cc',
'protocol/host_control_sender.h',
'protocol/host_message_dispatcher.cc',