언어 사양

이 페이지에서는 ISO/IEC 14977 확장 Backus-Naur 형식 (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)의 루트 컨테이너 역할을 합니다. 이 메시지는 단일 VSIDL 파일의 모든 정의와 구성을 캡슐화합니다. VsidlEntry는 다른 모든 요소를 바인딩하는 최상위 요소입니다.

목적:

  • VSIDL 파일의 전체 구조를 정의합니다.
  • 파일 내 모든 항목의 패키지 네임스페이스를 지정합니다.
  • 서비스 번들 정의 모음을 포함합니다.
  • 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):
    • 서비스 번들에는 이름이 입력되어 있어야 합니다.
    • 이름은 유효한 유니코드 식별자 시작 문자(일반적으로 문자)로 시작해야 합니다.
    • 이름의 후속 문자는 유효한 유니코드 식별자 연속 문자 (일반적으로 문자 또는 숫자)여야 합니다.
    • 이름은 Rust, Java, C++에서 예약된 키워드가 아니어야 합니다.
  • 전역 번들 고유성(E309): 모든 서비스 번들에는 패키지 및 이름을 기반으로 하는 고유한 정규화된 이름이 있어야 합니다.
  • 내부 고유성 (E100, E300, E302, E303, E308):
    • 단일 서비스 번들 내에서 각 RPC 서비스는 최대 하나의 서버 정의로 제공될 수 있습니다.
    • 단일 서비스 번들 내에서 각 MULTI_PUB 게시 유형은 최대 하나의 게시자 정의에 의해 게시될 수 있습니다.
    • 단일 서비스 번들 내에서 모든 사용자 정의 서비스 단위 이름 (게시자 또는 서버용)은 고유해야 합니다.
    • 단일 서비스 번들 내에서 모든 서비스 단위 이름 (사용자 정의 또는 자동 생성)은 고유해야 합니다.
  • 빌드 타겟 이름 지정 규칙 (E205, E206, E207, E208): 맞춤 빌드 타겟 이름 (build_cfg.target_name)이 제공되는 경우 스네이크 케이스 형식 (소문자, 숫자, 단일 밑줄, 밑줄로 시작하거나 끝나지 않음)을 따라야 합니다.
  • 빌드 타겟 이름 고유성 (E301): 사용자 정의 빌드 타겟 이름이 다른 서비스 번들의 자동으로 생성된 타겟 이름과 충돌해서는 안 됩니다.

게시자

이 섹션에서는 게시자 메시지 유형을 설명합니다.

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 인스턴스에는 게시되는 프로토 메시지를 참조하는 message 필드가 있습니다. 주제 (topic로 표시)와 용량 (capacity로 표시)을 지정해야 합니다.

  • 주제: 간행물 주제의 고유 식별자입니다. 소문자 대시 케이스를 따라야 합니다 (예: my-topic).
  • 용량: 읽지 않은 메시지가 삭제되기 전에 대기열에 보관할 수 있는 메시지 수, 즉 대기열의 크기를 지정합니다. 2 이상의 짝수여야 합니다.

사용자 정의 이름

게시자는 자동으로 선택된 서비스 단위 이름을 재정의하는 사용자 정의 서비스 단위 이름을 사용할 수 있습니다. 이 어포던스를 사용하면 더 짧은 이름을 선택할 수 있습니다. 게시자가 사용자 정의 서비스 단위 이름을 사용하는 경우 서비스 단위 이름이 하나의 인스턴스에 고유하게 할당되도록 하나의 인스턴스만 사용할 수 있습니다.

# 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): 단일 서비스 번들 내에서 모든 게시자는 사용자 정의 서비스 단위 이름이 고유해야 합니다.
  • 전역 이름 고유성 (E304): 동일한 간행물 유형의 게시자는 모든 서비스 번들에서 전역적으로 고유한 사용자 정의 서비스 단위 이름을 가져야 합니다.
  • 단일 채널 이름 지정 (E306): 사용자 정의 서비스 단위 이름은 인스턴스를 정확히 하나만 처리하는 게시자에게만 할당할 수 있습니다.
  • 단일 게시자 제한 (E307): SINGLE_PUB로 표시된 protobuf 메시지는 전체 시스템에서 하나의 게시자만 게시할 수 있습니다.
  • 서비스 단위 이름 고유성 (E308): 모든 서비스 단위 이름 (생성된 이름이든 사용자 정의 이름이든)은 서비스 번들 내에서 고유해야 합니다. 사용자 정의 이름은 생성된 이름과의 충돌을 해결하는 데 사용해야 합니다.
  • 변형 사양 요구사항 (E501): 게시자가 변형이 여러 개인 유형에 사용자 정의 이름을 사용하는 경우 게시하는 변형을 명시적으로 지정해야 합니다.
  • 구독자의 게시자 존재 (E504): 정의된 모든 구독자에게는 지정된 유형 및 변형에 해당하는 게시자가 하나 이상 필요합니다.
  • 유효한 게시자 유형 (E601): 게시자는 기존 protobuf 메시지에 해당하는 유형을 참조해야 합니다.
  • 게시 주석 요구사항 (E602): 게시자가 참조하는 protobuf 메시지 유형에는 SdvPublication 주석이 포함되어야 합니다.
  • 유효한 변형 사용 (E606): 게시자가 변형(인스턴스)을 지정하는 경우 해당 변형은 protobuf에서 게시 유형에 정의된 instances_enum 내에 있어야 합니다.
  • 변형 사양 조건 (E607): 게시자는 게시 유형이 protobuf에서 instances_enum를 정의하는 경우에만 명시적 변형 (인스턴스)을 지정할 수 있습니다.
  • 주제 이름 지정 (E20D, E20F): 주제는 소문자 대시 케이스여야 하며 127자를 초과해서는 안 됩니다.
  • 주제 고유성 (E314): 주제는 모든 게시자에서 전역적으로 고유해야 합니다.
  • 용량 요구사항 (E406, E407): 용량은 필수이며 2 이상의 짝수여야 합니다.

구독자

이 섹션에서는 구독자 메시지 유형을 설명합니다.

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): 정의된 모든 구독자에 대해 지정된 게시 유형과 변형을 게시하는 해당 게시자가 하나 이상 있어야 합니다.
  • 유효한 구독 유형 (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 코드에 구현되어 있습니다. RPC 서비스에는 protobuf 서비스 정의에 정의된 대로 단항, 클라이언트 스트리밍, 서버 스트리밍 메서드가 포함될 수 있습니다. channel 필드는 통신 엔드포인트를 정의하며 필수입니다 (E409).

제약조건

  • 서비스 정의 (E603): RPC 서버는 기존 protobuf RPC service 값에 해당하는 service 값을 지정해야 합니다.
  • 서비스당 서버 제한 (E100): 단일 서비스 번들 내에서 특정 RPC service는 최대 하나의 서버 정의에 의해 제공될 수 있습니다.
  • 채널 이름 지정 (E20E): RPC 채널은 소문자 대시 케이스여야 합니다.
  • 채널 필수 (E409): RPC 채널은 필수입니다.
  • 채널 고유성 (E40B): RPC 채널은 하나의 서비스에서만 사용해야 합니다.

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"
}

설명

clientServiceBundle가 사용하는 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)이 제공되는 경우 스네이크 케이스 형식을 엄격하게 따라야 합니다.
    • 소문자 (a~z), 숫자 (0~9), 밑줄 (_)만 포함해야 합니다.
    • 연속된 밑줄 (__)이 포함되어서는 안 됩니다.
    • 밑줄로 시작할 수 없습니다.
    • 밑줄로 끝나면 안 됩니다.
  • 타겟 이름 고유성 (E301): 사용자 정의 build_cfg.target_name는 빌드 시스템 전체에서 고유해야 하며 다른 서비스 번들 정의에서 파생된 자동으로 생성된 타겟 이름과 충돌해서는 안 됩니다.