// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Use the <code>chrome.serial</code> API to read from and write to a device
// connected to a serial port.
namespace serial {

  dictionary DeviceInfo {
    // The device's system path. This should be passed as the <code>path</code>
    // argument to <code>chrome.serial.connect</code> in order to connect to
    // this device.
    DOMString path;

    // A PCI or USB vendor ID if one can be determined for the underlying
    // device.
    long? vendorId;

    // A USB product ID if one can be determined for the underlying device.
    long? productId;

    // A human-readable display name for the underlying device if one can be
    // queried from the host driver.
    DOMString? displayName;
  };

  callback GetDevicesCallback = void (DeviceInfo[] ports);

  enum DataBits { seven, eight };
  enum ParityBit { no, odd, even };
  enum StopBits { one, two };

  dictionary ConnectionOptions {
    // Flag indicating whether or not the connection should be left open when
    // the application is suspended (see
    // <a href="http://developer.chrome.com/apps/app_lifecycle.html">Manage App
    // Lifecycle</a>). The default value is "false." When the application is
    // loaded, any serial connections previously opened with persistent=true
    // can be fetched with <code>getConnections</code>.
    boolean? persistent;

    // An application-defined string to associate with the connection.
    DOMString? name;

    // The size of the buffer used to receive data. The default value is 4096.
    long? bufferSize;

    // The requested bitrate of the connection to be opened. For compatibility
    // with the widest range of hardware, this number should match one of
    // commonly-available bitrates, such as 110, 300, 1200, 2400, 4800, 9600,
    // 14400, 19200, 38400, 57600, 115200. There is no guarantee, of course,
    // that the device connected to the serial port will support the requested
    // bitrate, even if the port itself supports that bitrate. <code>9600</code>
    // will be passed by default.
    long? bitrate;

    // <code>"eight"</code> will be passed by default.
    DataBits? dataBits;

    // <code>"no"</code> will be passed by default.
    ParityBit? parityBit;

    // <code>"one"</code> will be passed by default.
    StopBits? stopBits;

    // Flag indicating whether or not to enable RTS/CTS hardware flow control.
    // Defaults to false.
    boolean? ctsFlowControl;

    // The maximum amount of time (in milliseconds) to wait for new data before
    // raising an <code>onReceiveError</code> event with a "timeout" error.
    // If zero, receive timeout errors will not be raised for the connection.
    // Defaults to 0.
    long? receiveTimeout;

    // The maximum amount of time (in milliseconds) to wait for a
    // <code>send</code> operation to complete before calling the callback with
    // a "timeout" error. If zero, send timeout errors will not be triggered.
    // Defaults to 0.
    long? sendTimeout;
  };

  // Result of the <code>getInfo</code> method.
  dictionary ConnectionInfo {
    // The id of the serial port connection.
    long connectionId;

    // Flag indicating whether the connection is blocked from firing onReceive
    // events.
    boolean paused;

    // See <code>ConnectionOptions.persistent</code>
    boolean persistent;

    // See <code>ConnectionOptions.name</code>
    DOMString name;

    // See <code>ConnectionOptions.bufferSize</code>
    long bufferSize;

    // See <code>ConnectionOptions.receiveTimeout</code>
    long receiveTimeout;

    // See <code>ConnectionOptions.sendTimeout</code>
    long sendTimeout;

    // See <code>ConnectionOptions.bitrate</code>. This field may be omitted
    // or inaccurate if a non-standard bitrate is in use, or if an error
    // occurred while querying the underlying device.
    long? bitrate;

    // See <code>ConnectionOptions.dataBits</code>. This field may be omitted
    // if an error occurred while querying the underlying device.
    DataBits? dataBits;

    // See <code>ConnectionOptions.parityBit</code>. This field may be omitted
    // if an error occurred while querying the underlying device.
    ParityBit? parityBit;

    // See <code>ConnectionOptions.stopBits</code>. This field may be omitted
    // if an error occurred while querying the underlying device.
    StopBits? stopBits;

    // See <code>ConnectionOptions.ctsFlowControl</code>. This field may be
    // omitted if an error occurred while querying the underlying device.
    boolean? ctsFlowControl;
  };

  // Callback from the <code>connect</code> method;
  callback ConnectCallback = void (ConnectionInfo connectionInfo);

  // Callback from the <code>update</code> method.
  callback UpdateCallback = void (boolean result);

  // Callback from the <code>disconnect</code> method. Returns true if the
  // operation was successful.
  callback DisconnectCallback = void (boolean result);

  // Callback from the <code>setPaused</code> method.
  callback SetPausedCallback = void ();

  // Callback from the <code>getInfo</code> method.
  callback GetInfoCallback = void (ConnectionInfo connectionInfo);

  // Callback from the <code>getConnections</code> method.
  callback GetConnectionsCallback = void (ConnectionInfo[] connectionInfos);

  enum SendError {
    // The connection was disconnected.
    disconnected,

    // A send was already pending.
    pending,

    // The send timed out.
    timeout,

    // A system error occurred and the connection may be unrecoverable.
    system_error
  };

  dictionary SendInfo {
    // The number of bytes sent.
    long bytesSent;

    // An error code if an error occurred.
    SendError? error;
  };

  callback SendCallback = void (SendInfo sendInfo);

  callback FlushCallback = void (boolean result);

  // The set of control signals which may be sent to a connected serial device
  // using <code>setControlSignals</code>. Note that support for these signals
  // is device-dependent.
  dictionary HostControlSignals {
    // DTR (Data Terminal Ready).
    boolean? dtr;

    // RTS (Request To Send).
    boolean? rts;
  };

  // The set of control signals which may be set by a connected serial device.
  // These can be queried using <code>getControlSignals</code>. Note that
  // support for these signals is device-dependent.
  dictionary DeviceControlSignals {
    // DCD (Data Carrier Detect) or RLSD (Receive Line Signal/ Detect).
    boolean dcd;

    // CTS (Clear To Send).
    boolean cts;

    // RI (Ring Indicator).
    boolean ri;

    // DSR (Data Set Ready).
    boolean dsr;
  };

  // Returns a snapshot of current control signals.
  callback GetControlSignalsCallback = void (DeviceControlSignals signals);

  // Returns true if operation was successful.
  callback SetControlSignalsCallback = void (boolean result);

  // Data from an <code>onReceive</code> event.
  dictionary ReceiveInfo {
    // The connection identifier.
    long connectionId;

    // The data received.
    ArrayBuffer data;
  };

  enum ReceiveError {
    // The connection was disconnected.
    disconnected,

    // No data has been received for <code>receiveTimeout</code> milliseconds.
    timeout,

    // The device was most likely disconnected from the host.
    device_lost,

    // A system error occurred and the connection may be unrecoverable.
    system_error
  };

  // Data from an <code>onReceiveError</code> event.
  dictionary ReceiveErrorInfo {
    // The connection identifier.
    long connectionId;

    // An error code indicating what went wrong.
    ReceiveError error;
  };

  interface Functions {
    // Returns information about available serial devices on the system.
    // The list is regenerated each time this method is called.
    // |callback| : Called with the list of <code>DeviceInfo</code> objects.
    static void getDevices(GetDevicesCallback callback);

    // Connects to a given serial port.
    // |path| : The system path of the serial port to open.
    // |options| : Port configuration options.
    // |callback| : Called when the connection has been opened.
    static void connect(DOMString path,
                        optional ConnectionOptions options,
                        ConnectCallback callback);

    // Update the option settings on an open serial port connection.
    // |connectionId| : The id of the opened connection.
    // |options| : Port configuration options.
    // |callback| : Called when the configuation has completed.
    static void update(long connectionId,
                       ConnectionOptions options,
                       UpdateCallback callback);

    // Disconnects from a serial port.
    // |connectionId| : The id of the opened connection.
    // |callback| : Called when the connection has been closed.
    static void disconnect(long connectionId, DisconnectCallback callback);

    // Pauses or unpauses an open connection.
    // |connectionId| : The id of the opened connection.
    // |paused| : Flag to indicate whether to pause or unpause.
    // |callback| : Called when the connection has been successfully paused or
    //              unpaused.
    static void setPaused(long connectionId,
                          boolean paused,
                          SetPausedCallback callback);

    // Retrieves the state of a given connection.
    // |connectionId| : The id of the opened connection.
    // |callback| : Called with connection state information when available.
    static void getInfo(long connectionId, GetInfoCallback callback);

    // Retrieves the list of currently opened serial port connections owned by
    // the application.
    // |callback| : Called with the list of connections when available.
    static void getConnections(GetConnectionsCallback callback);

    // Writes data to the given connection.
    // |connectionId| : The id of the connection.
    // |data| : The data to send.
    // |callback| : Called when the operation has completed.
    static void send(long connectionId,
                     ArrayBuffer data,
                     SendCallback callback);

    // Flushes all bytes in the given connection's input and output buffers.
    static void flush(long connectionId, FlushCallback callback);

    // Retrieves the state of control signals on a given connection.
    // |connectionId| : The id of the connection.
    // |callback| : Called when the control signals are available.
    static void getControlSignals(long connectionId,
                                  GetControlSignalsCallback callback);

    // Sets the state of control signals on a given connection.
    // |connectionId| : The id of the connection.
    // |signals| : The set of signal changes to send to the device.
    // |callback| : Called once the control signals have been set.
    static void setControlSignals(long connectionId,
                                  HostControlSignals signals,
                                  SetControlSignalsCallback callback);
  };

  interface Events {
    // Event raised when data has been read from the connection.
    // |info| : Event data.
    static void onReceive(ReceiveInfo info);

    // Event raised when an error occurred while the runtime was waiting for
    // data on the serial port. Once this event is raised, the connection may be
    // set to <code>paused</code>. A <code>"timeout"</code> error does not pause
    // the connection.
    static void onReceiveError(ReceiveErrorInfo info);
  };
};
