• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::ffi::{c_char, c_int, c_uint, c_ulonglong, CString};
15 
16 /// Length limit for the name of a HiSysEventParam.
17 const MAX_LENGTH_OF_PARAM_NAME: usize = 49;
18 
19 /// This type represent to HiSysEventParamValue defined in C.
20 #[repr(C)]
21 #[derive(Copy, Clone)]
22 pub union HiSysEventParamValue {
23     /// Bool.
24     pub b_: bool,
25 
26     /// Int8_t.
27     pub i8_: i8,
28 
29     /// Uint8_t.
30     pub u8_: u8,
31 
32     /// Int16_t.
33     pub i16_: i16,
34 
35     /// Uint16_t.
36     pub u16_: u16,
37 
38     /// Int32_t.
39     pub i32_: i32,
40 
41     /// Uint32_t.
42     pub u32_: u32,
43 
44     /// Int64_t.
45     pub i64_: i64,
46 
47     /// Uint64_t.
48     pub u64_: u64,
49 
50     /// Float.
51     pub f32_: f32,
52 
53     /// Double.
54     pub f64_: f64,
55 
56     /// String.
57     pub char_ptr_: *const c_char,
58 
59     /// Array.
60     pub void_ptr_: *const (),
61 }
62 
63 /// This type represent to HiSysEventParamType defined in C.
64 #[derive(Copy, Clone)]
65 pub enum HiSysEventParamType {
66     /// Invalid type.
67     Invalid = 0,
68 
69     /// Bool type.
70     Bool,
71 
72     /// Int8_t type.
73     Int8,
74 
75     /// Uint8_t type.
76     Uint8,
77 
78     /// Int16_t type.
79     Int16,
80 
81     /// Uint16_t type.
82     Uint16,
83 
84     /// Int32_t type.
85     Int32,
86 
87     /// Uint32_t type.
88     Uint32,
89 
90     /// Int64_t type.
91     Int64,
92 
93     /// Uint64_t type.
94     Uint64,
95 
96     /// Float type.
97     Float,
98 
99     /// Double type.
100     Double,
101 
102     /// String type.
103     ParamTypeString,
104 
105     /// Bool array type.
106     BoolArray,
107 
108     /// Int8_t array type.
109     Int8Array,
110 
111     /// Uint8_t array type.
112     Uint8Array,
113 
114     /// Int16_t array type.
115     Int16Array,
116 
117     /// Uint16_t array type.
118     Uint16Array,
119 
120     /// Int32_t array type.
121     Int32Array,
122 
123     /// Unt32_t array type.
124     Uint32Array,
125 
126     /// Int64_t array type.
127     Int64Array,
128 
129     /// Uint16_t array type.
130     Uint64Array,
131 
132     /// Float array type.
133     FloatArray,
134 
135     /// Double array type.
136     DoubleArray,
137 
138     /// String array type.
139     ParamTypeStringArray,
140 }
141 
142 /// Definition customized param.
143 pub struct HiSysEventParam<'a> {
144     /// Param key
145     pub param_name: &'a str,
146 
147     /// Param type
148     pub param_type: HiSysEventParamType,
149 
150     /// Param value
151     pub param_value: HiSysEventParamValue,
152 
153     /// Size of param value
154     pub array_size: usize,
155 }
156 
157 /// This type represent to HiSysEventParamWrapper defined in C.
158 #[repr(C)]
159 #[derive(Copy, Clone)]
160 struct HiSysEventParamWrapper {
161     /// Param name.
162     pub param_name: [u8; MAX_LENGTH_OF_PARAM_NAME],
163 
164     /// Param type.
165     pub param_type: c_int,
166 
167     /// Param value.
168     pub param_value: HiSysEventParamValue,
169 
170     /// Length of a param with array type.
171     pub array_size: c_uint,
172 }
173 
174 /// Parse type and length of a variable.
175 #[allow(dead_code)]
parse_type_len<T>(_: T) -> (&'static str, usize)176 pub fn parse_type_len<T>(_: T) -> (&'static str, usize) {
177     let mut value_type = std::any::type_name::<T>();
178     let mut bytes = value_type.as_bytes();
179     if bytes[0] == b'&' {
180         value_type = &value_type[1..];
181         bytes = value_type.as_bytes();
182     }
183     if bytes[0] != b'[' {
184         // not a array
185         if bytes[0] == b'&' {
186             // reference
187             return (&value_type[1..], 0);
188         } else {
189             return (value_type, 0);
190         }
191     }
192     // array
193     let mut val_end: usize = 0;
194     let mut len_start: usize = 0;
195     for (i, &item) in bytes.iter().enumerate() {
196         if item == b';' {
197             val_end = i;
198         }
199         if item == b' ' {
200             len_start = i + 1;
201             break;
202         }
203     }
204     let array_len = value_type[len_start..(bytes.len() - 1)]
205         .parse::<usize>()
206         .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())
228                 as *const c_int as *const (),
229         },
230         array_size: str_arr.len(),
231     }
232 }
233 
234 /// Write system event.
write( event_domain: &str, event_name: &str, event_type: c_int, event_params: &[HiSysEventParam], ) -> i32235 pub(crate) fn write(
236     event_domain: &str,
237     event_name: &str,
238     event_type: c_int,
239     event_params: &[HiSysEventParam],
240 ) -> i32 {
241     let mut params_wrapper: Vec<HiSysEventParamWrapper> = vec![];
242     for i in 0..event_params.len() {
243         params_wrapper.push(HiSysEventParamWrapper {
244             param_name: [0; MAX_LENGTH_OF_PARAM_NAME],
245             param_type: event_params[i].param_type as i32 as c_int,
246             param_value: event_params[i].param_value,
247             array_size: event_params[i].array_size as c_uint,
248         });
249         crate::utils::trans_slice_to_array(
250             event_params[i].param_name,
251             &mut params_wrapper[i].param_name,
252         );
253     }
254     let func = CString::new(crate::function!()).expect("Need a valid function name");
255     let domain = CString::new(event_domain).expect("Need a valid domain name");
256     let event_name = CString::new(event_name).expect("Need a valid event name");
257     // Safty: call C ffi border function, all risks are under control.
258     unsafe {
259         HiSysEventWriteWrapper(
260             func.as_ptr() as *const c_char,
261             line!() as c_ulonglong,
262             domain.as_ptr() as *const c_char,
263             event_name.as_ptr() as *const c_char,
264             event_type,
265             params_wrapper.as_mut_ptr(),
266             event_params.len() as c_uint,
267         )
268     }
269 }
270 
271 extern "C" {
272     /// 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_int273     fn HiSysEventWriteWrapper(
274         func: *const c_char,
275         line: c_ulonglong,
276         domain: *const c_char,
277         name: *const c_char,
278         event_type: c_int,
279         params: *const HiSysEventParamWrapper,
280         size: c_uint,
281     ) -> c_int;
282 }
283