chromium/services/device/public/mojom/serial.mojom

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module device.mojom;

import "device/bluetooth/public/mojom/uuid.mojom";
import "mojo/public/mojom/base/file_path.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";

struct SerialPortInfo {
  mojo_base.mojom.UnguessableToken token;
  mojo_base.mojom.FilePath path;

  // The backend implementation for the serial port.
  SerialPortType type = PLATFORM_SERIAL;

  // On macOS a serial device may have two paths, one for the call-out device
  // and one for the dial-in device. The call-out device is preferred. If
  // there is also an associated dial-in device its path is provided here. If
  // the dial-in device is the only option its path will be in |path|.
  [EnableIf=is_mac] mojo_base.mojom.FilePath? alternate_path;

  // On macOS a single serial port can be enumerated by multiple drivers. This
  // field permits disambiguation.
  [EnableIf=is_mac] string? usb_driver_name;

  // On Windows the "device instance ID" provides a stable identifier that can
  // be used for device permissions.
  [EnableIf=is_win] string device_instance_id;

  // The USB device vendor and product IDs.
  uint16 vendor_id;
  bool has_vendor_id = false;
  uint16 product_id;
  bool has_product_id = false;

  // The Bluetooth service class ID of the port if the port is from a Bluetooth
  // device. It is a 128-bit canonical UUID.
  bluetooth.mojom.UUID? bluetooth_service_class_id;

  // A string suitable for display to the user for describing this device. May
  // be, for example, the USB device product name string.
  // If no display_name is provided, the path will be displayed to the user
  // instead.
  string? display_name;

  // The USB device serial number.
  // Note: This field is not populated on Windows nor for non-USB devices.
  string? serial_number;

  // True if the port was connected when the SerialPortInfo was returned from
  // the SerialPortManager. SerialPortManagerClients are notified on port
  // connected state changes.
  //
  // A wired serial port is considered connected if it is physically attached
  // to the system.
  //
  // A wireless serial port is considered connected if the wireless device
  // hosting the port has any active connections to the system.
  bool connected = true;
};

enum SerialSendError {
  NONE,
  DISCONNECTED,
  SYSTEM_ERROR,
};

enum SerialReceiveError {
  NONE,
  DISCONNECTED,
  DEVICE_LOST,
  BREAK,
  FRAME_ERROR,
  OVERRUN,
  BUFFER_OVERFLOW,
  PARITY_ERROR,
  SYSTEM_ERROR,
};

enum SerialDataBits {
  NONE,
  SEVEN,
  EIGHT,
};

enum SerialParityBit {
  NONE,
  NO_PARITY,
  ODD,
  EVEN,
};

enum SerialStopBits {
  NONE,
  ONE,
  TWO,
};

enum SerialPortFlushMode {
  // Flushes both receive and transmit buffers without discarding any bytes in
  // the data pipes. This is for compatibility with chrome.serial.flush().
  kReceiveAndTransmit,

  // Flushes the receive buffers and discards data in the data_pipe_producer by
  // closing it.
  kReceive,

  // Flushes the send buffers and discards data in the data_pipe_consumer by
  // closing it.
  kTransmit,
};

enum SerialPortType {
  // The serial port is implemented using the platform's serial device API.
  PLATFORM_SERIAL,
  // The serial port is implemented using the Bluetooth classic RFCOMM protocol.
  BLUETOOTH_CLASSIC_RFCOMM,
};

struct SerialConnectionOptions {
  uint32 bitrate = 0;
  SerialDataBits data_bits = NONE;
  SerialParityBit parity_bit = NONE;
  SerialStopBits stop_bits = NONE;
  bool cts_flow_control;
  bool has_cts_flow_control = false;
};

struct SerialConnectionInfo {
  uint32 bitrate = 0;
  SerialDataBits data_bits = NONE;
  SerialParityBit parity_bit = NONE;
  SerialStopBits stop_bits = NONE;
  bool cts_flow_control;
};

struct SerialHostControlSignals {
  // DTR (Data Terminal Ready)
  bool dtr;
  bool has_dtr = false;
  // RTS (Request to Send)
  bool rts;
  bool has_rts = false;
  // BRK (Break)
  bool brk;
  bool has_brk = false;
};

struct SerialPortControlSignals {
  bool dcd;
  bool cts;
  bool ri;
  bool dsr;
};

// Discovers and enumerates serial devices available to the host.
interface SerialPortManager {
  // Associates an interface the port manager can used to notify the client of
  // events such as the addition or removal of serial ports from the host.
  SetClient(pending_remote<SerialPortManagerClient> client);

  // Returns the list of serial ports currently available on the host.
  GetDevices() => (array<SerialPortInfo> devices);

  // Opens the port represented by |token| using |options| and returns a
  // connection to it as |port|. If |use_alternate_path| is specified then the
  // |alternate_path| for the port will be used instead. When the pipe returned
  // in |port| is closed the optional pipe passed in |watcher| will also be
  // closed and vice a versa.
  OpenPort(mojo_base.mojom.UnguessableToken token,
           bool use_alternate_path,
           SerialConnectionOptions options,
           pending_remote<SerialPortClient> client,
           pending_remote<SerialPortConnectionWatcher>? watcher)
      => (pending_remote<SerialPort>? port);
};

// Client interface for SerialPortManager.
interface SerialPortManagerClient {
  // This message indicates that a port has been added to the host.
  OnPortAdded(SerialPortInfo port_info);

  // This message indicates that a port has been removed from the host.
  OnPortRemoved(SerialPortInfo port_info);

  // This message indicates that the connected state of a port has changed. No
  // message is sent if the port is added or removed.
  OnPortConnectedStateChanged(SerialPortInfo port_info);
};

// Performs asynchronous I/O on serial devices.
interface SerialPort {
  // Start writing data from |consumer| to the port. This should be called after
  // Open() or to restart data flow after when SerialPortClient#OnSendError is
  // called on |client| to indicate an error.
  StartWriting(handle<data_pipe_consumer> consumer);

  // Start reading data from the port into |producer|. This should be called
  // after Open() or to restart data flow when SerialPortClient#OnReadError is
  // called on |client| to indicate an error.
  StartReading(handle<data_pipe_producer> producer);

  // Flushes buffers according to the selected |mode|.
  Flush(SerialPortFlushMode mode) => ();

  // Waits for the data_pipe_consumer passed to StartWriting() to be closed and
  // all buffered data to be transmitted by the port.
  Drain() => ();

  // Reads current control signals (DCD, CTS, etc.). Returns null on failure.
  GetControlSignals() => (SerialPortControlSignals? signals);

  // Sets one or more control signals and returns result.
  SetControlSignals(SerialHostControlSignals signals) => (bool success);

  // Performs platform-specific port configuration and returns result.
  ConfigurePort(SerialConnectionOptions options) => (bool success);

  // Performs a platform-specific port configuration query and returns got info.
  GetPortInfo() => (SerialConnectionInfo info);

  // Closes the port and this pipe. Once this returns no more data will be sent
  // or received from |consumer| and |producer|. If |flush| is true the port's
  // transmit and receive buffers are flushed before closing.
  Close(bool flush) => ();
};

interface SerialPortClient {
  OnReadError(SerialReceiveError error);
  OnSendError(SerialSendError error);
};

interface SerialPortConnectionWatcher {
};