言語仕様

このページでは、ISO/IEC 14977 拡張バッカス・ナウア記法(EBNF)と protobuf を使用して、車両サービス インターフェース定義言語(VSIDL)を指定します。このページでは、言語の文脈自由文法と、言語要素の意味について説明します。

言語の階層

Meta Object Facility(MOF)によると、VSIDL コンパイラ(VSIDLC)は 図 1 に示す言語を使用します。

VSIDLC 言語

図 1.VSIDLC 言語。

VSIDLC は主にプロトコル バッファ(protobuf)言語に基づいています。protobuf は、パブリッシュ / サブスクライブとリモート プロシージャ コール(RPC)呼び出しを使用して交換されるデータ型を指定するために使用されます。技術的な観点から見ると、VSIDL モデルは TextProto ファイルです。VSIDL の構文は protobuf ファイル(syntax.proto)で定義されています。データ型を指定する protobuf ファイルと VSIDL モデルの両方を使用して、Rust コードを生成します。生成されたコードには主に、交換されるメッセージのデータ構造を実装する構造体と、これらのサービス ユニットを自動的に呼び出すことなく、Rust でサービス ユニットを作成する関数を実装する Rust 関数が含まれています。この生成された Rust コードには、生成されたコードを使用してサービス ユニットをインスタンス化し、アプリケーションのビジネス ロジックを実装するカスタム Rust コードが付属しています。

抽象構文

図 2 に、VSIDL のコア メッセージ タイプを示します。

VSIDL のコア メッセージ タイプ

図 2.VSIDL のコア メッセージ タイプ。

VSIDL エントリ

このセクションでは、VSIDL エントリ メッセージ タイプについて説明します。

EBNF 文法

start VsidlEntry =
  "package" , ":" , String , ";" ,
  { "service_bundle" , ServiceBundle } ,
  { "extension" , ":" , Any } ,
  { "some_ip_mapping" , ":" , SomeIpMapping } ,
  { "vhal_mapping" , ":" , VhalMapping }
;

proto 定義

// The root message for VSIDL files
message VsidlEntry {
  // Required. Package name for entities mentioned in the file.
  string package = 1;
  // Enables custom extensions beyond the standard VSIDL model.
  repeated google.protobuf.Any extension = 3;

  // SOMEIP mapping rules
  repeated sdv.someip.v1.SomeIpMapping some_ip_mapping = 4;
  // VHAL mapping rules
  repeated VhalMapping vhal_mapping = 5;
  // List of SDV service bundles defined in the file.
  repeated ServiceBundle service_bundle = 6;
}

使用例

package: "com.android.sdv.sample.vsidl"

service_bundle {
  name: "Manager"

  publisher {
    message: "TirePressure"
    topic: "front-left"
    topic: "front-right"
    capacity: 10
  }
}

説明

VsidlEntry メッセージは、VSIDL ファイル(拡張子 .vsidl)のルート コンテナとして機能します。このメッセージは、1 つの VSIDL ファイル内のすべての定義と構成をカプセル化します。VsidlEntry は、他のすべてをバインドする最上位の要素です。

目的:

  • VSIDL ファイルの全体的な構造を定義します。
  • ファイル内のすべてのエンティティのパッケージ Namespace を指定します。
  • サービス バンドル定義のコレクションが含まれています。
  • VSIDL モデルのカスタム拡張を可能にします。
  • SOME/IP と VHAL のマッピング ルールが含まれています。

制約

  • パッケージ名(E211): パッケージ名は 127 文字以下にしてください。
  • ダングリング ファイル(E10B): カタログ内のすべてのファイルは、Android.bp ファイルグループで参照する必要があります。

サービス バンドル

このセクションでは、サービス バンドル メッセージ タイプについて説明します。

EBNF 文法

ServiceBundle = "{" , { ServiceBundleElement } , "}" ;

ServiceBundleElement =
  "name" , ":" , String |
  "publisher" , Publisher |
  "subscriber" , Subscriber |
  "server" , Server |
  "client" , Client |
  "extension" , ":" , Any |
  "diagnostics_declaration" , DiagnosticsDeclaration |
  "build_cfg" , BuildConfiguration |
  "register_reflection_metadata" , Boolean
;

proto 定義

// Defines an SDV service
message ServiceBundle {
  // Required. Name of the service bundle (without the package name).
  string name = 1;
  // List of publications the service bundle provides.
  repeated Publisher publisher = 2;
  // List of publications a service bundle subscribes to.
  repeated Subscriber subscriber = 3;
  // RPC services offered by a service bundle.
  repeated Server server = 4;
  // RPC services consumed by a service bundle.
  repeated Client client = 5;
  // Enables custom extensions beyond the standard VSIDL model.
  repeated google.protobuf.Any extension = 7;

  // Diagnostics declarations
  sdv.diagnostics.v1.DiagnosticsDeclaration diagnostics_declaration = 8;

  // Build Configuration
  optional BuildConfiguration build_cfg = 9;

  // Register metadata for service units provided by this service bundle.
  // Setting this to true will increase the memory footprint
  // and network load significantly.
  bool register_reflection_metadata = 10;
}

使用例

service_bundle {
    name: "SeatController"

    publisher {
      message: "SeatHeating"
      topic: "driver-seat"
      capacity: 10
    }
}

説明

サービス バンドルは、関連するサービス、パブリッシャー、サブスクライバー、RPC サーバー、RPC クライアントの論理グループを定義します。サービス バンドルは、特定の機能セットとそのインタラクションのコンテナとして機能します。

制約

  • バンドル名の要件(E209、E20A、E20B、E20C):
    • サービス バンドルには名前を入力する必要があります。
    • 名前は、有効な Unicode 識別子の開始文字(通常は文字)で始める必要があります。
    • 名前の以降の文字は、有効な Unicode 識別子の継続文字(通常は文字または数字)にする必要があります。
    • 名前は、Rust、Java、C++ の予約キーワードにすることはできません。
  • グローバル バンドルの一意性(E309): すべてのサービス バンドルには、一意の完全修飾された名前(パッケージと名前に基づく)が必要です。
  • 内部の一意性(E100、E300、E302、E303、E308):
    • 1 つのサービス バンドル内で、各 RPC サービスは最大 1 つのサーバー定義で提供できます。
    • 1 つのサービス バンドル内で、各 MULTI_PUB パブリッシュ タイプは最大 1 つのパブリッシャー定義でパブリッシュできます。
    • 1 つのサービス バンドル内で、すべてのユーザー定義のサービス ユニット名(パブリッシャーまたはサーバー用)は一意である必要があります。
    • 1 つのサービス バンドル内で、すべてのサービス ユニット名(ユーザー定義または自動生成)は一意である必要があります。
  • ビルドターゲットの命名規則(E205、E206、E207、E208): カスタム ビルドターゲット名(build_cfg.target_name)が指定されている場合は、スネークケース形式(小文字、数字、単一のアンダースコア。アンダースコアで始まったり、アンダースコアで終わったりしない)に準拠する必要があります。
  • ビルドターゲット名の一意性(E301): ユーザー定義のビルドターゲット名は、他のサービス バンドルの自動生成されたターゲット名と競合しないようにする必要があります。

パブリッシャー

このセクションでは、Publisher メッセージ タイプについて説明します。

EBNF 文法

Publisher = "{" , { PublisherElement } , "}" ;

PublisherElement =
  "message" , ":" , String |
  "topic" , ":" , String |
  "capacity" , ":" , Integer |
  "service_unit_name" , ":" , String
;

proto 定義

// Represents a publisher within a service bundle.
message Publisher {
  // Name of the service unit. Name may only use characters from [a-z0-9\-]+,
  // must start with [a-z], may not end with a hyphen,
  // and may not contain consecutive hyphens.
  string service_unit_name = 3;
  // Required. The type of data being published.
  string message = 4;
  // Required. The number of messages a publication queue can hold.
  // Must be an even number >= 2.
  int64 capacity = 6;
  // Required. Unique identifier for the publication topic.
  // Must be in lowercase dash-case.
  repeated string topic = 7;
}

使用例

publisher {
  message: "SeatHeating"
  topic: "driver-heating"
  capacity: 10
}

説明

Publisher メッセージ タイプは、ServiceBundle が提供するデータソースを定義します。このメッセージ タイプは、パブリッシュされるデータのタイプと、そのデータの特定のトピックと容量を指定します。

トピック

すべての Publisher インスタンスには、パブリッシュされる proto メッセージを参照する message フィールドがあります。トピック(topic で表される)と容量(capacity で表される)を指定する必要があります。

  • トピック: パブリッシュ トピックの一意の識別子。小文字のダッシュケース(例: my-topic)に従う必要があります。
  • 容量: キューのサイズを指定します。つまり、未読のメッセージが破棄される前にキューに保持できるメッセージの数です。2 以上の偶数にする必要があります。

ユーザー定義名

パブリッシャーには、自動的に選択されたサービス ユニット名をオーバーライドするユーザー定義のサービス ユニット名を付けることができます。このアフォーダンスにより、短い名前を選択できます。パブリッシャーがユーザー定義のサービス ユニット名を使用する場合、サービス ユニット名が 1 つのインスタンスに一意に割り当てられるように、1 つのインスタンスのみを使用できます。

# VALID: A publisher assigns a user-defined name to a single instance
publisher {
  message: "SeatHeating"
  topic: "seat-heating-status"
  service_unit_name: "heating-is-off"
}

# ERROR: user-defined names are only allowed if there's only a single instance
publisher {
  message: "SeatHeating"
  topic: "seat-heating-status"
  service_unit_name: "heating-status"
}

制約

  • パブリッシャーの配置(E300): 同じ MULTI_PUB タイプのパブリッシャーは、別々のサービス バンドルで定義する必要があります。
  • ローカル名の一意性(E302): 1 つのサービス バンドル内で、すべてのパブリッシャーに一意のユーザー定義のサービス ユニット名が必要です。
  • グローバル名の一意性(E304): 同じパブリケーション タイプのパブリッシャーには、すべてのサービス バンドルでグローバルに一意のユーザー定義のサービス ユニット名が必要です。
  • 単一チャネルの命名(E306): ユーザー定義のサービス ユニット名は、1 つのインスタンスのみを処理するパブリッシャーにのみ割り当てることができます。
  • 単一パブリッシャーの制限(E307): SINGLE_PUB としてマークされた protobuf メッセージは、システム全体で 1 つのパブリッシャーのみがパブリッシュできます。
  • サービス ユニット名の一意性(E308): すべてのサービス ユニット名(生成された名前かユーザー定義の名前かに関わらず)は、サービス バンドル内で一意である必要があります。ユーザー定義の名前は、生成された名前との競合を解決するために使用する必要があります。
  • バリアントの指定要件(E501): パブリッシャーが複数のバリアントを持つタイプにユーザー定義の名前を使用する場合、パブリッシュするバリアントを明示的に指定する必要があります。
  • サブスクライバーのパブリッシャーの存在(E504): 定義されたすべてのサブスクライバーには、指定されたタイプとバリアントに対応するパブリッシャーが少なくとも 1 つ必要です。
  • 有効なパブリッシャー タイプ(E601): パブリッシャーは、既存の protobuf メッセージに対応するタイプを参照する必要があります。
  • パブリケーション アノテーションの要件(E602): パブリッシャーが参照する protobuf メッセージ タイプには、SdvPublication アノテーションを含める必要があります。
  • 有効なバリアントの使用(E606): パブリッシャーがバリアント(インスタンス)を指定する場合、そのバリアントは protobuf のパブリッシュ タイプに定義された instances_enum 内に存在する必要があります。
  • バリアントの指定条件(E607): パブリッシャーは、パブリッシュ タイプが protobuf で instances_enum を定義している場合にのみ、明示的なバリアント(インスタンス)を指定できます。
  • トピックの命名(E20D、E20F): トピックは小文字のダッシュケースで、127 文字以下にする必要があります。
  • トピックの一意性(E314): トピックは、すべてのパブリッシャーでグローバルに一意である必要があります。
  • 容量の要件(E406、E407): 容量は必須で、2 以上の偶数にする必要があります。

サブスクライバー

このセクションでは、Subscriber メッセージ タイプについて説明します。

EBNF 文法

Subscriber = "{" , { SubscriberElement } , "}" ;

SubscriberElement =
  "message" , ":" , String |
  "topic" , ":" , String
;

proto 定義

// Represents a subscriber within a service bundle.
message Subscriber {
  // Required. The type of data being subscribed to.
  string message = 4;
  // Required. Specific topic(s) of the message to subscribe to.
  // Must match the publisher's topic.
  repeated string topic = 6;
}

使用例

subscriber {
  message: "SeatHeating"
  topic: "driver-seat"
}

説明

Subscriber メッセージは、ServiceBundle が提供するパブリッシュ レシーバーを定義します。このメッセージは、サブスクライブするデータのタイプと、そのパブリッシュの特定のトピックを指定します。トピックに複数のパブリッシャーがある場合、サブスクライバーはそれらすべてがパブリッシュしたメッセージを受信します。

制約

  • パブリッシャーの存在(E504): 定義されたすべてのサブスクライバーに対して、指定されたパブリケーション タイプとバリアントをパブリッシュする対応するパブリッシャーが少なくとも 1 つ存在する必要があります。
  • 有効なサブスクリプション タイプ(E608): サブスクライバーは、SdvPublication アノテーションで定義された既存の protobuf メッセージに対応するタイプを参照する必要があります。
  • 有効なバリアント サブスクリプション(E609): サブスクライバーがバリアント(インスタンス)を指定する場合、そのバリアントは対応する protobuf パブリッシュ タイプの instances_enum 内で定義された有効な値にする必要があります。
  • トピックは必須(E408): サブスクライバーにはトピックが必須です。
  • トピックの再宣言(E311): サブスクライバーのトピックは、同じサービス バンドルで再宣言しないでください。

RPC サーバー

このセクションでは、RPC サーバー メッセージ タイプについて説明します。

EBNF 文法

Server = "{" , { ServerElement } , "}" ;

ServerElement =
  "service" , ":" , String |
  "channel" , ":" , String |
  "service_unit_name" , ":" , String
;

proto 定義

// Represents an RPC server within a service bundle.
message Server {
  // Deprecated. Name of the service unit.
  string service_unit_name = 3 [ deprecated = true ];
  // Required. Name of the RPC service.
  string service = 4;
  // Required. Name of the RPC channel.
  // Must be in lowercase dash-case.
  string channel = 5;
}

使用例

server {
  service: "SetTemperature"
  channel: "temp-setter"
}

説明

Server メッセージは、ServiceBundle が提供する RPC サーバーを定義します。このメッセージは、サーバーが実装するサービスと RPC チャネルを指定します。

RPC サーバーは、クライアントがリモートで呼び出すことができる一連のメソッドを公開します。service フィールドは、サーバーが実装する RPC サービスの名前を指定します。このサービスは proto ファイルで定義され、カスタム Rust コードで実装されます。protobuf サービス定義で定義されているように、RPC サービスにはユニタリ、クライアント ストリーミング、サーバー ストリーミングのメソッドを含めることができます。channel フィールドは通信エンドポイントを定義し、必須です(E409)。

制約

  • サービス定義(E603): RPC サーバーは、既存の protobuf RPC service 値に対応する service 値を指定する必要があります。
  • サービスごとのサーバーの制限(E100): 1 つのサービス バンドル内で、特定の RPC service は最大 1 つのサーバー定義で提供できます。
  • チャネルの命名(E20E): RPC チャネルは小文字のダッシュケースにする必要があります。
  • チャネルは必須(E409): RPC チャネルは必須です。
  • チャネルの一意性(E40B): RPC チャネルは 1 つのサービスでのみ使用する必要があります。

RPC クライアント

このセクションでは、RPC クライアント メッセージ タイプについて説明します。

EBNF 文法

Client = "{" , { ClientElement } , "}" ;

ClientElement =
  "service" , ":" , String |
  "channel" , ":" , String
;

proto 定義

// Represents an RPC client within a service bundle.
message Client {
  // Required. Name of the RPC service.
  string service = 2;
  // Required. Name of the RPC channel.
  // Must match the server's channel and be in lowercase dash-case.
  string channel = 3;
}

使用例

client {
  service: "SetTemperature"
  channel: "temp-setter"
}

説明

client は、ServiceBundle が使用する RPC クライアントを定義します。client は、クライアントがやり取りするサービスと、接続するチャネルを指定します。クライアントは、サービス定義に応じて、ユニタリ、クライアント ストリーミング、サーバー ストリーミングのメソッドとやり取りできます。

制約

  • サービス定義(E60A): RPC クライアントは、既存の protobuf service 定義に対応する service を指定する必要があります。
  • 一意のサービスソース(E60B): RPC クライアントの service が参照する protobuf service 定義は、すべての protobuf ファイルで一意に定義する必要があります(複数回定義しないでください)。
  • チャネルは必須(E409): RPC チャネルは必須です。

ビルド構成

このセクションでは、ビルド構成メッセージ タイプについて説明します。

EBNF 文法

BuildConfiguration = "{" , BuildConfigurationElement, "}" ;

BuildConfigurationElement =
  "target_name" , ":" , String |
  "skip_codegen" , ":" , Boolean
;

proto 定義

// Defines additional information used to configure build settings
message BuildConfiguration {
  /// Build target name
  optional string target_name = 1;
  // Do not generate code for this service bundle
  optional bool skip_codegen = 2;
}

使用例

build_cfg {
  target_name: "my_custom_target_name"
  skip_codegen: false
}

説明

BuildConfiguration は、コード生成のために ServiceBundle の非標準パラメータを構成します。すべてのビルド構成は省略可能です。

  • target_name (省略可、string): Android.bp ファイルのビルドターゲットの名前を指定します。これを使用して、自動的に選択された名前よりも短い名前でターゲット名を設定します。
  • skip_codegen (省略可、bool): このサービス バンドルのコード生成をスキップするかどうかを示します。true に設定すると、この特定のサービス バンドルに対してコードは生成されません。これは、手動で実装されるサービス バンドルに役立ちます。デフォルトは false です。

制約

  • ターゲット名の形式(E205、E206、E207、E208): カスタム ビルドターゲット名(build_cfg.target_name)が指定されている場合は、スネークケース形式に厳密に従う必要があります。
    • 使用できるのは、小文字(az)、数字(09)、アンダースコア(_)のみです。
    • 連続するアンダースコア(__)を含めることはできません。
    • アンダースコアで始めることはできません。
    • 末尾をアンダースコアにすることはできません。
  • ターゲット名の一意性(E301): ユーザー定義の build_cfg.target_name は、ビルドシステム全体で一意である必要があり、他のサービス バンドル定義から派生した自動生成されたターゲット名と競合しないようにする必要があります。