diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 20:59:56 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 20:59:56 +0000 |
commit | 2fc3b4267fd4f28dd864c2858cea0e84f55cbb0a (patch) | |
tree | 726f9dc89d195927c151dd969c68051b0c135a02 /remoting/jingle_glue/channel_socket_adapter.cc | |
parent | e393b9fc0267deaf55f3624aa7b0bfb08707dfda (diff) | |
download | chromium_src-2fc3b4267fd4f28dd864c2858cea0e84f55cbb0a.zip chromium_src-2fc3b4267fd4f28dd864c2858cea0e84f55cbb0a.tar.gz chromium_src-2fc3b4267fd4f28dd864c2858cea0e84f55cbb0a.tar.bz2 |
Implemented basic support Chromotocol connection.
New code supports multiple PseudoTCP and UDP channels. Client and host still use old JjngleChannel for connection.
BUG=53986
TEST=None
Review URL: http://codereview.chromium.org/3319021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60842 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/jingle_glue/channel_socket_adapter.cc')
-rw-r--r-- | remoting/jingle_glue/channel_socket_adapter.cc | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/remoting/jingle_glue/channel_socket_adapter.cc b/remoting/jingle_glue/channel_socket_adapter.cc new file mode 100644 index 0000000..583eed1 --- /dev/null +++ b/remoting/jingle_glue/channel_socket_adapter.cc @@ -0,0 +1,171 @@ +// Copyright (c) 2010 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/jingle_glue/channel_socket_adapter.h" + +#include <limits> + +#include "base/logging.h" +#include "base/message_loop.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "remoting/jingle_glue/utils.h" +#include "third_party/libjingle/source/talk/p2p/base/transportchannel.h" + +namespace remoting { + +TransportChannelSocketAdapter::TransportChannelSocketAdapter( + cricket::TransportChannel* channel) + : channel_(channel), + read_pending_(false), + write_pending_(false), + closed_error_code_(net::OK) { + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + DCHECK(channel_); + + channel_->SignalReadPacket.connect( + this, &TransportChannelSocketAdapter::OnNewPacket); + channel_->SignalWritableState.connect( + this, &TransportChannelSocketAdapter::OnWritableState); + channel_->SignalDestroyed.connect( + this, &TransportChannelSocketAdapter::OnChannelDestroyed); +} + +TransportChannelSocketAdapter::~TransportChannelSocketAdapter() { +} + +int TransportChannelSocketAdapter::Read( + net::IOBuffer* buf, int buffer_size, net::CompletionCallback* callback) { + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + DCHECK(buf); + CHECK(!read_pending_); + + if (!channel_) { + DCHECK(closed_error_code_ != net::OK); + return closed_error_code_; + } + + read_callback_ = callback; + read_buffer_ = buf; + read_buffer_size_ = buffer_size; + read_pending_ = true; + + return net::ERR_IO_PENDING; +} + +int TransportChannelSocketAdapter::Write( + net::IOBuffer* buffer, int buffer_size, net::CompletionCallback* callback) { + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + DCHECK(buffer); + CHECK(!write_pending_); + + if (!channel_) { + DCHECK(closed_error_code_ != net::OK); + return closed_error_code_; + } + + int result = channel_->SendPacket(buffer->data(), buffer_size); + if (result < 0) { + result = MapPosixToChromeError(channel_->GetError()); + if (result == net::ERR_IO_PENDING) { + write_pending_ = true; + write_callback_ = callback; + write_buffer_ = buffer; + write_buffer_size_ = buffer_size; + } + } + return result; +} + +bool TransportChannelSocketAdapter::SetReceiveBufferSize(int32 size) { + NOTIMPLEMENTED(); + return false; +} + +bool TransportChannelSocketAdapter::SetSendBufferSize(int32 size) { + NOTIMPLEMENTED(); + return false; +} + +void TransportChannelSocketAdapter::Close(int error_code) { + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + if (!channel_) // Already closed. + return; + + DCHECK(error_code != net::OK); + closed_error_code_ = error_code; + channel_->SignalReadPacket.disconnect(this); + channel_->SignalDestroyed.disconnect(this); + channel_ = NULL; + + if (read_pending_) { + net::CompletionCallback* callback = read_callback_; + read_pending_ = false; + read_buffer_ = NULL; + callback->Run(error_code); + } + + if (write_pending_) { + net::CompletionCallback* callback = write_callback_; + write_pending_ = false; + write_buffer_ = NULL; + callback->Run(error_code); + } +} + +void TransportChannelSocketAdapter::OnNewPacket( + cricket::TransportChannel* channel, const char* data, size_t data_size) { + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + DCHECK_EQ(channel, channel_); + if (read_pending_) { + DCHECK(read_buffer_); + CHECK_LT(data_size, static_cast<size_t>(std::numeric_limits<int>::max())); + + if (read_buffer_size_ < static_cast<int>(data_size)) { + LOG(WARNING) << "Data buffer is smaller than the received packet. " + << "Dropping the data that doesn't fit."; + data_size = read_buffer_size_; + } + + memcpy(read_buffer_->data(), data, data_size); + + net::CompletionCallback* callback = read_callback_; + read_pending_ = false; + read_buffer_ = NULL; + + callback->Run(data_size); + } else { + LOG(WARNING) + << "Data was received without a callback. Dropping the packet."; + } +} + +void TransportChannelSocketAdapter::OnWritableState( + cricket::TransportChannel* channel) { + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + // Try to send the packet if there is a pending write. + if (write_pending_) { + int result = channel_->SendPacket(write_buffer_->data(), + write_buffer_size_); + if (result < 0) + result = MapPosixToChromeError(channel_->GetError()); + + if (result != net::ERR_IO_PENDING) { + net::CompletionCallback* callback = write_callback_; + write_pending_ = false; + write_buffer_ = NULL; + callback->Run(result); + } + } +} + +void TransportChannelSocketAdapter::OnChannelDestroyed( + cricket::TransportChannel* channel) { + DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + DCHECK_EQ(channel, channel_); + Close(net::ERR_CONNECTION_ABORTED); +} + +} // namespace remoting |