1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 //! Implementation of device status service.
17 
18 #![allow(dead_code)]
19 #![allow(unused_variables)]
20 
21 use std::ffi::{ c_char, CString };
22 use std::os::fd::RawFd;
23 use std::sync::{ Mutex, Once };
24 use hilog_rust::{ error, hilog, HiLogLabel, LogType };
25 use fusion_utils_rust::{ call_debug_enter, FusionResult, FusionErrorCode };
26 use crate::binding::FusionNativeService;
27 
28 const LOG_LABEL: HiLogLabel = HiLogLabel {
29     log_type: LogType::LogCore,
30     domain: 0xD002220,
31     tag: "FusionService"
32 };
33 
34 #[derive(Default)]
35 struct FusionServiceImpl {
36     native_service: FusionNativeService,
37 }
38 
39 impl FusionServiceImpl {
on_start(&self)40     fn on_start(&self)
41     {
42         call_debug_enter!("FusionServiceImpl:on_start");
43         self.native_service.on_start();
44     }
45 
on_stop(&self)46     fn on_stop(&self)
47     {
48         call_debug_enter!("FusionServiceImpl:on_stop");
49         self.native_service.on_stop();
50     }
51 
alloc_socket_fd(&self, program_name: &str, module_type: i32, client_fd: &mut RawFd, token_type: &mut i32) -> FusionResult<()>52     fn alloc_socket_fd(&self, program_name: &str, module_type: i32,
53         client_fd: &mut RawFd, token_type: &mut i32) -> FusionResult<()>
54     {
55         call_debug_enter!("FusionServiceImpl:alloc_socket_fd");
56         self.native_service.alloc_socket_fd(program_name, module_type, client_fd, token_type)
57     }
58 }
59 
60 /// Proxy for device status service.
61 #[derive(Default)]
62 pub struct FusionService {
63     service_impl: Mutex<FusionServiceImpl>,
64 }
65 
66 impl FusionService {
67     /// Get the single instance of [`FusionService`].
get_instance() -> Option<&'static Self>68     pub fn get_instance() -> Option<&'static Self> {
69         static mut FUSION_SERVICE_PROXY: Option<FusionService> = None;
70         static INIT_ONCE: Once = Once::new();
71         unsafe {
72             INIT_ONCE.call_once(|| {
73                 FUSION_SERVICE_PROXY = Some(Self::default());
74             });
75             FUSION_SERVICE_PROXY.as_ref()
76         }
77     }
78 
79     /// Called when service is starting.
on_start(&self)80     pub fn on_start(&self)
81     {
82         match self.service_impl.lock() {
83             Ok(guard) => {
84                 guard.on_start();
85             }
86             Err(err) => {
87                 error!(LOG_LABEL, "lock error: {}", err);
88             }
89         }
90     }
91 
92     /// Called when service is stopping.
on_stop(&self)93     pub fn on_stop(&self)
94     {
95         match self.service_impl.lock() {
96             Ok(guard) => {
97                 guard.on_stop();
98             }
99             Err(err) => {
100                 error!(LOG_LABEL, "lock error: {}", err);
101             }
102         }
103     }
104 
105     /// Call to allocate socket pair for client/server communication.
alloc_socket_fd(&self, program_name: &str, module_type: i32, client_fd: &mut RawFd, token_type: &mut i32) -> FusionResult<()>106     pub fn alloc_socket_fd(&self, program_name: &str, module_type: i32,
107         client_fd: &mut RawFd, token_type: &mut i32) -> FusionResult<()>
108     {
109         match self.service_impl.lock() {
110             Ok(guard) => {
111                 guard.alloc_socket_fd(program_name, module_type, client_fd, token_type)
112             }
113             Err(err) => {
114                 error!(LOG_LABEL, "lock error: {}", err);
115                 Err(FusionErrorCode::Fail)
116             }
117         }
118     }
119 }
120