Implementar a lógica de negócios

  1. Verifique se o diretório do catálogo do VSIDL tem os arquivos de build, protobuf e VSIDL necessários. Para começar com uma amostra, encontre um exemplo de pasta de catálogo válida em /system/software_defined_vehicle/samples/vsidl/stable/catalog.

    Exemplo de estrutura de catálogo:

    my_catalog/
    ├── Android.bp          # Defines rust_protobuf modules for .proto files
    ├── types.proto         # Protobuf message / RPC service definitions
    └── architecture.vsidl  # VSIDL service bundle definitions
    
  2. Escreva um código personalizado para implementar sua lógica de negócios.

    O vsidlc gera vinculações de middleware e scaffolding de pacote de serviços (lib.rs, service_bundle.rs e main.rs) para Rust. Se você escrever um pacote de serviços em C++, implemente as interfaces de ciclo de vida (libsdv_lifecycle_client_cpp) e comunicação (libsdv_comms_cpp) diretamente:

    • Servidores RPC (Rust): implemente as características geradas de lib.rs.
    • Clientes de publicação, assinatura e RPC (Rust): chame as funções geradas em service_bundle.rs para interagir com outros serviços.
    • Ciclo de vida e comunicação (C++): crie uma subclasse de ServiceBundle e inicialize seus editores, assinantes ou endpoints RPC em onStart.

    Rust

    1. Gere uma implementação de esqueleto executando:

      vsidlc -c /path/to/catalog -o /path/to/output --services
      

      A execução de vsidlc com a flag --services gera uma implementação padrão do Rust para cada pacote de serviço. Isso fornece o código-fonte (main.rs) e um arquivo de configuração do build (Android.bp) com todas as dependências, para que seu pacote possa trocar mensagens padrão imediatamente enquanto você se concentra na lógica de negócios.

    2. Para cada pacote de serviços, encontre a implementação do Rust em:

      /path/to/output/services/ServiceBundleName/src/main.rs.

    3. Por padrão, a implementação gerada cria mensagens com valores padrão e as envia entre editores e assinantes ou clientes e servidores RPC. Para modificar esse comportamento, encontre os comentários TODO em main.rs e ajuste-os de acordo com suas preferências. Exemplo:

      rust async fn handle_tire_pressure_range_unique_publisher( publisher: sdv::mw::Publisher<TirePressureRange>, ) { loop { // TODO: Modify the frequency of publishing messages here. sleep(Duration::from_secs(1)).await; // TODO: Modify the message content here. let message = TirePressureRange::default(); info!("Publishing on TirePressureRange#UNIQUE"); publisher.publish(&message).unwrap(); } }

    4. Para garantir que as modificações nos arquivos gerados não sejam substituídas na próxima vez que o vsidlc for executado, mova a pasta services para fora da pasta /path/to/output.

    C++

    1. Crie um novo arquivo principal, src/lib.hpp, com uma classe para o pacote de serviços:

      #pragma once
      #include <sdv/service_bundle.h>
      #include <sdv/context.hpp>
      
      namespace com::sdv::oem::service_bundle {
      
      // Sample implementation of the service bundle interface.
      class ServiceBundleName : public android::sdv::service_bundle::ServiceBundle {
      public:
          ServiceBundleName(sdv_comms::ctx::Context context);
          ~ServiceBundleName();
          void onStart() override;
          void onStop() override;
      };
      }  // namespace com::sdv::oem::service_bundle
      
    2. Crie um novo arquivo de origem, src/lib.cpp, com a implementação da classe:

      #include "src/lib.hpp"
      #include <sdv/sb_macro.h>
      #include <iostream>
      using com::sdv::oem::service_bundle::ServiceBundleName;
      
      // Register the new service bundle.
      REGISTER_SERVICE_BUNDLE(ServiceBundleName);
      
      // Sample implementation of the service bundle interface.
      namespace com::sdv::oem::service_bundle {
      // Creates a new instance of the ServiceBundleName.
      // Called when service bundle is created by the system.
      // Context object is provided as a parameter that gives access to the
      // communication stack APIs.
      ServiceBundleName::ServiceBundleName([[maybe_unused]] sdv_comms::ctx::Context context) :
        ServiceBundle(context) {
          // Memory allocations and static data loading should be done as
          // part of this method.
          //
          // Loading of the dynamic resources (sockets, files, etc)
          // is strongly discouraged due to possible Suspend-to-RAM scenario.
          //
          // The dynamic data can be loaded in the onStart method.
      }
      
      // Called when the service bundle is started by the system.
      void ServiceBundleName::onStart() {
          // Allocate dynamic resources (sockets, files, publishers, and
          // subscribers such as TirePressureRange#UNIQUE) during this call.
      }
      
      // Called when the service bundle is stopped by the system in preparation
      // for shutdown or suspend to RAM/Disc.
      void ServiceBundleName::onStop() {
          // Stop active publishing loops and release the dynamic resources
          // that were allocated in the onStart method.
      }
      
      // Called when the service bundle is destroyed by the system.
      ServiceBundleName::~ServiceBundleName() {
          // Static resources deallocation needs to be implemented in the destructor.
      }
      }  // namespace com::sdv::oem::service_bundle
      
    3. Crie um destino do Soong da biblioteca de pacotes de serviços em um arquivo Android.bp novo ou atual:

      // Service bundle library.
      cc_library_shared {
        name: "libservice_bundle",
        srcs: ["src/lib.cpp",],
        // Allows the library to be available inside APEX.
        apex_available: [
            "//apex_available:platform",
            "//apex_available:anyapex",
        ],
        shared_libs: [
          // Service Bundle lifecycle C++ API.
          "libsdv_lifecycle_client_cpp",
          // commstack library that provides context object reference
          "libsdv_comms_cpp",
        ],
      
        // Service bundle package is packed into /product apexes.
        product_specific: true,
      }
      

A seguir

Para implantar os pacotes de serviços, consulte Criar e implantar pacotes de serviços.