update micodus_server

This commit is contained in:
Paul 2024-12-27 21:12:18 +01:00
parent d54a73244a
commit 83dd157ae1
6 changed files with 227 additions and 150 deletions

7
Cargo.lock generated
View File

@ -115,6 +115,12 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.169" version = "0.2.169"
@ -144,6 +150,7 @@ dependencies = [
"bcd-convert", "bcd-convert",
"bitvec", "bitvec",
"encoding_rs", "encoding_rs",
"lazy_static",
"rand", "rand",
"tokio", "tokio",
] ]

View File

@ -7,5 +7,6 @@ edition = "2021"
bcd-convert = { version = "0.1" } bcd-convert = { version = "0.1" }
bitvec = { version = "1.0.1" } bitvec = { version = "1.0.1" }
encoding_rs = { version = "0.8" } encoding_rs = { version = "0.8" }
lazy_static = { version = "1.5" }
rand = { version = "0.8" } rand = { version = "0.8" }
tokio = { version = "1.42", features = ["full", "sync"] } tokio = { version = "1.42", features = ["full", "sync"] }

View File

@ -9,6 +9,7 @@ use tokio::net::TcpListener;
//use tokio::sync::RwLock; //use tokio::sync::RwLock;
const ADDR: &'static str = "0.0.0.0:7700"; const ADDR: &'static str = "0.0.0.0:7700";
const BUFSIZE: usize = 1024;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
@ -30,8 +31,9 @@ pub async fn apiserver() -> io::Result<()> {
loop { loop {
let (socket, _remote_addr) = listener.accept().await?; let (socket, _remote_addr) = listener.accept().await?;
tokio::spawn(async move { tokio::spawn(async move {
let mut buf = vec![0; 1024]; let mut buf = vec![0; BUFSIZE];
loop { loop {
let mut terminal_id = 0;
match socket.readable().await { match socket.readable().await {
Ok(_) => { Ok(_) => {
match socket.try_read(&mut buf) { match socket.try_read(&mut buf) {
@ -55,6 +57,14 @@ pub async fn apiserver() -> io::Result<()> {
println!("error socket readable: {e}"); println!("error socket readable: {e}");
} }
} }
match socket.writable().await {
Ok(_) => {
let msg = Message::default();
}
Err(e) => {
println!("error socket writable: {e}")
}
}
} }
}); });
} }

View File

@ -31,6 +31,7 @@ pub trait BodyMessage {
fn to_raw(&self) -> Vec<u8> { fn to_raw(&self) -> Vec<u8> {
vec![] vec![]
} }
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
@ -43,11 +44,12 @@ pub struct TerminalUniversalResponse {
impl TerminalUniversalResponse { impl TerminalUniversalResponse {
pub const ID: u16 = 0x0001; pub const ID: u16 = 0x0001;
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
pub fn debug() {} pub fn debug() {}
} }
impl BodyMessage for TerminalUniversalResponse {} impl BodyMessage for TerminalUniversalResponse {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct PlatformUniversalResponse { pub struct PlatformUniversalResponse {
@ -107,7 +109,19 @@ pub struct TerminalRegistration {
impl TerminalRegistration { impl TerminalRegistration {
pub const ID: u16 = 0x0100; pub const ID: u16 = 0x0100;
pub fn parse(&mut self, rawbody: &Vec<u8>) { pub fn generate_reply(&self, terminal_id: Vec<u8>, serial: u16) -> TerminalRegistrationReply {
let mut res = TerminalRegistrationReply::default();
res.answer_serial_no = serial;
res.result = TerminalRegistrationResult::Success as u8;
//res.authentication_code = String::from_utf8(terminal_id).unwrap();
println!("{:?}", terminal_id);
res.authentication_code = vec![0x36, 0x31, 0x33, 0x32, 0x31, 0x31, 0x38];
res
}
}
impl BodyMessage for TerminalRegistration {
fn parse(&mut self, rawbody: &Vec<u8>) {
let mut bd = rawbody.into_iter(); //self.body_to_iter(rawbody); let mut bd = rawbody.into_iter(); //self.body_to_iter(rawbody);
self.provincial_id = u16::from_be_bytes( self.provincial_id = u16::from_be_bytes(
vec![*bd.next().unwrap(), *bd.next().unwrap()] vec![*bd.next().unwrap(), *bd.next().unwrap()]
@ -138,16 +152,6 @@ impl TerminalRegistration {
let (cow, _encoding_used, _had_errors) = GBK.decode(plate_decode); let (cow, _encoding_used, _had_errors) = GBK.decode(plate_decode);
self.license_plate = cow.into(); self.license_plate = cow.into();
} }
pub fn generate_reply(&self, terminal_id: Vec<u8>, serial: u16) -> TerminalRegistrationReply {
let mut res = TerminalRegistrationReply::default();
res.answer_serial_no = serial;
res.result = TerminalRegistrationResult::Success as u8;
//res.authentication_code = String::from_utf8(terminal_id).unwrap();
println!("{:?}", terminal_id);
res.authentication_code = vec![0x36, 0x31, 0x33, 0x32, 0x31, 0x31, 0x38];
res
}
} }
impl std::fmt::Display for TerminalRegistration { impl std::fmt::Display for TerminalRegistration {
@ -183,11 +187,10 @@ pub struct TerminalRegistrationReply {
impl TerminalRegistrationReply { impl TerminalRegistrationReply {
pub const ID: u16 = 0x8100; pub const ID: u16 = 0x8100;
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
impl BodyMessage for TerminalRegistrationReply { impl BodyMessage for TerminalRegistrationReply {
fn parse(&mut self, rawbody: &Vec<u8>) {}
fn to_raw(&self) -> Vec<u8> { fn to_raw(&self) -> Vec<u8> {
let mut res: Vec<u8> = vec![]; let mut res: Vec<u8> = vec![];
for b in self.answer_serial_no.to_be_bytes() { for b in self.answer_serial_no.to_be_bytes() {
@ -208,8 +211,6 @@ pub struct TerminalLogout {}
impl TerminalLogout { impl TerminalLogout {
pub const ID: u16 = 0x0003; pub const ID: u16 = 0x0003;
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse { pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
let mut res = PlatformUniversalResponse::default(); let mut res = PlatformUniversalResponse::default();
res.answer_serial_no = serial; res.answer_serial_no = serial;
@ -219,6 +220,10 @@ impl TerminalLogout {
} }
} }
impl BodyMessage for TerminalLogout {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
impl std::fmt::Display for TerminalLogout { impl std::fmt::Display for TerminalLogout {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self) write!(f, "{}", self)
@ -233,7 +238,17 @@ pub struct TerminalAuthentication {
impl TerminalAuthentication { impl TerminalAuthentication {
pub const ID: u16 = 0x0102; pub const ID: u16 = 0x0102;
pub fn parse(&mut self, rawbody: &Vec<u8>) { pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
let mut res = PlatformUniversalResponse::default();
res.answer_serial_no = serial;
res.answer_id = answer_id;
res.result = TerminalRegistrationResult::Success as u8;
res
}
}
impl BodyMessage for TerminalAuthentication {
fn parse(&mut self, rawbody: &Vec<u8>) {
let mut bd = rawbody.into_iter(); let mut bd = rawbody.into_iter();
let plate_decode: &mut Vec<u8> = &mut vec![]; let plate_decode: &mut Vec<u8> = &mut vec![];
while let Some(i) = bd.next() { while let Some(i) = bd.next() {
@ -243,14 +258,6 @@ impl TerminalAuthentication {
let (cow, _encoding_used, _had_errors) = GBK.decode(plate_decode); let (cow, _encoding_used, _had_errors) = GBK.decode(plate_decode);
self.authentication_code = cow.into(); self.authentication_code = cow.into();
} }
pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
let mut res = PlatformUniversalResponse::default();
res.answer_serial_no = serial;
res.answer_id = answer_id;
res.result = TerminalRegistrationResult::Success as u8;
res
}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
@ -261,8 +268,10 @@ pub struct TerminalParameterSetting {
impl TerminalParameterSetting { impl TerminalParameterSetting {
pub const ID: u16 = 0x8103; pub const ID: u16 = 0x8103;
}
pub fn parse(&mut self, rawbody: &Vec<u8>) {} impl BodyMessage for TerminalParameterSetting {
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
@ -272,16 +281,20 @@ pub struct TerminalParameterData {
pub parameter_value: u8, pub parameter_value: u8,
} }
impl TerminalParameterData { impl TerminalParameterData {}
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
impl BodyMessage for TerminalParameterData {
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct QueryTerminalParameter {} pub struct QueryTerminalParameter {}
impl QueryTerminalParameter { impl QueryTerminalParameter {
pub const ID: u16 = 0x8104; pub const ID: u16 = 0x8104;
}
pub fn parse(&mut self, rawbody: &Vec<u8>) {} impl BodyMessage for QueryTerminalParameter {
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
@ -293,8 +306,10 @@ pub struct QueryTerminalParameterResponse {
impl QueryTerminalParameterResponse { impl QueryTerminalParameterResponse {
pub const ID: u16 = 0x0104; pub const ID: u16 = 0x0104;
}
pub fn parse(&mut self, rawbody: &Vec<u8>) {} impl BodyMessage for QueryTerminalParameterResponse {
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
@ -305,8 +320,10 @@ pub struct TerminalControl {
impl TerminalControl { impl TerminalControl {
pub const ID: u16 = 0x8105; pub const ID: u16 = 0x8105;
}
pub fn parse(&mut self, rawbody: &Vec<u8>) {} impl BodyMessage for TerminalControl {
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
@ -324,7 +341,17 @@ pub struct LocationInformationReport {
impl LocationInformationReport { impl LocationInformationReport {
pub const ID: u16 = 0x0200; pub const ID: u16 = 0x0200;
pub fn parse(&mut self, rawbody: &Vec<u8>) { pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
let mut res = PlatformUniversalResponse::default();
res.answer_serial_no = serial;
res.answer_id = answer_id;
res.result = TerminalRegistrationResult::Success as u8;
res
}
}
impl BodyMessage for LocationInformationReport {
fn parse(&mut self, rawbody: &Vec<u8>) {
let mut bd = rawbody.into_iter(); let mut bd = rawbody.into_iter();
self.alert_mark = u32::from_be_bytes( self.alert_mark = u32::from_be_bytes(
vec![ vec![
@ -388,30 +415,26 @@ impl LocationInformationReport {
let code = BcdNumber::try_from(&tmptime as &[u8]).unwrap(); let code = BcdNumber::try_from(&tmptime as &[u8]).unwrap();
self.time = format!("{}", code.to_u64().unwrap()); self.time = format!("{}", code.to_u64().unwrap());
} }
pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
let mut res = PlatformUniversalResponse::default();
res.answer_serial_no = serial;
res.answer_id = answer_id;
res.result = TerminalRegistrationResult::Success as u8;
res
}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct StartOfTrip {} pub struct StartOfTrip {}
impl StartOfTrip { impl StartOfTrip {
pub const ID: u16 = 0x0202; pub const ID: u16 = 0x0202;
}
pub fn parse(&mut self, rawbody: &Vec<u8>) {} impl BodyMessage for StartOfTrip {
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct EndOfTrip {} pub struct EndOfTrip {}
impl EndOfTrip { impl EndOfTrip {
pub const ID: u16 = 0x0203; pub const ID: u16 = 0x0203;
}
pub fn parse(&mut self, rawbody: &Vec<u8>) {} impl BodyMessage for EndOfTrip {
fn parse(&mut self, rawbody: &Vec<u8>) {}
} }
struct BCDTime { struct BCDTime {

95
src/parser/header.rs Normal file
View File

@ -0,0 +1,95 @@
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,
pub encrypted: bool,
pub 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
)
}
}

View File

@ -1,25 +1,15 @@
mod body; mod body;
mod error; mod error;
mod header;
use body::*; use body::*;
use error::*; use error::*;
use header::*;
use std::collections::VecDeque; use std::collections::VecDeque;
use bcd_convert::BcdNumber;
use rand::prelude::*;
const FLAGDELIMITER: u8 = 0x7E; const FLAGDELIMITER: u8 = 0x7E;
#[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;
pub fn parse_inbound_msg( pub fn parse_inbound_msg(
rawdata: &mut InboundDataWrapper, rawdata: &mut InboundDataWrapper,
) -> std::result::Result<Message, MessageError> { ) -> std::result::Result<Message, MessageError> {
@ -98,39 +88,36 @@ pub struct Message {
valid: bool, valid: bool,
} }
impl std::fmt::Display for Message {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"Message: (header: {}), content: {}, checksum: {}, valid: {}",
self.header, self.content, self.checksum, self.valid
)
}
}
impl Message { impl Message {
pub fn new() -> Self {
let msg = Self::default();
return msg;
}
fn parse_header( fn parse_header(
&mut self, &mut self,
rawdata: &mut InboundDataWrapper, rawdata: &mut InboundDataWrapper,
) -> std::result::Result<(), NotOurProtocolError> { ) -> std::result::Result<(), NotOurProtocolError> {
let data = rawdata.into_iter(); let data = rawdata.into_iter();
self.header.id = u16::from_be_bytes( self.header.set_id(u16::from_be_bytes(
vec![data.next().unwrap(), data.next().unwrap()] vec![data.next().unwrap(), data.next().unwrap()]
.try_into() .try_into()
.unwrap(), .unwrap(),
); ));
self.header.properties = u16::from_be_bytes( self.header.set_properties(u16::from_be_bytes(
vec![data.next().unwrap(), data.next().unwrap()] vec![data.next().unwrap(), data.next().unwrap()]
.try_into() .try_into()
.unwrap(), .unwrap(),
); ));
self.parse_properties(); self.header.parse_properties();
for i in 0..self.header.raw_terminal_id.len() { let mut rtid: [u8; 6] = [0; 6];
self.header.raw_terminal_id[i] = data.next().unwrap(); for i in 0..rtid.len() {
rtid[i] = data.next().unwrap();
} }
self.parse_terminal_id(); self.header.set_raw_terminal_id(rtid);
self.header.parse_terminal_id();
self.header.serial_number = u16::from_be_bytes( self.header.serial_number = u16::from_be_bytes(
vec![data.next().unwrap(), data.next().unwrap()] vec![data.next().unwrap(), data.next().unwrap()]
@ -148,21 +135,6 @@ impl Message {
Ok(()) Ok(())
} }
fn parse_properties(&mut self) {
self.header.bodylength = (self.header.properties & PROPS_SIZE_MASK) as u8;
self.header.encryption =
((self.header.properties & PROPS_DATAENCRYPTION_MASK) as u16 >> 10) as u8;
self.header.encrypted = self.header.encryption != 0;
self.header.subcontract =
((self.header.properties & PROPS_SUBCONTRACT_MASK) as u16 >> 13) == 1;
self.header.reserved = ((self.header.properties & PROPS_RESERVED_MASK) as u16 >> 14) as u16;
}
fn parse_terminal_id(&mut self) {
let code = BcdNumber::try_from(&self.header.raw_terminal_id as &[u8]).unwrap();
self.header.terminal_id = code.to_u64().unwrap();
}
pub fn inbound_check(&mut self, rawdata: &mut InboundDataWrapper) { pub fn inbound_check(&mut self, rawdata: &mut InboundDataWrapper) {
let data = rawdata.into_iter(); let data = rawdata.into_iter();
let mut check: u8 = 0; let mut check: u8 = 0;
@ -181,7 +153,7 @@ impl Message {
} }
fn parse_body(&mut self) { fn parse_body(&mut self) {
match self.header.id { match self.header.get_id() {
TerminalUniversalResponse::ID => { TerminalUniversalResponse::ID => {
self.content = MessageType::TerminalUniversalResponse( self.content = MessageType::TerminalUniversalResponse(
TerminalUniversalResponse::new(&self.body), TerminalUniversalResponse::new(&self.body),
@ -246,50 +218,52 @@ impl Message {
pub fn set_reply(inmsg: Message) -> Option<Message> { pub fn set_reply(inmsg: Message) -> Option<Message> {
let mut reply: Message = Message::default(); let mut reply: Message = Message::default();
let mut rng = rand::thread_rng(); let terminal_id = inmsg.header.get_raw_terminal_id().clone();
match inmsg.content { match inmsg.content {
MessageType::TerminalRegistration(t) => { MessageType::TerminalRegistration(t) => {
let cnt = t.generate_reply( let cnt = t.generate_reply(terminal_id.into(), inmsg.header.serial_number);
inmsg.header.raw_terminal_id.into(), reply.header.build(
inmsg.header.serial_number, TerminalRegistrationReply::ID,
cnt.to_raw().len(),
terminal_id,
); );
reply.header.id = TerminalRegistrationReply::ID;
reply.header.properties = cnt.to_raw().len() as u16;
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id;
reply.header.serial_number = rng.gen();
reply.content = MessageType::TerminalRegistrationReply(cnt); reply.content = MessageType::TerminalRegistrationReply(cnt);
} }
MessageType::TerminalAuthentication(t) => { MessageType::TerminalAuthentication(t) => {
let cnt = t.generate_reply(TerminalAuthentication::ID, inmsg.header.serial_number); let cnt = t.generate_reply(TerminalAuthentication::ID, inmsg.header.serial_number);
reply.header.id = PlatformUniversalResponse::ID; reply.header.build(
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id; PlatformUniversalResponse::ID,
reply.header.properties = cnt.to_raw().len() as u16; cnt.to_raw().len(),
reply.header.serial_number = rng.gen(); terminal_id,
);
reply.content = MessageType::PlatformUniversalResponse(cnt); reply.content = MessageType::PlatformUniversalResponse(cnt);
} }
MessageType::LocationInformationReport(t) => { MessageType::LocationInformationReport(t) => {
let cnt = let cnt =
t.generate_reply(LocationInformationReport::ID, inmsg.header.serial_number); t.generate_reply(LocationInformationReport::ID, inmsg.header.serial_number);
reply.header.id = PlatformUniversalResponse::ID; reply.header.build(
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id; PlatformUniversalResponse::ID,
reply.header.properties = cnt.to_raw().len() as u16; cnt.to_raw().len(),
reply.header.serial_number = rng.gen(); terminal_id,
);
reply.content = MessageType::PlatformUniversalResponse(cnt); reply.content = MessageType::PlatformUniversalResponse(cnt);
} }
MessageType::TerminalHeartbeat(t) => { MessageType::TerminalHeartbeat(t) => {
let cnt = t.generate_reply(TerminalHeartbeat::ID, inmsg.header.serial_number); let cnt = t.generate_reply(TerminalHeartbeat::ID, inmsg.header.serial_number);
reply.header.id = PlatformUniversalResponse::ID; reply.header.build(
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id; PlatformUniversalResponse::ID,
reply.header.properties = cnt.to_raw().len() as u16; cnt.to_raw().len(),
reply.header.serial_number = rng.gen(); terminal_id,
);
reply.content = MessageType::PlatformUniversalResponse(cnt); reply.content = MessageType::PlatformUniversalResponse(cnt);
} }
MessageType::TerminalLogout(t) => { MessageType::TerminalLogout(t) => {
let cnt = t.generate_reply(TerminalHeartbeat::ID, inmsg.header.serial_number); let cnt = t.generate_reply(TerminalHeartbeat::ID, inmsg.header.serial_number);
reply.header.id = PlatformUniversalResponse::ID; reply.header.build(
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id; PlatformUniversalResponse::ID,
reply.header.properties = cnt.to_raw().len() as u16; cnt.to_raw().len(),
reply.header.serial_number = rng.gen(); terminal_id,
);
reply.content = MessageType::PlatformUniversalResponse(cnt); reply.content = MessageType::PlatformUniversalResponse(cnt);
} }
_ => { _ => {
@ -342,45 +316,12 @@ impl Message {
} }
} }
#[derive(Default, Debug)] impl std::fmt::Display for Message {
pub struct MessageHeader {
id: u16,
properties: u16,
pub bodylength: u8,
encryption: u8,
pub encrypted: bool,
pub subcontract: bool,
reserved: u16,
raw_terminal_id: [u8; 6],
pub terminal_id: u64,
pub serial_number: u16,
}
impl MessageHeader {
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 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!( write!(
f, f,
"message header: id: {:X?}, length: {}, terminal id: {}, serial: {:X?}", "Message: (header: {}), content: {}, checksum: {}, valid: {}",
self.id, self.bodylength, self.terminal_id, self.serial_number self.header, self.content, self.checksum, self.valid
) )
} }
} }