xref: /base/msdp/device_status/rust/ipc/client/src/lib.rs (revision f857971d)
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 client side of IPC.
17
18#![allow(dead_code)]
19#![allow(unused_variables)]
20
21use std::ffi::{ c_char, CString };
22
23use hilog_rust::{ info, error, hilog, HiLogLabel, LogType };
24use ipc_rust::{
25    BorrowedMsgParcel, FromRemoteObj, InterfaceToken, MsgParcel,
26    RemoteObjRef, Serialize, get_service,
27};
28
29use fusion_data_rust::Intention;
30use fusion_utils_rust::{ call_debug_enter, FusionResult, FusionErrorCode };
31use fusion_ipc_service_rust::{ IDeviceStatus, FusionIpcProxy, MSDP_DEVICESTATUS_SERVICE_ID };
32
33const LOG_LABEL: HiLogLabel = HiLogLabel {
34    log_type: LogType::LogCore,
35    domain: 0xD002220,
36    tag: "FusionIpcClient"
37};
38
39/// Representation of client side of IPC.
40pub struct FusionIpcClient(RemoteObjRef<dyn IDeviceStatus>);
41
42impl FusionIpcClient {
43    /// Connect device status service.
44    pub fn connect() -> FusionResult<Self> {
45        call_debug_enter!("FusionIpcClient::connect");
46        match get_service(MSDP_DEVICESTATUS_SERVICE_ID) {
47            Ok(obj) => {
48                match <dyn IDeviceStatus as FromRemoteObj>::try_from(obj) {
49                    Ok(obj_ref) => {
50                        info!(LOG_LABEL, "Connect to service successfully");
51                        Ok(FusionIpcClient(obj_ref))
52                    }
53                    Err(err) => {
54                        error!(LOG_LABEL, "Can not dereference remote object");
55                        Err(FusionErrorCode::Fail)
56                    }
57                }
58            }
59            Err(err) => {
60                error!(LOG_LABEL, "Can not connect to service");
61                Err(FusionErrorCode::Fail)
62            }
63        }
64    }
65
66    fn add_interface_token(&self, data_parcel: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
67        call_debug_enter!("FusionIpcClient::add_interface_token");
68        let token = InterfaceToken::new(FusionIpcProxy::get_descriptor());
69        match token.serialize(data_parcel) {
70            Ok(_) => {
71                Ok(())
72            }
73            Err(_) => {
74                error!(LOG_LABEL, "Failed to serialize interface token");
75                Err(FusionErrorCode::Fail)
76            }
77        }
78    }
79
80    /// Request to enable the service identified by [`intention`].
81    pub fn enable(&self, intention: Intention, data: &dyn Serialize,
82        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
83        call_debug_enter!("FusionIpcClient::enable");
84        match MsgParcel::new() {
85            Some(mut data_parcel) => {
86                let mut borrowed_data_parcel = data_parcel.borrowed();
87                info!(LOG_LABEL, "Serialize interface token");
88                self.add_interface_token(&mut borrowed_data_parcel)?;
89
90                if data.serialize(&mut borrowed_data_parcel).is_err() {
91                    return Err(FusionErrorCode::Fail);
92                }
93                info!(LOG_LABEL, "Call proxy.enable()");
94                self.0.enable(intention, &borrowed_data_parcel, reply)
95            }
96            None => {
97                error!(LOG_LABEL, "Can not instantiate MsgParcel");
98                Err(FusionErrorCode::Fail)
99            }
100        }
101    }
102
103    /// Request to disable the service identified by [`intention`].
104    pub fn disable(&self, intention: Intention, data: &dyn Serialize,
105        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
106        call_debug_enter!("FusionIpcClient::disable");
107        match MsgParcel::new() {
108            Some(mut data_parcel) => {
109                let mut borrowed_data_parcel = data_parcel.borrowed();
110                info!(LOG_LABEL, "Serialize interface token");
111                self.add_interface_token(&mut borrowed_data_parcel)?;
112
113                if data.serialize(&mut borrowed_data_parcel).is_err() {
114                    return Err(FusionErrorCode::Fail);
115                }
116                info!(LOG_LABEL, "Call proxy.disable()");
117                self.0.disable(intention, &borrowed_data_parcel, reply)
118            }
119            None => {
120                error!(LOG_LABEL, "Can not instantiate MsgParcel");
121                Err(FusionErrorCode::Fail)
122            }
123        }
124    }
125
126    /// Request to start the service identified by [`intention`].
127    pub fn start(&self, intention: Intention, data: &dyn Serialize,
128        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
129        call_debug_enter!("FusionIpcClient::start");
130        match MsgParcel::new() {
131            Some(mut data_parcel) => {
132                let mut borrowed_data_parcel = data_parcel.borrowed();
133                info!(LOG_LABEL, "Serialize interface token");
134                self.add_interface_token(&mut borrowed_data_parcel)?;
135
136                if data.serialize(&mut borrowed_data_parcel).is_err() {
137                    return Err(FusionErrorCode::Fail);
138                }
139                info!(LOG_LABEL, "Call proxy.start()");
140                self.0.start(intention, &borrowed_data_parcel, reply)
141            }
142            None => {
143                error!(LOG_LABEL, "Can not instantiate MsgParcel");
144                Err(FusionErrorCode::Fail)
145            }
146        }
147    }
148
149    /// Request to stop the service identified by [`intention`].
150    pub fn stop(&self, intention: Intention, data: &dyn Serialize,
151        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
152        call_debug_enter!("FusionIpcClient::stop");
153        match MsgParcel::new() {
154            Some(mut data_parcel) => {
155                let mut borrowed_data_parcel = data_parcel.borrowed();
156                info!(LOG_LABEL, "Serialize interface token");
157                self.add_interface_token(&mut borrowed_data_parcel)?;
158
159                if data.serialize(&mut borrowed_data_parcel).is_err() {
160                    return Err(FusionErrorCode::Fail);
161                }
162                info!(LOG_LABEL, "Call proxy.stop()");
163                self.0.stop(intention, &borrowed_data_parcel, reply)
164            }
165            None => {
166                error!(LOG_LABEL, "Can not instantiate MsgParcel");
167                Err(FusionErrorCode::Fail)
168            }
169        }
170    }
171
172    /// Request to add a watch of state of service, with the service identified by
173    /// [`intention`], the state to watch identified by [`id`], parameters packed in
174    /// [`data`] parcel.
175    pub fn add_watch(&self, intention: Intention, id: u32, data: &dyn Serialize,
176        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
177        call_debug_enter!("FusionIpcClient::add_watch");
178        match MsgParcel::new() {
179            Some(mut data_parcel) => {
180                let mut borrowed_data_parcel = data_parcel.borrowed();
181                info!(LOG_LABEL, "Serialize interface token");
182                self.add_interface_token(&mut borrowed_data_parcel)?;
183
184                if data.serialize(&mut borrowed_data_parcel).is_err() {
185                    return Err(FusionErrorCode::Fail);
186                }
187                info!(LOG_LABEL, "Call proxy.add_watch()");
188                self.0.add_watch(intention, id, &borrowed_data_parcel, reply)
189            }
190            None => {
191                error!(LOG_LABEL, "Can not instantiate MsgParcel");
192                Err(FusionErrorCode::Fail)
193            }
194        }
195    }
196
197    /// Request to remove a watch of state of service.
198    pub fn remove_watch(&self, intention: Intention, id: u32, data: &dyn Serialize,
199        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
200        call_debug_enter!("FusionIpcClient::remove_watch");
201        match MsgParcel::new() {
202            Some(mut data_parcel) => {
203                let mut borrowed_data_parcel = data_parcel.borrowed();
204                info!(LOG_LABEL, "Serialize interface token");
205                self.add_interface_token(&mut borrowed_data_parcel)?;
206
207                if data.serialize(&mut borrowed_data_parcel).is_err() {
208                    return Err(FusionErrorCode::Fail);
209                }
210                info!(LOG_LABEL, "Call proxy.remove_watch()");
211                self.0.remove_watch(intention, id, &borrowed_data_parcel, reply)
212            }
213            None => {
214                error!(LOG_LABEL, "Can not instantiate MsgParcel");
215                Err(FusionErrorCode::Fail)
216            }
217        }
218    }
219
220    /// Request to set a parameter of service, with the service identified by
221    /// [`intention`], the parameter identified by [`id`], and values packed in
222    /// [`data`] parcel.
223    pub fn set_param(&self, intention: Intention, id: u32, data: &dyn Serialize,
224        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
225        call_debug_enter!("FusionIpcClient::set_param");
226        match MsgParcel::new() {
227            Some(mut data_parcel) => {
228                let mut borrowed_data_parcel = data_parcel.borrowed();
229                info!(LOG_LABEL, "Serialize interface token");
230                self.add_interface_token(&mut borrowed_data_parcel)?;
231
232                if data.serialize(&mut borrowed_data_parcel).is_err() {
233                    return Err(FusionErrorCode::Fail);
234                }
235                info!(LOG_LABEL, "Call proxy.set_param()");
236                self.0.set_param(intention, id, &borrowed_data_parcel, reply)
237            }
238            None => {
239                error!(LOG_LABEL, "Can not instantiate MsgParcel");
240                Err(FusionErrorCode::Fail)
241            }
242        }
243    }
244
245    /// Request to get a parameter of service, with the service identified by
246    /// [`intention`], the parameter identified by [`id`].
247    pub fn get_param(&self, intention: Intention, id: u32, data: &dyn Serialize,
248        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
249        call_debug_enter!("FusionIpcClient::get_param");
250        match MsgParcel::new() {
251            Some(mut data_parcel) => {
252                let mut borrowed_data_parcel = data_parcel.borrowed();
253                info!(LOG_LABEL, "Serialize interface token");
254                self.add_interface_token(&mut borrowed_data_parcel)?;
255
256                if data.serialize(&mut borrowed_data_parcel).is_err() {
257                    return Err(FusionErrorCode::Fail);
258                }
259                info!(LOG_LABEL, "Call proxy.get_param()");
260                self.0.get_param(intention, id, &borrowed_data_parcel, reply)
261            }
262            None => {
263                error!(LOG_LABEL, "Can not instantiate MsgParcel");
264                Err(FusionErrorCode::Fail)
265            }
266        }
267    }
268
269    /// Request to interact with service identified by [`intention`] for general purpose.
270    /// This interface supplements functions of previous intefaces. Functionalities of
271    /// this interface is service spicific.
272    pub fn control(&self, intention: Intention, id: u32, data: &dyn Serialize,
273        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
274        call_debug_enter!("FusionIpcClient::control");
275        match MsgParcel::new() {
276            Some(mut data_parcel) => {
277                let mut borrowed_data_parcel = data_parcel.borrowed();
278                info!(LOG_LABEL, "Serialize interface token");
279                self.add_interface_token(&mut borrowed_data_parcel)?;
280
281                if data.serialize(&mut borrowed_data_parcel).is_err() {
282                    return Err(FusionErrorCode::Fail);
283                }
284                info!(LOG_LABEL, "Call proxy.control()");
285                self.0.control(intention, id, &borrowed_data_parcel, reply)
286            }
287            None => {
288                error!(LOG_LABEL, "Can not instantiate MsgParcel");
289                Err(FusionErrorCode::Fail)
290            }
291        }
292    }
293}
294