1 // Copyright 2015 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.
5 #include "remoting/protocol/channel_socket_adapter.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h"
13 #include "third_party/webrtc/p2p/base/transportchannel.h"
18 TransportChannelSocketAdapter::TransportChannelSocketAdapter(
19 cricket::TransportChannel
* channel
)
21 closed_error_code_(net::OK
) {
24 channel_
->SignalReadPacket
.connect(
25 this, &TransportChannelSocketAdapter::OnNewPacket
);
26 channel_
->SignalWritableState
.connect(
27 this, &TransportChannelSocketAdapter::OnWritableState
);
28 channel_
->SignalDestroyed
.connect(
29 this, &TransportChannelSocketAdapter::OnChannelDestroyed
);
32 TransportChannelSocketAdapter::~TransportChannelSocketAdapter() {
33 if (!destruction_callback_
.is_null())
34 destruction_callback_
.Run();
37 void TransportChannelSocketAdapter::SetOnDestroyedCallback(
38 const base::Closure
& callback
) {
39 destruction_callback_
= callback
;
42 int TransportChannelSocketAdapter::Recv(
43 const scoped_refptr
<net::IOBuffer
>& buf
, int buffer_size
,
44 const net::CompletionCallback
& callback
) {
45 DCHECK(thread_checker_
.CalledOnValidThread());
47 DCHECK(!callback
.is_null());
48 CHECK(read_callback_
.is_null());
51 DCHECK(closed_error_code_
!= net::OK
);
52 return closed_error_code_
;
55 read_callback_
= callback
;
57 read_buffer_size_
= buffer_size
;
59 return net::ERR_IO_PENDING
;
62 int TransportChannelSocketAdapter::Send(
63 const scoped_refptr
<net::IOBuffer
>& buffer
, int buffer_size
,
64 const net::CompletionCallback
& callback
) {
65 DCHECK(thread_checker_
.CalledOnValidThread());
67 DCHECK(!callback
.is_null());
68 CHECK(write_callback_
.is_null());
71 DCHECK(closed_error_code_
!= net::OK
);
72 return closed_error_code_
;
76 rtc::PacketOptions options
;
77 if (channel_
->writable()) {
78 result
= channel_
->SendPacket(buffer
->data(), buffer_size
, options
);
80 result
= net::MapSystemError(channel_
->GetError());
82 // If the underlying socket returns IO pending where it shouldn't we
83 // pretend the packet is dropped and return as succeeded because no
84 // writeable callback will happen.
85 if (result
== net::ERR_IO_PENDING
)
89 // Channel is not writable yet.
90 result
= net::ERR_IO_PENDING
;
91 write_callback_
= callback
;
92 write_buffer_
= buffer
;
93 write_buffer_size_
= buffer_size
;
99 void TransportChannelSocketAdapter::Close(int error_code
) {
100 DCHECK(thread_checker_
.CalledOnValidThread());
102 if (!channel_
) // Already closed.
105 DCHECK(error_code
!= net::OK
);
106 closed_error_code_
= error_code
;
107 channel_
->SignalReadPacket
.disconnect(this);
108 channel_
->SignalDestroyed
.disconnect(this);
111 if (!read_callback_
.is_null()) {
112 net::CompletionCallback callback
= read_callback_
;
113 read_callback_
.Reset();
115 callback
.Run(error_code
);
118 if (!write_callback_
.is_null()) {
119 net::CompletionCallback callback
= write_callback_
;
120 write_callback_
.Reset();
121 write_buffer_
= NULL
;
122 callback
.Run(error_code
);
126 void TransportChannelSocketAdapter::OnNewPacket(
127 cricket::TransportChannel
* channel
,
130 const rtc::PacketTime
& packet_time
,
132 DCHECK(thread_checker_
.CalledOnValidThread());
133 DCHECK_EQ(channel
, channel_
);
134 if (!read_callback_
.is_null()) {
135 DCHECK(read_buffer_
.get());
136 CHECK_LT(data_size
, static_cast<size_t>(std::numeric_limits
<int>::max()));
138 if (read_buffer_size_
< static_cast<int>(data_size
)) {
139 LOG(WARNING
) << "Data buffer is smaller than the received packet. "
140 << "Dropping the data that doesn't fit.";
141 data_size
= read_buffer_size_
;
144 memcpy(read_buffer_
->data(), data
, data_size
);
146 net::CompletionCallback callback
= read_callback_
;
147 read_callback_
.Reset();
150 callback
.Run(data_size
);
153 << "Data was received without a callback. Dropping the packet.";
157 void TransportChannelSocketAdapter::OnWritableState(
158 cricket::TransportChannel
* channel
) {
159 DCHECK(thread_checker_
.CalledOnValidThread());
160 // Try to send the packet if there is a pending write.
161 if (!write_callback_
.is_null()) {
162 rtc::PacketOptions options
;
163 int result
= channel_
->SendPacket(write_buffer_
->data(),
167 result
= net::MapSystemError(channel_
->GetError());
169 if (result
!= net::ERR_IO_PENDING
) {
170 net::CompletionCallback callback
= write_callback_
;
171 write_callback_
.Reset();
172 write_buffer_
= NULL
;
173 callback
.Run(result
);
178 void TransportChannelSocketAdapter::OnChannelDestroyed(
179 cricket::TransportChannel
* channel
) {
180 DCHECK(thread_checker_
.CalledOnValidThread());
181 DCHECK_EQ(channel
, channel_
);
182 Close(net::ERR_CONNECTION_ABORTED
);
185 } // namespace protocol
186 } // namespace remoting