Home | History | Annotate | Download | only in serial
      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.
      4 
      5 #ifndef EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_
      6 #define EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_
      7 
      8 #include <string>
      9 
     10 #include "base/callback.h"
     11 #include "base/memory/weak_ptr.h"
     12 #include "base/time/time.h"
     13 #include "content/public/browser/browser_thread.h"
     14 #include "device/serial/serial_io_handler.h"
     15 #include "extensions/browser/api/api_resource.h"
     16 #include "extensions/browser/api/api_resource_manager.h"
     17 #include "extensions/common/api/serial.h"
     18 #include "net/base/io_buffer.h"
     19 
     20 using content::BrowserThread;
     21 
     22 namespace extensions {
     23 
     24 // Encapsulates an open serial port.
     25 // NOTE: Instances of this object should only be constructed on the IO thread,
     26 // and all methods should only be called on the IO thread unless otherwise
     27 // noted.
     28 class SerialConnection : public ApiResource,
     29                          public base::SupportsWeakPtr<SerialConnection> {
     30  public:
     31   typedef device::SerialIoHandler::OpenCompleteCallback OpenCompleteCallback;
     32 
     33   // This is the callback type expected by Receive. Note that an error result
     34   // does not necessarily imply an empty |data| string, since a receive may
     35   // complete partially before being interrupted by an error condition.
     36   typedef base::Callback<
     37       void(const std::string& data, core_api::serial::ReceiveError error)>
     38       ReceiveCompleteCallback;
     39 
     40   // This is the callback type expected by Send. Note that an error result
     41   // does not necessarily imply 0 bytes sent, since a send may complete
     42   // partially before being interrupted by an error condition.
     43   typedef base::Callback<
     44       void(int bytes_sent, core_api::serial::SendError error)>
     45       SendCompleteCallback;
     46 
     47   SerialConnection(const std::string& port,
     48                    const std::string& owner_extension_id);
     49   virtual ~SerialConnection();
     50 
     51   // ApiResource override.
     52   virtual bool IsPersistent() const OVERRIDE;
     53 
     54   void set_persistent(bool persistent) { persistent_ = persistent; }
     55   bool persistent() const { return persistent_; }
     56 
     57   void set_name(const std::string& name) { name_ = name; }
     58   const std::string& name() const { return name_; }
     59 
     60   void set_buffer_size(int buffer_size);
     61   int buffer_size() const { return buffer_size_; }
     62 
     63   void set_receive_timeout(int receive_timeout);
     64   int receive_timeout() const { return receive_timeout_; }
     65 
     66   void set_send_timeout(int send_timeout);
     67   int send_timeout() const { return send_timeout_; }
     68 
     69   void set_paused(bool paused);
     70   bool paused() const { return paused_; }
     71 
     72   // Initiates an asynchronous Open of the device. It is the caller's
     73   // responsibility to ensure that this SerialConnection stays alive
     74   // until |callback| is run.
     75   void Open(const OpenCompleteCallback& callback);
     76 
     77   // Begins an asynchronous receive operation. Calling this while a Receive
     78   // is already pending is a no-op and returns |false| without calling
     79   // |callback|.
     80   bool Receive(const ReceiveCompleteCallback& callback);
     81 
     82   // Begins an asynchronous send operation. Calling this while a Send
     83   // is already pending is a no-op and returns |false| without calling
     84   // |callback|.
     85   bool Send(const std::string& data, const SendCompleteCallback& callback);
     86 
     87   // Flushes input and output buffers.
     88   bool Flush() const;
     89 
     90   // Configures some subset of port options for this connection.
     91   // Omitted options are unchanged. Returns |true| iff the configuration
     92   // changes were successful.
     93   bool Configure(const core_api::serial::ConnectionOptions& options);
     94 
     95   // Connection configuration query. Fills values in an existing
     96   // ConnectionInfo. Returns |true| iff the connection's information
     97   // was successfully retrieved.
     98   bool GetInfo(core_api::serial::ConnectionInfo* info) const;
     99 
    100   // Reads current control signals (DCD, CTS, etc.) into an existing
    101   // DeviceControlSignals structure. Returns |true| iff the signals were
    102   // successfully read.
    103   bool GetControlSignals(
    104       core_api::serial::DeviceControlSignals* control_signals) const;
    105 
    106   // Sets one or more control signals (DTR and/or RTS). Returns |true| iff
    107   // the signals were successfully set. Unininitialized flags in the
    108   // HostControlSignals structure are left unchanged.
    109   bool SetControlSignals(
    110       const core_api::serial::HostControlSignals& control_signals);
    111 
    112   // Overrides |io_handler_| for testing.
    113   void SetIoHandlerForTest(scoped_refptr<device::SerialIoHandler> handler);
    114 
    115   static const BrowserThread::ID kThreadId = BrowserThread::IO;
    116 
    117  private:
    118   friend class ApiResourceManager<SerialConnection>;
    119   static const char* service_name() { return "SerialConnectionManager"; }
    120 
    121   // Encapsulates a cancelable, delayed timeout task. Posts a delayed
    122   // task upon construction and implicitly cancels the task upon
    123   // destruction if it hasn't run yet.
    124   class TimeoutTask {
    125    public:
    126     TimeoutTask(const base::Closure& closure, const base::TimeDelta& delay);
    127     ~TimeoutTask();
    128 
    129    private:
    130     void Run() const;
    131 
    132     base::WeakPtrFactory<TimeoutTask> weak_factory_;
    133     base::Closure closure_;
    134     base::TimeDelta delay_;
    135   };
    136 
    137   // Handles a receive timeout.
    138   void OnReceiveTimeout();
    139 
    140   // Handles a send timeout.
    141   void OnSendTimeout();
    142 
    143   // Receives read completion notification from the |io_handler_|.
    144   void OnAsyncReadComplete(int bytes_read, device::serial::ReceiveError error);
    145 
    146   // Receives write completion notification from the |io_handler_|.
    147   void OnAsyncWriteComplete(int bytes_sent, device::serial::SendError error);
    148 
    149   // The pathname of the serial device.
    150   std::string port_;
    151 
    152   // Flag indicating whether or not the connection should persist when
    153   // its host app is suspended.
    154   bool persistent_;
    155 
    156   // User-specified connection name.
    157   std::string name_;
    158 
    159   // Size of the receive buffer.
    160   int buffer_size_;
    161 
    162   // Amount of time (in ms) to wait for a Read to succeed before triggering a
    163   // timeout response via onReceiveError.
    164   int receive_timeout_;
    165 
    166   // Amount of time (in ms) to wait for a Write to succeed before triggering
    167   // a timeout response.
    168   int send_timeout_;
    169 
    170   // Flag indicating that the connection is paused. A paused connection will not
    171   // raise new onReceive events.
    172   bool paused_;
    173 
    174   // Callback to handle the completion of a pending Receive() request.
    175   ReceiveCompleteCallback receive_complete_;
    176 
    177   // Callback to handle the completion of a pending Send() request.
    178   SendCompleteCallback send_complete_;
    179 
    180   // Closure which will trigger a receive timeout unless cancelled. Reset on
    181   // initialization and after every successful Receive().
    182   scoped_ptr<TimeoutTask> receive_timeout_task_;
    183 
    184   // Write timeout closure. Reset on initialization and after every successful
    185   // Send().
    186   scoped_ptr<TimeoutTask> send_timeout_task_;
    187 
    188   scoped_refptr<net::IOBuffer> receive_buffer_;
    189 
    190   // Asynchronous I/O handler.
    191   scoped_refptr<device::SerialIoHandler> io_handler_;
    192 };
    193 
    194 }  // namespace extensions
    195 
    196 namespace mojo {
    197 
    198 template <>
    199 struct TypeConverter<device::serial::HostControlSignalsPtr,
    200                      extensions::core_api::serial::HostControlSignals> {
    201   static device::serial::HostControlSignalsPtr Convert(
    202       const extensions::core_api::serial::HostControlSignals& input);
    203 };
    204 
    205 template <>
    206 struct TypeConverter<device::serial::ConnectionOptionsPtr,
    207                      extensions::core_api::serial::ConnectionOptions> {
    208   static device::serial::ConnectionOptionsPtr Convert(
    209       const extensions::core_api::serial::ConnectionOptions& input);
    210 };
    211 
    212 }  // namespace mojo
    213 
    214 #endif  // EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_
    215