비즈니스 로직 구현

  1. VSIDL 카탈로그 디렉터리에 필요한 빌드, 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. 커스텀 코드를 작성하여 비즈니스 로직을 구현합니다.

    vsidlc는 Rust용 미들웨어 바인딩 및 서비스 번들 스캐폴딩(lib.rs, service_bundle.rs, main.rs)을 생성합니다. C++로 서비스 번들을 작성하는 경우 수명 주기(libsdv_lifecycle_client_cpp) 및 통신 (libsdv_comms_cpp) 인터페이스를 직접 구현합니다.

    • RPC 서버 (Rust): lib.rs에서 생성된 특성을 구현합니다.
    • 게시, 구독, RPC 클라이언트 (Rust): service_bundle.rs 내에서 생성된 함수를 호출하여 다른 서비스와 상호작용합니다.
    • 수명 주기 및 통신 (C++): ServiceBundle를 서브클래스로 지정하고 onStart에서 게시자, 구독자 또는 RPC 엔드포인트를 초기화합니다.

    Rust

    1. 다음을 실행하여 스켈레톤 구현을 생성합니다.

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

      --services 플래그를 사용하여 vsidlc를 실행하면 각 서비스 번들에 대한 상용구 Rust 구현이 생성됩니다. 이렇게 하면 소스 코드 (main.rs)와 모든 종속 항목이 포함된 빌드 구성 파일 (Android.bp)이 제공되므로 비즈니스 로직에 집중하는 동안 번들이 기본 메시지를 즉시 교환할 수 있습니다.

    2. 각 서비스 번들의 Rust 구현은 다음에서 찾을 수 있습니다.

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

    3. 기본적으로 생성된 구현은 기본값으로 메시지를 만들고 게시자와 구독자 또는 RPC 클라이언트와 서버 간에 전송합니다. 이 동작을 수정하려면 main.rs에서 TODO 주석을 찾아 원하는 대로 조정합니다. 예를 들면 다음과 같습니다.

      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. 다음에 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() {
          // 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. 새 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,
      }
      

다음 단계

서비스 번들을 배포하려면 서비스 번들 빌드 및 배포를 참조하세요.