This page specifies the Vehicle Service Interface Definition Language (VSIDL) using ISO/IEC 14977 Extended Backus-Naur Form (EBNF) and protobuf. This page focuses on the context-free grammar of the language and the meaning of the language elements.
Language hierarchy
According to the Meta Object Facility (MOF), VSIDL compiler (VSIDLC) uses the languages shown in Figure 1:
Figure 1. VSIDLC languages.
VSIDLC is mainly based on the protocol buffer (protobuf) language. Protobuf
is used to specify the data types that are exchanged using publish-subscribe and
remote procedure calls (RPCs) calls. From a technical point of view, VSIDL
models are TextProto files, where VSIDL's syntax is defined in a protobuf file
(syntax.proto). Both the protobuf files for specifying data types and VSIDL
models are used to generate Rust code. The generated code mainly contains
structs that implement the data structures for the exchanged messages and Rust
functions that implement functions for creating service units in Rust, without
calling these service units automatically. This generated Rust code is
accompanied by custom Rust code that uses the generated code to instantiate
service units and implement the business logic of the application.
Abstract syntax
Figure 2 shows the core message types in VSIDL:
Figure 2. Core message types in VSIDL.
VSIDL entry
This section explains the VSIDL entry message type.
EBNF grammar
start VsidlEntry =
"package" , ":" , String , ";" ,
{ "service_bundle" , ServiceBundle } ,
{ "extension" , ":" , Any } ,
{ "some_ip_mapping" , ":" , SomeIpMapping } ,
{ "vhal_mapping" , ":" , VhalMapping }
;
Proto definition
// 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;
}
Usage example
package: "com.android.sdv.sample.vsidl"
service_bundle {
name: "Manager"
publisher {
message: "TirePressure"
topic: "front-left"
topic: "front-right"
capacity: 10
}
}
Explanation
The VsidlEntry message serves as the root container for VSIDL file (with the
extension .vsidl). This message encapsulates all definitions and
configurations in a single VSIDL file. The VsidlEntry is the top-level element
that binds everything else.
Purpose:
- Defines the overall structure of a VSIDL file.
- Specifies the package namespace for all entities within the file.
- Contains a collection of service bundle definitions.
- Allows custom extensions to the VSIDL model.
- Includes mapping rules for SOME/IP and VHAL.
Constraints
- Package name (E211): The package name must not exceed 127 characters.
- Dangling files (E10B): All files in a catalog must be referenced in an
Android.bpfilegroup.
Service bundle
This section explains the service bundle message type.
EBNF grammar
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 definition
// 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;
}
Usage example
service_bundle {
name: "SeatController"
publisher {
message: "SeatHeating"
topic: "driver-seat"
capacity: 10
}
}
Explanation
A service bundle defines a logical grouping of related services, publishers, subscribers, RPC servers, and RPC clients. A service bundle acts as a container for a specific set of functionalities and their interactions.
Constraints
- Bundle name requirements (E209, E20A, E20B, E20C):
- A service bundle must have a populated name.
- The name must start with a valid Unicode identifier start character (typically a letter).
- Subsequent characters in the name must be valid Unicode identifier continuation characters (typically letters or numbers).
- The name must not be a reserved keyword in Rust, Java, or C++.
- Global bundle uniqueness (E309): Every service bundle must have a unique fully qualified name (based on its package and name).
- Internal uniqueness (E100, E300, E302, E303, E308):
- Within a single service bundle, each RPC service can be served by at most one server definition.
- Within a single service bundle, each
MULTI_PUBpublication type can be published by at most one publisher definition. - Within a single service bundle, all user-defined service unit names (for publishers or servers) must be unique.
- Within a single service bundle, all service unit names (whether user-defined or automatically generated) must be unique.
- Build target naming conventions (E205, E206, E207, E208): If a custom
build target name (
build_cfg.target_name) is provided, it must adhere to snake case format (lowercase letters, numbers, and single underscores, not starting or ending with an underscore). - Build target name uniqueness (E301): A user-defined build target name must not clash with any automatically generated target names for other service bundles.
Publisher
This section explains the Publisher message type.
EBNF grammar
Publisher = "{" , { PublisherElement } , "}" ;
PublisherElement =
"message" , ":" , String |
"topic" , ":" , String |
"capacity" , ":" , Integer |
"service_unit_name" , ":" , String
;
Proto definition
// 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;
}
Usage example
publisher {
message: "SeatHeating"
topic: "driver-heating"
capacity: 10
}
Explanation
The Publisher message type defines a data source that ServiceBundle
provides. This message type specifies the type of data being published and the
specific topics and capacity of that data.
Topics
Every Publisher instance has a message field that refers to the proto
message being published. It must specify a topic (represented by topic) and a
capacity (represented by capacity).
- Topic: A unique identifier for the publication topic. It must follow
lowercase dash-case (for example,
my-topic). - Capacity: Specifies the size of the queue, that is, how many messages the queue can hold before unread messages are discarded. It must be an even number greater than or equal to 2.
User-defined names
Publishers can have user-defined service unit names that override the automatically chosen service unit names. This affordance enables choosing shorter names. If a publisher uses a user-defined service unit name, it might use only a single instance, so that the service unit name is uniquely assigned to one instance.
# 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"
}
Constraints
- Publisher placement (E300): Publishers for the same
MULTI_PUBtype must be defined in separate service bundles. - Local name uniqueness (E302): Within any single service bundle, all publishers must have unique user-defined service unit names.
- Global name uniqueness (E304): Publishers of the same publication type must have globally unique user-defined service unit names across all service bundles.
- Naming single channels (E306): User-defined service unit names can be assigned only to publishers that handle exactly one instance.
- Single publisher limit (E307): A protobuf message marked as
SINGLE_PUBcan be published by only one publisher across the entire system. - Service unit name uniqueness (E308): All service unit names (whether generated or user defined) must be unique within their service bundle; user-defined names should be used to resolve conflicts with generated names.
- Variant specification requirement (E501): When a publisher uses a user-defined name for a type with multiple variants, it must explicitly specify the variant it publishes.
- Publisher existence for subscribers (E504): Every defined subscriber requires at least one corresponding publisher for the specified type and variant.
- Valid publisher type (E601): A publisher must reference a type that corresponds to an existing protobuf message.
- Publication annotation requirement (E602): The protobuf message type
referenced by a publisher must include the
SdvPublicationannotation. - Valid variant usage (E606): If a publisher specifies a variant
(instance), that variant must exist within the
instances_enumdefined for the publication type in protobuf. - Variant specification condition (E607): A publisher can specify an
explicit variant (instance) only if the publication type defines an
instances_enumin protobuf. - Topic naming (E20D, E20F): Topics must be in lowercase dash-case and not exceed 127 characters.
- Topic uniqueness (E314): Topics must be globally unique across all publishers.
- Capacity requirements (E406, E407): Capacity is mandatory and must be an even number >= 2.
Subscriber
This section explains the Subscriber message type.
EBNF grammar
Subscriber = "{" , { SubscriberElement } , "}" ;
SubscriberElement =
"message" , ":" , String |
"topic" , ":" , String
;
Proto definition
// 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;
}
Usage example
subscriber {
message: "SeatHeating"
topic: "driver-seat"
}
Explanation
The Subscriber message defines a publication receiver that ServiceBundle
provides. This message specifies the type of data being subscribed to and the
specific topics of that publication. If there are multiple publishers for a
topic, the subscriber receives the messages published by all of them.
Constraints
- Publisher existence (E504): For every defined subscriber, at least one corresponding publisher must exist that publishes the specified publication type and variant.
- Valid subscription type (E608): A subscriber must reference a type that
corresponds to an existing protobuf message defined with the
SdvPublicationannotation. - Valid variant subscription (E609): If a subscriber specifies a variant
(instance), that variant must be a valid value defined within
instances_enumof the corresponding protobuf publication type. - Topic mandatory (E408): Topic is mandatory for subscribers.
- Topic redeclaration (E311): Subscriber topics shouldn't be redeclared in the same service bundle.
RPC server
This section explains the RPC server message type.
EBNF grammar
Server = "{" , { ServerElement } , "}" ;
ServerElement =
"service" , ":" , String |
"channel" , ":" , String |
"service_unit_name" , ":" , String
;
Proto definition
// 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;
}
Usage example
server {
service: "SetTemperature"
channel: "temp-setter"
}
Explanation
The Server message defines an RPC server that ServiceBundle provides. This
message specifies the service that the server implements and the RPC channel.
An RPC server exposes a set of methods that clients can invoke remotely. The
service field specifies the name of the RPC service that the server
implements. This service is defined in a proto file and implemented in custom
Rust code. RPC services can include unary, client-streaming, and
server-streaming methods, as defined in the protobuf service definition. The
channel field defines the communication endpoint and is mandatory (E409).
Constraints
- Service definition (E603): An RPC server must specify a
servicevalue that corresponds to an existing protobuf RPCservicevalue. - Server limit per service (E100): Within a single service bundle, a
specific RPC
servicecan be served by at most one server definition. - Channel naming (E20E): RPC channels must be in lowercase dash-case.
- Channel mandatory (E409): RPC channel is mandatory.
- Channel uniqueness (E40B): RPC channel must be used by only one service.
RPC client
This section explains the RPC client message type.
EBNF grammar
Client = "{" , { ClientElement } , "}" ;
ClientElement =
"service" , ":" , String |
"channel" , ":" , String
;
Proto definition
// 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;
}
Usage example
client {
service: "SetTemperature"
channel: "temp-setter"
}
Explanation
client defines an RPC client that ServiceBundle consumes. client specifies
the service that the client interacts with and the channel to connect to. The
client can interact with unary, client-streaming, and server-streaming methods,
depending on the service definition.
Constraints
- Service definition (E60A): An RPC client must specify a
servicethat corresponds to an existing protobufservicedefinition. - Unique service source (E60B): The protobuf
servicedefinition referenced by an RPC client'sservicemust be uniquely defined (not defined multiple times) across all protobuf files. - Channel mandatory (E409): RPC channel is mandatory.
Build configuration
This section explains the Build configuration message type.
EBNF grammar
BuildConfiguration = "{" , BuildConfigurationElement, "}" ;
BuildConfigurationElement =
"target_name" , ":" , String |
"skip_codegen" , ":" , Boolean
;
Proto definition
// 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;
}
Usage example
build_cfg {
target_name: "my_custom_target_name"
skip_codegen: false
}
Explanation
BuildConfiguration configures nonstandard parameters of ServiceBundle for
code generation. All build configurations are optional.
target_name(optionalstring): Specifies the name of the build target inAndroid.bpfiles. Use this to set target names with shorter names than the automatically chosen names.skip_codegen(optionalbool): Indicates whether code generation should be skipped for this service bundle. If set totrue, no code is generated for this particular service bundle. This can be useful for service bundles that are implemented manually. By default, this is set tofalse.
Constraints
- Target name format (E205, E206, E207, E208): If a custom build target
name (
build_cfg.target_name) is provided, it must strictly follow snake case formatting:- It must contain only lowercase letters (
athroughz), numbers (0through9), and underscores (_). - It must not contain consecutive underscores (
__). - It must not start with an underscore.
- It must not end with an underscore.
- It must contain only lowercase letters (
- Target name uniqueness (E301): A user-defined
build_cfg.target_namemust be unique across the build system and must not conflict with any automatically generated target names derived from other service bundle definitions.