Implementare la logica di business

  1. Verifica che la directory del catalogo VSIDL contenga i file di build, protobuf e VSIDL necessari. Per iniziare da un esempio esistente, puoi trovare un esempio di cartella del catalogo valida in /system/software_defined_vehicle/samples/vsidl/stable/catalog.

    Struttura di esempio del catalogo:

    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. Scrivi codice personalizzato per implementare la logica di business:

    • Server RPC: implementa i tratti di lib.rs.
    • Client RPC e di pubblicazione/sottoscrizione: chiama le funzioni generate all'interno di service_bundle.rs per interagire con altri servizi.

    Ruggine

    1. Genera un'implementazione scheletrica eseguendo:

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

      L'esecuzione di vsidlc con il flag --services genera un'implementazione Rust standard per ogni bundle di servizi. In questo modo viene fornita l'impalcatura necessaria, inclusi il codice sorgente (main.rs) e un file di configurazione di compilazione (Android.bp) con tutte le dipendenze, consentendo lo scambio immediato di messaggi predefiniti mentre ti concentri sull'implementazione della logica di business principale.

    2. Per ogni pacchetto di servizi, trova l'implementazione Rust in:

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

    3. Per impostazione predefinita, l'implementazione generata crea messaggi con valori predefiniti e li invia tra publisher e sottoscrittori o client e server RPC. Per modificare questo comportamento, trova i commenti TODO in main.rs e modificali in base alle tue preferenze. Ad esempio:

      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. Per assicurarti che le modifiche apportate ai file generati non vengano sovrascritte la volta successiva che esegui vsidlc, sposta la cartella services fuori dalla cartella /path/to/output.

    C++

    1. Crea un nuovo file di intestazione, src/lib.hpp, con una classe per il bundle di servizi:

      #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. Crea un nuovo file di origine, src/lib.cpp, con l'implementazione della 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() {
          // Dynamic resources(sockets, files, etc) should be allocated 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 phase requires the service bundle to delete the dynamic resources
          // (sockets, files, etc) that were previously 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. Crea un target Soong della libreria di bundle di servizi in un file Android.bp nuovo o esistente:

      // 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,
      }
      

Passaggi successivi

Per eseguire il deployment dei bundle di servizi, vedi Creare ed eseguire il deployment dei bundle di servizi.