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 //! Delegator of IPC service. 17 //! 18 //! This is part of implementation of IPC service as required by IPC framework. 19 //! As IPC request will first be delegated to this [`delegator`]. [`delegator`] 20 //! will check user token, and then redirect request to business module. 21 22 #![allow(unused_variables)] 23 24 use std::cell::Cell; 25 use std::sync::Mutex; 26 use std::ffi::{ c_char, CString }; 27 use hilog_rust::{ debug, info, error, hilog, HiLogLabel, LogType }; 28 use ipc_rust::{ BorrowedMsgParcel, Deserialize, InterfaceToken, IRemoteBroker, IRemoteStub }; 29 use fusion_data_rust::{ Intention, IPlugin, CallingContext }; 30 use fusion_utils_rust::{ call_debug_enter, FusionResult, FusionErrorCode }; 31 use fusion_ipc_service_rust::{ IDeviceStatus, FusionIpcStub }; 32 use fusion_plugin_manager_rust::PluginManager; 33 34 const LOG_LABEL: HiLogLabel = HiLogLabel { 35 log_type: LogType::LogCore, 36 domain: 0xD002220, 37 tag: "FusionIpcDelegator" 38 }; 39 40 pub struct FusionIpcDelegator { 41 plugin_mgr: Mutex<Cell<PluginManager>>, 42 } 43 44 impl FusionIpcDelegator { new() -> Self45 pub fn new() -> Self { 46 Self { 47 plugin_mgr: Mutex::new(Cell::new(PluginManager::default())) 48 } 49 } 50 check_interface_token(&self, data: &BorrowedMsgParcel) -> FusionResult<()>51 fn check_interface_token(&self, data: &BorrowedMsgParcel) -> FusionResult<()> { 52 call_debug_enter!("FusionIpcDelegator::check_interface_token"); 53 match InterfaceToken::deserialize(data) { 54 Ok(token) => { 55 debug!(LOG_LABEL, "check interface token"); 56 if token.get_token() != FusionIpcStub::get_descriptor() { 57 error!(LOG_LABEL, "Unexpected token"); 58 Err(FusionErrorCode::Fail) 59 } else { 60 Ok(()) 61 } 62 } 63 Err(_) => { 64 error!(LOG_LABEL, "Deserialization of interface token failed"); 65 Err(FusionErrorCode::Fail) 66 } 67 } 68 } 69 load_plugin(&self, intention: Intention) -> FusionResult<Box<dyn IPlugin>>70 fn load_plugin(&self, intention: Intention) -> FusionResult<Box<dyn IPlugin>> { 71 call_debug_enter!("FusionIpcDelegator::load_plugin"); 72 match self.plugin_mgr.lock() { 73 Ok(mut guard) => { 74 let plugin = guard.get_mut().load_plugin(intention); 75 match plugin { 76 Some(plugin) => { 77 debug!(LOG_LABEL, "Plugin loaded"); 78 Ok(plugin) 79 } 80 None => { 81 error!(LOG_LABEL, "Failed to load intention module"); 82 Err(FusionErrorCode::Fail) 83 } 84 } 85 } 86 Err(_) => { 87 error!(LOG_LABEL, "Error locking"); 88 Err(FusionErrorCode::Fail) 89 } 90 } 91 } 92 } 93 94 impl IDeviceStatus for FusionIpcDelegator { enable(&self, intention: Intention, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>95 fn enable(&self, intention: Intention, data: &BorrowedMsgParcel, 96 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 97 call_debug_enter!("FusionIpcDelegator::enable"); 98 self.check_interface_token(data)?; 99 100 let plugin = self.load_plugin(intention)?; 101 let context = CallingContext::current(); 102 info!(LOG_LABEL, "Call plugin.enable()"); 103 plugin.enable(&context, data, reply) 104 } 105 disable(&self, intention: Intention, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>106 fn disable(&self, intention: Intention, data: &BorrowedMsgParcel, 107 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 108 call_debug_enter!("FusionIpcDelegator::disable"); 109 self.check_interface_token(data)?; 110 111 let plugin = self.load_plugin(intention)?; 112 let context = CallingContext::current(); 113 info!(LOG_LABEL, "Call plugin.disable()"); 114 plugin.disable(&context, data, reply) 115 } 116 start(&self, intention: Intention, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>117 fn start(&self, intention: Intention, data: &BorrowedMsgParcel, 118 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 119 call_debug_enter!("FusionIpcDelegator::start"); 120 self.check_interface_token(data)?; 121 122 let plugin = self.load_plugin(intention)?; 123 let context = CallingContext::current(); 124 info!(LOG_LABEL, "Call plugin.start()"); 125 plugin.start(&context, data, reply) 126 } 127 stop(&self, intention: Intention, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>128 fn stop(&self, intention: Intention, data: &BorrowedMsgParcel, 129 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 130 call_debug_enter!("FusionIpcDelegator::stop"); 131 self.check_interface_token(data)?; 132 133 let plugin = self.load_plugin(intention)?; 134 let context = CallingContext::current(); 135 info!(LOG_LABEL, "Call plugin.stop()"); 136 plugin.stop(&context, data, reply) 137 } 138 add_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>139 fn add_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, 140 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 141 call_debug_enter!("FusionIpcDelegator::add_watch"); 142 self.check_interface_token(data)?; 143 144 let plugin = self.load_plugin(intention)?; 145 let context = CallingContext::current(); 146 info!(LOG_LABEL, "Call plugin.add_watch()"); 147 plugin.add_watch(&context, id, data, reply) 148 } 149 remove_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>150 fn remove_watch(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, 151 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 152 call_debug_enter!("FusionIpcDelegator::remove_watch"); 153 self.check_interface_token(data)?; 154 155 let plugin = self.load_plugin(intention)?; 156 let context = CallingContext::current(); 157 info!(LOG_LABEL, "Call plugin.remove_watch()"); 158 plugin.remove_watch(&context, id, data, reply) 159 } 160 set_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>161 fn set_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, 162 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 163 call_debug_enter!("FusionIpcDelegator::set_param"); 164 self.check_interface_token(data)?; 165 166 let plugin = self.load_plugin(intention)?; 167 let context = CallingContext::current(); 168 info!(LOG_LABEL, "Call plugin.set_param()"); 169 plugin.set_param(&context, id, data, reply) 170 } 171 get_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>172 fn get_param(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, 173 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 174 call_debug_enter!("FusionIpcDelegator::get_param"); 175 self.check_interface_token(data)?; 176 177 let plugin = self.load_plugin(intention)?; 178 let context = CallingContext::current(); 179 info!(LOG_LABEL, "Call plugin.get_param()"); 180 plugin.get_param(&context, id, data, reply) 181 } 182 control(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> FusionResult<()>183 fn control(&self, intention: Intention, id: u32, data: &BorrowedMsgParcel, 184 reply: &mut BorrowedMsgParcel) -> FusionResult<()> { 185 call_debug_enter!("FusionIpcDelegator::control"); 186 self.check_interface_token(data)?; 187 188 let plugin = self.load_plugin(intention)?; 189 let context = CallingContext::current(); 190 info!(LOG_LABEL, "Call plugin.control()"); 191 plugin.control(&context, id, data, reply) 192 } 193 } 194 195 impl IRemoteBroker for FusionIpcDelegator {} 196