update micodus_server

This commit is contained in:
Paul 2024-12-27 14:47:32 +01:00
parent bcd452c117
commit 65461f6f9e
3 changed files with 222 additions and 115 deletions

View File

@ -1,6 +1,5 @@
pub mod parser;
pub use crate::parser::body::*;
pub use crate::parser::*;
use std::io;
@ -28,12 +27,11 @@ pub async fn apiserver() -> io::Result<()> {
}
};
tokio::spawn(async move {
loop {
match listener.accept().await {
Ok((socket, _remote_addr)) => {
let (socket, _remote_addr) = listener.accept().await?;
tokio::spawn(async move {
let mut buf = vec![0; 1024];
loop {
match socket.readable().await {
Ok(_) => {
match socket.try_read(&mut buf) {
@ -41,35 +39,34 @@ pub async fn apiserver() -> io::Result<()> {
Some(o) => {
let _ = socket.try_write(&o).unwrap();
}
None => {}
None => {
break;
}
},
Err(e) => {
println!("error: {e}");
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
println!("error read: {e}");
}
};
}
Err(e) => {
println!("error: {e}");
continue;
}
}
}
Err(err) => {
println!("error: {err}");
println!("error socket readable: {e}");
}
}
}
});
Ok(())
}
}
pub fn handle(buf: &Vec<u8>) -> Option<Vec<u8>> {
let mut rawdata = DataWrapper::new(buf.to_vec());
let mut rawdata = InboundDataWrapper::new(buf.to_vec());
let reply = match parse_inbound_msg(&mut rawdata) {
Ok(o) => {
Ok(mut o) => {
println!("query: {}", o);
println!("raw query: {:?}", o.to_raw());
println!("raw query: {:X?}", o.to_raw());
Message::store(&o);
Message::set_reply(o)
}
Err(e) => {
@ -79,9 +76,9 @@ pub fn handle(buf: &Vec<u8>) -> Option<Vec<u8>> {
};
match reply {
Some(o) => {
Some(mut o) => {
println!("reply: {}", o);
println!("raw reply {:?}", o.to_raw());
println!("raw reply {:X?}", o.to_raw());
return Some(o.to_raw().into());
}
None => {

View File

@ -1,3 +1,4 @@
use bcd_convert::BcdNumber;
use encoding_rs::*;
macro_rules! generate_impl {
@ -80,7 +81,16 @@ pub struct TerminalHeartbeat {}
impl TerminalHeartbeat {
pub const ID: u16 = 0x0002;
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
}
}
#[derive(Default, Debug, Clone)]
@ -296,15 +306,87 @@ pub struct LocationInformationReport {
pub status: u32,
pub latitude: u32,
pub longitude: u32,
pub height: u32,
pub speed: u32,
pub direction: u32,
pub time: u32,
pub height: u16,
pub speed: u16,
pub direction: u16,
pub time: u64,
}
impl LocationInformationReport {
pub const ID: u16 = 0x0200;
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
pub fn parse(&mut self, rawbody: &Vec<u8>) {
let mut bd = rawbody.into_iter();
self.alert_mark = u32::from_be_bytes(
vec![
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
]
.try_into()
.unwrap(),
);
self.status = u32::from_be_bytes(
vec![
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
]
.try_into()
.unwrap(),
);
self.latitude = u32::from_be_bytes(
vec![
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
]
.try_into()
.unwrap(),
);
self.longitude = u32::from_be_bytes(
vec![
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
]
.try_into()
.unwrap(),
);
self.height = u16::from_be_bytes(
vec![*bd.next().unwrap(), *bd.next().unwrap()]
.try_into()
.unwrap(),
);
self.speed = u16::from_be_bytes(
vec![*bd.next().unwrap(), *bd.next().unwrap()]
.try_into()
.unwrap(),
);
self.direction = u16::from_be_bytes(
vec![*bd.next().unwrap(), *bd.next().unwrap()]
.try_into()
.unwrap(),
);
let mut tmptime: [u8; 6] = [0; 6];
for i in 0..tmptime.len() {
tmptime[i] = *bd.next().unwrap();
}
let code = BcdNumber::try_from(&tmptime as &[u8]).unwrap();
self.time = 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)]

View File

@ -1,5 +1,5 @@
pub mod body;
pub mod error;
mod body;
mod error;
use body::*;
use error::*;
@ -20,12 +20,14 @@ const PROPS_RESERVED_MASK: u16 = 0xC000;
#[allow(dead_code)]
const PROPS_DATAENCRYPTION_MASK: u16 = 0x0E00;
pub fn parse_inbound_msg(rawdata: &mut DataWrapper) -> std::result::Result<Message, MessageError> {
pub fn parse_inbound_msg(
rawdata: &mut InboundDataWrapper,
) -> std::result::Result<Message, MessageError> {
let mut msg: Message = Message::default();
match msg.parse_header(rawdata) {
Ok(_) => {
msg.check(rawdata);
msg.inbound_check(rawdata);
}
Err(e) => {
println!("error parsing header {e}");
@ -37,30 +39,49 @@ pub fn parse_inbound_msg(rawdata: &mut DataWrapper) -> std::result::Result<Messa
}
#[derive(Default, Debug)]
pub struct DataWrapper {
pub struct InboundDataWrapper {
pub data: VecDeque<u8>,
pub count: usize,
pub start: bool,
pub end: bool,
}
impl DataWrapper {
pub fn new(data: Vec<u8>) -> DataWrapper {
DataWrapper {
impl InboundDataWrapper {
pub fn new(data: Vec<u8>) -> InboundDataWrapper {
InboundDataWrapper {
data: data.into(),
count: 0,
start: false,
end: false,
}
}
}
impl Iterator for DataWrapper {
impl Iterator for InboundDataWrapper {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
let res: Option<u8>;
if self.count < 6 {
res = self.data.pop_front()
} else {
res = None
loop {
match self.data.pop_front() {
Some(o) => {
if o == FLAGDELIMITER {
if self.start {
self.end = true;
res = None;
break;
}
self.start = true;
continue;
}
res = Some(o);
}
None => {
res = None;
}
};
break;
}
self.count += 1;
@ -88,22 +109,22 @@ impl std::fmt::Display for Message {
}
impl Message {
pub fn parse_header(
fn parse_header(
&mut self,
rawdata: &mut DataWrapper,
rawdata: &mut InboundDataWrapper,
) -> std::result::Result<(), NotOurProtocolError> {
let mut data = rawdata.data.clone().into_iter();
let first_byte = data.next().unwrap();
if first_byte != FLAGDELIMITER {
return Err(NotOurProtocolError);
};
let mut tmpid = vec![];
tmpid.push(data.next().unwrap());
tmpid.push(data.next().unwrap());
self.header.id = u16::from_be_bytes(tmpid.try_into().unwrap());
//self.header.id = ((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
let data = rawdata.into_iter();
self.header.id = u16::from_be_bytes(
vec![data.next().unwrap(), data.next().unwrap()]
.try_into()
.unwrap(),
);
self.header.properties = ((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
self.header.properties = u16::from_be_bytes(
vec![data.next().unwrap(), data.next().unwrap()]
.try_into()
.unwrap(),
);
self.parse_properties();
for i in 0..self.header.raw_terminal_id.len() {
@ -111,8 +132,11 @@ impl Message {
}
self.parse_terminal_id();
self.header.serial_number =
((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
self.header.serial_number = u16::from_be_bytes(
vec![data.next().unwrap(), data.next().unwrap()]
.try_into()
.unwrap(),
);
for _ in 0..self.header.bodylength as usize {
self.body.push(data.next().unwrap());
@ -120,14 +144,11 @@ impl Message {
self.checksum = data.next().unwrap();
if data.next().unwrap() != FLAGDELIMITER {
return Err(NotOurProtocolError);
}
self.parse_body();
Ok(())
}
pub fn parse_properties(&mut self) {
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;
@ -137,36 +158,29 @@ impl Message {
self.header.reserved = ((self.header.properties & PROPS_RESERVED_MASK) as u16 >> 14) as u16;
}
pub fn parse_terminal_id(&mut self) {
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 check(&mut self, rawdata: &mut DataWrapper) {
let mut data = rawdata.data.iter();
data.next().unwrap();
pub fn inbound_check(&mut self, rawdata: &mut InboundDataWrapper) {
let data = rawdata.into_iter();
let mut check: u8 = 0;
loop {
let b = data.next().unwrap();
if *b == FLAGDELIMITER {
break;
}
check = *b ^ check;
let _ = data.map(|b| check ^= b);
self.inbound_validate(check);
}
self.validate(check);
}
fn validate(&mut self, check: u8) {
fn inbound_validate(&mut self, check: u8) {
self.valid = check == 0;
}
pub fn is_valid(&self) -> bool {
fn _is_valid(&self) -> bool {
self.valid
}
pub fn parse_body(&mut self) {
fn parse_body(&mut self) {
match self.header.id {
TerminalUniversalResponse::ID => {
self.content = MessageType::TerminalUniversalResponse(
@ -253,19 +267,57 @@ impl Message {
reply.header.serial_number = rng.gen();
reply.content = MessageType::PlatformUniversalResponse(cnt);
}
MessageType::LocationInformationReport(t) => {
let cnt =
t.generate_reply(LocationInformationReport::ID, inmsg.header.serial_number);
reply.header.id = PlatformUniversalResponse::ID;
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id;
reply.header.properties = cnt.to_raw().len() as u16;
reply.header.serial_number = rng.gen();
reply.content = MessageType::PlatformUniversalResponse(cnt);
}
MessageType::TerminalHeartbeat(t) => {
let cnt = t.generate_reply(TerminalHeartbeat::ID, inmsg.header.serial_number);
reply.header.id = PlatformUniversalResponse::ID;
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id;
reply.header.properties = cnt.to_raw().len() as u16;
reply.header.serial_number = rng.gen();
reply.content = MessageType::PlatformUniversalResponse(cnt);
}
_ => {
println!("no type");
return None;
}
}
reply.outbound_finalize();
Some(reply)
}
pub fn to_raw(&self) -> VecDeque<u8> {
let mut resp: VecDeque<u8> = vec![].into();
pub fn store(inmsg: &Message) {
match inmsg.content {
MessageType::LocationInformationReport(ref t) => {
println!("{:?}", t);
}
_ => {}
}
}
pub fn outbound_finalize(&mut self) {
let mut checksum: u8 = 0;
for v in vec![self.header.to_raw(), self.content.to_raw()] {
for b in v {
checksum = checksum ^ b;
}
}
self.checksum = checksum;
self.valid = true;
}
pub fn to_raw(&mut self) -> VecDeque<u8> {
let mut resp: VecDeque<u8> = vec![].into();
for b in self.header.to_raw() {
resp.push_back(b);
}
@ -274,11 +326,7 @@ impl Message {
resp.push_back(b);
}
for b in resp.iter() {
checksum = checksum ^ b;
}
resp.push_back(checksum);
resp.push_back(self.checksum);
resp.push_front(FLAGDELIMITER);
resp.push_back(FLAGDELIMITER);
@ -371,23 +419,3 @@ impl std::fmt::Display for MessageType {
write!(f, "{:?}", self)
}
}
/*
macro_rules! generate_switch {
($($t:ty),*) => {
$(
//impl BodyMessage for $t {
// fn build() {}
// fn body_to_iter<'a>(&'a self, rawbody: &'a Vec<u8>) -> std::slice::Iter<'a, u8> {
// rawbody.into_iter()
// }
//}
impl $t {
pub fn new(rawbody: &Vec<u8>) -> Self {
let mut res = Self::default();
res.parse(rawbody);
res
}
})*
};
}*/