pub trait BodyMessage { fn build() {} fn body_to_iter<'a>(&'a self, rawbody: &'a Vec<u8>) -> std::slice::Iter<'a, u8> { rawbody.into_iter() } fn print(&mut self, rawbody: &Vec<u8>) { println!("{:?}", rawbody); } } macro_rules! generate_impl { ($($t:ty),*) => { $( impl BodyMessage for $t { fn build() {} } impl $t { pub fn new(rawbody: &Vec<u8>) -> Self { let mut res = Self::default(); res.parse(rawbody); res } })* }; } #[derive(Default, Debug)] pub struct TerminalUniversalResponse { pub answer_serial_no: u16, pub answer_id: u16, pub result: u8, } impl TerminalUniversalResponse { pub const ID: u16 = 0x0001; pub fn parse(&mut self, rawbody: &Vec<u8>) {} pub fn debug() {} } #[derive(Default, Debug)] pub struct PlatformUniversalResponse { pub answer_serial_no: u16, pub answer_id: u16, pub result: u8, } impl PlatformUniversalResponse { pub const ID: u16 = 0x8001; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct TerminalHeartbeat {} impl TerminalHeartbeat { pub const ID: u16 = 0x0002; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[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; 20], //8 or 20 bytes pub terminal_id: [u8; 7], pub license_plate_color: u8, pub license_plate: String, } impl TerminalRegistration { pub const ID: u16 = 0x0100; pub fn parse(&mut self, rawbody: &Vec<u8>) { let mut bd = rawbody.into_iter(); //self.body_to_iter(rawbody); self.provincial_id = u16::from_be_bytes( vec![*bd.next().unwrap(), *bd.next().unwrap()] .try_into() .unwrap(), ); self.city_and_prefecture_id = u16::from_be_bytes( vec![*bd.next().unwrap(), *bd.next().unwrap()] .try_into() .unwrap(), ); for i in 0..self.manufacturer_id.len() { self.manufacturer_id[i] = *bd.next().unwrap(); } for i in 0..self.terminal_models.len() { self.terminal_models[i] = *bd.next().unwrap(); } for i in 0..self.terminal_id.len() { self.terminal_id[i] = *bd.next().unwrap(); } self.license_plate_color = *bd.next().unwrap(); while let Some(i) = bd.next() { let c = char::from(*i); self.license_plate.push(c); } } 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(); res } } impl std::fmt::Display for TerminalRegistration { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "provincial: {}, city/pref: {}, manufacturer: {:?}, model: {:?}, terminal id: {}, license_plate_color: {}, license_plate: {}", self.provincial_id, self.city_and_prefecture_id, self.manufacturer_id, self.terminal_models, String::from_utf8(self.terminal_id.try_into().unwrap()).unwrap(), self.license_plate_color, self.license_plate, ) } } enum TerminalRegistrationResult { Success = 0x00, VehicleRegistered, VehicleNotInDatabase, TerminalRegistered, VehicleNotInDatabase2, } #[derive(Default, Debug)] pub struct TerminalRegistrationReply { pub answer_serial_no: u16, pub result: u8, pub authentication_code: String, } impl TerminalRegistrationReply { pub const ID: u16 = 0x8100; pub fn parse(&mut self, rawbody: &Vec<u8>) {} pub fn body_to_vec(&self) -> Vec<u8> { let mut res: Vec<u8> = vec![]; for b in self.answer_serial_no.to_be_bytes() { res.push(b); } res.push(self.result); for b in self.authentication_code.as_bytes() { res.push(*b); } res } } #[derive(Default, Debug)] pub struct TerminalLogout {} impl TerminalLogout { pub const ID: u16 = 0x0003; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } impl std::fmt::Display for TerminalLogout { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self) } } #[derive(Default, Debug)] pub struct TerminalAuthentication { pub authentication_code: String, } impl TerminalAuthentication { pub const ID: u16 = 0x0102; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct TerminalParameterSetting { pub total_parameters: u8, pub parameters: Vec<TerminalParameterData>, } impl TerminalParameterSetting { pub const ID: u16 = 0x8103; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct TerminalParameterData { pub parameter_id: u32, pub parameter_length: u8, pub parameter_value: u8, } impl TerminalParameterData { pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct QueryTerminalParameter {} impl QueryTerminalParameter { pub const ID: u16 = 0x8104; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct QueryTerminalParameterResponse { pub response_serial_no: u16, pub response_parameter_quantity: u16, pub parameters: Vec<TerminalParameterData>, } impl QueryTerminalParameterResponse { pub const ID: u16 = 0x0104; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct TerminalControl { pub command_word: u8, pub command_parameter: String, } impl TerminalControl { pub const ID: u16 = 0x8105; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[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, } impl LocationInformationReport { pub const ID: u16 = 0x0200; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct StartOfTrip {} impl StartOfTrip { pub const ID: u16 = 0x0202; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } #[derive(Default, Debug)] pub struct EndOfTrip {} impl EndOfTrip { pub const ID: u16 = 0x0203; pub fn parse(&mut self, rawbody: &Vec<u8>) {} } generate_impl!( TerminalUniversalResponse, PlatformUniversalResponse, TerminalHeartbeat, TerminalRegistration, TerminalRegistrationReply, TerminalLogout, TerminalAuthentication, TerminalParameterSetting, TerminalParameterData, QueryTerminalParameter, QueryTerminalParameterResponse, TerminalControl, LocationInformationReport, StartOfTrip, EndOfTrip );