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