Define messages and RPC services

VSIDLC's type system operates at two levels: Protobuf and VSIDL. Protobuf is used to define messages that are exchanged between the publisher and subscribers defined by VSIDL. VSIDL references types declared by protobuf.

This page explains how to define messages and remote procedure call (RPC) methods for calling and responding to requests.

Define messages

This section explains how messages are defined in VSIDL and protobuf.

The following code sample defines a TirePressure message:

syntax = "proto3";

package com.android.sdv.sample.vsidl;

message TirePressure {
  uint32 pressure = 1;
}

Define RPC services

In protobuf, an RPC service defines a set of methods that can be called remotely as though they were local function calls. The following example defines a request and response message types and the RPC service method used to make a request and receive a response:

syntax = "proto3";

package com.google.sdv;

enum SeatHeatingLevel {
  OFF = 0;
  LOW = 1;
  HIGH = 2;
}

// Request to set seat heating
message SetSeatHeatingRequest {
  enum Seat {
    DRIVER = 0;
    PASSENGER = 1;
  }
  Seat seat = 1;
  SeatHeatingLevel level = 2;
}

// Response to setting seat heating
message SetSeatHeatingResponse {
  bool success = 1;
}

// Seat heating service
service SeatHeatingService {
  rpc SetSeatHeating (SetSeatHeatingRequest) returns (SetSeatHeatingResponse);
}

Where:

  • service identifies a collection of related RPC methods.
  • rpc identifies a single RPC method with input and output message types (SetSeatHeatingRequest and SetSeatHeatingResponse, respectively).

Configure build system integration

To enable vsidlc to discover your protobuf definitions and allow the Android build system to compile them, you must include an Android.bp file in the topmost folder of your catalog directory.

This file must define a rust_protobuf target that groups your protobuf files (with a .proto extension). Every file in your catalog must be accounted for in a filegroup. If there are multiple filegroups in the Android.bp file, vsidlc takes the first one.

The following example shows a typical rust_protobuf target for a VSIDL catalog:

  rust_protobuf {
      name: "liboem_vehicle_messages",
      crate_name: "oem_vehicle_messages",
      source_stem: "oem_vehicle_messages_source",
      protos: [
          "**/*.proto",
      ],
      rustlibs: [
          "libvsidl_v1_proto_rs",
      ],
      proto_flags: [
          "-I external/protobuf/src",
      ],
      apex_available: [
          "//apex_available:platform",
          "//apex_available:anyapex",
      ],
      vendor_available: true,
      product_available: true,
      min_sdk_version: "35",
  }

  filegroup {
      name: "catalog_oem_vehicle_messages",
      srcs: ["**/*"],
  }

Where:

  • name: A unique identifier for the build target. By convention, this starts with lib.
  • crate_name: The name of the generated Rust crate.
  • protos: A list of all protobuf files in the catalog. Globs like **/*.proto are supported.
  • rustlibs: Must include libvsidl_v1_proto_rs to provide the standard SDV annotations and types.
  • proto_flags: Used to specify include paths. -I external/protobuf/src is often required to resolve standard protobuf types.
  • min_sdk_version: Set to "35" (Android 15) to declare compatibility with the corresponding SDV platform APIs and Rust toolchain requirements.
  • filegroup: Required for build-time discovery. Include every VSIDL, protobuf, and Android.bp file in srcs so the build system can copy them into the compilation sandbox.

What's next

To continue implementing your service architecture, see Define service architecture.