1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_ 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/weak_ptr.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/serial/serial_io_handler.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/api_resource.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/api_resource_manager.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/api/serial.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/io_buffer.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Encapsulates an open serial port. 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// NOTE: Instances of this object should only be constructed on the IO thread, 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// and all methods should only be called on the IO thread unless otherwise 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// noted. 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SerialConnection : public ApiResource, 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public base::SupportsWeakPtr<SerialConnection> { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef device::SerialIoHandler::OpenCompleteCallback OpenCompleteCallback; 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This is the callback type expected by Receive. Note that an error result 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // does not necessarily imply an empty |data| string, since a receive may 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // complete partially before being interrupted by an error condition. 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef base::Callback< 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void(const std::string& data, core_api::serial::ReceiveError error)> 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReceiveCompleteCallback; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This is the callback type expected by Send. Note that an error result 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // does not necessarily imply 0 bytes sent, since a send may complete 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // partially before being interrupted by an error condition. 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef base::Callback< 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void(int bytes_sent, core_api::serial::SendError error)> 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SendCompleteCallback; 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SerialConnection(const std::string& port, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& owner_extension_id); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SerialConnection(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ApiResource override. 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool IsPersistent() const OVERRIDE; 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_persistent(bool persistent) { persistent_ = persistent; } 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool persistent() const { return persistent_; } 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_name(const std::string& name) { name_ = name; } 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& name() const { return name_; } 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_buffer_size(int buffer_size); 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int buffer_size() const { return buffer_size_; } 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_receive_timeout(int receive_timeout); 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int receive_timeout() const { return receive_timeout_; } 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_send_timeout(int send_timeout); 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int send_timeout() const { return send_timeout_; } 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_paused(bool paused); 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool paused() const { return paused_; } 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Initiates an asynchronous Open of the device. It is the caller's 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // responsibility to ensure that this SerialConnection stays alive 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // until |callback| is run. 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void Open(const OpenCompleteCallback& callback); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Begins an asynchronous receive operation. Calling this while a Receive 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is already pending is a no-op and returns |false| without calling 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |callback|. 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool Receive(const ReceiveCompleteCallback& callback); 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Begins an asynchronous send operation. Calling this while a Send 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is already pending is a no-op and returns |false| without calling 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |callback|. 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool Send(const std::string& data, const SendCompleteCallback& callback); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Flushes input and output buffers. 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool Flush() const; 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Configures some subset of port options for this connection. 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Omitted options are unchanged. Returns |true| iff the configuration 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // changes were successful. 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool Configure(const core_api::serial::ConnectionOptions& options); 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Connection configuration query. Fills values in an existing 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ConnectionInfo. Returns |true| iff the connection's information 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // was successfully retrieved. 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool GetInfo(core_api::serial::ConnectionInfo* info) const; 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reads current control signals (DCD, CTS, etc.) into an existing 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // DeviceControlSignals structure. Returns |true| iff the signals were 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // successfully read. 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool GetControlSignals( 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch core_api::serial::DeviceControlSignals* control_signals) const; 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Sets one or more control signals (DTR and/or RTS). Returns |true| iff 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the signals were successfully set. Unininitialized flags in the 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // HostControlSignals structure are left unchanged. 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool SetControlSignals( 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const core_api::serial::HostControlSignals& control_signals); 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overrides |io_handler_| for testing. 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void SetIoHandlerForTest(scoped_refptr<device::SerialIoHandler> handler); 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static const BrowserThread::ID kThreadId = BrowserThread::IO; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) friend class ApiResourceManager<SerialConnection>; 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const char* service_name() { return "SerialConnectionManager"; } 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Encapsulates a cancelable, delayed timeout task. Posts a delayed 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // task upon construction and implicitly cancels the task upon 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // destruction if it hasn't run yet. 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) class TimeoutTask { 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TimeoutTask(const base::Closure& closure, const base::TimeDelta& delay); 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ~TimeoutTask(); 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Run() const; 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::WeakPtrFactory<TimeoutTask> weak_factory_; 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Closure closure_; 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta delay_; 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) }; 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Handles a receive timeout. 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void OnReceiveTimeout(); 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Handles a send timeout. 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void OnSendTimeout(); 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Receives read completion notification from the |io_handler_|. 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void OnAsyncReadComplete(int bytes_read, device::serial::ReceiveError error); 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Receives write completion notification from the |io_handler_|. 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void OnAsyncWriteComplete(int bytes_sent, device::serial::SendError error); 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The pathname of the serial device. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string port_; 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Flag indicating whether or not the connection should persist when 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // its host app is suspended. 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool persistent_; 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // User-specified connection name. 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string name_; 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Size of the receive buffer. 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int buffer_size_; 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Amount of time (in ms) to wait for a Read to succeed before triggering a 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // timeout response via onReceiveError. 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int receive_timeout_; 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Amount of time (in ms) to wait for a Write to succeed before triggering 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // a timeout response. 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int send_timeout_; 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Flag indicating that the connection is paused. A paused connection will not 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // raise new onReceive events. 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool paused_; 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Callback to handle the completion of a pending Receive() request. 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReceiveCompleteCallback receive_complete_; 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Callback to handle the completion of a pending Send() request. 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SendCompleteCallback send_complete_; 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Closure which will trigger a receive timeout unless cancelled. Reset on 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // initialization and after every successful Receive(). 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<TimeoutTask> receive_timeout_task_; 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Write timeout closure. Reset on initialization and after every successful 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Send(). 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<TimeoutTask> send_timeout_task_; 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<net::IOBuffer> receive_buffer_; 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Asynchronous I/O handler. 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<device::SerialIoHandler> io_handler_; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace mojo { 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <> 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct TypeConverter<device::serial::HostControlSignalsPtr, 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::core_api::serial::HostControlSignals> { 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static device::serial::HostControlSignalsPtr Convert( 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const extensions::core_api::serial::HostControlSignals& input); 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <> 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct TypeConverter<device::serial::ConnectionOptionsPtr, 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::core_api::serial::ConnectionOptions> { 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static device::serial::ConnectionOptionsPtr Convert( 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const extensions::core_api::serial::ConnectionOptions& input); 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace mojo 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_ 215