From 9866c0f34c268a09ecaaa9a4361c1c267799358e Mon Sep 17 00:00:00 2001 From: Graham Northup Date: Tue, 19 Sep 2017 23:56:15 -0400 Subject: Starting work on proto decode --- src/proto.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/proto.rs (limited to 'src/proto.rs') diff --git a/src/proto.rs b/src/proto.rs new file mode 100644 index 0000000..06d7b49 --- /dev/null +++ b/src/proto.rs @@ -0,0 +1,58 @@ +use std::mem; +use std::time::Duration; +use super::*; + +use ::byteorder::{ByteOrder, NetworkEndian}; + +const OBLIGATE_POLYPHONE: u32 = 0xffffffff; + +pub enum Command { + KeepAlive, + Ping{data: [u8; 32]}, + Quit, + Play{sec: u32, usec: u32, freq: u32, amp: f32, voice: u32}, + Caps{voices: u32, tp: [u8; 4], ident: [u8; 24]}, + PCM{samples: [i16; 16]}, + Unknown{data: [u8; 36]}, +} + +impl Command { + const SIZE: usize = 36; + + fn duration(&self) -> Option { + match *self { + Command::Play{sec, usec, ..} => Some(Duration::new(sec as u64, usec * 1000)), + _ => None, + } + } + + fn pitch(&self) -> Option { + match *self { + Command::Play{freq, ..} => Some(Pitch::Freq(freq as f32)), + _ => None, + } + } +} + +impl<'a> From<&'a [u8; 36]> for Command { + fn from(packet: &'a [u8; 36]) -> Command { + let mut fields_u32: [u32; 9] = unsafe { mem::uninitialized() }; + let mut fields_f32: [f32; 9] = unsafe { mem::uninitialized() }; + NetworkEndian::read_u32_into(packet, &mut fields_u32); + unsafe { NetworkEndian::read_f32_into_unchecked(packet, &mut fields_f32); } + + match fields_u32[0] { + 0 => Command::KeepAlive, + 1 => { + let mut data: [u8; 32] = unsafe { mem::uninitialized() }; + data.copy_from_slice(&packet[4..]); + Command::Ping{data: data} + } + _ => { + let mut data: [u8; 36] = unsafe { mem::uninitialized() }; + data.copy_from_slice(packet); + Command::Unknown{data: data} + } + } + } +} -- cgit v1.2.3-70-g09d2