پیاده سازی منطق کسب و کار

  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 را برای تعامل با سایر سرویس‌ها فراخوانی کنید.

    زنگ زدگی

    1. با اجرای دستور زیر، یک پیاده‌سازی اسکلتی ایجاد کنید:

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

      اجرای vsidlc با فلگ --services ، یک فلگ ایجاد می‌کند که برای هر بسته سرویس، یک پیاده‌سازی Rust از نوع boilerplate ایجاد می‌کند. این کار، چارچوب لازم - شامل کد منبع ( main.rs ) و یک فایل پیکربندی ساخت ( Android.bp ) با تمام وابستگی‌ها - را فراهم می‌کند و امکان تبادل فوری پیام‌های پیش‌فرض را در حالی که شما بر پیاده‌سازی منطق اصلی کسب‌وکار تمرکز می‌کنید، فراهم می‌کند.

    2. برای هر بسته سرویس، پیاده‌سازی Rust را در مسیر زیر پیدا کنید:

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

    3. به طور پیش‌فرض، پیاده‌سازی تولید شده پیام‌هایی با مقادیر پیش‌فرض ایجاد می‌کند و آنها را بین ناشران و مشترکین یا کلاینت‌ها و سرورهای RPC ارسال می‌کند. برای تغییر این رفتار، نظرات TODO را در main.rs پیدا کنید و آنها را مطابق با تنظیمات خود تنظیم کنید. به عنوان مثال:

      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 خارج کنید.

    سی++

    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 جدید یا موجود ایجاد کنید:

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

قدم بعدی چیست؟

برای استقرار بسته‌های خدماتی خود، به بخش «ساخت و استقرار بسته‌های خدماتی» مراجعه کنید.