feat: rust proto implementation
This commit is contained in:
parent
1e68840042
commit
e4b508ae86
12 changed files with 381 additions and 0 deletions
94
domo_proto/src/packet/mod.rs
Normal file
94
domo_proto/src/packet/mod.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
pub mod data_types;
|
||||
pub mod identifier;
|
||||
pub mod packet_data;
|
||||
|
||||
use crate::prelude;
|
||||
use identifier::Identifier;
|
||||
use packet_data::PacketData;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Packet {
|
||||
V1 {
|
||||
src: Identifier,
|
||||
dest: Identifier,
|
||||
packet_id: Identifier,
|
||||
reply_to: Identifier,
|
||||
command: u8,
|
||||
data: PacketData,
|
||||
},
|
||||
}
|
||||
|
||||
impl Packet {
|
||||
/// Build packet **without** CRC32
|
||||
pub fn build_base_packet(&self) -> Vec<u8> {
|
||||
match self {
|
||||
Packet::V1 {
|
||||
src,
|
||||
dest,
|
||||
packet_id,
|
||||
reply_to,
|
||||
command,
|
||||
data,
|
||||
} => {
|
||||
let mut buf = Vec::new();
|
||||
let data_length = data.len();
|
||||
buf.push(0x01);
|
||||
buf.extend_from_slice(&src.bytes);
|
||||
buf.extend_from_slice(&dest.bytes);
|
||||
buf.extend_from_slice(&packet_id.bytes);
|
||||
buf.extend_from_slice(&reply_to.bytes);
|
||||
buf.push(command.clone());
|
||||
buf.push((data_length >> 8) as u8);
|
||||
buf.push((data_length & 0xFF) as u8);
|
||||
buf.extend(data.get_data());
|
||||
buf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_full_packet(&self) -> Vec<u8> {
|
||||
match self {
|
||||
Packet::V1 { .. } => {
|
||||
let mut buf = self.build_base_packet();
|
||||
buf.extend_from_slice(crc32fast::hash(&buf.as_slice()).to_be_bytes().as_ref());
|
||||
buf
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for Packet {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
match value[0] {
|
||||
0x01 => {
|
||||
let header: Vec<u16> = value[..0x15].iter().map(|v| u16::from(*v)).collect();
|
||||
let data_length = (header[0x12] << 8) | header[0x13];
|
||||
let crc32 = prelude::as_u32_be(&value[(0x14 + data_length as usize)..]);
|
||||
let packet = Packet::V1 {
|
||||
src: Identifier::from(&value[0x01..0x05]),
|
||||
dest: Identifier::from(&value[0x05..0x09]),
|
||||
packet_id: Identifier::from(&value[0x09..0x0D]),
|
||||
reply_to: Identifier::from(&value[0x0D..0x11]),
|
||||
command: value[0x11],
|
||||
data: PacketData::new(value[0x14..(data_length as usize + 0x14)].to_owned()),
|
||||
};
|
||||
if crc32fast::hash(packet.build_base_packet().as_slice()) != crc32 {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(packet)
|
||||
}
|
||||
}
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Vec<u8>> for Packet {
|
||||
fn into(self) -> Vec<u8> {
|
||||
self.build_full_packet()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue