Provedor VSIDL para reflexão

O provedor VSIDL é um conjunto de bibliotecas e ferramentas que permitem que pacotes de serviços forneçam metadados declarados em VSIDL aos agentes da plataforma SDV (diagnóstico, telemetria e SOME/IP).

Em particular, o provedor VSIDL permite que os agentes de SDV descubram os seguintes metadados:

Guia do provedor VSIDL para desenvolvedores de pacotes de serviços

A biblioteca do provedor VSIDL executa as seguintes operações:

  • Localiza arquivos em dois lugares específicos:
    • Em Apexes em caminhos definidos em sdv_service_bundle_metadata.
    • Na imagem em caminhos estáticos.
  • Inicia chamadas de RPC para consultar a API em agentes que residem nas mesmas ou em VMs diferentes.

Figura 1.Visão geral do provedor VSIDL.

Se você estiver desenvolvendo um pacote de serviços, não precisará saber os detalhes da biblioteca do provedor VSIDL. Basta seguir estas etapas, que permitem que o provedor VSIDL encontre os arquivos necessários no momento da execução.

Gerar configurações de ambiente de execução para o catálogo

Todos os três tipos de arquivos (esquemas vsidl, declarações de diagnóstico, mapeamentos someip) são gerados pela ferramenta vsidl_rc_generator.

Use a ferramenta binária de host vsidl_rc_generator com os mesmos parâmetros usados para vsidlc e os seguintes parâmetros adicionais:

  • --variant runtime-config-prebuilts
  • --filegroup para especificar o nome de destino do grupo de arquivos que contém todos os arquivos do catálogo (incluindo o Android.bp).

Para referência, os parâmetros vsidlc relevantes são os seguintes:

  • --catalog-path para especificar o caminho raiz do catálogo.
  • --dependency-catalog-path para especificar catálogos dependentes.
  • -- -path para especificar onde gravar o Android.bp com todos os destinos genrule e prebuilt_etc gerados.

O gerador vai criar um arquivo Android.bp com destinos genrule e prebuilt_etc relevantes. Além dos blocos de destino gerados em Android.bp, haverá comentários que indicam o uso pretendido dos respectivos destinos.

Atualizar o Android.bp do APEX

Conforme indicado pelos comentários do arquivo Android.bp gerado, que dizem:

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

Adicione essas metas (abaixo dos comentários Usage indicados) ao Android.bp que define o Apex:

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

}

Atualize o sdv_service_bundles_manifest.textproto do APEX

Nos blocos sdv_service_bundle_metadata dos arquivos sdv_service_bundles_manifest.textproto do Apex, defina (somente para caminhos aplicáveis):

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

Não defina seus próprios caminhos. Em vez disso, copie os caminhos mostrados nos comentários do arquivo Android.bp gerado, encontrados como:

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

Isso permite que a instância do provedor VSIDL consulte os caminhos especificados pelas respectivas entradas sdv_service_bundle_metadata.

Adicionar destinos à imagem

Os arquivos Android.bp gerados também criam destinos que podem ser carregados diretamente na imagem. Os comentários também indicam os destinos que devem ser usados dessa forma, por:

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

O destino prebuilt_etc gerado vai colocar os arquivos criados com os genrules em um local pré-especificado na imagem. É necessário incluir os destinos prebuilt_etc nos respectivos arquivos *.mk (por exemplo, device/google/sdv/sdv_core_base/sdv_samples_automotive_services.mk).

Guia do provedor VSIDL para desenvolvedores de plataforma

Em geral, se você estiver desenvolvendo um agente de SDV que precise de recursos de reflexão, use a biblioteca de provedores VSIDL.

A API da biblioteca do provedor VSIDL contém as seguintes funções:

    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>;

onde

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

Todas as funções são consultadas usando um parâmetro source_fqin. Isso garante que diferentes FQINs que usam o mesmo unit_type ou message_name retornem os dados corretos. O parâmetro direciona a biblioteca do provedor VSIDL para o APEX específico que contém o esquema de mensagem mais preciso. Isso é necessário porque os APEXs são atualizados de forma independente e podem usar esquemas diferentes para a mesma mensagem ou serviço do protobuf.

Uso da função get_message_descriptor

Isso retorna apenas o pub struct MessageDescriptor da caixa externa usada para reflexão. Um MessageDescriptor é um metadado que permite a reflexão, possibilitando a inspeção e manipulação dinâmica de mensagens protobuf durante a execução.

Uso da função get_publication_descriptor

Essa função retorna um PublicationDescriptor, que é:

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

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

O campo size_metadata contém informações sobre o tamanho e as restrições de uma mensagem de publicação. Esses metadados são derivados da configuração do 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>,
}

Uso da função get_rpc_method_descriptor

Essa função retorna um RpcMethodDescriptor, que é:

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

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

Essa struct contém o MessageDescriptor para as mensagens de solicitação e resposta do método RPC.

Uso da função get_someip_mappings

Essa é uma função para recuperar mapeamentos de serviços SOME/IP locais, que são definidos em core_services/vsidl/protos/sdv/someip/v1/someip.proto.

Uso da função get_diagnostics_declaration

Essa é uma função para recuperar declarações de diagnóstico, que são definidas em core_services/vsidl/protos/sdv/diagnostics/v1/diagnostics_syntax.proto

Uso da função subscribe_availability_change_by_vm

Essa função retorna um fluxo de disponibilidade para uma máquina virtual especificada, servindo como um mecanismo de fallback crítico. Use quando as chamadas padrão da API do provedor VSIDL falharem com um erro SdvStatusCode::Unavailable, permitindo que o sistema aguarde eficientemente que a interface do provedor VSIDL volte a ficar on-line.

Os principais comportamentos dessa função incluem:

  • Emissão imediata:após a assinatura, o stream emite o status de disponibilidade atual da máquina virtual de destino.
  • Paridade comportamental:o fluxo resultante se comporta de maneira idêntica à função subscribe_service_unit_change_by_name usada pelo ServiceDiscoveryManager.

Agente do provedor VSIDL

Cada VM executa o próprio agente do provedor VSIDL, que é essencialmente um servidor RPC encaminhando solicitações na API do provedor VSIDL (de uma instância local da biblioteca no agente). O agente é usado para consultar o provedor VSIDL em uma VM diferente. Ou seja, um serviço em uma VM pode consultar metadados VSIDL de outra VM usando esse agente.

Uso da API na base de código

SOMEIP:

  • get_publication_descriptor (todos os campos de estrutura são usados)
  • get_rpc_method_descriptor (todos os campos de estrutura são usados)
  • get_someip_mappings

Telemetria:

  • get_publication_descriptor (apenas o campo message_descriptor é usado)
  • get_rpc_method_descriptor (todos os campos de estrutura são usados)

Diagnóstico:

  • get_message_descriptor
  • get_diagnostics_declaration

As várias opções com as várias fontes de dados e prioridades de origem podem ser encontradas em core_services/vsidl/provider/src/vsidl_provider.rs.

O crate vsidl_provider oferece várias funções públicas para criar instâncias de provedor adaptadas para diferentes agentes de SDV. Cada configuração especifica uma cadeia exclusiva de fontes de dados para resolver dados relacionados ao VSIDL. A tabela descreve o comportamento de cada função construtora:

Função construtoraTipo de dadoPesquisa (e ordem) da fonte de dados
new_for_vsidl_provider_agent SomeIpAPEXes
DiagnosticsAPEXes
VsidlSchemasAPEXes, arquivos
new_for_diagnostics_agentDiagnosticsAgente (remoto), APEXes
VsidlSchemasArquivos
new_for_someip_broker_agent SomeIpAPEXes
VsidlSchemasArquivos
new_for_telemetry_agentVsidlSchemasAgente (remoto e local)
new_for_integration_test SomeIpAgente (remoto e local)
DiagnosticsAgente (remoto e local)
VsidlSchemasAgente (remoto e local)

As fontes de dados da tabela se referem a chamadas na Figura 1.