Web Bluetooth API と Web Serial API を使用すると、ウェブアプリはそれぞれ Bluetooth Low Energy(BLE)デバイスとシリアル デバイスと通信できます。多くのウェブ デベロッパーがすでにこれらの API を活用して大きな成果を上げていますが、Bluetooth Classic デバイスのサポートも求められています。
このたび、ウェブ シリアル API が、ペア設定された Bluetooth クラシック デバイスの RFCOMM サービスとの通信をサポートするようになりました。これには、パソコン版 Chrome 117 のシリアルポート プロファイル(SPP)が含まれます。これにより、ウェブ デベロッパーにもユーザーにも新たな可能性が開かれます。以下に、この機能のメリットを享受できるデバイスをいくつか示します。
- Google Pixel Buds Pro やその他のワイヤレス イヤホンは、RFCOMM を使用して音声設定とファームウェアの更新を管理します。
- モバイル POS システムは、Bluetooth SPP を使用してレシート プリンタと通信します。
- 家畜の RFID タグリーダーは、Bluetooth SPP を使用して動物の移動を記録します。
Bluetooth RFCOMM プロトコル
90 年代後半にタイムスリップしましょう。Palm Pilot をホルダーに置くだけで、翌日のカレンダーが同期されます。代わりに、ワイヤレスでデータを転送できたら便利だと思いませんか?この新しい「Bluetooth」技術により、煩雑なコードをすべて排除できます。未来のワイヤレスに。問題は 1 つだけです。既存のすべては RS-232 ケーブルで接続するように設計されています。そのため、Bluetooth は高周波通信(RFCOMM)プロトコルを使用して、既存のすべてのソフトウェアとハードウェアにこのインターフェースを提供します。
現在でも、RFCOMM サービスは新規および既存のハードウェアで広く使用されています。これにより、これまで Bluetooth Low Energy では満たせなかった特定のレイテンシと帯域幅の要件を満たすことができます。そのため、Google は、シリアル デバイスに接続するための API である Web Serial と Bluetooth を統合し、メーカーが Bluetooth Low Energy に移行し、デベロッパーが代わりに Web Bluetooth API を使用できるようになるまで、これらのレガシー RFCOMM サービスへのアクセスを可能にしました。
Web Serial API の変更
パソコン版 Chrome 117 以降では、ウェブ デベロッパーは Web Serial API を使用して、RFCOMM サービス経由でペア設定された Bluetooth Classic デバイスと確実に通信できるようになりました。これは、Web Serial API の次の更新によって可能になりました。
- Chrome で、標準化された Bluetooth 従来型シリアル ポート プロファイルを使用してシリアル インターフェースを公開するペア設定済みの Bluetooth デバイスが列挙されるようになりました。
- オペレーティング システムがエミュレートされたシリアルポートを介してデバイスノードを作成していない場合でも、Chrome はシリアル インターフェースと通信できるようになりました。
- Chrome は、RFCOMM シリアル インターフェースを公開するシリアルポート以外のサービスと通信できるようになりました(非標準のサービスクラス ID をご覧ください)。
Web Serial API の使用方法については、シリアルポートに対する読み取りと書き込みの記事をご覧ください。この記事では、Bluetooth に関する基本的な知識があることを前提とし、Bluetooth 経由のシリアル通信の変更に焦点を当てて説明します。
フィルタを指定せずに navigator.serial.requestPort()
を呼び出すと、Bluetooth 以外のシリアルポート、すでにマッピングされている Bluetooth シリアルポート、標準化された Bluetooth Classic シリアルポート プロファイルによって提供される未マッピングのシリアルポートを選択できます。
// Prompt user to select any serial port.
const port = await navigator.serial.requestPort();
ほとんどのデバイスは、標準化された Bluetooth Classic シリアル ポート プロファイルを通じて SPP ベースの通信を公開していますが、カスタム RFCOMM ベースのサービスを使用するデバイスもあります。これらのデバイスのサービスクラス ID は、標準の Bluetooth UUID の範囲にありません。
次の例に示すように、これらのカスタム RFCOMM ベースのサービスにアクセスするには、allowedBluetoothServiceClassIds
リストを navigator.serial.requestPort()
に渡す必要があります。
const myBluetoothServiceUuid = "01234567-89ab-cdef-0123-456789abcdef";
// Prompt user to select any serial port.
// Access to the custom Bluetooth RFCOMM service above will be allowed.
const port = await navigator.serial.requestPort({
allowedBluetoothServiceClassIds: [myBluetoothServiceUuid],
});
Chrome は音声や動画などの Bluetooth Classic サービスをサポートしていないため、Bluetooth SIG ベースの UUID を使用するすべてのサービスクラス ID(つまり、末尾が「-0000-1000-8000-00805f9b34fb」のすべての UUID)は、シリアルポート プロファイル ID を除きブロックされます。
また、navigator.serial.requestPort()
の呼び出し時に bluetoothServiceClassId
フィルタキーを使用して、サービスクラス ID で識別されるフィルタ済み Bluetooth シリアルポートのリストをユーザーに表示することもできます。下記の例をご覧ください。
const myBluetoothServiceUuid = "01234567-89ab-cdef-0123-456789abcdef";
// Prompt the user to select Bluetooth serial ports with
// the custom Bluetooth RFCOMM service above.
const port = await navigator.serial.requestPort({
allowedBluetoothServiceClassIds: [myBluetoothServiceUuid],
filters: [{ bluetoothServiceClassId: myBluetoothServiceUuid }],
});
シリアルポートが Bluetooth デバイスの一部である場合、port.getInfo()
の呼び出しによって返されるシリアルポート情報には、ポートが接続されている RFCOMM チャネルに関連付けられたサービスクラス ID を含む新しい bluetoothServiceClassId
キーが含まれています。シリアルポートがマッピングされている場合は、「00001101-0000-1000-8000-00805f9b34fb」または短縮形式の 0x1101 を返します。
const { bluetoothServiceClassId } = port.getInfo();
ユースケースの例: Google Pixel Buds Pro を操作する
Google Pixel Buds Pro ウェブ コンパニオン アプリは、ウェブブラウザを搭載した任意のデバイスから Google Pixel Buds Pro を操作できる新しいウェブアプリです。プログレッシブ ウェブアプリ技術を使用して構築されているため、即時読み込みが可能です。必要に応じて、他のオペレーティング システム アプリと一緒にインストールすることもできます。
このアプリは、Web Serial API を使用して Google Pixel Buds Pro と通信します。これにより、アクティブ ノイズ コントロール、イコライザー、装着検知、ファームウェア アップデートなど、Google Pixel Buds Pro のさまざまな設定をユーザーが操作できるようになります。
Google Pixel Buds Pro ウェブ コンパニオン アプリをお試しいただくには、ChromeOS デバイスで mypixelbuds.google.com にアクセスしてください(他のプラットフォームは近日提供予定)。
リソース
謝辞
レビューを送信していただいた Reilly Grant 様、Thomas Steiner 様、Ben Morss 様、Vincent Scheib 様に感謝いたします。