1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef DEVICE_SERIAL_SERIAL_IO_HANDLER_H_ 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define DEVICE_SERIAL_SERIAL_IO_HANDLER_H_ 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/files/file.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/ref_counted.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/message_loop/message_loop_proxy.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/threading/non_thread_safe.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/serial/buffer.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/serial/serial.mojom.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace device { 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Provides a simplified interface for performing asynchronous I/O on serial 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// devices by hiding platform-specific MessageLoop interfaces. Pending I/O 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// operations hold a reference to this object until completion so that memory 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// doesn't disappear out from under the OS. 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SerialIoHandler : public base::NonThreadSafe, 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public base::RefCounted<SerialIoHandler> { 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Constructs an instance of some platform-specific subclass. 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static scoped_refptr<SerialIoHandler> Create( 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> file_thread_message_loop); 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef base::Callback<void(bool success)> OpenCompleteCallback; 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Initiates an asynchronous Open of the device. 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void Open(const std::string& port, 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const OpenCompleteCallback& callback); 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Performs an async Read operation. Behavior is undefined if this is called 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // while a Read is already pending. Otherwise, the Done or DoneWithError 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // method on |buffer| will eventually be called with a result. 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void Read(scoped_ptr<WritableBuffer> buffer); 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Performs an async Write operation. Behavior is undefined if this is called 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // while a Write is already pending. Otherwise, the Done or DoneWithError 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // method on |buffer| will eventually be called with a result. 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void Write(scoped_ptr<ReadOnlyBuffer> buffer); 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Indicates whether or not a read is currently pending. 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool IsReadPending() const; 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Indicates whether or not a write is currently pending. 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool IsWritePending() const; 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Attempts to cancel a pending read operation. 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void CancelRead(serial::ReceiveError reason); 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Attempts to cancel a pending write operation. 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void CancelWrite(serial::SendError reason); 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Flushes input and output buffers. 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual bool Flush() const = 0; 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Reads current control signals (DCD, CTS, etc.) into an existing 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // DeviceControlSignals structure. Returns |true| iff the signals were 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // successfully read. 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual serial::DeviceControlSignalsPtr GetControlSignals() const = 0; 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Sets one or more control signals (DTR and/or RTS). Returns |true| iff 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the signals were successfully set. Unininitialized flags in the 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // HostControlSignals structure are left unchanged. 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual bool SetControlSignals( 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const serial::HostControlSignals& control_signals) = 0; 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Performs platform-specific port configuration. Returns |true| iff 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // configuration was successful. 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual bool ConfigurePort(const serial::ConnectionOptions& options) = 0; 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Performs a platform-specific port configuration query. Fills values in an 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // existing ConnectionInfo. Returns |true| iff port configuration was 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // successfully retrieved. 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual serial::ConnectionInfoPtr GetPortInfo() const = 0; 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected: 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) explicit SerialIoHandler( 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> file_thread_message_loop); 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~SerialIoHandler(); 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Performs a platform-specific read operation. This must guarantee that 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ReadCompleted is called when the underlying async operation is completed 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // or the SerialIoHandler instance will leak. 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // NOTE: Implementations of ReadImpl should never call ReadCompleted directly. 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Use QueueReadCompleted instead to avoid reentrancy. 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void ReadImpl() = 0; 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Performs a platform-specific write operation. This must guarantee that 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // WriteCompleted is called when the underlying async operation is completed 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // or the SerialIoHandler instance will leak. 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // NOTE: Implementations of Writempl should never call WriteCompleted 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // directly. Use QueueWriteCompleted instead to avoid reentrancy. 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void WriteImpl() = 0; 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Platform-specific read cancelation. 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void CancelReadImpl() = 0; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Platform-specific write cancelation. 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void CancelWriteImpl() = 0; 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Performs platform-specific, one-time port configuration on open. 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual bool PostOpen(); 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Called by the implementation to signal that the active read has completed. 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // WARNING: Calling this method can destroy the SerialIoHandler instance 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // if the associated I/O operation was the only thing keeping it alive. 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void ReadCompleted(int bytes_read, serial::ReceiveError error); 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Called by the implementation to signal that the active write has completed. 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // WARNING: Calling this method may destroy the SerialIoHandler instance 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // if the associated I/O operation was the only thing keeping it alive. 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void WriteCompleted(int bytes_written, serial::SendError error); 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Queues a ReadCompleted call on the current thread. This is used to allow 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ReadImpl to immediately signal completion with 0 bytes and an error, 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // without being reentrant. 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void QueueReadCompleted(int bytes_read, serial::ReceiveError error); 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Queues a WriteCompleted call on the current thread. This is used to allow 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // WriteImpl to immediately signal completion with 0 bytes and an error, 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // without being reentrant. 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void QueueWriteCompleted(int bytes_written, serial::SendError error); 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::File& file() const { return file_; } 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char* pending_read_buffer() const { 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pending_read_buffer_ ? pending_read_buffer_->GetData() : NULL; 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32_t pending_read_buffer_len() const { 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pending_read_buffer_ ? pending_read_buffer_->GetSize() : 0; 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch serial::ReceiveError read_cancel_reason() const { 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return read_cancel_reason_; 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool read_canceled() const { return read_canceled_; } 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const char* pending_write_buffer() const { 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pending_write_buffer_ ? pending_write_buffer_->GetData() : NULL; 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32_t pending_write_buffer_len() const { 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pending_write_buffer_ ? pending_write_buffer_->GetSize() : 0; 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch serial::SendError write_cancel_reason() const { return write_cancel_reason_; } 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool write_canceled() const { return write_canceled_; } 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Possibly fixes up a serial port path name in a platform-specific manner. 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static std::string MaybeFixUpPortName(const std::string& port_name); 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) friend class base::RefCounted<SerialIoHandler>; 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Continues an Open operation on the FILE thread. 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void StartOpen(const std::string& port, 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<base::MessageLoopProxy> io_message_loop); 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Finalizes an Open operation (continued from StartOpen) on the IO thread. 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void FinishOpen(base::File file); 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void Close(); 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Continues a Close operation on the FILE thread. 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static void DoClose(base::File port); 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // File for the opened serial device. This value is only modified from the IO 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // thread. 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::File file_; 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<WritableBuffer> pending_read_buffer_; 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch serial::ReceiveError read_cancel_reason_; 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool read_canceled_; 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ReadOnlyBuffer> pending_write_buffer_; 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch serial::SendError write_cancel_reason_; 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool write_canceled_; 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Callback to handle the completion of a pending Open() request. 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OpenCompleteCallback open_complete_; 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<base::MessageLoopProxy> file_thread_message_loop_; 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SerialIoHandler); 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace device 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // DEVICE_SERIAL_SERIAL_IO_HANDLER_H_ 197