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