Chromium Code Reviews| Index: remoting/protocol/pepper_p2p_channel.cc |
| diff --git a/remoting/protocol/pepper_p2p_channel.cc b/remoting/protocol/pepper_p2p_channel.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c3f77164486f80827f3c6b666be17b396ce66075 |
| --- /dev/null |
| +++ b/remoting/protocol/pepper_p2p_channel.cc |
| @@ -0,0 +1,154 @@ |
| +// 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/pepper_p2p_channel.h" |
| + |
| +#include "base/logging.h" |
| +#include "net/base/io_buffer.h" |
| +#include "net/base/net_errors.h" |
| +#include "ppapi/c/pp_errors.h" |
| +#include "ppapi/cpp/dev/transport_dev.h" |
| +#include "ppapi/cpp/var.h" |
| + |
| +namespace remoting { |
| + |
| +namespace { |
| + |
| +const char kPepperUdpProtocol[] = "udp"; |
|
Wez
2011/06/20 22:19:31
nit: Should this be kPepper[Transport]UdpProtocolN
Sergey Ulanov
2011/06/21 00:23:20
Done.
|
| + |
| +// Maps value returned by Recv() and Send() Pepper methods to net::Error. |
| +int MapPepperError(int result) { |
|
Wez
2011/06/20 22:19:31
nit: PPErrorToNetError?
Sergey Ulanov
2011/06/21 00:23:20
Done.
|
| + if (result > 0) |
| + return result; |
| + |
| + switch (result) { |
| + case PP_OK: |
| + return net::OK; |
| + case PP_OK_COMPLETIONPENDING: |
| + return net::ERR_IO_PENDING; |
| + default: |
| + return net::ERR_FAILED; |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| + |
| +PepperP2PChannel::PepperP2PChannel( |
| + pp::Instance* pp_instance, |
| + const char* name, |
| + const IncomingCandidateCallback& candidate_callback) |
| + : candidate_callback_(candidate_callback), |
| + read_callback_(NULL), |
| + write_callback_(NULL) { |
| + transport_.reset( |
| + new pp::Transport_Dev(pp_instance, name, kPepperUdpProtocol)); |
| + ProcessCandidates(); |
| +} |
| + |
| +PepperP2PChannel::~PepperP2PChannel() { |
| +} |
| + |
| +void PepperP2PChannel::AddRemoteCandidate(const std::string& candidate) { |
|
Wez
2011/06/20 22:19:31
DCHECK(CalledOnValidThread())?
Sergey Ulanov
2011/06/21 00:23:20
Done.
|
| + transport_->ReceiveRemoteAddress(candidate); |
| +} |
| + |
| +int PepperP2PChannel::Read(net::IOBuffer* buf, int buf_len, |
| + net::CompletionCallback* callback) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(!read_callback_); |
| + DCHECK(!read_buffer_); |
| + |
| + int result = MapPepperError(transport_->Recv( |
| + buf->data(), buf_len, |
| + pp::CompletionCallback(&PepperP2PChannel::ReadCallback, this))); |
| + |
| + if (result == net::ERR_IO_PENDING) { |
| + read_callback_ = callback; |
| + read_buffer_ = buf; |
| + } |
| + |
| + return result; |
| +} |
| + |
| +int PepperP2PChannel::Write(net::IOBuffer* buf, int buf_len, |
| + net::CompletionCallback* callback) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(!write_callback_); |
| + DCHECK(!write_buffer_); |
| + |
| + int result = MapPepperError(transport_->Send( |
| + buf->data(), buf_len, |
| + pp::CompletionCallback(&PepperP2PChannel::WriteCallback, this))); |
| + |
| + if (result == net::ERR_IO_PENDING) { |
| + write_callback_ = callback; |
| + write_buffer_ = buf; |
| + } |
| + |
| + return result; |
| +} |
| + |
| +bool PepperP2PChannel::SetReceiveBufferSize(int32 size) { |
| + DCHECK(CalledOnValidThread()); |
| + NOTIMPLEMENTED(); |
| + return false; |
| +} |
| + |
| +bool PepperP2PChannel::SetSendBufferSize(int32 size) { |
| + DCHECK(CalledOnValidThread()); |
| + NOTIMPLEMENTED(); |
| + return false; |
| +} |
| + |
| +void PepperP2PChannel::ProcessCandidates() { |
| + pp::Var address; |
| + while (true) { |
| + int result = transport_->GetNextAddress( |
| + &address, |
| + pp::CompletionCallback(&PepperP2PChannel::NextAddressCallback, this)); |
| + if (result == PP_OK_COMPLETIONPENDING) |
| + break; |
| + |
| + if (result == PP_OK) { |
| + candidate_callback_.Run(address.AsString()); |
| + } else { |
| + LOG(ERROR) << "GetNextAddress() returned an error " << result; |
|
Wez
2011/06/20 22:19:31
Are there any failure modes for GetNextAddress() t
Sergey Ulanov
2011/06/21 00:23:20
Yes, it returns PP_ERROR_NOINTERFACE in that case.
|
| + break; |
| + } |
| + } |
| +} |
| + |
| +// static |
| +void PepperP2PChannel::NextAddressCallback(void* data, int32_t result) { |
| + PepperP2PChannel* channel = reinterpret_cast<PepperP2PChannel*>(data); |
| + DCHECK(channel->CalledOnValidThread()); |
| + channel->ProcessCandidates(); |
| +} |
| + |
| +// static |
| +void PepperP2PChannel::ReadCallback(void* data, int32_t result) { |
| + PepperP2PChannel* channel = reinterpret_cast<PepperP2PChannel*>(data); |
| + DCHECK(channel->CalledOnValidThread()); |
| + DCHECK(channel->read_callback_); |
| + DCHECK(channel->read_buffer_); |
| + net::CompletionCallback* callback = channel->read_callback_; |
| + channel->read_callback_ = NULL; |
| + channel->read_buffer_ = NULL; |
| + callback->Run(result); |
|
Wez
2011/06/20 22:19:31
The net::Socket interface allows for the Socket be
Sergey Ulanov
2011/06/21 00:23:20
Yes, Pepper implementation should be able to handl
|
| +} |
| + |
| +// static |
| +void PepperP2PChannel::WriteCallback(void* data, int32_t result) { |
| + PepperP2PChannel* channel = reinterpret_cast<PepperP2PChannel*>(data); |
| + DCHECK(channel->CalledOnValidThread()); |
| + DCHECK(channel->write_callback_); |
| + DCHECK(channel->write_buffer_); |
| + net::CompletionCallback* callback = channel->write_callback_; |
| + channel->write_callback_ = NULL; |
| + channel->write_buffer_ = NULL; |
| + callback->Run(result); |
| +} |
| + |
| +} // namespace remoting |