1f857971dSopenharmony_ci/*
2f857971dSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f857971dSopenharmony_ci * you may not use this file except in compliance with the License.
5f857971dSopenharmony_ci * You may obtain a copy of the License at
6f857971dSopenharmony_ci *
7f857971dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f857971dSopenharmony_ci *
9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f857971dSopenharmony_ci * See the License for the specific language governing permissions and
13f857971dSopenharmony_ci * limitations under the License.
14f857971dSopenharmony_ci */
15f857971dSopenharmony_ci
16f857971dSopenharmony_ci//! Binding of native service implementation.
17f857971dSopenharmony_ci
18f857971dSopenharmony_ci#![allow(dead_code)]
19f857971dSopenharmony_ci#![allow(unused_variables)]
20f857971dSopenharmony_ci
21f857971dSopenharmony_ciuse std::ffi::{ c_char, c_int, CString };
22f857971dSopenharmony_ciuse std::os::fd::RawFd;
23f857971dSopenharmony_ciuse hilog_rust::{ error, hilog, HiLogLabel, LogType };
24f857971dSopenharmony_ciuse fusion_utils_rust::{ call_debug_enter, FusionResult, FusionErrorCode };
25f857971dSopenharmony_ci
26f857971dSopenharmony_ciconst LOG_LABEL: HiLogLabel = HiLogLabel {
27f857971dSopenharmony_ci    log_type: LogType::LogCore,
28f857971dSopenharmony_ci    domain: 0xD002220,
29f857971dSopenharmony_ci    tag: "FusionNativeService"
30f857971dSopenharmony_ci};
31f857971dSopenharmony_ci
32f857971dSopenharmony_ci/// Represent service instance.
33f857971dSopenharmony_ci#[repr(C)]
34f857971dSopenharmony_cistruct NativeService {
35f857971dSopenharmony_ci    _private: [u8; 0],
36f857971dSopenharmony_ci}
37f857971dSopenharmony_ci
38f857971dSopenharmony_ciextern "C" {
39f857971dSopenharmony_ci    /// Call to create an instance of service.
40f857971dSopenharmony_ci    fn NativeServiceNew() -> *mut NativeService;
41f857971dSopenharmony_ci    /// Call to increase reference count of the service instance.
42f857971dSopenharmony_ci    fn NativeServiceRef(service: *mut NativeService) -> *mut NativeService;
43f857971dSopenharmony_ci    /// Call to decrease reference count of the service instance.
44f857971dSopenharmony_ci    fn NativeServiceUnref(service: *mut NativeService) -> *mut NativeService;
45f857971dSopenharmony_ci    /// Called on dump operation.
46f857971dSopenharmony_ci    fn NativeServiceOnDump(service: *mut NativeService);
47f857971dSopenharmony_ci    /// Called when service is starting.
48f857971dSopenharmony_ci    fn NativeServiceOnStart(service: *mut NativeService);
49f857971dSopenharmony_ci    /// Called when service is stopping.
50f857971dSopenharmony_ci    fn NativeServiceOnStop(service: *mut NativeService);
51f857971dSopenharmony_ci    /// Call to allocate socket pair for client/server communication.
52f857971dSopenharmony_ci    fn NativeServiceAllocSocketFd(service: *mut NativeService,
53f857971dSopenharmony_ci        program_name: *const c_char, module_type: i32,
54f857971dSopenharmony_ci        client_fd: *mut i32, token_type: *mut i32) -> i32;
55f857971dSopenharmony_ci}
56f857971dSopenharmony_ci
57f857971dSopenharmony_cipub struct FusionNativeService {
58f857971dSopenharmony_ci    service: *mut NativeService,
59f857971dSopenharmony_ci}
60f857971dSopenharmony_ci
61f857971dSopenharmony_ciimpl FusionNativeService {
62f857971dSopenharmony_ci    pub fn is_valid(&self) -> bool
63f857971dSopenharmony_ci    {
64f857971dSopenharmony_ci        !self.service.is_null()
65f857971dSopenharmony_ci    }
66f857971dSopenharmony_ci
67f857971dSopenharmony_ci    pub fn on_start(&self)
68f857971dSopenharmony_ci    {
69f857971dSopenharmony_ci        call_debug_enter!("FusionNativeService:on_start");
70f857971dSopenharmony_ci        unsafe { NativeServiceOnStart(self.service) };
71f857971dSopenharmony_ci    }
72f857971dSopenharmony_ci
73f857971dSopenharmony_ci    pub fn on_stop(&self)
74f857971dSopenharmony_ci    {
75f857971dSopenharmony_ci        call_debug_enter!("FusionNativeService:on_stop");
76f857971dSopenharmony_ci        unsafe { NativeServiceOnStop(self.service) };
77f857971dSopenharmony_ci    }
78f857971dSopenharmony_ci
79f857971dSopenharmony_ci    pub fn alloc_socket_fd(&self, program_name: &str, module_type: i32,
80f857971dSopenharmony_ci        client_fd: &mut RawFd, token_type: &mut i32) -> FusionResult<()>
81f857971dSopenharmony_ci    {
82f857971dSopenharmony_ci        call_debug_enter!("FusionNativeService:alloc_socket_fd");
83f857971dSopenharmony_ci        let mut fd: c_int = 0;
84f857971dSopenharmony_ci
85f857971dSopenharmony_ci        let ret = unsafe {
86f857971dSopenharmony_ci            NativeServiceAllocSocketFd(self.service, program_name.as_ptr() as *const c_char,
87f857971dSopenharmony_ci                module_type, &mut fd, token_type)
88f857971dSopenharmony_ci        };
89f857971dSopenharmony_ci        if ret == 0 {
90f857971dSopenharmony_ci            *client_fd = fd as RawFd;
91f857971dSopenharmony_ci            Ok(())
92f857971dSopenharmony_ci        } else {
93f857971dSopenharmony_ci            error!(LOG_LABEL, "Failed to allocate socket pair");
94f857971dSopenharmony_ci            Err(FusionErrorCode::Fail)
95f857971dSopenharmony_ci        }
96f857971dSopenharmony_ci    }
97f857971dSopenharmony_ci}
98f857971dSopenharmony_ci
99f857971dSopenharmony_ciimpl Default for FusionNativeService {
100f857971dSopenharmony_ci    fn default() -> Self
101f857971dSopenharmony_ci    {
102f857971dSopenharmony_ci        Self {
103f857971dSopenharmony_ci            service: unsafe {
104f857971dSopenharmony_ci                NativeServiceNew()
105f857971dSopenharmony_ci            },
106f857971dSopenharmony_ci        }
107f857971dSopenharmony_ci    }
108f857971dSopenharmony_ci}
109f857971dSopenharmony_ci
110f857971dSopenharmony_ciimpl Drop for FusionNativeService {
111f857971dSopenharmony_ci    fn drop(&mut self)
112f857971dSopenharmony_ci    {
113f857971dSopenharmony_ci        unsafe {
114f857971dSopenharmony_ci            NativeServiceUnref(self.service);
115f857971dSopenharmony_ci        }
116f857971dSopenharmony_ci    }
117f857971dSopenharmony_ci}
118f857971dSopenharmony_ci
119f857971dSopenharmony_ciimpl Clone for FusionNativeService {
120f857971dSopenharmony_ci    fn clone(&self) -> Self
121f857971dSopenharmony_ci    {
122f857971dSopenharmony_ci        Self {
123f857971dSopenharmony_ci            service: unsafe {
124f857971dSopenharmony_ci                NativeServiceRef(self.service)
125f857971dSopenharmony_ci            },
126f857971dSopenharmony_ci        }
127f857971dSopenharmony_ci    }
128f857971dSopenharmony_ci}
129