socket.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2020 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.
  4. #include "device/bluetooth/socket.h"
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/bind.h"
  9. #include "base/callback_helpers.h"
  10. #include "base/memory/ptr_util.h"
  11. #include "device/bluetooth/bluetooth_socket.h"
  12. #include "mojo/public/cpp/bindings/pending_receiver.h"
  13. #include "mojo/public/cpp/bindings/receiver.h"
  14. #include "net/base/io_buffer.h"
  15. namespace bluetooth {
  16. Socket::Socket(scoped_refptr<device::BluetoothSocket> bluetooth_socket,
  17. mojo::ScopedDataPipeProducerHandle receive_stream,
  18. mojo::ScopedDataPipeConsumerHandle send_stream)
  19. : bluetooth_socket_(std::move(bluetooth_socket)),
  20. receive_stream_(std::move(receive_stream)),
  21. send_stream_(std::move(send_stream)),
  22. receive_stream_watcher_(FROM_HERE,
  23. mojo::SimpleWatcher::ArmingPolicy::MANUAL),
  24. send_stream_watcher_(FROM_HERE,
  25. mojo::SimpleWatcher::ArmingPolicy::MANUAL) {
  26. receive_stream_watcher_.Watch(
  27. receive_stream_.get(),
  28. MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
  29. base::BindRepeating(&Socket::OnReceiveStreamWritable,
  30. base::Unretained(this)));
  31. send_stream_watcher_.Watch(
  32. send_stream_.get(),
  33. MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
  34. base::BindRepeating(&Socket::OnSendStreamReadable,
  35. base::Unretained(this)));
  36. ReceiveMore();
  37. SendMore();
  38. }
  39. Socket::~Socket() {
  40. ShutdownReceive();
  41. ShutdownSend();
  42. bluetooth_socket_->Disconnect(base::DoNothing());
  43. }
  44. void Socket::Disconnect(DisconnectCallback callback) {
  45. bluetooth_socket_->Disconnect(std::move(callback));
  46. }
  47. void Socket::OnReceiveStreamWritable(MojoResult result) {
  48. DCHECK(receive_stream_.is_valid());
  49. if (result == MOJO_RESULT_OK) {
  50. ReceiveMore();
  51. return;
  52. }
  53. ShutdownReceive();
  54. }
  55. void Socket::ShutdownReceive() {
  56. receive_stream_watcher_.Cancel();
  57. receive_stream_.reset();
  58. }
  59. void Socket::ReceiveMore() {
  60. DCHECK(receive_stream_.is_valid());
  61. // The destination to which we will write incoming bytes from
  62. // |bluetooth_socket_|. The allocated buffer and its max available size
  63. // (assigned to |pending_write_buffer_max_size|) will be fetched by calling
  64. // BeginWriteData() below. This already-allocated buffer is a buffer shared
  65. // between the 2 sides of |receive_stream_|.
  66. void* pending_write_buffer = nullptr;
  67. // Passing 0 as the initial value allows |pending_write_buffer_max_size| to be
  68. // assigned the buffer's max size.
  69. uint32_t pending_write_buffer_max_size = 0;
  70. MojoResult result = receive_stream_->BeginWriteData(
  71. &pending_write_buffer, &pending_write_buffer_max_size,
  72. MOJO_WRITE_DATA_FLAG_NONE);
  73. if (result == MOJO_RESULT_SHOULD_WAIT) {
  74. receive_stream_watcher_.ArmOrNotify();
  75. return;
  76. } else if (result != MOJO_RESULT_OK) {
  77. ShutdownReceive();
  78. return;
  79. }
  80. bluetooth_socket_->Receive(
  81. pending_write_buffer_max_size,
  82. base::BindOnce(&Socket::OnBluetoothSocketReceive,
  83. weak_ptr_factory_.GetWeakPtr(), pending_write_buffer),
  84. base::BindOnce(&Socket::OnBluetoothSocketReceiveError,
  85. weak_ptr_factory_.GetWeakPtr()));
  86. }
  87. void Socket::OnBluetoothSocketReceive(void* pending_write_buffer,
  88. int num_bytes_received,
  89. scoped_refptr<net::IOBuffer> io_buffer) {
  90. DCHECK_GT(num_bytes_received, 0);
  91. DCHECK(io_buffer->data());
  92. if (!receive_stream_.is_valid())
  93. return;
  94. memcpy(pending_write_buffer, io_buffer->data(), num_bytes_received);
  95. receive_stream_->EndWriteData(static_cast<uint32_t>(num_bytes_received));
  96. ReceiveMore();
  97. }
  98. void Socket::OnBluetoothSocketReceiveError(
  99. device::BluetoothSocket::ErrorReason error_reason,
  100. const std::string& error_message) {
  101. DLOG(ERROR) << "Failed to receive data for reason '" << error_reason << "': '"
  102. << error_message << "'";
  103. if (receive_stream_.is_valid()) {
  104. receive_stream_->EndWriteData(0);
  105. ShutdownReceive();
  106. }
  107. }
  108. void Socket::OnSendStreamReadable(MojoResult result) {
  109. DCHECK(send_stream_.is_valid());
  110. if (result == MOJO_RESULT_OK)
  111. SendMore();
  112. else
  113. ShutdownSend();
  114. }
  115. void Socket::ShutdownSend() {
  116. send_stream_watcher_.Cancel();
  117. send_stream_.reset();
  118. }
  119. void Socket::SendMore() {
  120. DCHECK(send_stream_.is_valid());
  121. // The source from which we will write outgoing bytes to
  122. // |bluetooth_socket_|. The allocated buffer and the number of bytes already
  123. // written by the other side of |send_stream_| (assigned to
  124. // |pending_read_buffer_size|) will be fetched by calling BeginReadData()
  125. // below. This already-allocated buffer is a buffer shared between the 2 sides
  126. // of |send_stream_|.
  127. const void* pending_read_buffer = nullptr;
  128. // Passing 0 as the initial value allows |pending_read_buffer_size| to be
  129. // assigned the number of bytes that the other side of |send_stream_| has
  130. // already written.
  131. uint32_t pending_read_buffer_size = 0;
  132. MojoResult result = send_stream_->BeginReadData(&pending_read_buffer,
  133. &pending_read_buffer_size,
  134. MOJO_WRITE_DATA_FLAG_NONE);
  135. if (result == MOJO_RESULT_SHOULD_WAIT) {
  136. send_stream_watcher_.ArmOrNotify();
  137. return;
  138. } else if (result != MOJO_RESULT_OK) {
  139. ShutdownSend();
  140. return;
  141. }
  142. bluetooth_socket_->Send(base::MakeRefCounted<net::WrappedIOBuffer>(
  143. static_cast<const char*>(pending_read_buffer)),
  144. pending_read_buffer_size,
  145. base::BindOnce(&Socket::OnBluetoothSocketSend,
  146. weak_ptr_factory_.GetWeakPtr()),
  147. base::BindOnce(&Socket::OnBluetoothSocketSendError,
  148. weak_ptr_factory_.GetWeakPtr()));
  149. }
  150. void Socket::OnBluetoothSocketSend(int num_bytes_sent) {
  151. DCHECK_GE(num_bytes_sent, 0);
  152. if (!send_stream_.is_valid())
  153. return;
  154. send_stream_->EndReadData(static_cast<uint32_t>(num_bytes_sent));
  155. SendMore();
  156. }
  157. void Socket::OnBluetoothSocketSendError(const std::string& error_message) {
  158. DLOG(ERROR) << "Failed to send data: '" << error_message << "'";
  159. if (send_stream_.is_valid()) {
  160. send_stream_->EndReadData(0);
  161. ShutdownSend();
  162. }
  163. }
  164. } // namespace bluetooth