Web Serial API

リビングドキュメント

ドラフト コミュニティグループ報告

最新の公開版:
なし
最新の編集者ドラフト:
https://wicg.github.io/serial/
編集者:
GHのコントリビューターを見る
フィードバック:
GitHub wicg/serial (プルリクエスト, 新しい issue, 未解決の issue)

要約

Serial API は、Webサイトがスクリプトを通じてシリアルデバイスからの読み書きを可能にする方法を提供します。このようなAPIは、ドキュメントがマイコン、3Dプリンターや他のシリアルデバイスなどの機器と通信できるようにすることで、Webと物理世界を繋ぎます。また、解説ドキュメントもあります。

この文書のステータス

本仕様書は Web Platform Incubator Community Group により発行されました。これはW3C標準でもなく、W3C Standards Track上のものでもありません。 W3C Community Contributor License Agreement (CLA) の下では限定的なオプトアウトやその他の条件があることにご注意ください。 W3C Community and Business Groups について詳しくはリンクをご参照ください。

本仕様は作業中のドラフトです。全ての貢献を歓迎します。

本仕様について議論する場合はGitHub Issuesを推奨します。

1. Navigator インターフェイスの拡張

WebIDL[Exposed=Window, SecureContext]
partial interface Navigator {
  [SameObject] readonly attribute Serial serial;
};

1.1 serial 属性

取得時、serial属性は常に同じSerialオブジェクトのインスタンスを返します。

2. WorkerNavigator インターフェイスの拡張

WebIDL[Exposed=DedicatedWorker, SecureContext]
partial interface WorkerNavigator {
  [SameObject] readonly attribute Serial serial;
};

2.1 serial 属性

取得時、serial属性は常に同じSerialオブジェクトのインスタンスを返します。

3. Serial インターフェイス

WebIDL[Exposed=(DedicatedWorker, Window), SecureContext]
interface Serial : EventTarget {
  attribute EventHandler onconnect;
  attribute EventHandler ondisconnect;
  Promise<sequence<SerialPort>> getPorts();
  [Exposed=Window] Promise<SerialPort> requestPort(optional SerialPortRequestOptions options = {});
};

3.1 requestPort() メソッド

requestPort()メソッドの手順は以下のとおりです:

  1. promise新しいプロミスとする。
  2. this関連する グローバルオブジェクト関連付けられた Document使用を 許可されていないポリシー制御 機能の名前が「serial」である場合、拒否promiseを「SecurityErrorDOMExceptionで行い、 promiseを返す。
  3. 関連する グローバルオブジェクトthisのもの)が 一時的な 有効化を持たない場合、拒否promiseを 「SecurityErrorDOMExceptionで行い、 promiseを返す。
  4. options["filters"]が存在する場合、 filterごとに、 options["filters"]について次の 手順を実行する:
    1. filter["bluetoothServiceClassId"]が 存在する 場合:
      1. filter["usbVendorId"]が 存在する場合、 拒否promiseTypeError で行い、promiseを返す。
      2. filter["usbProductId"]が 存在する場合、 拒否promiseTypeError で行い、promiseを返す。
    2. filter["usbVendorId"]が 存在しない場合、拒否promiseTypeError で行い、 promiseを返す。
      注記
      この検査は、次の複合規則を実装する: SerialPortFilterを 空にすることはできず、 usbProductId が指定されている場合は、 usbVendorId も指定されなければならない。
  5. 次の手順を並列に実行する:
    1. allPortsを空のリストとする。
    2. システムに登録されている Bluetooth デバイスについて:
      1. BluetoothServiceUUID uuid(デバイスがサポートするもの)について:
        1. uuidブロック対象の Bluetooth サービスクラス UUIDでない場合:
    3. 利用可能な非 Bluetooth シリアルポートについて:
      1. portSerialPortとする。これは そのポートを表す。
      2. 追加として、 portallPortsに加える。
    4. シリアルポートへのアクセスをサイトに許可するようユーザーに求めるため、 次の条件で選んだallPorts内のポートのリストをユーザーに提示する。その選別では、いずれかのフィルターに一致するという条件をoptions["filters"] が存在する場合に適用し、そうでない場合はallPortsをそのまま使用する。
    5. ユーザーがポートを選択しない場合、グローバル タスクをキューに入れる。 これは関連する グローバルオブジェクトthisのもの)上で、シリアルポートタスクソースを使用する。このタスクで拒否promiseを 「NotFoundErrorDOMException で行い、これらの手順を中止する。
    6. portSerialPortとする。これは ユーザーが選択したポートを表す。
    7. グローバル タスクをキューに入れる。これは関連する グローバルオブジェクトthisのもの)上で、シリアルポートタスクソースを使用する。このタスクにより解決されるのは promiseであり、その値はportとする。
  6. promiseを返す。

シリアルポートは、利用可能とは、有線の場合は物理的にシステムに接続されているポート、無線の場合はデバイスがシステムに登録されているポートを指します。

3.1.1 SerialPortRequestOptions 辞書

WebIDLdictionary SerialPortRequestOptions {
  sequence<SerialPortFilter> filters;
  sequence<BluetoothServiceUUID> allowedBluetoothServiceClassIds;
};
filters メンバー
シリアルポートのフィルター
allowedBluetoothServiceClassIds メンバー
BluetoothServiceUUID 型のBluetoothサービスクラスIDのリスト。BluetoothポートがカスタムサービスクラスIDを持つ場合は、このリストに含まれていない限り、ユーザーへの提示リストから除外されます。

3.1.2 SerialPortFilter 辞書

WebIDLdictionary SerialPortFilter {
  unsigned short usbVendorId;
  unsigned short usbProductId;
  BluetoothServiceUUID bluetoothServiceClassId;
};
usbVendorId メンバー
USBベンダーID
usbProductId メンバー
USBプロダクトID
bluetoothServiceClassId メンバー
BluetoothサービスクラスID

シリアルポートportがフィルターfilterマッチする条件は以下です:

  1. infoを、 port.getInfo()を呼び出した結果とする。
  2. filter["bluetoothServiceClassId"]が 存在する 場合:
    1. シリアルポートが Bluetooth デバイスの一部でない場合、 falseを返す。
    2. filter["bluetoothServiceClassId"]と info["bluetoothServiceClassId"]が等しい場合、 trueを返す。
    3. それ以外の場合、falseを返す。
  3. filter["usbVendorId"]が 存在しない場合、 trueを返す。
  4. シリアルポートが USB デバイスの一部でない場合、falseを返す。
  5. info["usbVendorId"]と filter["usbVendorId"]が等しくない場合、 falseを返す。
  6. filter["usbProductId"]が 存在しない場合、trueを返す。
  7. info["usbProductId"]と filter["usbProductId"]が等しくない場合、 falseを返す。
  8. それ以外の場合、trueを返す。

シリアルポートportは、シーケンス内の SerialPortFilterのいずれかにマッチする条件は下記:

  1. filterについて下記を実施:
    1. もしportマッチするならtrueを返す。
  2. falseを返す。

3.2 getPorts() メソッド

getPorts()メソッドの手順は以下の通りです:

  1. promise新しいpromiseとして作成する。
  2. this関連グローバルオブジェクト関連付けられたDocument使用許可のある "serial"というポリシー制御機能でない場合、 reject promiseに"SecurityError" DOMExceptionで返し、終了。
  3. 並列で以下を実行:
    1. availablePortsを、ユーザーがrequestPort()の実行でサイトにアクセス許可を付与した利用可能なシリアルポートとする。
    2. portsを、availablePorts内のSerialPort一覧とする。
    3. グローバルタスクをキューし、関連グローバルオブジェクトserial port task sourceresolve promiseportsを渡す。
  4. promise を返す。

3.3 onconnect 属性

onconnectイベントハンドラーIDL属性であり、 connectイベントタイプ用です。

3.4 ondisconnect 属性

ondisconnectイベントハンドラーIDL属性であり、 disconnectイベントタイプ用です。

4. SerialPort インターフェイス

WebIDL[Exposed=(DedicatedWorker,Window), SecureContext]
interface SerialPort : EventTarget {
  attribute EventHandler onconnect;
  attribute EventHandler ondisconnect;
  readonly attribute boolean connected;
  readonly attribute ReadableStream? readable;
  readonly attribute WritableStream? writable;

  SerialPortInfo getInfo();

  Promise<undefined> open(SerialOptions options);
  Promise<undefined> setSignals(optional SerialOutputSignals signals = {});
  Promise<SerialInputSignals> getSignals();
  Promise<undefined> close();
  Promise<undefined> forget();
};

このインターフェイスのメソッドは、通常非同期に完了し、シリアルポートタスクソース上で作業をキューします。

SerialPort親を取得するアルゴリズムは、そのSerialインスタンスを返します。このインスタンスはSerialPort関連グローバルオブジェクトNavigator オブジェクトのserialゲッターで返されるものと同じです。

SerialPortのインスタンスは、以下の表で説明される内部スロットを持ちます。

内部スロット 初期値 説明(非規範的)
[[state]] "closed" SerialPortの動作状態を追跡します
[[bufferSize]] undefined 送受信でバッファするデータ量
[[connected]] false シリアルポートの論理的接続状態を示すフラグ
[[readable]] null ポートからデータを受信するReadableStream
[[readFatal]] false ポートで重大な読み取りエラーが発生したことを示すフラグ
[[writable]] null ポートへデータを送信するWritableStream
[[writeFatal]] false ポートで重大な書き込みエラーが発生したことを示すフラグ
[[pendingClosePromise]] null Promisereadablewritableのクローズ待機などに利用

4.1 onconnect 属性

onconnectイベントハンドラーIDL属性です。 connectイベント型用です。

ユーザーがrequestPort()の呼び出しでサイトへのアクセスを許可したシリアルポートが 論理的に接続された場合、以下の手順を実行します:

  1. portとして該当のSerialPortを用意する。
  2. port.[[connected]]trueに設定。
  3. イベントconnectportで発火し、そのbubbles属性をtrueで初期化する。

シリアルポートは論理的に接続とは、有線シリアルポートの場合は物理的に接続されているとき、無線の場合はシステムが該当デバイスにアクティブ接続(例: Bluetooth L2CAPチャネルが開いている)を持っているときです。

4.2 ondisconnect 属性

ondisconnectイベントハンドラーIDL属性であり、 disconnectイベント型用です。

ユーザーがrequestPort()の呼び出しでサイトへのアクセスを許可したシリアルポートが 論理的に接続でなくなった場合、以下の手順を実行します:

  1. portとして該当のSerialPortを用意する。
  2. port.[[connected]]falseに設定。
  3. イベントdisconnectportで発火し、そのbubbles属性をtrueで初期化する。

4.3 getInfo() メソッド

getInfo() メソッドの手順は以下の通りです:
  1. infoを空の順序付きマップとして用意する。
  2. ポートがUSBデバイスの一部の場合、以下の手順を実施する:
    1. info["usbVendorId"] にデバイスのベンダーIDを設定。
    2. info["usbProductId"] にデバイスのプロダクトIDを設定。
  3. ポートがBluetoothデバイス上のサービスである場合、以下の手順を実施する:
    1. info["bluetoothServiceClassId"] にBluetoothサービスのサービスクラスUUIDを設定
  4. infoを返す。

4.3.1 SerialPortInfo 辞書

WebIDLdictionary SerialPortInfo {
  unsigned short usbVendorId;
  unsigned short usbProductId;
  BluetoothServiceUUID bluetoothServiceClassId;
};
usbVendorId メンバー
ポートがUSBデバイスの一部である場合、このメンバーはそのデバイスの16ビットベンダーIDとなります。それ以外の場合はundefinedです。
usbProductId メンバー
ポートがUSBデバイスの一部である場合、このメンバーはそのデバイスの16ビットプロダクトIDとなります。それ以外の場合はundefinedです。
bluetoothServiceClassId メンバー
ポートがBluetoothデバイス上のサービスである場合、このメンバーはサービスクラスUUIDを含む BluetoothServiceUUID となります。それ以外の場合はundefinedです。

4.4 open() メソッド

open() メソッドの手順は以下の通りです:

  1. promise新しい promise とする。
  2. this.[[state]]"closed" でない場合、 promise を "InvalidStateError" DOMException で拒否し、 promise を返す。
  3. options["baudRate"] が 0 の場合、 promiseTypeError で拒否し、 promise を返す。
  4. options["dataBits"] が 7 または 8 でない場合、 promiseTypeError で拒否し、 promise を返す。
  5. options["stopBits"] が 1 または 2 でない場合、 promiseTypeError で拒否し、 promise を返す。
  6. options["bufferSize"] が 0 の場合、 promiseTypeError で拒否し、 promise を返す。
  7. 必要に応じて、options["bufferSize"] が 実装でサポートできるサイズより大きい場合、 promiseTypeError で拒否し、 promise を返す。
  8. this.[[state]]"opening" に設定する。
  9. 次の手順を 並行して実行する。
    1. オペレーティングシステムを呼び出し、options で指定された接続パラメータ(またはデフォルト値)を使って シリアルポートを開く。
    2. これが何らかの理由で失敗した場合、グローバルタスクをキューし、 関連するグローバルオブジェクト上で thisserial port task source を使い、 reject して promise を "NetworkError" DOMException で拒否し、これらの手順を中止する。
    3. this.[[state]]"opened" に設定する。
    4. this.[[bufferSize]]options["bufferSize"] に設定する。
    5. グローバルタスクをキューし、 関連するグローバルオブジェクト上で thisserial port task source を使い、 resolve し、 promiseundefined で解決する。
  10. promise を返す。

4.4.1 SerialOptions 辞書

WebIDLdictionary SerialOptions {
  [EnforceRange] required unsigned long baudRate;
  [EnforceRange] octet dataBits = 8;
  [EnforceRange] octet stopBits = 1;
  ParityType parity = "none";
  [EnforceRange] unsigned long bufferSize = 255;
  FlowControlType flowControl = "none";
};
baudRate メンバー
シリアル通信を確立する際の、正かつ0でないボーレート(通信速度)値。
baudRate はこの 辞書で唯一必須なメンバーです。他の接続パラメータには一般的なデフォルトがありますが、接続する機器に応じて正しい値を検討・機器のドキュメントで確認することが重要です。多くは一般的な値ですが、標準化されたボーレートはありません。このパラメータを必須とすることで、仕様が任意のデフォルト値を選択した場合の混乱を防ぎます。
dataBits メンバー
1フレームあたりのデータビット数。7または8。
stopBits メンバー
フレーム末尾のストップビット数。1または2。
parity メンバー
パリティモード。
bufferSize メンバー
読み書き用バッファのサイズを示す正かつ0でない値。
flowControl メンバー
フロー制御のモード。
4.4.1.1 ParityType 列挙型
WebIDLenum ParityType {
  "none",
  "even",
  "odd"
};
none
各データワードごとにパリティビットは送出されません。
even
データワード+パリティビットの合計値が偶数パリティとなります。
odd
データワード+パリティビットの合計値が奇数パリティとなります。
4.4.1.2 FlowControlType 列挙型
WebIDLenum FlowControlType {
  "none",
  "hardware"
};
none
フロー制御なし。
hardware
RTSおよびCTS信号を使用するハードウェアフロー制御を有効化。

4.5 connected 属性

connected ゲッターの手順は:

  1. this.[[connected]] を返す。

4.6 readable 属性

readable ゲッターの手順は以下の通りです:

  1. this.[[readable]]nullでない場合、 this.[[readable]]を返す。
  2. this.[[state]]"opened"でない場合、 nullを返す。
  3. this.[[readFatal]]trueである場合、 nullを返す。
  4. stream新しい ReadableStreamとする。
  5. pullAlgorithmを次の手順とする:
    1. desiredSizeハイウォーターマークまで 満たすための望ましいサイズとする。その対象は this.[[readable]]である。
    2. this.[[readable]]現在の BYOB 要求ビューが null でない場合、 desiredSizethis.[[readable]]現在の BYOB 要求ビューバイト 長に設定する。
    3. promise新しいプロミスとする。
    4. 次の手順を並列に 実行する:
      1. オペレーティングシステムを呼び出し、ポートから最大desiredSize バイトを読み取り、その結果をバイト列 bytesに格納する。
        注記
        this.[[state]]"forgotten"になることは、 the port was disconnectedであるかのように扱わなければならない。
      2. グローバル タスクをキューに入れる。対象は関連する グローバルオブジェクトthisのもの)であり、 タスクソースにはシリアルポートタスク ソースを使用し、 次の手順を実行する:
        1. エラーが発生しなかった場合:
          1. this.[[readable]]現在の BYOB 要求ビューが null でない場合、書き込みでは bytesthis.[[readable]]現在の BYOB 要求ビューに書き込み、 viewthis.[[readable]]現在の BYOB 要求ビューに設定する。
          2. それ以外の場合、viewを、次の方法で 作成した Uint8Array に設定する。これはbytesから、this関連する Realm内で作成する。
          3. エンキューとして、 viewthis.[[readable]]に追加する。
          4. 解決する対象を promise、値をundefinedとする。
        2. バッファーオーバーラン状態が発生した場合、 エラーを 次に対して呼び出す: this.[[readable]]。その際、 "BufferOverrunError" DOMException を用いる。さらに、 次の手順を呼び出す: 読み取り可能ストリームの終了を 処理する
        3. ブレーク状態が発生した場合、 エラーを 次に対して呼び出す: this.[[readable]]。その際、 "BreakError" DOMException を用いる。さらに、 次の手順を呼び出す: 読み取り可能ストリームの終了を 処理する
        4. フレーミングエラーが発生した場合、 エラーを 次に対して呼び出す: this.[[readable]]。その際、 "FramingError" DOMException を用いる。さらに、 次の手順を呼び出す: 読み取り可能ストリームの終了を 処理する
        5. パリティエラーが発生した場合、 エラーを 次に対して呼び出す: this.[[readable]]。その際、 "ParityError" DOMException を用いる。さらに、 次の手順を呼び出す: 読み取り可能ストリームの終了を 処理する
        6. オペレーティングシステムエラーが発生した場合、 エラーを 次に対して呼び出す: this.[[readable]]。その際、 "UnknownError" DOMException を用いる。さらに、次の手順を呼び出す: 読み取り可能ストリームの終了を 処理する
        7. the port was disconnectedの場合、次の 手順を実行する:
          1. this.[[readFatal]]trueに設定する。
          2. エラーを 次に対して呼び出す: this.[[readable]]。その際、 次の "NetworkError" DOMExceptionを用いる。
          3. 次の手順を呼び出す: 読み取り可能 ストリームの終了を処理する
    5. promiseを返す。
  6. cancelAlgorithmを次の手順とする:
    1. promise新しいプロミスとする。
    2. 次の手順を並列に 実行する。
      1. オペレーティングシステムを呼び出して、ポートの すべてのソフトウェアおよびハードウェア受信バッファーの内容を破棄する。
      2. グローバル タスクをキューに入れる。対象は関連する グローバルオブジェクトthisのもの)であり、 タスクソースにはシリアルポートタスク ソースを使用し、 次の手順を実行する:
        1. 次の手順を呼び出す: 読み取り可能ストリームの終了を 処理する
        2. 解決する対象を promise、値をundefinedとする。
    3. promiseを返す。
  7. バイト読み取りを サポートするようセットアップするstreamについて、 pullAlgorithmpullAlgorithmに設定し、 cancelAlgorithmcancelAlgorithmに設定し、 highWaterMarkthis.[[bufferSize]]に設定する。
  8. this.[[readable]]streamに設定する。
  9. streamを返す。
readableストリームのクローズ処理を行う手順は下記:
  1. this.[[readable]]null を設定。
  2. もしthis.[[writable]]null かつ this.[[pendingClosePromise]]null でなければ resolvethis.[[pendingClosePromise]]undefined で完了。

4.7 writable 属性

writable ゲッターの手順は以下の通りです:

  1. this.[[writable]]nullでない場合、 this.[[writable]]を返す。
  2. this.[[state]]"opened"でない場合、 nullを返す。
  3. this.[[writeFatal]]trueである場合、 nullを返す。
  4. stream新しい WritableStreamとする。
  5. signalstreamシグナルとする。
  6. writeAlgorithmを次の手順とし、chunkを与える:
    1. promise新しいプロミスとする。
    2. 表明: signal中止済みではない。
    3. chunkIDL 値に 変換することができず、変換先の型が BufferSourceである場合、 拒否はpromiseTypeError で行い、 promiseを返す。それ以外の場合、変換結果を 変数 sourceに保存する。
    4. バッファーソースの コピーを取得する対象をsourceとし、 結果をbytesに保存する。
    5. 並列 に、次の手順を実行する:
      1. オペレーティングシステムを呼び出し、bytesをポートに書き込む。 または、将来の結合のためにチャンクを保存する。
        注記
        オペレーティングシステムは、この操作から、 bytesが送信用にキューに入れられた時点で戻ってもよく、 実際に送信された後まで待つ必要はない。
        注記
        this.[[state]]"forgotten"になることは、 the port was disconnectedであるかのように扱わなければならない。
      2. グローバル タスクをキューに入れる。対象は関連する グローバルオブジェクトthisのもの)であり、 タスクソースにはシリアルポートタスク ソースを使用し、 次の手順を実行する:
        1. チャンクが正常に書き込まれたか、または 将来の結合のために保存された場合、解決する対象をpromise、値を undefinedとする。
          注記
          [STREAMS]は、次を規定する: writeAlgorithmの呼び出しは、 Promise がこのアルゴリズムの 前回の呼び出しによって返され、解決された後にのみ行われる。 効率化のため、実装は このPromiseを 早期に解決して、 複数のチャンク(WritableStreamの 内部キュー内で待機しているもの)を、オペレーティング システムへの単一の要求に結合してもよい。
        2. オペレーティングシステムエラーが発生した場合、 拒否promiseを"UnknownError" DOMExceptionで行う。
        3. the port was disconnectedの場合、次の 手順を実行する:
          1. this.[[writeFatal]]trueに設定する。
          2. 拒否promiseを"NetworkError" DOMExceptionで行う。
          3. 次の手順を呼び出す: 書き込み可能 ストリームの終了を処理する
        4. signal中止済みである場合、拒否promisesignal中止 理由で行う。
    6. promiseを返す。
  7. abortAlgorithmを次の手順とする:
    1. promise新しいプロミスとする。
    2. 次の手順を並列に 実行する。
      1. オペレーティングシステムを呼び出して、ポートの すべてのソフトウェアおよびハードウェア送信バッファーの内容を破棄する。
      2. グローバル タスクをキューに入れる。対象は関連する グローバルオブジェクトthisのもの)であり、 タスクソースにはシリアルポートタスク ソースを使用し、 次の手順を実行する:
        1. 次の手順を呼び出す: 書き込み可能ストリームの終了を 処理する
        2. 解決する対象をpromise、値をundefinedとする。
    3. promiseを返す。
  8. closeAlgorithmを次の手順とする:
    1. promise新しいプロミスとする。
    2. 次の手順を並列に 実行する。
      1. オペレーティングシステムを呼び出して、ポートのすべての ソフトウェアおよびハードウェア送信バッファーの内容をフラッシュする。
      2. グローバル タスクをキューに入れる。対象は関連する グローバルオブジェクトthisのもの)であり、 タスクソースにはシリアルポートタスク ソースを使用し、 次の手順を実行する:
        1. 次の手順を呼び出す: 書き込み可能ストリームの終了を 処理する
        2. signal中止済みである場合、拒否promisesignal中止 理由で行う。
        3. それ以外の場合、解決する対象をpromise、値をundefinedとする。
    3. promiseを返す。
  9. セットアップする streamについて、 writeAlgorithmwriteAlgorithmに設定し、 abortAlgorithmabortAlgorithmに設定し、 closeAlgorithmcloseAlgorithmに設定し、 highWaterMarkthis.[[bufferSize]]に設定し、 さらに sizeAlgorithmをバイト数を数えるサイズアルゴリズムに設定する。
  10. 追加として、次の 中止手順をsignalに加える:
    1. ポートへ書き込むためのオペレーティングシステムの呼び出しが、 書き込まれたデータ量にかかわらず、可能な限り早く 戻るようにする。
  11. this.[[writable]]streamに設定する。
  12. streamを返す。
to writableストリームのクローズ処理は下記手順:
  1. this.[[writable]]null に設定。
  2. もしthis.[[readable]]null かつ this.[[pendingClosePromise]]null でなければ resolvethis.[[pendingClosePromise]]undefined で完了。

4.8 setSignals() メソッド

setSignals() メソッドの手順は以下の通りです:

  1. promise新しい promise として用意する。
  2. this.[[state]]"opened" でなければ、 promise を "InvalidStateError" DOMException で reject し、返す。
  3. 指定された signals のすべてのメンバーが存在しない場合、 promiseTypeError で拒否し、 promise を返す。
  4. 並列で次を実行:
    本来は signals で指定された内容をアトミック(一度に)適用すべきですが、これを実現する手段はPOSIXやWindows APIにはないため、実装側はこの順序に依存することになります。
    1. signals["dataTerminalReady"] が存在すれば、OSに「data terminal ready(DTR)」信号をアサート(true)またはディアサート(false)を指示。
    2. signals["requestToSend"] が 存在すれば、OSに「request to send(RTS)」信号をアサートまたはディアサートを指示。
    3. signals["break"] があれば、OSに「break」信号のアサートまたはディアサートを指示。
      「break」信号は一般的に送信線を「mark」電圧で保持する帯域内信号として実装されており、その間はデータ送信が停止します。
    4. 何らかの理由でOSがこれらの信号状態変更に失敗した場合、 グローバルタスクをキューし、 関連グローバルオブジェクトserial port task sourcepromise を "NetworkError" DOMException で reject。
    5. グローバルタスクをキューし、 関連グローバルオブジェクトserial port task sourceresolve promiseundefined で完了。
  5. promise を返す。

4.8.1 SerialOutputSignals 辞書

WebIDLdictionary SerialOutputSignals {
  boolean dataTerminalReady;
  boolean requestToSend;
  boolean break;
};
dataTerminalReady
Data Terminal Ready (DTR)
requestToSend
Request To Send (RTS)
break
ブレーク

4.9 getSignals() メソッド

getSignals() メソッドの手順は以下の通りです:
  1. promise新しい promise とする。
  2. this.[[state]]"opened" でなければ promise を "InvalidStateError" DOMException で reject し返す。
  3. 並列で下記を実行:
    1. シリアルポートに接続されているデバイスがアサートしている制御信号の状態をOSに問い合わせる。
    2. 何らかの理由でOSがこれらの信号の状態取得に失敗した場合は、 グローバルタスクをキューし、 関連グローバルオブジェクトserial port task sourcepromise を "NetworkError" DOMException で reject し、処理を中断。
    3. dataCarrierDetect を「data carrier detect(DCD)」信号がデバイスでアサートされていれば true、それ以外は falseとする。
    4. clearToSend を「clear to send(CTS)」信号がアサートされていれば true、それ以外は false
    5. ringIndicator を「ring indicator(RI)」信号がアサートされていれば true、それ以外は false
    6. dataSetReady を「data set ready(DSR)」信号がアサートされていれば true、それ以外は false
    7. signals順序付きマップ «[ "dataCarrierDetect" → dataCarrierDetect, "clearToSend" → clearToSend, "ringIndicator" → ringIndicator, "dataSetReady" → dataSetReady ]» として用意。
    8. グローバルタスクをキュー関連グローバルオブジェクトserial port task sourceresolve promisesignals を渡す。
  4. promise を返す。

4.9.1 SerialInputSignals 辞書

WebIDLdictionary SerialInputSignals {
  required boolean dataCarrierDetect;
  required boolean clearToSend;
  required boolean ringIndicator;
  required boolean dataSetReady;
};
dataCarrierDetect メンバー
Data Carrier Detect (DCD)
clearToSend メンバー
Clear To Send (CTS)
ringIndicator メンバー
Ring Indicator (RI)
dataSetReady メンバー
Data Set Ready (DSR)

4.10 close() メソッド

close() メソッドの手順は以下の通りです:

  1. promise新しい promise として用意。
  2. this.[[state]]"opened" でなければ promise を "InvalidStateError" DOMException で reject し返す。
  3. cancelPromisecancelthis.[[readable]] に呼び出した結果か、 a promise resolved with undefined(もし this.[[readable]]null の場合)。
  4. abortPromiseabortthis.[[writable]] に呼び出した結果か、 a promise resolved with undefined(もし this.[[writable]]null の場合)。
  5. pendingClosePromise新しい promise として用意。
  6. もし this.[[readable]] および this.[[writable]] がともに null であれば、 resolve pendingClosePromiseundefined で完了。
  7. this.[[pendingClosePromise]]pendingClosePromise をセット。
  8. combinedPromisegetting a promise to wait for all で «cancelPromise, abortPromise, pendingClosePromise» を対象に取得。
  9. this.[[state]]"closing" に。
  10. React to combinedPromise.
  11. promise を返す。

4.11 forget() メソッド

forget() メソッドの手順は以下の通りです:

  1. ユーザーエージェントがこの操作を実施できない場合(例:管理者ポリシーで許可された場合)は、a promise resolved with undefined を返す。
  2. 並列で下記を実行:
    1. this.[[state]]"forgetting" にする。
    2. ユーザーがrequestPort()の結果としてサイトに許可したシリアルポート一覧から this を削除する。
    3. this.[[state]]"forgotten" にする。
    4. グローバルタスクをキュー関連グローバルオブジェクトserial port task sourceresolve promiseundefined で実施。
  3. promise を返す。

5. ブロックリスト

この仕様は https://github.com/WICG/serial リポジトリ内のブロックリストファイルに依存しており、ウェブサイトがアクセスできるポートの集合を制限します。

URL urlBluetoothサービスクラスIDブロックリストのパース の結果は、カスタムサービスIDを表す リスト 型の UUID 値です。

シリアルポートプロファイル サービスクラスID は 値 "00001101-0000-1000-8000-00805f9b34fb" を持った BluetoothServiceUUID です。

BluetoothServiceUUID serviceUuid は、次の手順が true を返す場合、 ブロックされた Bluetooth サービスクラス UUID である:

  1. uuid を、 BluetoothUUID.getService()serviceUuid で呼び出した結果とする。
  2. blocklist を、 Bluetooth サービスクラス ID ブロックリストを構文解析することを https://github.com/WICG/serial/blob/main/bluetooth-service-blocklist.txt で行った結果とする。
  3. blocklistuuid含む場合、 true を返す。
  4. uuidであるものが、Serial Port Profile サービスクラス ID である場合、 false を返す。
  5. uuid が "-0000-1000-8000-00805f9b34fb" で 終わる場合、 true を返す。
  6. それ以外の場合、false を返す。

6. 統合

6.1 パーミッションポリシー

この仕様は、serial 属性で Navigator オブジェクトに公開されたメソッドを利用できるか制御する機能を定義します。

この機能のフィーチャ名は "serial" です。

この機能の デフォルト許可リスト'self' です。

7. セキュリティに関する考慮事項

このセクションは規範的ではありません。

このAPIは [WEB-BLUETOOTH] および [WEBUSB] と類似のセキュリティリスクがあり、それらの教訓がここにも適用されます。主な脅威は次の通りです: これらへの主要な対策は requestPort() パターンであり、これはユーザー操作を要し、かつ一度にひとつのデバイスだけのアクセス許可しか付与できません。このためサイトは接続デバイスを列挙して脆弱性を調べることができず、ユーザーが明示的に許可する必要があります。実装は、現在通信中であることやいつでも権限を取り消せるUIを視覚的に示すこともできます。

この仕様はネットワークベースの攻撃者によるコード注入を防ぐため、セキュアコンテキストから配信されることを要求します。これは、ユーザーがアクセス許可を判断する際、正しいサイトのアイデンティティを見せるためです。また、クロスオリジンのiframeで利用を許可するにはトップレベルドキュメントによる [PERMISSIONS-POLICY] でのopt-inも必要です。[CSP3]と組み合わせることで、これらの仕組みが悪意のあるコード注入攻撃の対策となります。

残る懸念は、ユーザーが悪意あるサイトに騙されてデバイスのアクセスを許可してしまうフィッシング攻撃です。これにより、デバイス本来の機能を用いた攻撃や、デバイスに悪意のあるファームウェアを仕込んでホストコンピュータ自体を攻撃することができます。ホストソフトは接続デバイスからの入力バリデーションが不十分である場合、攻撃されやすくなります。この分野のセキュリティ研究により、多くのソフトウェアベンダは接続デバイスを信頼すべきでないことを認識するようになっています。

この種の攻撃を完全に防ぐ仕組みはありません。ページからデバイスに送信されるデータは「不透明なバイト列」に過ぎないためです。特定のデータタイプを送信不可とする努力は、たいていメーカーが意図的にそれを送らせるための回避策を講じるなどして無効化されます。

ユーザーエージェントは更に機器へのアクセス制御手段を提供できます:

[WEB-BLUETOOTH], [WEBUSB] 各実装はこれらの手法を試みていますが、効果には限界があります。第一に、あるデバイスが exploitable かどうかの判断が難しいためです。たとえばこのAPIでは、教育・ホビー向け開発ボードへファーム書き込みが可能です。これらは一般的にファーム署名検証がないため簡単に悪意のファーム焼きができ、明らかにexploitableだが、利用ケースを阻害すべきではありません。

また、USBやBluetoothはプロトコル上メタデータを取得できるため、脆弱なデバイスリストの維持運用が現実的ですが、DB-25/DE-9/RJ-45等「純粋」なシリアルポートやUSB/Bluetooth-シリアル変換器といった一般的なものには識別可能なメタデータがありません。このため、こうしたデバイスを個別にブロックすることは不可能です。

8. プライバシーに関する考慮事項

このセクションは規範的ではありません。

シリアルポートおよびシリアルデバイスには2種類の機微な情報が含まれます。USB/Bluetoothデバイスの場合はベンダー/プロダクトID(=メーカー・型番)やシリアルナンバーやMACアドレスなどの識別情報、またシリアルコマンドで得られる機器固有ID等があります。加えて、機器自体が独自の個人情報を格納している場合もあります。

デバイス許可管理を行うため、実装はUSBベンダーID・プロダクトID・シリアル番号といった情報をユーザー設定ファイルに保存して、許可済みデバイスを一意に識別するために利用することになります。これら情報はサイトと直接共有されることはなく、許可解除やサイトデータ削除時にクリアされます。

ページがデバイスアクセス権を得た後であれば、ページは機器が保持している他の個人情報を含む多数の情報にアクセスできる可能性があります。7. セキュリティに関する考慮事項 で説明した通り、ページからこうした情報へのアクセスを完全に阻止することは現実的でも望ましくもありません。

実装は利用者がアクセス許可デバイスを完全にコントロールできること、かつ明示的なユーザー操作なしでデバイス権限が与えられないことを保証すべきです。これは requestPort() メソッドの意図です。これによりサイトは接続中全デバイスの列挙や情報収集ができず、ファイル選択UIと同様にユーザーが選択したポートやデバイス・ディレクトリだけをサイトが知ることになります。サイト利用中にユーザーに権限利用中である旨を通知(タブやアドレスバーのアイコン表示等)しても良いでしょう。

「プライベート」または「シークレット」ブラウジングモードのある実装は、通常のプロファイルで設定したデバイス権限が当該セッションに持ち越されず、そのセッション中に付与された権限も終了時には保存されないことを保証すべきです。こうしたセッションでデバイス権限を付与する際は、手動で個人情報を入力する場合と同様、デバイス識別子や個性情報を経由してセッション間ID特定につながる可能性があることを警告しても良いでしょう。

このAPIで許可を与えることが従来のWebセキュリティモデルの分離境界を破る側面を持つ場合があるため、利用者がAPIの力量を十分理解していない場合は驚くことがあります。セキュリティUIやドキュメントでは「サイトにデバイス権限を与える=そのデバイスや中身全てに完全アクセスできる」ことを必ず明示すべきです。

9. 適合性

規範的でない旨が明記されている節以外にも、この仕様で記載されたオーサリングガイド・図・例・注記はすべて規範的なものではありません。それ以外のすべては規範的です。

A. 謝辞

このドキュメントの作成に以下の方々が貢献しました。

B. 参考文献

B.1 規範的な参考文献

[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[html]
HTML Standard. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[PERMISSIONS-POLICY]
Permissions Policy. Ian Clelland. W3C. 6 October 2025. W3C Working Draft. URL: https://www.w3.org/TR/permissions-policy-1/
[STREAMS]
Streams Standard. Adam Rice; Domenic Denicola; Mattias Buelens; 吉野剛史 (Takeshi Yoshino). WHATWG. Living Standard. URL: https://streams.spec.whatwg.org/
[WEB-BLUETOOTH]
Web Bluetooth. Jeffrey Yasskin. W3C Web Bluetooth Community Group. Draft Community Group Report. URL: https://webbluetoothcg.github.io/web-bluetooth/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

B.2 参考情報

[CSP3]
Content Security Policy Level 3. Mike West; Antonio Sartori. W3C. 11 February 2026. W3C Working Draft. URL: https://www.w3.org/TR/CSP3/
[WEBUSB]
WebUSB API. W3C. Draft Community Group Report. URL: https://wicg.github.io/webusb/