Generate middleware

The Vehicle Services Interface Definition Language (VSIDL) middleware defines a set of Rust libraries creating an abstraction layer on top of the software defined vehicle (SDV) communication stack to simplify the usage of the SDV ecosystem. The middleware provides a standardized way for services to communicate and interact with each other. Both the VSIDLC generated code and your custom code use these libraries.

The Vehicle Services Interface Definition Language compiler (VSIDLC) validates definitions, generates build files (Android.bp) containing genrule targets to produce Rust middleware code during the build process, and creates deployment configurations from the VSIDL and protobuf files in a catalog. Figure 1 shows input to VSIDLC and output generated by VSIDLC:

VSIDLC inputs and outputs

Figure 1. VSIDLC inputs and outputs.

Following is an explanation of the diagram:

  1. As inputs, you provide the following files organized within directories known as catalogs:

    • Proto files (with the extension .proto) contain data structures that are exchanged between the service units defined by VSIDL.
    • VSIDL files (with the extension .vsidl) define service bundles, service units, and unit type ownership.
    • Android.bp files in each catalog directory define rust_protobuf build targets for all proto files within the catalog. VSIDLC uses the crate_name specified in these targets to reference the generated protobuf message types in Rust.
  2. You run VSIDLC to output the following files:

    • Android.bp files are generated within each service bundle's folder. If you set --genrule, these targets generate up-to-date Rust files during the build process and include the necessary rust_protobuf library dependencies.

    • service_bundle.rs files are generated for each service bundle and contain the main struct and functions for interacting with middleware components.

    • lib.rs files are generated for each RPC service owned by a bundle and are placed in a subfolder named after the RPC service. These files include:

    • An Interface trait implements the server-side logic.

    • A Client struct makes calls to an RPC service.

    • diagnostics.rs files are generated if a diagnostics_declaration is present in the VSIDL file, providing the necessary bindings for UDS-based diagnostics.

    • Deployment and security configurations are generated when using the --apex flag. These are placed in apex/ and configs/ directories and include orchestration .textproto files and security policies (permissions) required for service-to-service communication.

    • A service boilerplate is generated when using the --services flag. This is placed in a services/ directory and contains a Rust application skeleton, including a main.rs file, to jumpstart your implementation.

Run VSIDLC

To run VSIDLC:

  1. If you haven't set up your environment, run source build/envsetup.sh.

  2. Run the following command to build VSIDLC:

    m vsidlc
    
  3. Ensure your VSIDL catalog directory has the necessary build, protobuf, and VSIDL files.

  4. Run the vsidlc command:

    vsidlc -c path_to_catalog -o output_directory -p
    

    Where:

    • -c path_to_catalog identifies the path to the main catalog directory.
    • -o output_directory identifies the parent directory where the generated_rs output directory is created.
    • (optional) --apex generates orchestration and security configuration artifacts.
    • (optional) --services generates a jumpstart Rust application skeleton.
    • (optional) -p deletes existing generated directories (like generated_rs, and if applicable apex, configs, or services) before generating new files.
    • (optional) --genrule generates Android.bp genrules instead of Rust code. The genrules generate the necessary Rust code on the fly when running m to avoid putting generated artifacts under version control.

    A generated_rs directory is created containing an Android.bp and the generated middleware files. This directory is organized within subdirectories corresponding to the fully qualified names of your defined service bundles.

Handle dependencies

By default, VSIDLC generates code only for the main catalog, not for dependency catalogs. If your catalog uses types or service units defined in other catalogs, specify the path to each dependency catalog using the -d flag:

vsidlc -c path_to_catalog -o output_directory -d dep1_path -d dep2_path ...

You must provide paths for the entire dependency graph, including transitive dependencies (dependencies of dependencies). For example, suppose you have the following catalog dependency tree:

Example VSIDLC dependency tree

Figure 2. Example VSIDLC dependency tree.

To generate middleware for each catalog in the tree, you must run the following commands:

Target catalog Dependencies Command
SDV Core catalog N/A vsidlc -o ./generated -c ./path/to/sdv_core_catalog
Diagnostics catalog SDV Core catalog vsidlc -o ./generated -c ./path/to/diagnostics_catalog -d ./path/to/sdv_core_catalog
SOMEIP catalog Diagnostics catalog, SDV Core catalog vsidlc -o ./generated -c ./path/to/someip_catalog -d ./path/to/diagnostics_catalog -d ./path/to/sdv_core_catalog
OEM catalog Diagnostics catalog, SOMEIP catalog, (transitively) SDV Core catalog vsidlc -o ./generated -c ./path/to/oem_catalog -d ./path/to/someip_catalog -d ./path/to/diagnostics_catalog -d ./path/to/sdv_core_catalog

Format Rust output

By default, VSIDL uses rustfmt to format Rust output. For the default to work properly, set the $ANDROID_BUILD_TOP environment variable or the RUSTFMT_PATH and RUSTFMT_TOML_PATH environment variables. To change the default format that Rust outputs, use --rust-formatter option with either pretty-please or none:

  • To change output format to crate prettyplease, use the pretty-please value:

    vsidlc -c path_to_catalog -o output_directory -p --rust-formatter pretty-please
    
  • To change output format to none, use the none value:

    vsidlc -c path_to_catalog -o output_directory -p --rust-formatter none
    

What's next

After generating middleware, see Implement your business logic.