Dostawca VSIDL na potrzeby odbicia

Dostawca VSIDL to zestaw bibliotek i narzędzi, które umożliwiają pakietom usług udostępnianie metadanych zadeklarowanych w VSIDL agentom platformy SDV (diagnostyka, dane telemetryczne i SOME/IP).

W szczególności dostawca VSIDL umożliwia agentom SDV wykrywanie tych metadanych:

Przewodnik po dostawcy VSIDL dla deweloperów pakietów usług

Biblioteka dostawcy VSIDL wykonuje te operacje:

  • lokalizuje pliki w 2 określonych miejscach:
    • w Apexach w ścieżkach zdefiniowanych w sdv_service_bundle_metadata;
    • w obrazie w ścieżkach statycznych;
  • inicjuje wywołania RPC, aby wysyłać zapytania do interfejsu API na agentach znajdujących się na tych samych lub różnych maszynach wirtualnych.

Rysunek 1.Omówienie dostawcy VSIDL.

Jeśli tworzysz pakiet usług, nie musisz znać szczegółów biblioteki dostawcy VSIDL. Wystarczy, że wykonasz te czynności, które umożliwią dostawcy VSIDL znajdowanie potrzebnych plików w czasie działania.

Generowanie konfiguracji środowiska wykonawczego dla katalogu

Wszystkie 3 typy plików (schematy vsidl, deklaracje diagnostyczne, mapowania someip) są generowane za pomocą narzędzia vsidl_rc_generator.

Użyj narzędzia binarnego hosta vsidl_rc_generator z tymi samymi parametrami co w przypadku vsidlc oraz z tymi dodatkowymi parametrami:

  • --variant runtime-config-prebuilts
  • --filegroup do określenia nazwy docelowej grupy plików, która zawiera wszystkie pliki katalogu (w tym Android.bp).

Dla porównania odpowiednie parametry vsidlc to:

  • --catalog-path do określenia ścieżki głównej katalogu;
  • --dependency-catalog-path do określenia katalogów zależnych;
  • -- -path do określenia miejsca, w którym ma zostać zapisany plik Android.bp ze wszystkimi wygenerowanymi celami genrule i prebuilt_etc.

Generator utworzy plik Android.bp z odpowiednimi celami genrule i prebuilt_etc. Oprócz wygenerowanych bloków docelowych w Android.bp będą też komentarze wskazujące zamierzone użycie poszczególnych celów.

Aktualizowanie pliku Android.bp APEX

Jak wskazują komentarze w wygenerowanym pliku Android.bp:

// Usage: add the following line to ... declaration

Te cele (poniżej wskazanych komentarzy Usage) należy dodać do pliku Android.bp, który definiuje Apex:

apex {
    name: "some_apex_name",
    ...
    prebuilts: [
      // ADD THE prebuilt_etc TARGETS HERE
    ],
    ...

}

Aktualizowanie pliku sdv_service_bundles_manifest.textproto APEX

W blokach sdv_service_bundle_metadata plików sdv_service_bundles_manifest.textproto Apex musisz zdefiniować (tylko w przypadku odpowiednich ścieżek):

sdv_service_bundle_metadata {
    ...
    vsidl_schemas_path: "etc/vsidl_provider/SomeFile-vsidl-config.binpb"
    diagnostics_config_path: "etc/vsidl_provider/SomeFile-diag-config.binpb"
    external_protocol_mapping_path: "etc/vsidl_provider/someip-config.binpb"
    ...
}

Nie definiuj własnych ścieżek. Zamiast tego skopiuj ścieżki widoczne w komentarzach wygenerowanego pliku Android.bp, które są oznaczone jako:

// + vsidl_schemas_path:
// + diagnostics_config_path:
// + external_protocol_mapping_path:

Dzięki temu instancja dostawcy VSIDL może wysyłać zapytania ze ścieżek określonych w odpowiednich wpisach sdv_service_bundle_metadata.

Dodawanie celów do obrazu

Wygenerowane pliki Android.bp generują też cele, które można wczytać bezpośrednio do obrazu. Komentarze wskazują też cele, które mają być używane w ten sposób:

// Usage: add this target to the VM image.

Wygenerowany cel prebuilt_etc umieści pliki wygenerowane za pomocą genrule w określonej lokalizacji w obrazie. Musisz uwzględnić cele prebuilt_etc w odpowiednich plikach *.mk (np. device/google/sdv/sdv_core_base/sdv_samples_automotive_services.mk).

Przewodnik po dostawcy VSIDL dla deweloperów platformy

Jeśli tworzysz agenta SDV, który wymaga możliwości odbicia, możesz użyć biblioteki dostawcy VSIDL.

Interfejs API biblioteki dostawcy VSIDL zawiera te funkcje:

    async fn get_publication_descriptor(
        &self,
        source_fqin: &ServiceFqin,
        unit_type: &UnitType,
    ) -> SdvResult<PublicationDescriptor>;

    async fn get_rpc_method_descriptor(
        &self,
        source_fqin: &ServiceFqin,
        unit_type: &UnitType,
        method_name: &str,
    ) -> SdvResult<RpcMethodDescriptor>;

    async fn get_message_descriptor(
        &self,
        source_fqin: &ServiceFqin,
        message_name: &str,
    ) -> SdvResult<MessageDescriptor>;

    async fn get_someip_mappings(&self, source_fqin: &ServiceFqin)
        -> SdvResult<Vec<SomeIpMapping>>;

    async fn get_diagnostics_declaration(
        &self,
        fqin: &ServiceFqin,
    ) -> SdvResult<DiagnosticsDeclaration>;

    async fn subscribe_availability_change_by_vm(
        &self,
        vm_name: &str,
    ) -> SdvResult<AvailabilityStream>;

gdzie

pub type AvailabilityStream = Pin<Box<dyn Stream<Item = AvailabilityChangeEvent> + Send>>;

Wszystkie funkcje są wysyłane za pomocą parametru source_fqin. Dzięki temu różne FQIN używające tego samego unit_type lub message_name zwracają prawidłowe dane. Ten parametr kieruje bibliotekę dostawcy VSIDL do konkretnego APEX, który zawiera najdokładniejszy schemat wiadomości. Jest to konieczne, ponieważ APEX są aktualizowane niezależnie i mogą używać różnych schematów dla tej samej wiadomości lub usługi protobuf.

Używanie funkcji get_message_descriptor

Zwraca ona wyłącznie pub struct MessageDescriptor z zewnętrznego pakietu, który jest używany do odbicia. MessageDescriptor to fragment metadanych, który umożliwia odbicie, czyli dynamiczne sprawdzanie i manipulowanie wiadomościami protobuf w czasie działania.

Używanie funkcji get_publication_descriptor

Ta funkcja zwraca PublicationDescriptor, czyli:

pub struct PublicationDescriptor {
    /// Message descriptor for publication.
    pub message_descriptor: MessageDescriptor,

    /// Information about the size of the publication message.
    pub size_metadata: SizeMetadata,
}

Pole size_metadata zawiera informacje o rozmiarze i ograniczeniach wiadomości publikacji. Te metadane są wyprowadzane z konfiguracji VSIDL.

pub struct SizeMetadata {
    /// Message size in bytes.
    pub message_size: u32,

    /// Message count.
    pub message_count: u32,

    /// VSIDL-declared size constraints for the message fields.
    pub field_size_constraints: HashMap<String, FieldSizeConstraint>,
}

pub struct FieldSizeConstraint {
    /// Max number of repeated fields allowed for the field.
    pub repeated_max_count: Option<u32>,

    /// Max size of variable sized types (string, bytes) in bytes.
    pub variable_type_max_size: Option<u32>,
}

Używanie funkcji get_rpc_method_descriptor

Ta funkcja zwraca RpcMethodDescriptor, czyli:

pub struct RpcMethodDescriptor {
    /// Message descriptor for RPC request.
    pub request_message: Option<MessageDescriptor>,

    /// Message descriptor for RPC response.
    pub response_message: Option<MessageDescriptor>,
}

Ta struktura zawiera MessageDescriptor zarówno dla żądania, jak i odpowiedzi metody RPC.

Używanie funkcji get_someip_mappings

Jest to funkcja służąca do pobierania lokalnych mapowań usług SOME/IP, które są zdefiniowane w core_services/vsidl/protos/sdv/someip/v1/someip.proto.

Używanie funkcji get_diagnostics_declaration

Jest to funkcja służąca do pobierania deklaracji diagnostycznych, które są zdefiniowane w core_services/vsidl/protos/sdv/diagnostics/v1/diagnostics_syntax.proto.

Używanie funkcji subscribe_availability_change_by_vm

Ta funkcja zwraca strumień dostępności dla określonej maszyny wirtualnej, który służy jako krytyczny mechanizm rezerwowy. Używaj jej, gdy standardowe wywołania interfejsu API dostawcy VSIDL kończą się błędem SdvStatusCode::Unavailable, co pozwala systemowi efektywnie czekać na powrót interfejsu dostawcy VSIDL do trybu online.

Kluczowe zachowania tej funkcji:

  • Natychmiastowe emitowanie: po subskrypcji strumień emituje bieżący stan dostępności docelowej maszyny wirtualnej.
  • Parzystość zachowań: wynikowy strumień zachowuje się identycznie jak funkcja subscribe_service_unit_change_by_name używana przez ServiceDiscoveryManager.

Agent dostawcy VSIDL

Każda maszyna wirtualna ma własnego agenta dostawcy VSIDL, który jest zasadniczo serwerem RPC przekazującym żądania do interfejsu API dostawcy VSIDL (lokalnej instancji biblioteki w agencie). Agent służy do wysyłania zapytań do dostawcy VSIDL na innej maszynie wirtualnej, czyli usługa na jednej maszynie wirtualnej może wysyłać zapytania o metadane VSIDL z innej maszyny wirtualnej za pomocą tego agenta.

Używanie interfejsu API w bazie kodu

SOMEIP:

  • get_publication_descriptor (używane są wszystkie pola struktury)
  • get_rpc_method_descriptor (używane są wszystkie pola struktury)
  • get_someip_mappings

Dane telemetryczne:

  • get_publication_descriptor (używane jest tylko pole message_descriptor)
  • get_rpc_method_descriptor (używane są wszystkie pola struktury)

Diagnostyka:

  • get_message_descriptor
  • get_diagnostics_declaration

Różne warianty z różnymi źródłami danych i priorytetami źródeł znajdziesz w core_services/vsidl/provider/src/vsidl_provider.rs.

Pakiet vsidl_provider oferuje kilka funkcji publicznych do tworzenia instancji dostawcy dostosowanych do różnych agentów SDV. Każda konfiguracja określa unikalny łańcuch źródeł danych do rozwiązywania danych związanych z VSIDL. W tabeli opisano zachowanie każdej funkcji konstruktora:

Funkcja konstruktoraTyp danychWyszukiwanie źródła danych (i kolejność)
new_for_vsidl_provider_agent SomeIpAPEX
DiagnosticsAPEX
VsidlSchemasAPEX, pliki
new_for_diagnostics_agentDiagnosticsAgent (zdalny), APEX
VsidlSchemasPliki
new_for_someip_broker_agent SomeIpAPEX
VsidlSchemasPliki
new_for_telemetry_agentVsidlSchemasAgent (zdalny i lokalny)
new_for_integration_test SomeIpAgent (zdalny i lokalny)
DiagnosticsAgent (zdalny i lokalny)
VsidlSchemasAgent (zdalny i lokalny)

Źródła danych w tabeli odnoszą się do wywołań na rysunku 1.