2023-09-29 13:10:47 +00:00
|
|
|
use std::str::from_utf8;
|
|
|
|
|
|
|
|
use chrono::Local;
|
|
|
|
|
|
|
|
use crate::{command::RequestSerializer, security::Security};
|
|
|
|
|
|
|
|
pub struct PacketBuilder<S: RequestSerializer> {
|
|
|
|
command: S,
|
|
|
|
|
|
|
|
packet: [u8; 40],
|
2023-09-26 12:37:59 +00:00
|
|
|
}
|
|
|
|
|
2023-09-29 13:10:47 +00:00
|
|
|
impl<S: RequestSerializer> PacketBuilder<S> {
|
|
|
|
pub fn builder(device_id: u64, command: S) -> Self {
|
|
|
|
#[rustfmt::skip]
|
|
|
|
let mut packet = [
|
|
|
|
// 2 bytes - StaicHeader
|
|
|
|
0x5a, 0x5a,
|
|
|
|
// 2 bytes - mMessageType
|
|
|
|
0x01, 0x11,
|
|
|
|
// 2 bytes - PacketLenght
|
|
|
|
0x00, 0x00,
|
|
|
|
// 2 bytes
|
|
|
|
0x20, 0x00,
|
|
|
|
// 4 bytes - MessageId
|
|
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
// 8 bytes - Date&Time
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
// 6 bytes - mDeviceID
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
// 12 bytes
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
|
];
|
|
|
|
|
|
|
|
packet[12..20].copy_from_slice(&Self::packet_time());
|
|
|
|
packet[20..28].copy_from_slice(&device_id.to_le_bytes()[0..8]);
|
|
|
|
|
|
|
|
Self { command, packet }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn packet_time() -> [u8; 8] {
|
|
|
|
let mut t = Local::now()
|
|
|
|
.format("%Y%m%d%H%M%S%f")
|
|
|
|
.to_string()
|
|
|
|
.as_bytes()
|
|
|
|
.to_vec();
|
|
|
|
t.truncate(16);
|
|
|
|
|
|
|
|
let mut b = [0; 8];
|
|
|
|
|
|
|
|
for (index, chars) in t.chunks(2).enumerate() {
|
|
|
|
b[7 - index] = from_utf8(chars).unwrap().parse().unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
b
|
2023-09-26 12:37:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn finalize(self, msg_type: u8) -> Vec<u8> {
|
2023-09-29 13:10:47 +00:00
|
|
|
let mut packet = self.packet.to_vec();
|
|
|
|
|
|
|
|
if msg_type != 1 {
|
|
|
|
packet[3] = 0x10;
|
|
|
|
packet[6] = 0x7b;
|
|
|
|
} else {
|
|
|
|
let mut data = self.command.serialize();
|
2023-10-02 07:30:58 +00:00
|
|
|
|
|
|
|
// data
|
|
|
|
let d = b"\xaa\x1d\xe1\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b";
|
|
|
|
|
|
|
|
assert_eq!(data, d);
|
|
|
|
|
2023-09-29 13:10:47 +00:00
|
|
|
Security::aes_encrypt(&mut data);
|
|
|
|
|
|
|
|
packet.extend(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// packet length
|
|
|
|
packet[4..6].copy_from_slice(&(self.packet.len() as u16 + 16).to_le_bytes());
|
|
|
|
|
|
|
|
// append a basic checksum data (16 bytes) to the packet
|
|
|
|
packet.extend(Security::encode32_data(&self.packet));
|
|
|
|
|
|
|
|
packet
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use std::str::from_utf8;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn packet_time() {
|
|
|
|
let t = b"2023092913400641";
|
|
|
|
let b_ref = b")\x06(\r\x1d\t\x17\x14";
|
|
|
|
|
|
|
|
let mut b = [0; 8];
|
|
|
|
|
|
|
|
for (index, chars) in t.chunks(2).enumerate() {
|
|
|
|
b[7 - index] = from_utf8(chars).unwrap().parse().unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(&b, b_ref);
|
2023-09-26 12:37:59 +00:00
|
|
|
}
|
|
|
|
}
|