• 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 //! serialize
16 #![allow(missing_docs)]
17 
18 extern crate libc;
19 
20 use crate::serializer::native_struct::{FileMode, TransferConfig, TransferPayload};
21 use crate::serializer::native_struct::{PayloadHead, PayloadProtect, SessionHandShake};
22 use crate::serializer::pack_struct::*;
23 
24 use std::ffi::CStr;
25 use std::ffi::CString;
26 use std::io::{self, Error, ErrorKind};
27 
28 use super::native_struct::UartHead;
29 use super::native_struct::UsbHead;
30 
31 // use tokio::io::Result;
32 
33 #[repr(C)]
34 pub struct SerializedBuffer {
35     pub ptr: *const libc::c_char,
36     pub size: libc::c_ulonglong,
37 }
38 
39 impl Drop for SerializedBuffer {
drop(&mut self)40     fn drop(&mut self) {
41         unsafe {
42             free(self.ptr.cast());
43         }
44     }
45 }
46 
47 pub struct RawPayload {
48     pub bytes: Vec<u8>,
49 }
50 
51 extern "C" {
free(ptr: *const libc::c_void)52     fn free(ptr: *const libc::c_void);
53 
SerializeSessionHandShake(value: *const SessionHandShakePack) -> SerializedBuffer54     fn SerializeSessionHandShake(value: *const SessionHandShakePack) -> SerializedBuffer;
SerializePayloadProtect(value: *const PayloadProtectPack) -> SerializedBuffer55     fn SerializePayloadProtect(value: *const PayloadProtectPack) -> SerializedBuffer;
SerializeTransferConfig(value: *const TransferConfigPack) -> SerializedBuffer56     fn SerializeTransferConfig(value: *const TransferConfigPack) -> SerializedBuffer;
SerializeFileMode(value: *const FileModePack) -> SerializedBuffer57     fn SerializeFileMode(value: *const FileModePack) -> SerializedBuffer;
SerializeTransferPayload(value: *const TransferPayloadPack) -> SerializedBuffer58     fn SerializeTransferPayload(value: *const TransferPayloadPack) -> SerializedBuffer;
SerializePayloadHead(value: *const PayloadHeadPack) -> SerializedBuffer59     fn SerializePayloadHead(value: *const PayloadHeadPack) -> SerializedBuffer;
SerializeUsbHead(value: *const UsbHeadPack) -> SerializedBuffer60     fn SerializeUsbHead(value: *const UsbHeadPack) -> SerializedBuffer;
SerializeUartHead(value: *const UartHeadPack) -> SerializedBuffer61     fn SerializeUartHead(value: *const UartHeadPack) -> SerializedBuffer;
62 
ParseSessionHandShake( value: *mut SessionHandShakePack, buf: SerializedBuffer, ) -> libc::c_uchar63     fn ParseSessionHandShake(
64         value: *mut SessionHandShakePack,
65         buf: SerializedBuffer,
66     ) -> libc::c_uchar;
ParsePayloadProtect(value: *mut PayloadProtectPack, buf: SerializedBuffer) -> libc::c_uchar67     fn ParsePayloadProtect(value: *mut PayloadProtectPack, buf: SerializedBuffer) -> libc::c_uchar;
ParseTransferConfig(value: *mut TransferConfigPack, buf: SerializedBuffer) -> libc::c_uchar68     fn ParseTransferConfig(value: *mut TransferConfigPack, buf: SerializedBuffer) -> libc::c_uchar;
ParseFileMode(value: *mut FileModePack, buf: SerializedBuffer) -> libc::c_uchar69     fn ParseFileMode(value: *mut FileModePack, buf: SerializedBuffer) -> libc::c_uchar;
ParseTransferPayload( value: *mut TransferPayloadPack, buf: SerializedBuffer, ) -> libc::c_uchar70     fn ParseTransferPayload(
71         value: *mut TransferPayloadPack,
72         buf: SerializedBuffer,
73     ) -> libc::c_uchar;
ParsePayloadHead(value: *mut PayloadHeadPack, buf: SerializedBuffer) -> libc::c_uchar74     fn ParsePayloadHead(value: *mut PayloadHeadPack, buf: SerializedBuffer) -> libc::c_uchar;
ParseUsbHead(value: *mut UsbHeadPack, buf: SerializedBuffer) -> libc::c_uchar75     fn ParseUsbHead(value: *mut UsbHeadPack, buf: SerializedBuffer) -> libc::c_uchar;
ParseUartHead(value: *mut UartHeadPack, buf: SerializedBuffer) -> libc::c_uchar76     fn ParseUartHead(value: *mut UartHeadPack, buf: SerializedBuffer) -> libc::c_uchar;
77 }
78 
79 pub trait Serialization {
serialize(&self) -> Vec<u8>80     fn serialize(&self) -> Vec<u8>;
parse(&mut self, _: Vec<u8>) -> io::Result<()>81     fn parse(&mut self, _: Vec<u8>) -> io::Result<()> {
82         Ok(())
83     }
84 }
85 
86 impl Serialization for RawPayload {
serialize(&self) -> Vec<u8>87     fn serialize(&self) -> Vec<u8> {
88         self.bytes.clone()
89     }
90 }
91 
92 impl Serialization for SessionHandShake {
serialize(&self) -> Vec<u8>93     fn serialize(&self) -> Vec<u8> {
94         let banner = CString::new(self.banner.as_str()).unwrap();
95         let connect_key = CString::new(self.connect_key.as_str()).unwrap();
96         let buf = CString::new(self.buf.as_str()).unwrap();
97         let version = CString::new(self.version.as_str()).unwrap();
98         let pack = SessionHandShakePack {
99             banner: banner.as_ptr(),
100             auth_type: self.auth_type,
101             session_id: self.session_id,
102             connect_key: connect_key.as_ptr(),
103             buf: buf.as_ptr(),
104             version: version.as_ptr(),
105         };
106         let buf = unsafe { SerializeSessionHandShake(&pack) };
107         buf_to_vec(buf)
108     }
109 
parse(&mut self, input: Vec<u8>) -> io::Result<()>110     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
111         let mut pack = SessionHandShakePack {
112             banner: std::ptr::null(),
113             auth_type: 0,
114             session_id: 0,
115             connect_key: std::ptr::null(),
116             buf: std::ptr::null(),
117             version: std::ptr::null(),
118         };
119 
120         let buf = SerializedBuffer {
121             ptr: input.as_ptr() as *const libc::c_char,
122             size: input.len() as u64,
123         };
124         if unsafe { ParseSessionHandShake(&mut pack, buf) } == 0 {
125             return Err(Error::new(
126                 ErrorKind::Other,
127                 "cffi ParseSessionHandShake failed",
128             ));
129         }
130 
131         self.banner = ptr_to_string(pack.banner);
132         self.auth_type = pack.auth_type;
133         self.session_id = pack.session_id;
134         self.connect_key = ptr_to_string(pack.connect_key);
135         self.buf = ptr_to_string(pack.buf);
136         self.version = ptr_to_string(pack.version);
137 
138         Ok(())
139     }
140 }
141 
142 impl Serialization for PayloadProtect {
serialize(&self) -> Vec<u8>143     fn serialize(&self) -> Vec<u8> {
144         let pack = PayloadProtectPack {
145             channel_id: self.channel_id,
146             command_flag: self.command_flag,
147             check_sum: self.check_sum,
148             v_code: self.v_code,
149         };
150         let buf = unsafe { SerializePayloadProtect(&pack) };
151         buf_to_vec(buf)
152     }
153 
parse(&mut self, input: Vec<u8>) -> io::Result<()>154     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
155         let mut pack = PayloadProtectPack::default();
156 
157         let buf = SerializedBuffer {
158             ptr: input.as_ptr() as *const libc::c_char,
159             size: input.len() as u64,
160         };
161         if unsafe { ParsePayloadProtect(&mut pack, buf) } == 0 {
162             return Err(Error::new(
163                 ErrorKind::Other,
164                 "cffi ParsePayloadProtect failed",
165             ));
166         }
167 
168         self.channel_id = pack.channel_id;
169         self.command_flag = pack.command_flag;
170         self.check_sum = pack.check_sum;
171         self.v_code = pack.v_code;
172 
173         Ok(())
174     }
175 }
176 
177 impl Serialization for TransferConfig {
serialize(&self) -> Vec<u8>178     fn serialize(&self) -> Vec<u8> {
179         let options = CString::new(self.options.as_str()).unwrap();
180         let path = CString::new(self.path.as_str()).unwrap();
181         let optional_name = CString::new(self.optional_name.as_str()).unwrap();
182         let function_name = CString::new(self.function_name.as_str()).unwrap();
183         let client_cwd = CString::new(self.client_cwd.as_str()).unwrap();
184         let reserve1 = CString::new(self.reserve1.as_str()).unwrap();
185         let reserve2 = CString::new(self.reserve2.as_str()).unwrap();
186         let pack = TransferConfigPack {
187             file_size: self.file_size,
188             atime: self.atime,
189             mtime: self.mtime,
190             options: options.as_ptr(),
191             path: path.as_ptr(),
192             optional_name: optional_name.as_ptr(),
193             update_if_new: self.update_if_new as u8,
194             compress_type: self.compress_type,
195             hold_timestamp: self.hold_timestamp as u8,
196             function_name: function_name.as_ptr(),
197             client_cwd: client_cwd.as_ptr(),
198             reserve1: reserve1.as_ptr(),
199             reserve2: reserve2.as_ptr(),
200         };
201 
202         let buf = unsafe { SerializeTransferConfig(&pack) };
203         buf_to_vec(buf)
204     }
205 
parse(&mut self, input: Vec<u8>) -> io::Result<()>206     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
207         let mut pack = TransferConfigPack {
208             file_size: 0,
209             atime: 0,
210             mtime: 0,
211             options: std::ptr::null(),
212             path: std::ptr::null(),
213             optional_name: std::ptr::null(),
214             update_if_new: 0,
215             compress_type: 0,
216             hold_timestamp: 0,
217             function_name: std::ptr::null(),
218             client_cwd: std::ptr::null(),
219             reserve1: std::ptr::null(),
220             reserve2: std::ptr::null(),
221         };
222         let buf = SerializedBuffer {
223             ptr: input.as_ptr() as *const libc::c_char,
224             size: input.len() as u64,
225         };
226         if unsafe { ParseTransferConfig(&mut pack, buf) } == 0 {
227             return Err(Error::new(
228                 ErrorKind::Other,
229                 "cffi ParseTransferConfig failed",
230             ));
231         }
232         self.file_size = pack.file_size;
233         self.atime = pack.atime;
234         self.mtime = pack.mtime;
235         self.options = ptr_to_string(pack.options);
236         self.path = ptr_to_string(pack.path);
237         self.optional_name = ptr_to_string(pack.optional_name);
238         self.update_if_new = pack.update_if_new > 0;
239         self.compress_type = pack.compress_type;
240         self.hold_timestamp = pack.hold_timestamp > 0;
241         self.function_name = ptr_to_string(pack.function_name);
242         self.client_cwd = ptr_to_string(pack.client_cwd);
243         self.reserve1 = ptr_to_string(pack.reserve1);
244         self.reserve2 = ptr_to_string(pack.reserve2);
245         Ok(())
246     }
247 }
248 
249 impl Serialization for FileMode {
serialize(&self) -> Vec<u8>250     fn serialize(&self) -> Vec<u8> {
251         let context = CString::new(self.context.as_str()).unwrap();
252         let full_name = CString::new(self.full_name.as_str()).unwrap();
253         let pack = FileModePack {
254             perm: self.perm,
255             u_id: self.u_id,
256             g_id: self.g_id,
257             context: context.as_ptr(),
258             full_name: full_name.as_ptr(),
259         };
260         let buf = unsafe { SerializeFileMode(&pack) };
261         buf_to_vec(buf)
262     }
263 
parse(&mut self, input: Vec<u8>) -> io::Result<()>264     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
265         let mut pack = FileModePack {
266             perm: 0,
267             u_id: 0,
268             g_id: 0,
269             context: std::ptr::null(),
270             full_name: std::ptr::null(),
271         };
272 
273         let buf = SerializedBuffer {
274             ptr: input.as_ptr() as *const libc::c_char,
275             size: input.len() as u64,
276         };
277         if unsafe { ParseFileMode(&mut pack, buf) } == 0 {
278             return Err(Error::new(ErrorKind::Other, "cffi ParseFileMode failed"));
279         }
280 
281         self.perm = pack.perm;
282         self.u_id = pack.u_id;
283         self.g_id = pack.g_id;
284         self.context = ptr_to_string(pack.context);
285         self.full_name = ptr_to_string(pack.full_name);
286 
287         Ok(())
288     }
289 }
290 
291 impl Serialization for TransferPayload {
serialize(&self) -> Vec<u8>292     fn serialize(&self) -> Vec<u8> {
293         let pack = TransferPayloadPack {
294             index: self.index,
295             compress_type: self.compress_type,
296             compress_size: self.compress_size,
297             uncompress_size: self.uncompress_size,
298         };
299         let buf = unsafe { SerializeTransferPayload(&pack) };
300         buf_to_vec(buf)
301     }
302 
parse(&mut self, input: Vec<u8>) -> io::Result<()>303     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
304         let mut pack = TransferPayloadPack::default();
305 
306         let buf = SerializedBuffer {
307             ptr: input.as_ptr() as *const libc::c_char,
308             size: input.len() as u64,
309         };
310         if unsafe { ParseTransferPayload(&mut pack, buf) } == 0 {
311             return Err(Error::new(
312                 ErrorKind::Other,
313                 "cffi ParseTransferPayload failed",
314             ));
315         }
316 
317         self.index = pack.index;
318         self.compress_type = pack.compress_type;
319         self.compress_size = pack.compress_size;
320         self.uncompress_size = pack.uncompress_size;
321 
322         Ok(())
323     }
324 }
325 
326 impl Serialization for PayloadHead {
serialize(&self) -> Vec<u8>327     fn serialize(&self) -> Vec<u8> {
328         let pack = PayloadHeadPack {
329             flag: self.flag,
330             reserve: self.reserve,
331             protocol_ver: self.protocol_ver,
332             head_size: self.head_size,
333             data_size: self.data_size,
334         };
335         let buf = unsafe { SerializePayloadHead(&pack) };
336         buf_to_vec(buf)
337     }
338 
parse(&mut self, input: Vec<u8>) -> io::Result<()>339     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
340         let mut pack = PayloadHeadPack::default();
341         let buf = SerializedBuffer {
342             ptr: input.as_ptr() as *const libc::c_char,
343             size: input.len() as u64,
344         };
345         if unsafe { ParsePayloadHead(&mut pack, buf) == 0 } {
346             return Err(Error::new(ErrorKind::Other, "cffi ParsePayloadHead failed"));
347         }
348 
349         self.flag = pack.flag;
350         self.reserve = pack.reserve;
351         self.protocol_ver = pack.protocol_ver;
352         self.head_size = pack.head_size;
353         self.data_size = pack.data_size;
354 
355         Ok(())
356     }
357 }
358 
359 impl Serialization for UsbHead {
serialize(&self) -> Vec<u8>360     fn serialize(&self) -> Vec<u8> {
361         let pack = UsbHeadPack {
362             flag: self.flag,
363             option: self.option,
364             session_id: self.session_id,
365             data_size: self.data_size,
366         };
367         let buf = unsafe { SerializeUsbHead(&pack) };
368         buf_to_vec(buf)
369     }
370 
parse(&mut self, input: Vec<u8>) -> io::Result<()>371     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
372         let mut pack = UsbHeadPack::default();
373         let buf = SerializedBuffer {
374             ptr: input.as_ptr() as *const libc::c_char,
375             size: input.len() as u64,
376         };
377         if unsafe { ParseUsbHead(&mut pack, buf) == 0 } {
378             return Err(Error::new(ErrorKind::Other, "cffi ParseUsbHead failed"));
379         }
380 
381         self.flag = pack.flag;
382         self.option = pack.option;
383         self.session_id = pack.session_id;
384         self.data_size = pack.data_size;
385 
386         Ok(())
387     }
388 }
389 
390 impl Serialization for UartHead {
serialize(&self) -> Vec<u8>391     fn serialize(&self) -> Vec<u8> {
392         let pack = UartHeadPack {
393             flag: self.flag,
394             option: self.option,
395             session_id: self.session_id,
396             data_size: self.data_size,
397             package_index: self.package_index,
398             data_checksum: self.data_checksum,
399             head_checksum: self.head_checksum,
400         };
401         let buf = unsafe { SerializeUartHead(&pack) };
402         buf_to_vec(buf)
403     }
404 
parse(&mut self, input: Vec<u8>) -> io::Result<()>405     fn parse(&mut self, input: Vec<u8>) -> io::Result<()> {
406         let mut pack = UartHeadPack::default();
407         let buf = SerializedBuffer {
408             ptr: input.as_ptr() as *const libc::c_char,
409             size: input.len() as u64,
410         };
411         if unsafe { ParseUartHead(&mut pack, buf) == 0 } {
412             return Err(Error::new(ErrorKind::Other, "cffi ParseUartHead failed"));
413         }
414 
415         self.flag = pack.flag;
416         self.option = pack.option;
417         self.session_id = pack.session_id;
418         self.data_size = pack.data_size;
419         self.package_index = pack.package_index;
420         self.data_checksum = pack.data_checksum;
421         self.head_checksum = pack.head_checksum;
422 
423         Ok(())
424     }
425 }
426 
ptr_to_string(p: *const libc::c_char) -> String427 fn ptr_to_string(p: *const libc::c_char) -> String {
428     let c_str: &CStr = unsafe { CStr::from_ptr(p) };
429     c_str.to_str().unwrap().to_string()
430 }
431 
buf_to_vec(buf: SerializedBuffer) -> Vec<u8>432 pub fn buf_to_vec(buf: SerializedBuffer) -> Vec<u8> {
433     let slice =
434         unsafe { std::slice::from_raw_parts(buf.ptr as *const libc::c_uchar, buf.size as usize) };
435     slice.to_vec()
436 }
437