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