1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef SERVICES_DEVICE_SERIAL_BLUETOOTH_SERIAL_PORT_IMPL_H_
6 #define SERVICES_DEVICE_SERIAL_BLUETOOTH_SERIAL_PORT_IMPL_H_
8 #include "base/containers/span.h"
9 #include "base/sequence_checker.h"
10 #include "base/task/single_thread_task_runner.h"
11 #include "base/threading/thread_task_runner_handle.h"
12 #include "device/bluetooth/bluetooth_adapter.h"
13 #include "device/bluetooth/bluetooth_socket.h"
14 #include "mojo/public/cpp/bindings/receiver.h"
15 #include "mojo/public/cpp/system/data_pipe.h"
16 #include "services/device/public/mojom/serial.mojom.h"
17 #include "services/device/serial/serial_io_handler.h"
18 #include "services/device/serial/serial_port_impl.h"
24 // This class is intended to allow serial communication using a Bluetooth
25 // SPP device. The Bluetooth device is used to create a Bluetooth socket
26 // which is closed upon error in any of the interface functions.
27 class BluetoothSerialPortImpl : public mojom::SerialPort {
30 base::OnceCallback<void(mojo::PendingRemote<mojom::SerialPort>)>;
32 // Creates of instance of BluetoothSerialPortImpl using a Bluetooth
33 // adapter, a Bluetooth device address and a receiver/watcher to
34 // create a pipe. The receiver and watcher will own this object.
36 scoped_refptr<BluetoothAdapter> adapter,
37 const std::string& address,
38 const BluetoothUUID& service_class_id,
39 mojom::SerialConnectionOptionsPtr options,
40 mojo::PendingRemote<mojom::SerialPortClient> client,
41 mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher,
42 OpenCallback callback);
44 BluetoothSerialPortImpl(
45 scoped_refptr<BluetoothAdapter> adapter,
46 const std::string& address,
47 mojom::SerialConnectionOptionsPtr options,
48 mojo::PendingRemote<mojom::SerialPortClient> client,
49 mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher);
50 BluetoothSerialPortImpl(const BluetoothSerialPortImpl&) = delete;
51 BluetoothSerialPortImpl& operator=(const BluetoothSerialPortImpl&) = delete;
52 ~BluetoothSerialPortImpl() override;
55 // mojom::SerialPort methods:
56 void StartWriting(mojo::ScopedDataPipeConsumerHandle consumer) override;
57 void StartReading(mojo::ScopedDataPipeProducerHandle producer) override;
58 void Flush(mojom::SerialPortFlushMode mode, FlushCallback callback) override;
59 void Drain(DrainCallback callback) override;
60 void GetControlSignals(GetControlSignalsCallback callback) override;
61 void SetControlSignals(mojom::SerialHostControlSignalsPtr signals,
62 SetControlSignalsCallback callback) override;
63 void ConfigurePort(mojom::SerialConnectionOptionsPtr options,
64 ConfigurePortCallback callback) override;
65 void GetPortInfo(GetPortInfoCallback callback) override;
66 void Close(bool flush, CloseCallback callback) override;
68 void OpenSocket(const BluetoothUUID& service_class_id, OpenCallback callback);
69 void WriteToSocket(MojoResult result, const mojo::HandleSignalsState& state);
70 void ReadFromSocketAndWriteOut(MojoResult result,
71 const mojo::HandleSignalsState& state);
73 void ResetPendingWriteBuffer();
74 void ResetReceiveBuffer();
79 void OnSocketConnected(OpenCallback callback,
80 scoped_refptr<BluetoothSocket> socket);
81 void OnSocketConnectedError(OpenCallback callback,
82 const std::string& message);
84 void OnBluetoothSocketReceive(int num_bytes_received,
85 scoped_refptr<net::IOBuffer> receive_buffer);
86 void OnBluetoothSocketReceiveError(
87 device::BluetoothSocket::ErrorReason error_reason,
88 const std::string& error_message);
89 void OnBluetoothSocketSend(int num_bytes_sent);
90 void OnBluetoothSocketSendError(const std::string& error_message);
91 void OnSocketDisconnected(CloseCallback callback);
93 mojo::Receiver<mojom::SerialPort> receiver_{this};
94 mojo::Remote<mojom::SerialPortConnectionWatcher> watcher_;
95 mojo::Remote<mojom::SerialPortClient> client_;
97 // Data pipes for input and output.
98 mojo::ScopedDataPipeConsumerHandle in_stream_;
99 mojo::SimpleWatcher in_stream_watcher_;
100 mojo::ScopedDataPipeProducerHandle out_stream_;
101 mojo::SimpleWatcher out_stream_watcher_;
103 // Used for pending writes to |out_stream_|. When empty this indicates that
104 // |out_stream_| has been closed (and possibly replaced).
105 base::span<char> pending_write_buffer_;
107 // Holds the callback for a drain until pending operations have been
109 DrainCallback drain_callback_;
111 scoped_refptr<BluetoothSocket> bluetooth_socket_;
112 const scoped_refptr<BluetoothAdapter> bluetooth_adapter_;
113 const std::string address_;
115 bool read_pending_ = false;
116 bool write_pending_ = false;
118 // Field to track whether the a write had a Flush call.
119 bool flush_next_write_ = false;
121 // |receive_buffer_| is used to temporarily hold larger than expected
122 // BluetoothSocket::Receive() responses, or responses received on a replaced
124 size_t receive_buffer_size_ = 0;
125 size_t receive_buffer_next_byte_pos_ = 0;
126 scoped_refptr<net::IOBuffer> receive_buffer_;
128 mojom::SerialConnectionOptionsPtr options_;
130 SEQUENCE_CHECKER(sequence_checker_);
132 base::WeakPtrFactory<BluetoothSerialPortImpl> weak_ptr_factory_{this};
135 } // namespace device
137 #endif // SERVICES_DEVICE_SERIAL_BLUETOOTH_SERIAL_PORT_IMPL_H_