micodus_server/src/parser/body.rs

611 lines
16 KiB
Rust

#![allow(unused_variables)]
use bcd_convert::BcdNumber;
use bitvec::prelude::*;
use chrono::prelude::*;
use encoding_rs::*;
#[allow(dead_code)]
pub trait BodyMessage {
fn build(&self) {}
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);
}
fn to_raw(&self) -> Vec<u8> {
vec![]
}
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[allow(dead_code)]
#[derive(Default, Debug, Clone)]
pub struct TerminalUniversalResponse {
pub answer_serial_no: u16,
pub answer_id: u16,
pub result: u8,
}
#[allow(dead_code)]
impl TerminalUniversalResponse {
pub const ID: u16 = 0x0001;
pub fn debug() {}
}
#[allow(dead_code)]
impl BodyMessage for TerminalUniversalResponse {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[derive(Default, Debug, Clone)]
pub struct PlatformUniversalResponse {
pub answer_serial_no: u16,
pub answer_id: u16,
pub result: PlatformUniversalResponseResult,
}
impl PlatformUniversalResponse {
pub const ID: u16 = 0x8001;
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
}
impl BodyMessage for PlatformUniversalResponse {
fn to_raw(&self) -> Vec<u8> {
let mut res: Vec<u8> = vec![];
for b in self.answer_serial_no.to_be_bytes() {
res.push(b);
}
for b in self.answer_id.to_be_bytes() {
res.push(b);
}
res.push(self.result.clone() as u8);
res
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum PlatformUniversalResponseResult {
Success = 0x00,
Failed,
MessageError,
NotSupported,
AlertProcessingConfirm,
}
impl Default for PlatformUniversalResponseResult {
fn default() -> Self {
PlatformUniversalResponseResult::Success
}
}
#[derive(Default, Debug, Clone)]
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 = PlatformUniversalResponseResult::Success;
res
}
}
impl std::fmt::Display for TerminalHeartbeat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Default, Debug, Clone)]
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 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 = self.terminal_id.into();
res
}
}
impl BodyMessage for TerminalRegistration {
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();
let plate_decode: &mut Vec<u8> = &mut vec![];
while let Some(i) = bd.next() {
plate_decode.push(*i);
}
let (cow, _encoding_used, _had_errors) = GBK.decode(plate_decode);
self.license_plate = cow.into();
}
}
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,
)
}
}
#[allow(dead_code)]
pub enum TerminalRegistrationResult {
Success = 0x00,
VehicleRegistered,
VehicleNotInDatabase,
TerminalRegistered,
VehicleNotInDatabase2,
}
#[derive(Default, Debug, Clone)]
pub struct TerminalRegistrationReply {
pub answer_serial_no: u16,
pub result: u8,
pub authentication_code: Vec<u8>,
}
impl TerminalRegistrationReply {
pub const ID: u16 = 0x8100;
}
impl BodyMessage for TerminalRegistrationReply {
fn parse(&mut self, rawbody: &Vec<u8>) {}
fn to_raw(&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() {
for b in self.authentication_code.iter() {
res.push(*b);
}
res
}
}
#[derive(Default, Debug, Clone)]
pub struct TerminalLogout {}
impl TerminalLogout {
pub const ID: u16 = 0x0003;
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 = PlatformUniversalResponseResult::Success;
res
}
}
impl BodyMessage for TerminalLogout {
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, Clone)]
pub struct TerminalAuthentication {
pub authentication_code: String,
}
impl TerminalAuthentication {
pub const ID: u16 = 0x0102;
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 = PlatformUniversalResponseResult::Success;
res
}
}
impl BodyMessage for TerminalAuthentication {
fn parse(&mut self, rawbody: &Vec<u8>) {
let mut bd = rawbody.into_iter();
let plate_decode: &mut Vec<u8> = &mut vec![];
while let Some(i) = bd.next() {
plate_decode.push(*i);
}
let (cow, _encoding_used, _had_errors) = GBK.decode(plate_decode);
self.authentication_code = cow.into();
}
}
impl std::fmt::Display for TerminalAuthentication {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "authentication_code: {}", self.authentication_code,)
}
}
#[allow(dead_code)]
#[derive(Default, Debug, Clone)]
pub struct TerminalParameterSetting {
pub total_parameters: u8,
pub parameters: Vec<TerminalParameterData>,
}
impl TerminalParameterSetting {
pub const ID: u16 = 0x8103;
}
impl BodyMessage for TerminalParameterSetting {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[allow(dead_code)]
#[derive(Default, Debug, Clone)]
pub struct TerminalParameterData {
pub parameter_id: u32,
pub parameter_length: u8,
pub parameter_value: u8,
}
impl TerminalParameterData {}
impl BodyMessage for TerminalParameterData {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[derive(Default, Debug, Clone)]
pub struct QueryTerminalParameter {}
impl QueryTerminalParameter {
pub const ID: u16 = 0x8104;
}
impl BodyMessage for QueryTerminalParameter {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[allow(dead_code)]
#[derive(Default, Debug, Clone)]
pub struct QueryTerminalParameterResponse {
pub response_serial_no: u16,
pub response_parameter_quantity: u16,
pub parameters: Vec<TerminalParameterData>,
}
impl QueryTerminalParameterResponse {
pub const ID: u16 = 0x0104;
}
impl BodyMessage for QueryTerminalParameterResponse {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[allow(dead_code)]
#[derive(Default, Debug, Clone)]
pub struct TerminalControl {
pub command_word: u8,
pub command_parameter: String,
}
impl TerminalControl {
pub const ID: u16 = 0x8105;
}
impl BodyMessage for TerminalControl {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[derive(Default, Debug, Clone)]
pub struct LocationInformationReport {
pub alert_mark: u32,
pub status: LocationInformationReportStatus,
pub latitude: f64,
pub longitude: f64,
pub height: u16,
pub speed: u16,
pub direction: u16,
pub time: NaiveDateTime,
}
impl LocationInformationReport {
pub const ID: u16 = 0x0200;
//pub const TABLE: &'static str = "LocationInformationReport";
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 = PlatformUniversalResponseResult::Success;
res
}
fn parse_time(&mut self, timeslice: [u8; 6]) {
let code = BcdNumber::try_from(&timeslice as &[u8]).unwrap();
let time = format!("{}", code.to_u64().unwrap());
match NaiveDateTime::parse_from_str(time.as_str(), "%y%m%d%H%M%S") {
Ok(o) => {
self.time = o;
}
Err(e) => {
println!("{timeslice:?} {code} {time} {e}");
}
};
}
fn parse_latitude(&self, latitude: u32) -> f64 {
let mut res = latitude as f64 / 1_000_000.;
if self.status.south {
res = -res
};
res
}
fn parse_longitude(&self, longitude: u32) -> f64 {
let mut res = longitude as f64 / 1_000_000.;
if self.status.west {
res = -res
};
res
}
pub fn is_satellite(&self) -> bool {
self.status.gps | self.status.beidou | self.status.glonass
}
}
impl BodyMessage for LocationInformationReport {
fn parse(&mut self, rawbody: &Vec<u8>) {
let res: bool;
let mut bd = rawbody.into_iter();
//let z: [u8; 4] = bd.take(4).collect::<Vec<&u8>>().try_into().unwrap();
self.alert_mark = u32::from_be_bytes(
vec![
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
]
.try_into()
.unwrap(),
);
let status = u32::from_be_bytes(
vec![
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
]
.try_into()
.unwrap(),
);
self.status = status.into();
self.latitude = self.parse_latitude(u32::from_be_bytes(
vec![
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
*bd.next().unwrap(),
]
.try_into()
.unwrap(),
));
self.longitude = self.parse_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();
}
self.parse_time(tmptime);
()
}
}
impl std::fmt::Display for LocationInformationReport {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"latitude: {}, longitude: {}, direction: {}, speed: {}, time: {}",
self.latitude, self.longitude, self.direction, self.speed, self.time
)
}
}
#[derive(Default, Debug, Clone)]
pub struct LocationInformationReportStatus {
acc: bool,
positionning: bool,
south: bool,
west: bool,
stop_running: bool,
secret: bool,
vehicule_power_loop_disconnected: bool,
gps: bool,
beidou: bool,
glonass: bool,
}
impl From<u32> for LocationInformationReportStatus {
fn from(status: u32) -> Self {
let mut res = LocationInformationReportStatus::default();
let bits = status.view_bits::<Lsb0>();
res.acc = bits[0];
res.positionning = bits[1];
res.south = bits[2];
res.west = bits[3];
res.stop_running = bits[4];
res.secret = bits[5];
res.vehicule_power_loop_disconnected = bits[11];
res.gps = bits[18];
res.beidou = bits[19];
res.glonass = bits[20];
res
}
}
#[derive(Default, Debug, Clone)]
pub struct LocationInformationQuery {}
impl LocationInformationQuery {
pub const ID: u16 = 0x8201;
}
impl BodyMessage for LocationInformationQuery {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[derive(Default, Debug, Clone)]
pub struct LocationInformationQueryResponse {}
impl LocationInformationQueryResponse {
pub const ID: u16 = 0x0201;
}
impl BodyMessage for LocationInformationQueryResponse {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[derive(Default, Debug, Clone)]
pub struct StartOfTrip {}
impl StartOfTrip {
pub const ID: u16 = 0x0202;
}
impl BodyMessage for StartOfTrip {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
#[derive(Default, Debug, Clone)]
pub struct EndOfTrip {}
impl EndOfTrip {
pub const ID: u16 = 0x0203;
}
impl BodyMessage for EndOfTrip {
fn parse(&mut self, rawbody: &Vec<u8>) {}
}
/*
struct BCDTime {
pub time: String,
}
impl BCDTime {
pub fn parse() {}
}
*/
macro_rules! generate_impl {
($($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()
}
}*/
#[allow(unused)]
impl $t {
pub fn new(rawbody: &Vec<u8>) -> Self {
let mut res = Self::default();
res.parse(rawbody);
res
}
})*
};
}
generate_impl!(
TerminalUniversalResponse,
PlatformUniversalResponse,
TerminalHeartbeat,
TerminalRegistration,
TerminalRegistrationReply,
TerminalLogout,
TerminalAuthentication,
TerminalParameterSetting,
TerminalParameterData,
QueryTerminalParameter,
QueryTerminalParameterResponse,
TerminalControl,
LocationInformationReport,
LocationInformationQuery,
LocationInformationQueryResponse,
StartOfTrip,
EndOfTrip
);