デバイスタイプの追加
Sentinelの周辺機器カタログはハードウェアの事実を一覧表示します。 新しい種類のデバイス(たとえばディスプレイやシリアルアダプター)には、型付きのレコード、それを検出するプロバイダー、 テスト、およびこのディレクトリ内のページが必要です。 アプリケーションがデバイスをサポートするかどうかは、Sentinelではなく、そのアプリケーションが判断します。
1. レコードを定義する
src/peripherals/の下に、デバイス用のserde構造体を持つモジュールを追加し、
それをsrc/peripherals/mod.rsのPeripheralのバリアントとして追加します。
バリアント名はJSONのtypeタグになるため、Display(display::Display)は
{"type": "display", ...}としてシリアライズされます。Peripheral::id、kind、describeを
新しいバリアントに合わせて拡張してください。
idは再接続や再起動をまたいで安定している必要があります。バスパス、 シリアル番号、またはそれらを経ても変わらない別の属性から導出し、 カード番号や/dev/videoNのような列挙インデックスからは決して導出しないでください。idはカタログ全体で一意である必要もあります。ワーカーは これをチェックしません。既存のid(camera:v4l2:…、microphone:alsa:…)と同様にタイプとプロバイダーを接頭辞として付け、 残りの部分は、接続先のポートなど、 同一の2台のデバイスが共有できないものから構成してください。 シリアル番号だけでは不十分です。安価なデバイスでは同じ番号が繰り返されることがよくあります。- 省略可能な事実は
Optionフィールドとし、 既存のレコードと同様に#[serde(default, skip_serializing_if = "Option::is_none")]を付けます。 これにより、不明な事実はJSONから省かれます。単なるOptionではnullとしてシリアライズされてしまいます。 - カーネルやデバイスが公開する事実を報告してください。 モードがサポートされているかどうかなど、ポリシーを表すフィールドは追加しないでください。
2. プロバイダーを実装する
Providerトレイトを実装します:
pub trait Provider: Send {
fn name(&self) -> &'static str; // e.g. "display.drm"
fn subsystems(&self) -> &'static [&'static str]; // uevent subsystems, e.g. ["drm"]
fn discover(&mut self) -> Result<Vec<Peripheral>, ProviderError>;
}
discoverは、peripheralsスレッド上で1回の完全なスキャンを実行します。
ワーカーは起動時、subsystemsのいずれかからのuevent受信後、およびリフレッシュ時にこれを呼び出します。
- 読み取り専用。 デバイスノードは読み取り専用で開き、照会インターフェースのみを使用してください。 デバイスを取得、設定したり、デバイスからストリーミングしたりしないでください。
- 上限を設ける。 読み取るすべてのリストとすべての照会ループに上限を設け、
壊れたデバイスがスキャンを停滞させないようにしてください。
videodev2.rsのV4L2ヘルパーがそのパターンを示しています。 - エラー。 スキャンを完了できない場合は、
ProviderErrorを返します。コードにはio.permission_deniedやio.openなどを使用します(sysutil.rsを参照)。その後、カタログは このプロバイダーの最後の正常なデバイスを保持し、エラーをerrorsに記載します。 スキャン中に消えたデバイスはエラーではなくスキップされます。その取り外しによって送信される ueventが再スキャンをトリガーします。 - 失敗させずに縮退する。 省略可能な属性が欠けている場合は、そのフィールドを省きます。
存在するが読み取れない属性は、その用途に応じて扱います:
- デバイスの検出や識別にスキャンが必要とする属性(idやUSBの 識別情報)はエラーとし、プロバイダーの最後の正常なデバイスが保持されるようにします。
- 事実を追加するだけの属性の場合は、その事実を除いたうえでデバイスを公開し、
レコードに理由を記録します(マイクのレコードの
issuesは、 読み取れないキャプチャメタデータに対してこれを行っています)。
プロバイダーをsrc/peripherals/mod.rsのbuiltin_providers()に登録します。
3. テストする
テストはライブシステムではなくフィクスチャツリーを読み取ります。
プロバイダーにsysfs、procfs、/devのルートをパラメーターとして渡し、
alsa/tests.rsやv4l2/tests.rsのようにioctlレイヤーを偽装します。
手元のデバイスだけでなく、そのクラスのデバイスが異なり得るあらゆる点をカバーしてください:
数、フォーマット、範囲と離散値、欠落した省略可能フィールド、同時に存在する複数の同一デバイス、
スキャン中に消えるデバイスなど。
同一の2台のデバイスに異なるidが付くことをアサートしてください。
実際のハードウェアからコピーしたフィクスチャには、実キャプチャであることを示すラベルを付けてください。
cargo test --lockedが成功し、cargo fmt --checkとcargo clippy --locked --all-targetsが新たな問題を報告しないことが必要です。
4. ドキュメントを作成する
このディレクトリに、プロバイダー名、ueventサブシステム、idの導出方法、
各フィールドとその出現条件、エラーコード、およびJSONの例を記載したページを追加しま す。
そのページをAPIリファレンスと
ドキュメントインデックスからリンクし、翻訳を再生成してください
(ローカライズを参照)。