1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket_net.h"
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <queue>
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string>
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/location.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/logging.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/linked_ptr.h"
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/ref_counted.h"
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/sequenced_task_runner.h"
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/threading/thread_restrictions.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket_thread.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/base/io_buffer.h"
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/base/net_errors.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/net_log.h"
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace {
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kSocketNotConnected[] = "Socket is not connected.";
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static void DeactivateSocket(
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const scoped_refptr<device::BluetoothSocketThread>& socket_thread) {
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread->OnSocketDeactivate();
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace device {
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)BluetoothSocketNet::WriteRequest::WriteRequest()
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    : buffer_size(0) {}
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)BluetoothSocketNet::WriteRequest::~WriteRequest() {}
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)BluetoothSocketNet::BluetoothSocketNet(
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_refptr<BluetoothSocketThread> socket_thread)
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    : ui_task_runner_(ui_task_runner),
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      socket_thread_(socket_thread) {
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread_->OnSocketActivate();
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)BluetoothSocketNet::~BluetoothSocketNet() {
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(tcp_socket_.get() == NULL);
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE,
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            base::Bind(&DeactivateSocket, socket_thread_));
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::Close() {
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread_->task_runner()->PostTask(
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE, base::Bind(&BluetoothSocketNet::DoClose, this));
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::Disconnect(
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const base::Closure& success_callback) {
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread_->task_runner()->PostTask(
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          &BluetoothSocketNet::DoDisconnect,
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          this,
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          base::Bind(&BluetoothSocketNet::PostSuccess,
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     this,
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     success_callback)));
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::Receive(
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int buffer_size,
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveCompletionCallback& success_callback,
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveErrorCompletionCallback& error_callback) {
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread_->task_runner()->PostTask(
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          &BluetoothSocketNet::DoReceive,
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          this,
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          buffer_size,
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          base::Bind(&BluetoothSocketNet::PostReceiveCompletion,
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     this,
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     success_callback),
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          base::Bind(&BluetoothSocketNet::PostReceiveErrorCompletion,
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     this,
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     error_callback)));
92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::Send(
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer,
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int buffer_size,
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const SendCompletionCallback& success_callback,
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ErrorCompletionCallback& error_callback) {
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread_->task_runner()->PostTask(
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          &BluetoothSocketNet::DoSend,
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          this,
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          buffer,
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          buffer_size,
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          base::Bind(&BluetoothSocketNet::PostSendCompletion,
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     this,
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     success_callback),
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          base::Bind(&BluetoothSocketNet::PostErrorCompletion,
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     this,
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     error_callback)));
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::ResetData() {
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::ResetTCPSocket() {
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  tcp_socket_.reset(new net::TCPSocket(NULL, net::NetLog::Source()));
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::SetTCPSocket(scoped_ptr<net::TCPSocket> tcp_socket) {
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  tcp_socket_ = tcp_socket.Pass();
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::PostSuccess(const base::Closure& callback) {
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE, callback);
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::PostErrorCompletion(
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ErrorCompletionCallback& callback,
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& error) {
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, error));
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::DoClose() {
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (tcp_socket_) {
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    tcp_socket_->Close();
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    tcp_socket_.reset(NULL);
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Note: Closing |tcp_socket_| above released all potential pending
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Send/Receive operations, so we can no safely release the state associated
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // to those pending operations.
148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  read_buffer_ = NULL;
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::queue<linked_ptr<WriteRequest> > empty;
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::swap(write_queue_, empty);
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ResetData();
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::DoDisconnect(const base::Closure& callback) {
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DoClose();
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  callback.Run();
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::DoReceive(
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int buffer_size,
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveCompletionCallback& success_callback,
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveErrorCompletionCallback& error_callback) {
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!tcp_socket_) {
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_callback.Run(BluetoothSocket::kDisconnected, kSocketNotConnected);
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Only one pending read at a time
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (read_buffer_.get()) {
177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_callback.Run(BluetoothSocket::kIOPending,
178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                       net::ErrorToString(net::ERR_IO_PENDING));
179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> buffer(
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new net::IOBufferWithSize(buffer_size));
184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int read_result =
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      tcp_socket_->Read(buffer.get(),
186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                        buffer->size(),
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                        base::Bind(&BluetoothSocketNet::OnSocketReadComplete,
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   this,
189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   success_callback,
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   error_callback));
191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  read_buffer_ = buffer;
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (read_result != net::ERR_IO_PENDING)
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    OnSocketReadComplete(success_callback, error_callback, read_result);
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::OnSocketReadComplete(
198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveCompletionCallback& success_callback,
199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveErrorCompletionCallback& error_callback,
200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int read_result) {
201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> buffer;
205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  buffer.swap(read_buffer_);
206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (read_result > 0) {
207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    success_callback.Run(read_result, buffer);
208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else if (read_result == net::OK ||
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)             read_result == net::ERR_CONNECTION_CLOSED ||
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)             read_result == net::ERR_CONNECTION_RESET) {
211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_callback.Run(BluetoothSocket::kDisconnected,
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       net::ErrorToString(read_result));
213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else {
214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_callback.Run(BluetoothSocket::kSystemError,
215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                       net::ErrorToString(read_result));
216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::DoSend(
220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer,
221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int buffer_size,
222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const SendCompletionCallback& success_callback,
223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ErrorCompletionCallback& error_callback) {
224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!tcp_socket_) {
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_callback.Run(kSocketNotConnected);
229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  linked_ptr<WriteRequest> request(new WriteRequest());
233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  request->buffer = buffer;
234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  request->buffer_size = buffer_size;
235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  request->success_callback = success_callback;
236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  request->error_callback = error_callback;
237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  write_queue_.push(request);
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (write_queue_.size() == 1) {
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SendFrontWriteRequest();
241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::SendFrontWriteRequest() {
245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!tcp_socket_)
249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (write_queue_.size() == 0)
252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  linked_ptr<WriteRequest> request = write_queue_.front();
255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  net::CompletionCallback callback =
256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&BluetoothSocketNet::OnSocketWriteComplete,
257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 this,
258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 request->success_callback,
259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 request->error_callback);
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int send_result =
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      tcp_socket_->Write(request->buffer.get(), request->buffer_size, callback);
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (send_result != net::ERR_IO_PENDING) {
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    callback.Run(send_result);
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::OnSocketWriteComplete(
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const SendCompletionCallback& success_callback,
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ErrorCompletionCallback& error_callback,
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int send_result) {
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  write_queue_.pop();
275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (send_result >= net::OK) {
277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    success_callback.Run(send_result);
278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else {
279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_callback.Run(net::ErrorToString(send_result));
280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Don't call directly to avoid potentail large recursion.
283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread_->task_runner()->PostNonNestableTask(
284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&BluetoothSocketNet::SendFrontWriteRequest, this));
286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::PostReceiveCompletion(
289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveCompletionCallback& callback,
290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int io_buffer_size,
291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<net::IOBuffer> io_buffer) {
292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE,
293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            base::Bind(callback, io_buffer_size, io_buffer));
294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
295010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::PostReceiveErrorCompletion(
297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ReceiveErrorCompletionCallback& callback,
298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ErrorReason reason,
299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& error_message) {
300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE,
301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            base::Bind(callback, reason, error_message));
302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothSocketNet::PostSendCompletion(
305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const SendCompletionCallback& callback,
306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int bytes_written) {
307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, bytes_written));
308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace device
311