update micodus_server

This commit is contained in:
Paul 2024-12-22 09:28:00 +01:00
parent 97b2783672
commit 99b779c5f7
3 changed files with 225 additions and 59 deletions

View File

@ -1,10 +1,14 @@
use std::io; pub mod parser;
use std::sync::Arc;
use tokio::io::AsyncWriteExt;
use tokio::net::TcpListener;
use tokio::sync::RwLock;
const FLAG: u8 = 0x7e; pub use crate::parser::*;
use std::io;
//use std::sync::Arc;
use tokio::net::TcpListener;
//use tokio::sync::RwLock;
const ADDR: &'static str = "0.0.0.0:7700";
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
@ -15,8 +19,7 @@ async fn main() {
} }
pub async fn apiserver() -> io::Result<()> { pub async fn apiserver() -> io::Result<()> {
let addr = "0.0.0.0:7700"; let listener = match TcpListener::bind(ADDR).await {
let listener = match TcpListener::bind(addr).await {
Ok(o) => o, Ok(o) => o,
Err(e) => { Err(e) => {
println!("error: {e}"); println!("error: {e}");
@ -27,7 +30,7 @@ pub async fn apiserver() -> io::Result<()> {
tokio::spawn(async move { tokio::spawn(async move {
loop { loop {
match listener.accept().await { match listener.accept().await {
Ok((mut socket, _addr)) => { Ok((socket, _remote_addr)) => {
let mut buf = vec![0; 256]; let mut buf = vec![0; 256];
match socket.readable().await { match socket.readable().await {
@ -46,8 +49,8 @@ pub async fn apiserver() -> io::Result<()> {
} }
} }
let data = buf.to_vec(); let mut rawdata = buf.to_vec();
let msg = parse_msg(data); let msg = parse_inbound_msg(&mut rawdata);
println!("{:X?}", msg); println!("{:X?}", msg);
} }
Err(err) => { Err(err) => {
@ -58,51 +61,3 @@ pub async fn apiserver() -> io::Result<()> {
}); });
Ok(()) Ok(())
} }
fn parse_msg(data: Vec<u8>) -> Message {
if data[0] == FLAG {
println!("first flag ok");
};
let mut msg: Message = Message::default();
msg.Header.Id = msg.Header.Id + (data[1] << 1) as u16 + data[2] as u16;
msg.Header.Properties = msg.Header.Properties + (data[3] << 1) as u16 + data[4] as u16;
for (i, v) in data[5..11].iter().enumerate() {
msg.Header.TerminalId[i] = *v;
}
msg.Header.SerialNumber = msg.Header.SerialNumber + (data[11] << 1) as u16 + data[12] as u16;
let endbody = 13 + msg.Header.Properties as usize;
let range: std::ops::Range<usize> = 13..(endbody);
let check_idx = 13 + msg.Header.Properties as usize;
let endflag: u8 = check_idx as u8 + 1;
for i in data[range].iter() {
msg.Body.push(*i);
}
msg.Check = data[check_idx];
if data[endflag as usize] == FLAG {
println!("end flag ok");
} else {
println!("error with endflag");
}
msg
}
#[derive(Default, Debug)]
pub struct Message {
pub Header: MessageHeader,
pub Body: Vec<u8>,
pub Check: u8,
}
#[derive(Default, Debug)]
pub struct MessageHeader {
pub Id: u16,
pub Properties: u16,
pub TerminalId: [u8; 6],
pub SerialNumber: u16,
}

113
src/parser/body.rs Normal file
View File

@ -0,0 +1,113 @@
#[derive(Default, Debug)]
pub struct TerminalUniversalResponse {
pub answer_serial_no: u16,
pub answer_id: u16,
pub result: u8,
}
impl BodyMessage for TerminalUniversalResponse {}
#[derive(Default, Debug)]
pub struct PlatformUniversalResponse {
pub answer_serial_no: u16,
pub answer_id: u16,
pub result: u8,
}
#[derive(Default, Debug)]
pub struct TerminalHeartbeat {}
#[derive(Default, Debug)]
pub struct TerminalRegistration {
pub provincial_id: u16,
pub city_and_prefecture_id: u16,
pub manufacturer_id: [u8; 5],
pub terminal_models: [u8; 8],
pub terminal_id: [u8; 7],
pub license_plate_color: u8,
pub license_plate: String,
}
#[derive(Default, Debug)]
pub struct TerminalRegistrationReply {
pub answer_serial_no: u16,
pub result: u8,
pub authentication_code: String,
}
#[derive(Default, Debug)]
pub struct TerminalLogout {}
#[derive(Default, Debug)]
pub struct TerminalAuthentication {
pub authentication_code: String,
}
#[derive(Default, Debug)]
pub struct TerminalParameterSetting {
pub total_parameters: u8,
pub parameters: Vec<TerminalParameterData>,
}
#[derive(Default, Debug)]
pub struct TerminalParameterData {
pub parameter_id: u32,
pub parameter_length: u8,
pub parameter_value: u8,
}
#[derive(Default, Debug)]
pub struct QueryTerminalParameter {}
#[derive(Default, Debug)]
pub struct QueryTerminalParameterResponse {
pub response_serial_no: u16,
pub response_parameter_quantity: u16,
pub parameters: Vec<TerminalParameterData>,
}
#[derive(Default, Debug)]
pub struct TerminalControl {
pub command_word: u8,
pub command_parameter: String,
}
#[derive(Default, Debug)]
pub struct LocationInformationReport {
pub alert_mark: u32,
pub status: u32,
pub latitude: u32,
pub longitude: u32,
pub height: u32,
pub speed: u32,
pub direction: u32,
pub time: u32,
}
#[derive(Default, Debug)]
pub struct StartOfTrip {}
#[derive(Default, Debug)]
pub struct EndOfTrip {}
#[derive(Debug)]
pub enum BodyType {
TerminalUniversalResponse = 0x0001,
PlatformUniversalResponse = 0x8001,
TerminalHeartbeat = 0x0002,
TerminalRegistration = 0x0100,
TerminalRegistrationReply = 0x8100,
TerminalLogout = 0x0003,
TerminalAuthentication = 0x0102,
TerminalParameterSetting = 0x8103,
QueryTerminalParameter = 0x8104,
QueryTerminalParameterResponse = 0x0104,
TerminalControl = 0x8105,
LocationInformationReport = 0x0200,
StartOfTrip = 0x0202,
EndOfTrip = 0x0203,
}
pub trait BodyMessage {
fn parse() {}
}

98
src/parser/mod.rs Normal file
View File

@ -0,0 +1,98 @@
mod body;
use body::*;
const FLAGDELIMITER: u8 = 0x7E;
#[allow(dead_code)]
const PropsSizeMask: u16 = 0x01FF;
const PropsSubcontractMask: u16 = 0x3000;
const PropsReservedMask: u16 = 0xC000;
const PropsDataEncryptionMask: u16 = 0x0E00;
pub fn parse_inbound_msg(rawdata: &mut Vec<u8>) -> Message {
let mut msg: Message = Message::default();
msg.parse_header(rawdata);
msg.check(rawdata);
msg
}
#[derive(Default, Debug)]
pub struct Message {
pub header: MessageHeader,
pub body: Vec<u8>,
pub checksum: u8,
valid: bool,
}
impl Message {
pub fn parse_header(&mut self, rawdata: &mut Vec<u8>) {
let mut data = rawdata.clone().into_iter();
let first_byte = data.next().unwrap();
if first_byte == FLAGDELIMITER {
println!("first flag ok");
};
self.header.id = ((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
self.header.properties = ((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
for i in 0..self.header.terminal_id.len() {
self.header.terminal_id[i] = data.next().unwrap();
}
self.parse_properties();
self.header.serial_number =
((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
for _ in 0..self.header.properties as usize {
self.body.push(data.next().unwrap());
}
self.checksum = data.next().unwrap();
if data.next().unwrap() == FLAGDELIMITER {
println!("end flag ok");
} else {
println!("error with endflag");
}
}
pub fn parse_properties(&mut self) {
self.header.bodylength = (self.header.properties & PropsSizeMask) as u8;
}
pub fn check(&mut self, rawdata: &mut Vec<u8>) {
let mut data = rawdata.into_iter();
data.next().unwrap();
let mut check: u8 = 0;
loop {
let b = data.next().unwrap();
if *b == FLAGDELIMITER {
break;
}
check = *b ^ check;
}
self.validate(check);
}
fn validate(&mut self, check: u8) {
println!("{}", BodyType::TerminalHeartbeat as u16);
self.valid = check == 0;
}
pub fn is_valid(&self) -> bool {
self.valid
}
}
#[derive(Default, Debug)]
pub struct MessageHeader {
pub id: u16,
properties: u16,
pub bodylength: u8,
pub encryption: bool,
pub terminal_id: [u8; 6],
pub serial_number: u16,
}