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//! This module defines IPC interfaces and constants. 17 18use ipc::{parcel::MsgParcel, IpcStatusCode}; 19 20use asset_definition::{ 21 impl_enum_trait, log_throw_error, AssetError, AssetMap, Conversion, DataType, ErrCode, Result, Tag, Value, 22}; 23 24/// SA id for Asset service. 25pub const SA_ID: i32 = 8100; 26/// SA name for Asset service. 27pub const SA_NAME: &str = "security_asset_service"; 28/// IPC result code. 29pub const IPC_SUCCESS: u32 = 0; 30 31const MAX_MAP_CAPACITY: u32 = 64; 32const MAX_VEC_CAPACITY: u32 = 0x10000; 33 34impl_enum_trait! { 35 /// Code used to identify the function to be called. 36 #[derive(Clone, Copy)] 37 #[derive(Eq, PartialEq)] 38 pub enum IpcCode { 39 /// Code for AddAsset. 40 Add = ipc::FIRST_CALL_TRANSACTION, 41 /// Code for RemoveAsset. 42 Remove, 43 /// Code for UpdateAsset. 44 Update, 45 /// Code for PreQueryAsset. 46 PreQuery, 47 /// Code for QueryAsset. 48 Query, 49 /// Code for PostQueryAsset. 50 PostQuery, 51 } 52} 53 54/// serialize the map to parcel 55pub fn serialize_map(map: &AssetMap, parcel: &mut MsgParcel) -> Result<()> { 56 if map.len() as u32 > MAX_MAP_CAPACITY { 57 return log_throw_error!(ErrCode::InvalidArgument, "[FALTAL][IPC]The map size exceeds the limit."); 58 } 59 parcel.write(&(map.len() as u32)).map_err(ipc_err_handle)?; 60 for (&tag, value) in map.iter() { 61 if tag.data_type() != value.data_type() { 62 return log_throw_error!( 63 ErrCode::InvalidArgument, 64 "[FATAL][IPC]Data type mismatch, key type: {}, value type: {}", 65 tag.data_type(), 66 value.data_type() 67 ); 68 } 69 parcel.write(&(tag as u32)).map_err(ipc_err_handle)?; 70 match value { 71 Value::Bool(b) => parcel.write::<bool>(b).map_err(ipc_err_handle)?, 72 Value::Number(n) => parcel.write::<u32>(n).map_err(ipc_err_handle)?, 73 Value::Bytes(a) => parcel.write::<Vec<u8>>(a).map_err(ipc_err_handle)?, 74 } 75 } 76 Ok(()) 77} 78 79/// deserialize the map from parcel 80pub fn deserialize_map(parcel: &mut MsgParcel) -> Result<AssetMap> { 81 let len = parcel.read::<u32>().map_err(ipc_err_handle)?; 82 if len > MAX_MAP_CAPACITY { 83 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][IPC]The map size exceeds the limit."); 84 } 85 let mut map = AssetMap::with_capacity(len as usize); 86 for _ in 0..len { 87 let tag = parcel.read::<u32>().map_err(ipc_err_handle)?; 88 let tag = Tag::try_from(tag)?; 89 match tag.data_type() { 90 DataType::Bool => { 91 let v = parcel.read::<bool>().map_err(ipc_err_handle)?; 92 map.insert(tag, Value::Bool(v)); 93 }, 94 DataType::Number => { 95 let v = parcel.read::<u32>().map_err(ipc_err_handle)?; 96 map.insert(tag, Value::Number(v)); 97 }, 98 DataType::Bytes => { 99 let v = parcel.read::<Vec<u8>>().map_err(ipc_err_handle)?; 100 map.insert(tag, Value::Bytes(v)); 101 }, 102 } 103 } 104 Ok(map) 105} 106 107/// Serialize the collection of map to parcel. 108pub fn serialize_maps(vec: &Vec<AssetMap>, parcel: &mut MsgParcel) -> Result<()> { 109 if vec.len() as u32 > MAX_VEC_CAPACITY { 110 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][IPC]The vector size exceeds the limit."); 111 } 112 parcel.write::<u32>(&(vec.len() as u32)).map_err(ipc_err_handle)?; 113 for map in vec.iter() { 114 serialize_map(map, parcel)?; 115 } 116 Ok(()) 117} 118 119/// Deserialize the collection of map from parcel. 120pub fn deserialize_maps(parcel: &mut MsgParcel) -> Result<Vec<AssetMap>> { 121 let len = parcel.read::<u32>().map_err(ipc_err_handle)?; 122 if len > MAX_VEC_CAPACITY { 123 return log_throw_error!(ErrCode::InvalidArgument, "[FATAL][IPC]The vector size exceeds the limit."); 124 } 125 let mut res_vec = Vec::with_capacity(len as usize); 126 for _i in 0..len { 127 res_vec.push(deserialize_map(parcel)?); 128 } 129 Ok(res_vec) 130} 131 132/// Convert ipc error into Asset error. 133pub fn ipc_err_handle(e: IpcStatusCode) -> AssetError { 134 AssetError::new(ErrCode::IpcError, format!("[FATAL][IPC]Ipc status code = {}", e)) 135} 136