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