96 lines
2.6 KiB
Rust
96 lines
2.6 KiB
Rust
use bcd_convert::BcdNumber;
|
|
use rand::prelude::*;
|
|
|
|
#[allow(dead_code)]
|
|
const PROPS_SIZE_MASK: u16 = 0x01FF;
|
|
#[allow(dead_code)]
|
|
const PROPS_SUBCONTRACT_MASK: u16 = 0x3000;
|
|
#[allow(dead_code)]
|
|
const PROPS_RESERVED_MASK: u16 = 0xC000;
|
|
#[allow(dead_code)]
|
|
const PROPS_DATAENCRYPTION_MASK: u16 = 0x0E00;
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct MessageHeader {
|
|
id: u16,
|
|
properties: u16,
|
|
pub bodylength: u8,
|
|
encryption: u8,
|
|
encrypted: bool,
|
|
subcontract: bool,
|
|
reserved: u16,
|
|
raw_terminal_id: [u8; 6],
|
|
pub terminal_id: u64,
|
|
pub serial_number: u16,
|
|
}
|
|
|
|
impl MessageHeader {
|
|
pub fn build(&mut self, id: u16, properties: usize, raw_terminal_id: [u8; 6]) {
|
|
let mut rng = rand::thread_rng();
|
|
self.id = id;
|
|
self.properties = properties as u16;
|
|
self.raw_terminal_id = raw_terminal_id;
|
|
self.serial_number = rng.gen();
|
|
}
|
|
|
|
pub fn get_id(&mut self) -> u16 {
|
|
self.id
|
|
}
|
|
|
|
pub fn set_id(&mut self, id: u16) {
|
|
self.id = id;
|
|
}
|
|
|
|
pub fn set_properties(&mut self, properties: u16) {
|
|
self.properties = properties;
|
|
}
|
|
|
|
pub fn parse_properties(&mut self) {
|
|
self.bodylength = (self.properties & PROPS_SIZE_MASK) as u8;
|
|
self.encryption = ((self.properties & PROPS_DATAENCRYPTION_MASK) as u16 >> 10) as u8;
|
|
self.encrypted = self.encryption != 0;
|
|
self.subcontract = ((self.properties & PROPS_SUBCONTRACT_MASK) as u16 >> 13) == 1;
|
|
self.reserved = ((self.properties & PROPS_RESERVED_MASK) as u16 >> 14) as u16;
|
|
}
|
|
|
|
pub fn set_raw_terminal_id(&mut self, rtid: [u8; 6]) {
|
|
self.raw_terminal_id = rtid;
|
|
}
|
|
|
|
pub fn get_raw_terminal_id(&self) -> [u8; 6] {
|
|
self.raw_terminal_id
|
|
}
|
|
|
|
pub fn parse_terminal_id(&mut self) {
|
|
let code = BcdNumber::try_from(&self.raw_terminal_id as &[u8]).unwrap();
|
|
self.terminal_id = code.to_u64().unwrap();
|
|
}
|
|
|
|
pub fn to_raw(&self) -> Vec<u8> {
|
|
let mut r: Vec<u8> = vec![];
|
|
for b in self.id.to_be_bytes() {
|
|
r.push(b);
|
|
}
|
|
for b in self.properties.to_be_bytes() {
|
|
r.push(b);
|
|
}
|
|
for b in self.raw_terminal_id.into_iter() {
|
|
r.push(b);
|
|
}
|
|
for b in self.serial_number.to_be_bytes() {
|
|
r.push(b);
|
|
}
|
|
r
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for MessageHeader {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
write!(
|
|
f,
|
|
"message header: id: {:X?}, length: {}, terminal id: {}, serial: {:X?}",
|
|
self.id, self.bodylength, self.terminal_id, self.serial_number
|
|
)
|
|
}
|
|
}
|