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