diff --git a/src/main.rs b/src/main.rs index 6518d5f..28e45b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ pub mod parser; -pub use crate::parser::body::*; pub use crate::parser::*; use std::io; @@ -28,48 +27,46 @@ pub async fn apiserver() -> io::Result<()> { } }; - tokio::spawn(async move { - loop { - match listener.accept().await { - Ok((socket, _remote_addr)) => { - let mut buf = vec![0; 1024]; - - match socket.readable().await { - Ok(_) => { - match socket.try_read(&mut buf) { - Ok(_) => match handle(&buf) { - Some(o) => { - let _ = socket.try_write(&o).unwrap(); - } - None => {} - }, - Err(e) => { - println!("error: {e}"); - continue; + loop { + 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) { + Ok(_) => match handle(&buf) { + Some(o) => { + let _ = socket.try_write(&o).unwrap(); } - }; - } - Err(e) => { - println!("error: {e}"); - continue; - } + None => { + break; + } + }, + Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { + continue; + } + Err(e) => { + println!("error read: {e}"); + } + }; + } + Err(e) => { + println!("error socket readable: {e}"); } } - Err(err) => { - println!("error: {err}"); - } } - } - }); - Ok(()) + }); + } } pub fn handle(buf: &Vec) -> Option> { - 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) -> Option> { }; 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 => { diff --git a/src/parser/body.rs b/src/parser/body.rs index c9601ef..b4453a3 100644 --- a/src/parser/body.rs +++ b/src/parser/body.rs @@ -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) {} + + 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) {} + + pub fn parse(&mut self, rawbody: &Vec) { + 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)] diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 32359b3..f9cb529 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -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 { +pub fn parse_inbound_msg( + rawdata: &mut InboundDataWrapper, +) -> std::result::Result { 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, pub count: usize, + pub start: bool, + pub end: bool, } -impl DataWrapper { - pub fn new(data: Vec) -> DataWrapper { - DataWrapper { +impl InboundDataWrapper { + pub fn new(data: Vec) -> 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 { let res: Option; - 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.validate(check); + self.inbound_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 { - let mut resp: VecDeque = 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 { + let mut resp: VecDeque = 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) -> std::slice::Iter<'a, u8> { - // rawbody.into_iter() - // } - //} - impl $t { - pub fn new(rawbody: &Vec) -> Self { - let mut res = Self::default(); - res.parse(rawbody); - res - } - })* - }; -}*/