Android Open Accessory Protocol 2.0
本ドキュメントは、Android Open Accessory (AOA) プロトコル初版のドキュメントを補足する形でプロトコルに対する変更点をまとめます。
Android Open Accessory Protocol 2.0 では、2種類の機能が追加されました。Android端末からアクセサリに対する音声出力と、Android端末に対する1つ以上のヒューマンインターフェイスデバイス(HID)として振る舞うアクセサリです。Androidアプリケーション開発者向けの Android SDK APIに関する変更はありません。
Android Open Accessory 2.0 のサポートを検出する
接続されたAndroid端末がサポートするプロトコルレベルをアクセサリ側で判断するためには、アクセサリから getProtocol() コマンドを送信して結果を調べる必要があります。最初のバージョンの Android Open Accessory Protocol のみをサポートする Android 端末は、プロトコルバージョン番号として 1 を返します。本ドキュメントで解説する新機能をサポートする端末は、プロトコルバージョンとして 2 を返す必要があります。プロトコル 2.0 は上位互換性のあるもので、初期版のアクセサリプロトコル向けに設計されたアクセサリは新しい Android 端末と組み合わせても動作します。Android Development Kit 2011 AndroidAccessory ライブラリに含まれる以下のコードでプロトコルチェックについて確認できます。
bool AndroidAccessory::switchDevice(byte addr)
{
int protocol = getProtocol(addr);
if (protocol >= 1) {
Serial.print("device supports protocol 1 or higher\n");
} else {
Serial.print("could not read device protocol version\n");
return false;
}
sendString(addr, ACCESSORY_STRING_MANUFACTURER, manufacturer);
sendString(addr, ACCESSORY_STRING_MODEL, model);
sendString(addr, ACCESSORY_STRING_DESCRIPTION, description);
sendString(addr, ACCESSORY_STRING_VERSION, version);
sendString(addr, ACCESSORY_STRING_URI, uri);
sendString(addr, ACCESSORY_STRING_SERIAL, serial);
usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR |
USB_SETUP_RECIPIENT_DEVICE,
ACCESSORY_START, 0, 0, 0, 0, NULL);
return true;
}
AOA 2.0 では、アクセサリモード時に以下のそれぞれの USB インターフェイスを提供し、組み合わせに応じて新たな USB プロダクト IDを持ちます。
- accessory - Android アプリケーションと通信するための 2 つのバルクエンドポイントを提供するインターフェイス
- audio - Android 端末からアクセサリへのオーディオストリーミングに使われる、新しい標準 USB オーディオクラスのインターフェイス
- adb - アクセサリの開発中に使われるデバッグ目的のためだけのインターフェイス。ユーザが Android 端末の設定で USB デバッグを有効にしている場合のみに利用可能
AOA 1.0 では、 以下の 2 つの USB プロダクト IDのみが存在しました。
0x2D00
- accessory0x2D01
- accessory + adb
AOA 2.0 でオプションとして USB オーディオインターフェイスが追加されたため、USB インターフェイスの以下のような組み合わせが追加されました。
0x2D02
- audio0x2D03
- audio + adb0x2D04
- accessory + audio0x2D05
- accessory + audio + adb
オーディオサポート
AOA 2.0 では、Android端末からアクセサリへのオーディオ出力について、2 チャンネル 16-bit PCM / 44100 kHz に対応する標準の USB オーディオクラスインターフェイスをサポートしています。AOA 2.0 ではオーディオ出力のサポートのみに留まっていますが、将来的には他のモードが追加される可能性もあります。
オーディオサポートを有効にするためには、アクセサリから新たな USB コントロールリクエストを送信する必要があります。
SET_AUDIO_MODE requestType: USB_DIR_OUT | USB_TYPE_VENDOR request: 58 value: 0 ←オーディオ無し(標準) 1 ← 2 チャンネル 16-bit PCM / 44100 KHz index: 0 data none
このコマンドは、
ACCESSORY_START
コマンドを送信してアクセサリモードに入る前に送信しなければなりません。
HID サポート
AOA 2.0 では、アクセサリが Android 端末に対してひとつ以上の HID デバイスを登録出来るようになりました。このアプローチは、マウスやキーボードといった通常の USB HID デバイスのコミュニケーション方法と逆転したものです。通常、HID デバイスは PC などの USB ホストに対して周辺機器という形で接続されます。しかし、AOA プロトコルにおいては USB ホストが 1 つ以上の 入力デバイスとして動作します。
AOA 2.0 における HID サポートは、単純な HID イベントのプロキシとなっています。この実装において通信内容やイベントに関する一切の横取り(訳注:"加工"ぐらいの意)は行われず、入力システムへ単純に中継されます。このため AOA 2.0 アクセサリは任意の HID デバイス ( マウス、キーボード、ゲームコントローラほか ) として動作することができます。例えばメディアドックにおける再生 / 停止ボタン、マウスとフル QWERTY のキーボードを備えたドッキングステーション、といった格好です。
AOA 2.0 では、アクセサリが 1 つ以上の Android 端末用 HID 入力デバイスとして動作するために必要な4 つの USB コントロールリクエストが追加されました。HID サポートは常時エンドポイント 0 を利用するため、このサポートには新たな USB インターフェイスが必要となります。コントロールリクエストは以下の通りです。
- ACCESSORY_REGISTER_HID Android 端末に新たな HID デバイスを登録します。アクセサリから以下の3つのコールの際に HID デバイスを識別するための ID を指定します。この ID は、USB 接続が切られるか、またはアクセサリが ACCESSORY_UNREGISTER_HID コマンドで Android 端末から HID デバイスの登録を解除するまでの間有効となります。
- ACCESSORY_UNREGISTER_HID ACCESSORY_REGISTER_HID のコールにより登録された HID デバイスの登録を解除します。
- ACCESSORY_SET_HID_REPORT_DESC Android 端末に対して HID デバイスに関するデスクリプタを送信します。このリクエストは HID デバイスの持つ機能を明らかにするもので、あらゆる HID イベントより前に Android 端末に対して送信しておく必要があります。レポートデスクリプタのサイズがエンドポイント 0 の最大パケットサイズよりも大きな場合は、デスクリプタ全体を送信するために複数回 ACCESSORY_SET_HID_REPORT_DESC を発行してください。
- ACCESSORY_SEND_HID_EVENT アクセサリからの入力イベントを Android 端末へ送信します。
新たなコントロールリクエストのコード定義は以下のようになっています。
/* Control request for registering a HID device. * Upon registering, a unique ID is sent by the accessory in the * value parameter. This ID will be used for future commands for * the device * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_REGISTER_HID_DEVICE * value: Accessory assigned ID for the HID device * index: total length of the HID report descriptor * data none */ #define ACCESSORY_REGISTER_HID 54 /* Control request for unregistering a HID device. * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_REGISTER_HID * value: Accessory assigned ID for the HID device * index: 0 * data none */ #define ACCESSORY_UNREGISTER_HID 55 /* Control request for sending the HID report descriptor. * If the HID descriptor is longer than the endpoint zero max packet size, * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC * commands. The data for the descriptor must be sent sequentially * if multiple packets are needed. * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_SET_HID_REPORT_DESC * value: Accessory assigned ID for the HID device * index: offset of data in descriptor * (needed when HID descriptor is too big for one packet) * data the HID report descriptor */ #define ACCESSORY_SET_HID_REPORT_DESC 56 /* Control request for sending HID events. * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_SEND_HID_EVENT * value: Accessory assigned ID for the HID device * index: 0 * data the HID report for the event */ #define ACCESSORY_SEND_HID_EVENT 57
AOA 1.0 機能との総合運用性
オリジナルの AOA プロトコルでは、USB 経由で USB ホスト ( アクセサリ ) と直接通信するための仕組みを Android アプリケーションに対して提供していました。AOA 2.0 はこのサポートを継続しつつ、Android オペレーティングシステム自体と ( とりわけ、オーディオと入力システムについて ) アクセサリが通信することもできるようになりました。AOA 2.0 の設計は、オリジナルの機能セットに加えてオーディオや HID サポートを含むアクセサリを構築することを可能にしています。本ページで解説した内容は、単純にオリジナルの AOA プロトコルが提供する機能に付け加える形で実装できます。
AOA 2.0 を Android アプリ無しで接続する
オーディオドックのように、オーディオや HID をサポートするものの、Android 端末とのコミュニケーションが必須ではないようなアクセサリを設計することもできるでしょう。このような場合に、ユーザは Android 端末をアクセサリに接続して対応するアプリケーションを探すためのダイアログがポップアップしてくるのは見たくはないと考えられます。これらのダイアログがアクセサリ接続後に表示されるのを防ぐために、アクセサリ側から Android 端末に対して manufacturer と model name を送信しない、という方法があります。これらの文字列が Android 端末に対して提供されない場合、アクセサリからは連携アプリケーションを選択することなく AOA 2.0 のオーディオと HID サポートを利用することができます。また、これらの文字列が提供されなければ、アクセサリデバイスがアクセサリモードへ移行した後に Android 端末の USB コンフィグからアクセサリの USB インターフェイスが除外されます。
0 件のコメント:
コメントを投稿