• 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 use std::ffi::{CString, c_char, c_int, c_uint, c_ulonglong};
17 
18 /// Length limit for the name of a HiSysEventParam.
19 const MAX_LENGTH_OF_PARAM_NAME: usize = 49;
20 
21 /// This type represent to HiSysEventParamValue defined in C.
22 #[repr(C)]
23 #[derive(Copy, Clone)]
24 pub union HiSysEventParamValue {
25     /// Bool.
26     pub b_: bool,
27 
28     /// Int8_t.
29     pub i8_: i8,
30 
31     /// Uint8_t.
32     pub u8_: u8,
33 
34     /// Int16_t.
35     pub i16_: i16,
36 
37     /// Uint16_t.
38     pub u16_: u16,
39 
40     /// Int32_t.
41     pub i32_: i32,
42 
43     /// Uint32_t.
44     pub u32_: u32,
45 
46     /// Int64_t.
47     pub i64_: i64,
48 
49     /// Uint64_t.
50     pub u64_: u64,
51 
52     /// Float.
53     pub f32_: f32,
54 
55     /// Double.
56     pub f64_: f64,
57 
58     /// String.
59     pub char_ptr_: *const c_char,
60 
61     /// Array.
62     pub void_ptr_: *const (),
63 }
64 
65 /// This type represent to HiSysEventParamType defined in C.
66 #[derive(Copy, Clone)]
67 pub enum HiSysEventParamType {
68     /// Invalid type.
69     Invalid = 0,
70 
71     /// Bool type.
72     Bool,
73 
74     /// Int8_t type.
75     Int8,
76 
77     /// Uint8_t type.
78     Uint8,
79 
80     /// Int16_t type.
81     Int16,
82 
83     /// Uint16_t type.
84     Uint16,
85 
86     /// Int32_t type.
87     Int32,
88 
89     /// Uint32_t type.
90     Uint32,
91 
92     /// Int64_t type.
93     Int64,
94 
95     /// Uint64_t type.
96     Uint64,
97 
98     /// Float type.
99     Float,
100 
101     /// Double type.
102     Double,
103 
104     /// String type.
105     ParamTypeString,
106 
107     /// Bool array type.
108     BoolArray,
109 
110     /// Int8_t array type.
111     Int8Array,
112 
113     /// Uint8_t array type.
114     Uint8Array,
115 
116     /// Int16_t array type.
117     Int16Array,
118 
119     /// Uint16_t array type.
120     Uint16Array,
121 
122     /// Int32_t array type.
123     Int32Array,
124 
125     /// Unt32_t array type.
126     Uint32Array,
127 
128     /// Int64_t array type.
129     Int64Array,
130 
131     /// Uint16_t array type.
132     Uint64Array,
133 
134     /// Float array type.
135     FloatArray,
136 
137     /// Double array type.
138     DoubleArray,
139 
140     /// String array type.
141     ParamTypeStringArray,
142 }
143 
144 /// Definition customized param.
145 pub struct HiSysEventParam<'a> {
146     /// Param key
147     pub param_name: &'a str,
148 
149     /// Param type
150     pub param_type: HiSysEventParamType,
151 
152     /// Param value
153     pub param_value: HiSysEventParamValue,
154 
155     /// Size of param value
156     pub array_size: usize,
157 }
158 
159 /// This type represent to HiSysEventParamWrapper defined in C.
160 #[repr(C)]
161 #[derive(Copy, Clone)]
162 struct HiSysEventParamWrapper {
163     /// Param name.
164     pub param_name: [c_char; MAX_LENGTH_OF_PARAM_NAME],
165 
166     /// Param type.
167     pub param_type: c_int,
168 
169     /// Param value.
170     pub param_value: HiSysEventParamValue,
171 
172     /// Length of a param with array type.
173     pub array_size: c_uint,
174 }
175 
176 /// Parse type and length of a variable.
177 #[allow(dead_code)]
parse_type_len<T>(_: T) -> (&'static str, usize)178 pub fn parse_type_len<T>(_: T) -> (&'static str, usize) {
179     let mut value_type = std::any::type_name::<T>();
180     let mut bytes = value_type.as_bytes();
181     if bytes[0] == b'&' {
182         value_type = &value_type[1..];
183 		bytes = value_type.as_bytes();
184     }
185     if bytes[0] != b'[' {
186         // not a array
187         if bytes[0] == b'&' {
188             // reference
189             return (&value_type[1..], 0);
190         } else {
191             return (value_type, 0);
192         }
193     }
194     // array
195     let mut val_end: usize = 0;
196     let mut len_start: usize = 0;
197     for (i, &item) in bytes.iter().enumerate() {
198         if item == b';' {
199             val_end = i;
200         }
201         if item == b' ' {
202             len_start = i + 1;
203             break;
204         }
205     }
206     let array_len = value_type[len_start..(bytes.len() - 1)].parse::<usize>().unwrap();
207     if bytes[1] == b'&' {
208         // reference
209         (&value_type[2..val_end], array_len)
210     } else {
211         (&value_type[1..val_end], array_len)
212     }
213 }
214 
215 /// Build hisysevent param with string array type.
216 #[allow(dead_code)]
build_string_arrays<'a>(param_name: &'a str, str_arr: &[&'a str]) -> HiSysEventParam<'a>217 pub fn build_string_arrays<'a>(param_name: &'a str, str_arr: &[&'a str]) -> HiSysEventParam<'a> {
218     let mut dest: Vec<*const c_char> = vec![];
219     for &item in str_arr {
220         let str_wrapper = CString::new(item).expect("Need a valid value with &str type.");
221         dest.push(str_wrapper.into_raw() as *const c_char);
222     }
223     HiSysEventParam {
224         param_name,
225         param_type: HiSysEventParamType::ParamTypeStringArray,
226         param_value: HiSysEventParamValue {
227             void_ptr_: std::boxed::Box::<[*const c_char]>::into_raw(dest.into_boxed_slice()) as *const c_int as *const (),
228         },
229         array_size: str_arr.len(),
230     }
231 }
232 
233 /// Write system event.
write(event_domain: &str, event_name: &str, event_type: c_int, event_params: &[HiSysEventParam]) -> i32234 pub(crate) fn write(event_domain: &str, event_name: &str, event_type: c_int, event_params: &[HiSysEventParam]) -> i32 {
235     let mut params_wrapper: Vec<HiSysEventParamWrapper> = vec![];
236     for i in 0..event_params.len() {
237         params_wrapper.push(HiSysEventParamWrapper {
238             param_name: [0; MAX_LENGTH_OF_PARAM_NAME],
239             param_type: event_params[i].param_type as i32 as c_int,
240             param_value: event_params[i].param_value,
241             array_size: event_params[i].array_size as c_uint,
242         });
243         crate::utils::trans_slice_to_array(event_params[i].param_name, &mut params_wrapper[i].param_name);
244     }
245     let func = CString::new(crate::function!()).expect("Need a valid function name");
246     let domain = CString::new(event_domain).expect("Need a valid domain name");
247     let event_name = CString::new(event_name).expect("Need a valid event name");
248     // Safty: call C ffi border function, all risks are under control.
249     unsafe {
250         HiSysEventWriteWrapper(
251             func.as_ptr() as *const c_char,
252             line!() as c_ulonglong,
253             domain.as_ptr() as *const c_char,
254             event_name.as_ptr() as *const c_char,
255             event_type,
256             params_wrapper.as_mut_ptr(),
257             event_params.len() as c_uint
258         )
259     }
260 }
261 
262 extern "C" {
263     /// ffi border function.
HiSysEventWriteWrapper(func: *const c_char, line: c_ulonglong, domain: *const c_char, name: *const c_char, event_type: c_int, params: *const HiSysEventParamWrapper, size: c_uint) -> c_int264     fn HiSysEventWriteWrapper(func: *const c_char, line: c_ulonglong, domain: *const c_char,
265         name: *const c_char, event_type: c_int, params: *const HiSysEventParamWrapper,
266         size: c_uint) -> c_int;
267 }