リフレクション用の VSIDL プロバイダ

VSIDL プロバイダは、サービス バンドルが VSIDL 宣言されたメタデータを SDV プラットフォーム エージェント(診断、テレメトリー、SOME/IP)に提供できるようにするライブラリとツールのセットです。

特に、VSIDL プロバイダを使用すると、SDV エージェントは次のメタデータを検出できます。

サービス バンドル デベロッパー向けの VSIDL プロバイダ ガイド

VSIDL プロバイダ ライブラリは、次のオペレーションを実行します。

  • 次の 2 つの特定の場所にあるファイルを探します。
    • sdv_service_bundle_metadata で定義されたパス内の Apexes。
    • 静的パスの画像。
  • 同じ VM または異なる VM に存在するエージェントの API をクエリする RPC 呼び出しを開始します。

図 1.VSIDL プロバイダの概要。

サービス バンドルを開発する場合、VSIDL プロバイダ ライブラリの詳細を知る必要はありません。VSIDL プロバイダが実行時に必要なファイルを見つけられるようにするには、次の手順に沿って操作します。

カタログのランタイム構成を生成する

3 種類のファイル(vsidl スキーマ、診断宣言、someip マッピング)はすべて vsidl_rc_generator ツールから生成されます。

vsidlc で使用したパラメータと同じパラメータと、次の追加パラメータを指定して、vsidl_rc_generator ホスト バイナリ ツールを使用します。

  • --variant runtime-config-prebuilts
  • --filegroup: カタログのすべてのファイル(Android.bp を含む)を含むファイルグループ ターゲット名を指定します。

参考までに、関連する vsidlc パラメータは次のとおりです。

  • --catalog-path: カタログのルートパスを指定します。
  • --dependency-catalog-path: 依存カタログを指定します。
  • -- -path: 生成されたすべての genrule ターゲットと prebuilt_etc ターゲットを含む Android.bp を書き込む場所を指定します。

ジェネレータは、関連する genrule ターゲットと prebuilt_etc ターゲットを含む Android.bp ファイルを作成します。Android.bp で生成されたターゲット ブロックの上には、それぞれのターゲットの意図された使用方法を示すコメントがあります。

APEX の Android.bp を更新する

生成された Android.bp ファイルのコメントに示されているように、次のように読み取ります。

// Usage: add the following line to ... declaration

これらのターゲット(Usage コメントで示された場所の下)を、Apex を定義する Android.bp に追加する必要があります。

apex {
    name: "some_apex_name",
    ...
    prebuilts: [
      // ADD THE prebuilt_etc TARGETS HERE
    ],
    ...

}

APEX の sdv_service_bundles_manifest.textproto を更新する

Apex の sdv_service_bundles_manifest.textproto ファイルの sdv_service_bundle_metadata ブロック内で、以下を定義する必要があります(該当するパスの場合のみ)。

sdv_service_bundle_metadata {
    ...
    vsidl_schemas_path: "etc/vsidl_provider/SomeFile-vsidl-config.binpb"
    diagnostics_config_path: "etc/vsidl_provider/SomeFile-diag-config.binpb"
    external_protocol_mapping_path: "etc/vsidl_provider/someip-config.binpb"
    ...
}

独自のパスを定義しないでください。代わりに、生成された Android.bp ファイルのコメントに示されているパスをコピーします。

// + vsidl_schemas_path:
// + diagnostics_config_path:
// + external_protocol_mapping_path:

これにより、VSIDL プロバイダ インスタンスは、それぞれの sdv_service_bundle_metadata エントリで指定されたパスからクエリを実行できるようになります。

画像にターゲットを追加する

生成された Android.bp ファイルは、イメージに直接読み込むことができるターゲットも生成します。コメントには、この方法で使用されるターゲットも示されています。

// Usage: add this target to the VM image.

生成された prebuilt_etc ターゲットは、genrule で生成されたファイルをイメージ上の事前に指定された場所に配置します。prebuilt_etc ターゲットをそれぞれの *.mk ファイル(device/google/sdv/sdv_core_base/sdv_samples_automotive_services.mk など)に含める必要があります。

プラットフォーム デベロッパー向け VSIDL プロバイダ ガイド

一般に、リフレクション機能が必要な SDV エージェントを開発する場合は、VSIDL プロバイダ ライブラリを使用できます。

VSIDL プロバイダ ライブラリ API には、次の関数が含まれています。

    async fn get_publication_descriptor(
        &self,
        source_fqin: &ServiceFqin,
        unit_type: &UnitType,
    ) -> SdvResult<PublicationDescriptor>;

    async fn get_rpc_method_descriptor(
        &self,
        source_fqin: &ServiceFqin,
        unit_type: &UnitType,
        method_name: &str,
    ) -> SdvResult<RpcMethodDescriptor>;

    async fn get_message_descriptor(
        &self,
        source_fqin: &ServiceFqin,
        message_name: &str,
    ) -> SdvResult<MessageDescriptor>;

    async fn get_someip_mappings(&self, source_fqin: &ServiceFqin)
        -> SdvResult<Vec<SomeIpMapping>>;

    async fn get_diagnostics_declaration(
        &self,
        fqin: &ServiceFqin,
    ) -> SdvResult<DiagnosticsDeclaration>;

    async fn subscribe_availability_change_by_vm(
        &self,
        vm_name: &str,
    ) -> SdvResult<AvailabilityStream>;

ここで

pub type AvailabilityStream = Pin<Box<dyn Stream<Item = AvailabilityChangeEvent> + Send>>;

すべての関数は source_fqin パラメータを使用してクエリされます。これにより、同じ unit_type または message_name を使用する異なる FQIN が正しいデータを返します。このパラメータは、最も正確なメッセージ スキーマを含む特定の APEX を VSIDL プロバイダ ライブラリに指示します。APEX は個別に更新され、同じ protobuf メッセージまたはサービスに異なるスキーマを使用する可能性があるため、これは必要です。

get_message_descriptor 関数の使用

これは、リフレクションに使用される外部クレートから pub struct MessageDescriptor のみを返します。MessageDescriptor は、リフレクションを可能にするメタデータの一部です。これにより、実行時に protobuf メッセージの動的な検査と操作が可能になります。

get_publication_descriptor 関数の使用

この関数は、次の PublicationDescriptor を返します。

pub struct PublicationDescriptor {
    /// Message descriptor for publication.
    pub message_descriptor: MessageDescriptor,

    /// Information about the size of the publication message.
    pub size_metadata: SizeMetadata,
}

size_metadata フィールドには、パブリケーションのメッセージのサイズと制約に関する情報が含まれています。このメタデータは VSIDL 構成から派生します。

pub struct SizeMetadata {
    /// Message size in bytes.
    pub message_size: u32,

    /// Message count.
    pub message_count: u32,

    /// VSIDL-declared size constraints for the message fields.
    pub field_size_constraints: HashMap<String, FieldSizeConstraint>,
}

pub struct FieldSizeConstraint {
    /// Max number of repeated fields allowed for the field.
    pub repeated_max_count: Option<u32>,

    /// Max size of variable sized types (string, bytes) in bytes.
    pub variable_type_max_size: Option<u32>,
}

get_rpc_method_descriptor 関数の使用

この関数は、次の RpcMethodDescriptor を返します。

pub struct RpcMethodDescriptor {
    /// Message descriptor for RPC request.
    pub request_message: Option<MessageDescriptor>,

    /// Message descriptor for RPC response.
    pub response_message: Option<MessageDescriptor>,
}

この構造体は、RPC メソッドのリクエスト メッセージとレスポンス メッセージの両方の MessageDescriptor を保持します。

get_someip_mappings 関数の使用

これは、core_services/vsidl/protos/sdv/someip/v1/someip.proto で定義されているローカル SOME/IP サービス マッピングを取得するための関数です。

get_diagnostics_declaration 関数の使用

これは、core_services/vsidl/protos/sdv/diagnostics/v1/diagnostics_syntax.proto で定義されている診断宣言を取得するための関数です。

subscribe_availability_change_by_vm 関数の使用

この関数は、指定された仮想マシンの可用性ストリームを返し、重要なフォールバック メカニズムとして機能します。標準の VSIDL プロバイダ API 呼び出しが SdvStatusCode::Unavailable エラーで失敗した場合に使用します。これにより、システムは VSIDL プロバイダ インターフェースがオンラインに戻るのを効率的に待つことができます。

この関数の主な動作は次のとおりです。

  • 即時出力: サブスクリプション時に、ストリームはターゲット仮想マシンの現在の可用性ステータスを出力します。
  • 動作のパリティ: 結果のストリームは、ServiceDiscoveryManager で使用される subscribe_service_unit_change_by_name 関数と同じように動作します。

VSIDL プロバイダ エージェント

各 VM は独自の VSIDL プロバイダ エージェントを実行しています。これは、VSIDL プロバイダ API(エージェント内のライブラリのローカル インスタンス)でリクエストを転送する RPC サーバーです。エージェントは、別の VM の VSIDL プロバイダにクエリを実行するために使用されます。つまり、1 つの VM のサービスは、このエージェントを使用して別の VM から VSIDL メタデータをクエリできます。

コードベースでの API の使用状況

SOMEIP:

  • get_publication_descriptor(すべての構造体フィールドが使用されます)
  • get_rpc_method_descriptor(すべての構造体フィールドが使用されます)
  • get_someip_mappings

テレメトリー:

  • get_publication_descriptormessage_descriptor フィールドのみが使用されます)
  • get_rpc_method_descriptor(すべての構造体フィールドが使用されます)

診断:

  • get_message_descriptor
  • get_diagnostics_declaration

さまざまなデータソースとソースの優先度を持つさまざまなフレーバーは、core_services/vsidl/provider/src/vsidl_provider.rs で確認できます。

vsidl_provider クレートには、さまざまな SDV エージェントに合わせて調整されたプロバイダ インスタンスを作成するためのパブリック関数がいくつか用意されています。各構成は、VSIDL 関連のデータを解決する一意のデータソース チェーンを指定します。次の表に、各コンストラクタ関数の動作の概要を示します。

コンストラクタ関数データ型データソースのルックアップ(と順序)
new_for_vsidl_provider_agent SomeIpAPEX
DiagnosticsAPEX
VsidlSchemasAPEX、ファイル
new_for_diagnostics_agentDiagnosticsエージェント(リモート)、APEX
VsidlSchemasファイル
new_for_someip_broker_agent SomeIpAPEX
VsidlSchemasファイル
new_for_telemetry_agentVsidlSchemasエージェント(リモートとローカル)
new_for_integration_test SomeIpエージェント(リモートとローカル)
Diagnosticsエージェント(リモートとローカル)
VsidlSchemasエージェント(リモートとローカル)

テーブルのデータソースは、図 1 の呼び出しを参照しています。