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
20 mod identity;
21
22 use std::ffi::{ c_char, CString };
23
24 use hilog_rust::{ info, error, hilog, HiLogLabel, LogType };
25 use ipc_rust::{
26 BorrowedMsgParcel, IRemoteBroker, IRemoteObj, MsgParcel, IMsgParcel,
27 RemoteObj, RemoteStub, define_remote_object
28 };
29
30 use fusion_data_rust::Intention;
31 use fusion_utils_rust::{ call_debug_enter, FusionResult, FusionErrorCode };
32
33 use crate::identity::{ CommonAction, compose_param_id, split_action, split_intention, split_param };
34
35 const LOG_LABEL: HiLogLabel = HiLogLabel {
36 log_type: LogType::LogCore,
37 domain: 0xD002220,
38 tag: "FusionIpcService"
39 };
40
41 /// SA ID for "ohos.msdp.Idevicestatus"
42 pub 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.
49 pub trait IDeviceStatus: IRemoteBroker {
50 /// Enable the service identified by [`intention`].
enable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>51 fn enable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
52 /// Disable the service identified by [`intention`].
disable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>53 fn disable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
54 /// Start the service identified by [`intention`].
start(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>55 fn start(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
56 /// Stop the service identified by [`intention`].
stop(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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.
add_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>60 fn add_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
61 /// Remove a watch of state of service.
remove_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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.
set_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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`].
get_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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.
control(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>72 fn control(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>;
73 }
74
on_remote_request(stub: &dyn IDeviceStatus, code: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>75 fn 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
121 define_remote_object!(
122 IDeviceStatus["ohos.msdp.Idevicestatus"] {
123 stub: FusionIpcStub(on_remote_request),
124 proxy: FusionIpcProxy,
125 }
126 );
127
128 impl FusionIpcProxy {
transfer_data(&self, src: &dyn IMsgParcel, target: &mut dyn IMsgParcel) -> FusionResult<()>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
send_request(&self, action: CommonAction, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
179 impl IDeviceStatus for FusionIpcProxy {
enable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
disable(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
start(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
stop(&self, intention: Intention, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
add_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
remove_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
set_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
get_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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
control(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel<'_>, reply: &mut BorrowedMsgParcel<'_>) -> FusionResult<()>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