1 // Copyright 2014 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 #ifndef DEVICE_SERIAL_SERIAL_IO_HANDLER_H_
6 #define DEVICE_SERIAL_SERIAL_IO_HANDLER_H_
8 #include "base/callback.h"
9 #include "base/files/file.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/threading/non_thread_safe.h"
13 #include "device/serial/buffer.h"
14 #include "device/serial/serial.mojom.h"
18 // Provides a simplified interface for performing asynchronous I/O on serial
19 // devices by hiding platform-specific MessageLoop interfaces. Pending I/O
20 // operations hold a reference to this object until completion so that memory
21 // doesn't disappear out from under the OS.
22 class SerialIoHandler
: public base::NonThreadSafe
,
23 public base::RefCounted
<SerialIoHandler
> {
25 // Constructs an instance of some platform-specific subclass.
26 static scoped_refptr
<SerialIoHandler
> Create(
27 scoped_refptr
<base::MessageLoopProxy
> file_thread_message_loop
,
28 scoped_refptr
<base::MessageLoopProxy
> ui_thread_message_loop
);
30 typedef base::Callback
<void(bool success
)> OpenCompleteCallback
;
32 // Initiates an asynchronous Open of the device.
33 virtual void Open(const std::string
& port
,
34 const OpenCompleteCallback
& callback
);
36 // Signals that the access request for |port| is complete.
37 void OnRequestAccessComplete(const std::string
& port
, bool success
);
39 // Performs an async Read operation. Behavior is undefined if this is called
40 // while a Read is already pending. Otherwise, the Done or DoneWithError
41 // method on |buffer| will eventually be called with a result.
42 void Read(scoped_ptr
<WritableBuffer
> buffer
);
44 // Performs an async Write operation. Behavior is undefined if this is called
45 // while a Write is already pending. Otherwise, the Done or DoneWithError
46 // method on |buffer| will eventually be called with a result.
47 void Write(scoped_ptr
<ReadOnlyBuffer
> buffer
);
49 // Indicates whether or not a read is currently pending.
50 bool IsReadPending() const;
52 // Indicates whether or not a write is currently pending.
53 bool IsWritePending() const;
55 // Attempts to cancel a pending read operation.
56 void CancelRead(serial::ReceiveError reason
);
58 // Attempts to cancel a pending write operation.
59 void CancelWrite(serial::SendError reason
);
61 // Flushes input and output buffers.
62 virtual bool Flush() const = 0;
64 // Reads current control signals (DCD, CTS, etc.) into an existing
65 // DeviceControlSignals structure. Returns |true| iff the signals were
67 virtual serial::DeviceControlSignalsPtr
GetControlSignals() const = 0;
69 // Sets one or more control signals (DTR and/or RTS). Returns |true| iff
70 // the signals were successfully set. Unininitialized flags in the
71 // HostControlSignals structure are left unchanged.
72 virtual bool SetControlSignals(
73 const serial::HostControlSignals
& control_signals
) = 0;
75 // Performs platform-specific port configuration. Returns |true| iff
76 // configuration was successful.
77 virtual bool ConfigurePort(const serial::ConnectionOptions
& options
) = 0;
79 // Performs a platform-specific port configuration query. Fills values in an
80 // existing ConnectionInfo. Returns |true| iff port configuration was
81 // successfully retrieved.
82 virtual serial::ConnectionInfoPtr
GetPortInfo() const = 0;
85 explicit SerialIoHandler(
86 scoped_refptr
<base::MessageLoopProxy
> file_thread_message_loop
,
87 scoped_refptr
<base::MessageLoopProxy
> ui_thread_message_loop
);
88 virtual ~SerialIoHandler();
90 // Performs a platform-specific read operation. This must guarantee that
91 // ReadCompleted is called when the underlying async operation is completed
92 // or the SerialIoHandler instance will leak.
93 // NOTE: Implementations of ReadImpl should never call ReadCompleted directly.
94 // Use QueueReadCompleted instead to avoid reentrancy.
95 virtual void ReadImpl() = 0;
97 // Performs a platform-specific write operation. This must guarantee that
98 // WriteCompleted is called when the underlying async operation is completed
99 // or the SerialIoHandler instance will leak.
100 // NOTE: Implementations of WriteImpl should never call WriteCompleted
101 // directly. Use QueueWriteCompleted instead to avoid reentrancy.
102 virtual void WriteImpl() = 0;
104 // Platform-specific read cancelation.
105 virtual void CancelReadImpl() = 0;
107 // Platform-specific write cancelation.
108 virtual void CancelWriteImpl() = 0;
110 // Requests access to the underlying serial device, if needed.
111 virtual void RequestAccess(
112 const std::string
& port
,
113 scoped_refptr
<base::MessageLoopProxy
> file_message_loop
,
114 scoped_refptr
<base::MessageLoopProxy
> ui_message_loop
);
116 // Performs platform-specific, one-time port configuration on open.
117 virtual bool PostOpen();
119 // Called by the implementation to signal that the active read has completed.
120 // WARNING: Calling this method can destroy the SerialIoHandler instance
121 // if the associated I/O operation was the only thing keeping it alive.
122 void ReadCompleted(int bytes_read
, serial::ReceiveError error
);
124 // Called by the implementation to signal that the active write has completed.
125 // WARNING: Calling this method may destroy the SerialIoHandler instance
126 // if the associated I/O operation was the only thing keeping it alive.
127 void WriteCompleted(int bytes_written
, serial::SendError error
);
129 // Queues a ReadCompleted call on the current thread. This is used to allow
130 // ReadImpl to immediately signal completion with 0 bytes and an error,
131 // without being reentrant.
132 void QueueReadCompleted(int bytes_read
, serial::ReceiveError error
);
134 // Queues a WriteCompleted call on the current thread. This is used to allow
135 // WriteImpl to immediately signal completion with 0 bytes and an error,
136 // without being reentrant.
137 void QueueWriteCompleted(int bytes_written
, serial::SendError error
);
139 const base::File
& file() const { return file_
; }
141 char* pending_read_buffer() const {
142 return pending_read_buffer_
? pending_read_buffer_
->GetData() : NULL
;
145 uint32_t pending_read_buffer_len() const {
146 return pending_read_buffer_
? pending_read_buffer_
->GetSize() : 0;
149 serial::ReceiveError
read_cancel_reason() const {
150 return read_cancel_reason_
;
153 bool read_canceled() const { return read_canceled_
; }
155 const char* pending_write_buffer() const {
156 return pending_write_buffer_
? pending_write_buffer_
->GetData() : NULL
;
159 uint32_t pending_write_buffer_len() const {
160 return pending_write_buffer_
? pending_write_buffer_
->GetSize() : 0;
163 serial::SendError
write_cancel_reason() const { return write_cancel_reason_
; }
165 bool write_canceled() const { return write_canceled_
; }
167 // Possibly fixes up a serial port path name in a platform-specific manner.
168 static std::string
MaybeFixUpPortName(const std::string
& port_name
);
171 friend class base::RefCounted
<SerialIoHandler
>;
173 // Continues an Open operation on the FILE thread.
174 void StartOpen(const std::string
& port
,
175 scoped_refptr
<base::MessageLoopProxy
> io_message_loop
);
177 // Finalizes an Open operation (continued from StartOpen) on the IO thread.
178 void FinishOpen(base::File file
);
182 // Continues a Close operation on the FILE thread.
183 static void DoClose(base::File port
);
185 // File for the opened serial device. This value is only modified from the IO
189 scoped_ptr
<WritableBuffer
> pending_read_buffer_
;
190 serial::ReceiveError read_cancel_reason_
;
193 scoped_ptr
<ReadOnlyBuffer
> pending_write_buffer_
;
194 serial::SendError write_cancel_reason_
;
195 bool write_canceled_
;
197 // Callback to handle the completion of a pending Open() request.
198 OpenCompleteCallback open_complete_
;
200 scoped_refptr
<base::MessageLoopProxy
> file_thread_message_loop_
;
201 // On Chrome OS, PermissionBrokerClient should be called on the UI thread.
202 scoped_refptr
<base::MessageLoopProxy
> ui_thread_message_loop_
;
204 DISALLOW_COPY_AND_ASSIGN(SerialIoHandler
);
207 } // namespace device
209 #endif // DEVICE_SERIAL_SERIAL_IO_HANDLER_H_