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