Implémenter la logique métier

  1. Vérifiez que votre répertoire de catalogue VSIDL contient les fichiers de compilation, protobuf et VSIDL nécessaires. Pour partir d'un exemple existant, vous trouverez un exemple de dossier de catalogue valide sous /system/software_defined_vehicle/samples/vsidl/stable/catalog.

    Exemple de structure de catalogue :

    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. Écrivez du code personnalisé pour implémenter votre logique métier.

    vsidlc génère des liaisons de middleware et un échafaudage de bundle de services (lib.rs, service_bundle.rs et main.rs) pour Rust. Si vous écrivez un bundle de services en C++, implémentez directement les interfaces de cycle de vie (libsdv_lifecycle_client_cpp) et de communication (libsdv_comms_cpp) :

    • Serveurs RPC (Rust) : implémentez les traits générés à partir de lib.rs.
    • Clients de publication, d'abonnement et RPC (Rust) : appelez les fonctions générées dans service_bundle.rs pour interagir avec d'autres services.
    • Cycle de vie et communication (C++) : sous-classez ServiceBundle et initialisez vos éditeurs, abonnés ou points de terminaison RPC dans onStart.

    Rust

    1. Générez un squelette d'implémentation en exécutant la commande suivante :

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

      L'exécution de vsidlc avec l'option --services génère une implémentation Rust réutilisable pour chaque bundle de services. Vous obtenez ainsi le code source (main.rs) et un fichier de configuration de compilation (Android.bp) avec toutes les dépendances. Votre bundle peut ainsi échanger des messages par défaut immédiatement, tandis que vous vous concentrez sur votre logique métier.

    2. Pour chaque bundle de services, recherchez l'implémentation Rust dans :

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

    3. Par défaut, l'implémentation générée crée des messages avec des valeurs par défaut et les envoie entre les éditeurs et les abonnés ou les clients et les serveurs RPC. Pour modifier ce comportement, recherchez les commentaires TODO dans main.rs et ajustez-les selon vos préférences. Exemple :

      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. Pour vous assurer que vos modifications apportées aux fichiers générés ne sont pas écrasées lors de la prochaine exécution de vsidlc, déplacez le dossier services hors du dossier /path/to/output.

    C++

    1. Créez un fichier d'en-tête, src/lib.hpp, avec une classe pour votre bundle de services :

      #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. Créez un fichier source, src/lib.cpp, avec l'implémentation de la 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. Créez une cible Soong de bibliothèque de bundle de services dans un fichier Android.bp nouveau ou existant :

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

Étape suivante

Pour déployer vos bundles de services, consultez Créer et déployer des bundles de services.