diff --git a/src/improv.rs b/src/improv.rs index a98f950..a043a57 100644 --- a/src/improv.rs +++ b/src/improv.rs @@ -120,6 +120,20 @@ pub enum RPCCommand { RequestDeviceInformation = 0x03, } +impl TryFrom<&u8> for RPCCommand { + type Error= &'static str; + + fn try_from(b: &u8) -> Result { + match b { + 0x01 => Ok(Self::SendWifiSettings), + 0x02 => Ok(Self::RequestCurrentState), + 0x03 => Ok(Self::RequestDeviceInformation), + _ => Err("Cannot convert to RPC command"), + } + } +} + + pub fn calculate_checksum(data: &[u8]) -> u8 { // Pass data as full packet, with header, but without checksum byte @@ -318,7 +332,8 @@ impl ImprovDataToPacket for RequestDeviceInformationPacket { } pub struct RPCResultPacket { - results: Vec, + pub command_responded_to: RPCCommand, + pub results: Vec, } impl ImprovDataPacketType for RPCResultPacket { @@ -333,9 +348,30 @@ impl ImprovDataFromPacket for RPCResultPacket { return Err("Packet is not RPCResult"); } - let results: Vec = Vec::new(); + let mut results: Vec = Vec::new(); + + let mut data_position: usize = 2; + loop { + if data_position >= raw_packet.data.len() { + break; + } + + // find string bounds + let current_string_len: usize = usize::from(raw_packet.data[data_position]); + let current_string_begin = data_position + 1; + let current_string_end = data_position + current_string_len; + + // load string and append to results + let string_bytes = &raw_packet.data[current_string_begin..current_string_end+1]; + let string = std::str::from_utf8(string_bytes).unwrap().to_string(); + results.push(string); + + // next data position + data_position = data_position + current_string_len + 1; + } return Ok(Self { + command_responded_to: RPCCommand::try_from(&raw_packet.data[0]).unwrap(), results: results, }) } diff --git a/src/main.rs b/src/main.rs index 9702d25..574793e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -88,6 +88,23 @@ fn to_ascii_debug(bytes: &Vec) -> String { return out; } +fn to_bytewise_debug(bytes: &Vec) -> String { + let mut out = String::new(); + + for b in bytes { + out += &hex::encode(&[b.clone()]); + out += " "; + + if b.is_ascii_graphic() { + out += &b.escape_ascii().to_string(); + } + out += "\n"; + } + + return out; +} + + fn find_begin_of_improv_packet(buffer: &Vec) -> Result { let mut improv_header_char: usize = 0; @@ -186,9 +203,10 @@ async fn main() -> Result<()>{ let improv_packet_end = improv_packet_offset + 10 + >::into(buffer[improv_packet_offset+8]); let raw_packet = RawPacket::try_from_bytes(&buffer[improv_packet_offset..improv_packet_end].to_vec()).unwrap(); - if let ImprovPacket::RPCResult(rpc_result) = ImprovPacket::try_from_raw_packet(&raw_packet).unwrap() { - println!("Received RPCResult"); + for r in rpc_result.results { + println!("{}", &r); + } } }, };