| Index: webrtc/p2p/base/transportchannelproxy.cc
|
| diff --git a/webrtc/p2p/base/transportchannelproxy.cc b/webrtc/p2p/base/transportchannelproxy.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..74d1e1db762c016525ad7f0f22a2c73ea70ef626
|
| --- /dev/null
|
| +++ b/webrtc/p2p/base/transportchannelproxy.cc
|
| @@ -0,0 +1,276 @@
|
| +/*
|
| + * Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license
|
| + * that can be found in the LICENSE file in the root of the source
|
| + * tree. An additional intellectual property rights grant can be found
|
| + * in the file PATENTS. All contributing project authors may
|
| + * be found in the AUTHORS file in the root of the source tree.
|
| + */
|
| +
|
| +#include "webrtc/p2p/base/transport.h"
|
| +#include "webrtc/p2p/base/transportchannelimpl.h"
|
| +#include "webrtc/p2p/base/transportchannelproxy.h"
|
| +#include "webrtc/base/common.h"
|
| +#include "webrtc/base/logging.h"
|
| +#include "webrtc/base/thread.h"
|
| +
|
| +namespace cricket {
|
| +
|
| +enum {
|
| + MSG_UPDATESTATE,
|
| +};
|
| +
|
| +TransportChannelProxy::TransportChannelProxy(const std::string& content_name,
|
| + int component)
|
| + : TransportChannel(content_name, component),
|
| + impl_(NULL) {
|
| + worker_thread_ = rtc::Thread::Current();
|
| +}
|
| +
|
| +TransportChannelProxy::~TransportChannelProxy() {
|
| + // Clearing any pending signal.
|
| + worker_thread_->Clear(this);
|
| + if (impl_) {
|
| + impl_->GetTransport()->DestroyChannel(impl_->component());
|
| + }
|
| +}
|
| +
|
| +void TransportChannelProxy::SetImplementation(TransportChannelImpl* impl) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| +
|
| + if (impl == impl_) {
|
| + // Ignore if the |impl| has already been set.
|
| + LOG(LS_WARNING) << "Ignored TransportChannelProxy::SetImplementation call "
|
| + << "with a same impl as the existing one.";
|
| + return;
|
| + }
|
| +
|
| + // Destroy any existing impl_.
|
| + if (impl_) {
|
| + impl_->GetTransport()->DestroyChannel(impl_->component());
|
| + }
|
| +
|
| + // Adopt the supplied impl, and connect to its signals.
|
| + impl_ = impl;
|
| +
|
| + if (impl_) {
|
| + impl_->SignalWritableState.connect(
|
| + this, &TransportChannelProxy::OnWritableState);
|
| + impl_->SignalReceivingState.connect(
|
| + this, &TransportChannelProxy::OnReceivingState);
|
| + impl_->SignalReadPacket.connect(
|
| + this, &TransportChannelProxy::OnReadPacket);
|
| + impl_->SignalReadyToSend.connect(
|
| + this, &TransportChannelProxy::OnReadyToSend);
|
| + impl_->SignalRouteChange.connect(
|
| + this, &TransportChannelProxy::OnRouteChange);
|
| + for (const auto& pair : options_) {
|
| + impl_->SetOption(pair.first, pair.second);
|
| + }
|
| +
|
| + // Push down the SRTP ciphers, if any were set.
|
| + if (!pending_srtp_ciphers_.empty()) {
|
| + impl_->SetSrtpCiphers(pending_srtp_ciphers_);
|
| + }
|
| + }
|
| +
|
| + // Post ourselves a message to see if we need to fire state callbacks.
|
| + worker_thread_->Post(this, MSG_UPDATESTATE);
|
| +}
|
| +
|
| +int TransportChannelProxy::SendPacket(const char* data, size_t len,
|
| + const rtc::PacketOptions& options,
|
| + int flags) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + // Fail if we don't have an impl yet.
|
| + if (!impl_) {
|
| + return -1;
|
| + }
|
| + return impl_->SendPacket(data, len, options, flags);
|
| +}
|
| +
|
| +int TransportChannelProxy::SetOption(rtc::Socket::Option opt, int value) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + options_.push_back(OptionPair(opt, value));
|
| + if (!impl_) {
|
| + return 0;
|
| + }
|
| + return impl_->SetOption(opt, value);
|
| +}
|
| +
|
| +bool TransportChannelProxy::GetOption(rtc::Socket::Option opt, int* value) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (impl_) {
|
| + return impl_->GetOption(opt, value);
|
| + }
|
| +
|
| + for (const auto& pair : options_) {
|
| + if (pair.first == opt) {
|
| + *value = pair.second;
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +int TransportChannelProxy::GetError() {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return 0;
|
| + }
|
| + return impl_->GetError();
|
| +}
|
| +
|
| +TransportChannelState TransportChannelProxy::GetState() const {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return TransportChannelState::STATE_CONNECTING;
|
| + }
|
| + return impl_->GetState();
|
| +}
|
| +
|
| +bool TransportChannelProxy::GetStats(ConnectionInfos* infos) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->GetStats(infos);
|
| +}
|
| +
|
| +bool TransportChannelProxy::IsDtlsActive() const {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->IsDtlsActive();
|
| +}
|
| +
|
| +bool TransportChannelProxy::GetSslRole(rtc::SSLRole* role) const {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->GetSslRole(role);
|
| +}
|
| +
|
| +bool TransportChannelProxy::SetSslRole(rtc::SSLRole role) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->SetSslRole(role);
|
| +}
|
| +
|
| +bool TransportChannelProxy::SetSrtpCiphers(const std::vector<std::string>&
|
| + ciphers) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + pending_srtp_ciphers_ = ciphers; // Cache so we can send later, but always
|
| + // set so it stays consistent.
|
| + if (impl_) {
|
| + return impl_->SetSrtpCiphers(ciphers);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool TransportChannelProxy::GetSrtpCipher(std::string* cipher) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->GetSrtpCipher(cipher);
|
| +}
|
| +
|
| +bool TransportChannelProxy::GetSslCipher(std::string* cipher) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->GetSslCipher(cipher);
|
| +}
|
| +
|
| +rtc::scoped_refptr<rtc::RTCCertificate>
|
| +TransportChannelProxy::GetLocalCertificate() const {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return nullptr;
|
| + }
|
| + return impl_->GetLocalCertificate();
|
| +}
|
| +
|
| +bool TransportChannelProxy::GetRemoteSSLCertificate(
|
| + rtc::SSLCertificate** cert) const {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->GetRemoteSSLCertificate(cert);
|
| +}
|
| +
|
| +bool TransportChannelProxy::ExportKeyingMaterial(const std::string& label,
|
| + const uint8* context,
|
| + size_t context_len,
|
| + bool use_context,
|
| + uint8* result,
|
| + size_t result_len) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return false;
|
| + }
|
| + return impl_->ExportKeyingMaterial(label, context, context_len, use_context,
|
| + result, result_len);
|
| +}
|
| +
|
| +IceRole TransportChannelProxy::GetIceRole() const {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (!impl_) {
|
| + return ICEROLE_UNKNOWN;
|
| + }
|
| + return impl_->GetIceRole();
|
| +}
|
| +
|
| +void TransportChannelProxy::OnWritableState(TransportChannel* channel) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + ASSERT(channel == impl_);
|
| + set_writable(impl_->writable());
|
| + // Note: SignalWritableState fired by set_writable.
|
| +}
|
| +
|
| +void TransportChannelProxy::OnReceivingState(TransportChannel* channel) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + ASSERT(channel == impl_);
|
| + set_receiving(impl_->receiving());
|
| + // Note: SignalReceivingState fired by set_receiving.
|
| +}
|
| +
|
| +void TransportChannelProxy::OnReadPacket(
|
| + TransportChannel* channel, const char* data, size_t size,
|
| + const rtc::PacketTime& packet_time, int flags) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + ASSERT(channel == impl_);
|
| + SignalReadPacket(this, data, size, packet_time, flags);
|
| +}
|
| +
|
| +void TransportChannelProxy::OnReadyToSend(TransportChannel* channel) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + ASSERT(channel == impl_);
|
| + SignalReadyToSend(this);
|
| +}
|
| +
|
| +void TransportChannelProxy::OnRouteChange(TransportChannel* channel,
|
| + const Candidate& candidate) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + ASSERT(channel == impl_);
|
| + SignalRouteChange(this, candidate);
|
| +}
|
| +
|
| +void TransportChannelProxy::OnMessage(rtc::Message* msg) {
|
| + ASSERT(rtc::Thread::Current() == worker_thread_);
|
| + if (msg->message_id == MSG_UPDATESTATE) {
|
| + // If impl_ is already receiving or writable, push up those signals.
|
| + set_writable(impl_ ? impl_->writable() : false);
|
| + set_receiving(impl_ ? impl_->receiving() : false);
|
| + }
|
| +}
|
| +
|
| +} // namespace cricket
|
|
|