实现业务逻辑

  1. 验证您的 VSIDL 目录是否包含必要的 build、protobuf 和 VSIDL 文件。如需从现有示例入手,您可以在 /system/software_defined_vehicle/samples/vsidl/stable/catalog 下找到有效目录文件夹的示例。

    目录结构示例:

    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. 编写自定义代码以实现您的业务逻辑:

    • RPC 服务器:实现 lib.rs 中的特征。
    • 发布和订阅以及 RPC 客户端:调用 service_bundle.rs 中的生成函数以与其他服务互动。

    Rust

    1. 通过运行以下命令生成框架实现:

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

      使用 --services 标志运行 vsidlc 会为每个服务软件包生成一个样板 Rust 实现。 这提供了必要的脚手架(包括源代码 (main.rs) 和包含所有依赖项的 build 配置文件 (Android.bp)),让您在专注于实现核心业务逻辑的同时,能够立即交换默认消息。

    2. 对于每个服务软件包,请在以下位置找到 Rust 实现:

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

    3. 默认情况下,生成的实现会创建具有默认值的消息,并在发布者和订阅者或 RPC 客户端和服务器之间发送这些消息。如需修改此行为,请在 main.rs 中找到 TODO 注释,并根据您的偏好进行调整。例如:

      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. 为确保您对生成文件的修改在下次运行 vsidlc 时不会被覆盖,请将 services 文件夹移出 /path/to/output 文件夹。

    C++

    1. 创建一个新头文件 src/lib.hpp, 其中包含服务软件包的类:

      #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. 创建一个新源文件, src/lib.cpp, 其中包含类实现:

      #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. 在新的或现有的 Android.bp文件中创建一个服务软件包库 Soong 目标:

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

后续步骤

如需部署服务软件包,请参阅构建和部署服务软件包