xref: /base/msdp/device_status/rust/ipc/service/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//! IPC service definition.
17
18#![allow(unused_variables)]
19
20mod identity;
21
22use std::ffi::{ c_char, CString };
23
24use hilog_rust::{ info, error, hilog, HiLogLabel, LogType };
25use ipc_rust::{
26    BorrowedMsgParcel, IRemoteBroker, IRemoteObj, MsgParcel, IMsgParcel,
27    RemoteObj, RemoteStub, define_remote_object
28};
29
30use fusion_data_rust::Intention;
31use fusion_utils_rust::{ call_debug_enter, FusionResult, FusionErrorCode };
32
33use crate::identity::{ CommonAction, compose_param_id, split_action, split_intention, split_param };
34
35const LOG_LABEL: HiLogLabel = HiLogLabel {
36    log_type: LogType::LogCore,
37    domain: 0xD002220,
38    tag: "FusionIpcService"
39};
40
41/// SA ID for "ohos.msdp.Idevicestatus"
42pub const MSDP_DEVICESTATUS_SERVICE_ID: i32 = 2902;
43
44/// Abstration of services.
45///
46/// By design, for ease of extention, all service implementations are required to
47/// map its functions to this collection of interface, with services identified
48/// by Intentions.
49pub trait IDeviceStatus: IRemoteBroker {
50    /// Enable the service identified by [`intention`].
51    fn enable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
52    /// Disable the service identified by [`intention`].
53    fn disable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
54    /// Start the service identified by [`intention`].
55    fn start(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
56    /// Stop the service identified by [`intention`].
57    fn stop(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
58    /// Add a watch of state of service, with the service identified by [`intention`],
59    /// the state to watch identified by [`id`], parameters packed in [`data`] parcel.
60    fn add_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
61    /// Remove a watch of state of service.
62    fn remove_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
63    /// Set a parameter of service, with the service identified by [`intention`],
64    /// the parameter identified by [`id`], and values packed in [`data`] parcel.
65    fn set_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
66    /// Get a parameter of service, with the service identified by [`intention`],
67    /// the parameter identified by [`id`].
68    fn get_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
69    /// Interact with service identified by [`intention`] for general purpose. This interface
70    /// supplements functions of previous intefaces. Functionalities of this interface is
71    /// service spicific.
72    fn control(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
73}
74
75fn on_remote_request(stub: &dyn IDeviceStatus, code: u32, data: &BorrowedMsgParcel<'_>,
76                     reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
77    call_debug_enter!("FusionIpcService::on_remote_request");
78    let intention = split_intention(code)?;
79    let id = split_param(code);
80
81    match split_action(code)? {
82        CommonAction::Enable => {
83            info!(LOG_LABEL, "Call stub.enable()");
84            stub.enable(intention, data, reply)
85        }
86        CommonAction::Disable => {
87            info!(LOG_LABEL, "Call stub.disable()");
88            stub.disable(intention, data, reply)
89        }
90        CommonAction::Start => {
91            info!(LOG_LABEL, "Call stub.start()");
92            stub.start(intention, data, reply)
93        }
94        CommonAction::Stop => {
95            info!(LOG_LABEL, "Call stub.stop()");
96            stub.stop(intention, data, reply)
97        }
98        CommonAction::AddWatch => {
99            info!(LOG_LABEL, "Call stub.add_watch()");
100            stub.add_watch(intention, id, data, reply)
101        }
102        CommonAction::RemoveWatch => {
103            info!(LOG_LABEL, "Call stub.remove_watch()");
104            stub.remove_watch(intention, id, data, reply)
105        }
106        CommonAction::SetParam => {
107            info!(LOG_LABEL, "Call stub.set_param()");
108            stub.set_param(intention, id, data, reply)
109        }
110        CommonAction::GetParam => {
111            info!(LOG_LABEL, "Call stub.get_param()");
112            stub.get_param(intention, id, data, reply)
113        }
114        CommonAction::Control => {
115            info!(LOG_LABEL, "Call stub.control()");
116            stub.control(intention, id, data, reply)
117        }
118    }
119}
120
121define_remote_object!(
122    IDeviceStatus["ohos.msdp.Idevicestatus"] {
123        stub: FusionIpcStub(on_remote_request),
124        proxy: FusionIpcProxy,
125    }
126);
127
128impl FusionIpcProxy {
129    fn transfer_data(&self, src: &dyn IMsgParcel, target: &mut dyn IMsgParcel) -> FusionResult<()>
130    {
131        call_debug_enter!("FusionIpcProxy::transfer_data");
132        let data_size = src.get_data_size();
133        match src.read_buffer(data_size) {
134            Ok(data_vec) => {
135                if target.write_buffer(data_vec.as_slice()) {
136                    Ok(())
137                } else {
138                    error!(LOG_LABEL, "write_buffer() failed");
139                    Err(FusionErrorCode::Fail)
140                }
141            }
142            Err(_) => {
143                error!(LOG_LABEL, "read_buffer() failed");
144                Err(FusionErrorCode::Fail)
145            }
146        }
147    }
148
149    fn send_request(&self, action: CommonAction, intention: Intention, id: u32,
150        data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>
151    {
152        call_debug_enter!("FusionIpcProxy::send_request");
153        match MsgParcel::new() {
154            Some(mut data_parcel) => {
155                self.transfer_data(data, &mut data_parcel)?;
156                let code = compose_param_id(action, intention, id);
157                let rep = {
158                    match self.remote.send_request(code, &data_parcel, false) {
159                        Ok(tr) => {
160                            tr
161                        }
162                        Err(_) => {
163                            error!(LOG_LABEL, "Failed to send request");
164                            return Err(FusionErrorCode::Fail);
165                        }
166                    }
167                };
168
169                self.transfer_data(&rep, reply)
170            }
171            None => {
172                error!(LOG_LABEL, "Can not deref data");
173                Err(FusionErrorCode::Fail)
174            }
175        }
176    }
177}
178
179impl IDeviceStatus for FusionIpcProxy {
180    fn enable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>,
181        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
182        call_debug_enter!("FusionIpcProxy::enable");
183        self.send_request(CommonAction::Enable, intention, 0u32, data, reply)
184    }
185
186    fn disable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>,
187        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
188        call_debug_enter!("FusionIpcProxy::disable");
189        self.send_request(CommonAction::Disable, intention, 0u32, data, reply)
190    }
191
192    fn start(&self, intention: Intention, data: &BorrowedMsgParcel<'_>,
193        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
194        call_debug_enter!("FusionIpcProxy::start");
195        self.send_request(CommonAction::Start, intention, 0u32, data, reply)
196    }
197
198    fn stop(&self, intention: Intention, data: &BorrowedMsgParcel<'_>,
199        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
200        call_debug_enter!("FusionIpcProxy::stop");
201        self.send_request(CommonAction::Stop, intention, 0u32, data, reply)
202    }
203
204    fn add_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>,
205        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
206        call_debug_enter!("FusionIpcProxy::add_watch");
207        self.send_request(CommonAction::AddWatch, intention, id, data, reply)
208    }
209
210    fn remove_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>,
211        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
212        call_debug_enter!("FusionIpcProxy::remove_watch");
213        self.send_request(CommonAction::RemoveWatch, intention, id, data, reply)
214    }
215
216    fn set_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>,
217        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
218        call_debug_enter!("FusionIpcProxy::set_param");
219        self.send_request(CommonAction::SetParam, intention, id, data, reply)
220    }
221
222    fn get_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>,
223        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
224        call_debug_enter!("FusionIpcProxy::get_param");
225        self.send_request(CommonAction::GetParam, intention, id, data, reply)
226    }
227
228    fn control(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>,
229        reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()> {
230        call_debug_enter!("FusionIpcProxy::control");
231        self.send_request(CommonAction::Control, intention, id, data, reply)
232    }
233}
234