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