diff --git a/Cargo.lock b/Cargo.lock index 5309e0b..6f3c2c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,6 +70,13 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "color_test" +version = "0.1.0" +dependencies = [ + "lifx-core", +] + [[package]] name = "derive_arbitrary" version = "1.1.3" diff --git a/Cargo.toml b/Cargo.toml index c5e969d..d2fd94e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ readme = "README.md" edition = "2018" [workspace] -members = ["lifx-core", "examples/multizone_test", "examples/waveform_test", "utils/get_all_info", "xtask"] +members = ["lifx-core", "examples/color_test", "examples/multizone_test", "examples/waveform_test", "utils/get_all_info", "xtask"] [lib] diff --git a/lifx-core/src/lib.rs b/lifx-core/src/lib.rs index dfe70f9..be1ee85 100644 --- a/lifx-core/src/lib.rs +++ b/lifx-core/src/lib.rs @@ -67,6 +67,9 @@ pub enum Error { #[error("i/o error")] Io(#[from] io::Error), + + #[error("error unpacking raw message: `{0}`")] + RawMessage(&'static str), } impl From for Error { @@ -1778,10 +1781,18 @@ impl Frame { 8 } - fn validate(&self) { - assert!(self.origin < 4); - assert!(self.addressable); - assert_eq!(self.protocol, 1024); + fn validate(&self) -> Result<(), Error> { + if self.origin >= 4 { + return Err(Error::RawMessage("invalid origin value in frame")); + } + if !self.addressable { + return Err(Error::RawMessage("missing target address in frame")); + } + if self.protocol != 1024 { + return Err(Error::RawMessage("invalid protocol number in frame")); + } + + Ok(()) } fn pack(&self) -> Result, Error> { @@ -1840,9 +1851,12 @@ impl FrameAddress { fn packed_size() -> usize { 16 } - fn validate(&self) { - //assert_eq!(self.reserved, [0;6]); - //assert_eq!(self.reserved2, 0); + fn validate(&self, strict: bool) -> Result<(), Error> { + if strict && self.reserved != [0; 6] && self.reserved2 != 0 { + return Err(Error::RawMessage("reserved fields must be zeroed")); + } + + Ok(()) } fn pack(&self) -> Result, Error> { let mut v = Vec::with_capacity(Self::packed_size()); @@ -1884,7 +1898,7 @@ impl FrameAddress { res_required, sequence, }; - f.validate(); + f.validate(false)?; Ok(f) } } @@ -1893,9 +1907,12 @@ impl ProtocolHeader { fn packed_size() -> usize { 12 } - fn validate(&self) { - //assert_eq!(self.reserved, 0); - //assert_eq!(self.reserved2, 0); + fn validate(&self, strict: bool) -> Result<(), Error> { + if strict && self.reserved != 0 && self.reserved2 != 0 { + return Err(Error::RawMessage("reserved fields must be zeroed")); + } + + Ok(()) } /// Packs this part of the packet into some bytes @@ -1918,7 +1935,7 @@ impl ProtocolHeader { typ, reserved2, }; - f.validate(); + f.validate(false)?; Ok(f) } } @@ -2379,11 +2396,13 @@ impl RawMessage { + self.payload.len() } - /// Validates that this object was constructed correctly. Panics if not. - pub fn validate(&self) { - self.frame.validate(); - self.frame_addr.validate(); - self.protocol_header.validate(); + /// Validates that this object was constructed correctly. + pub fn validate(&self, strict: bool) -> Result<(), Error> { + self.frame.validate()?; + self.frame_addr.validate(strict)?; + self.protocol_header.validate(strict)?; + + Ok(()) } /// Packs this RawMessage into some bytes that can be send over the network. @@ -2402,13 +2421,13 @@ impl RawMessage { pub fn unpack(v: &[u8]) -> Result { let mut start = 0; let frame = Frame::unpack(v)?; - frame.validate(); + frame.validate()?; start += Frame::packed_size(); let addr = FrameAddress::unpack(&v[start..])?; - addr.validate(); + addr.validate(false)?; start += FrameAddress::packed_size(); let proto = ProtocolHeader::unpack(&v[start..])?; - proto.validate(); + proto.validate(false)?; start += ProtocolHeader::packed_size(); let body = Vec::from(&v[start..(frame.size as usize)]); @@ -2577,7 +2596,7 @@ mod tests { protocol: 1024, source: 1234567, }; - frame.validate(); + frame.validate().unwrap(); let v = frame.pack().unwrap(); println!("{:?}", v); @@ -2643,7 +2662,7 @@ mod tests { res_required: false, sequence: 248, }; - frame.validate(); + frame.validate(false).unwrap(); let v = frame.pack().unwrap(); assert_eq!(v.len(), FrameAddress::packed_size()); @@ -2663,7 +2682,7 @@ mod tests { assert_eq!(v.len(), FrameAddress::packed_size()); let frame = FrameAddress::unpack(&v).unwrap(); - frame.validate(); + frame.validate(false).unwrap(); println!("FrameAddress: {:?}", frame); } @@ -2674,7 +2693,7 @@ mod tests { reserved2: 0, typ: 0x4455, }; - frame.validate(); + frame.validate(false).unwrap(); let v = frame.pack().unwrap(); assert_eq!(v.len(), ProtocolHeader::packed_size()); @@ -2693,7 +2712,7 @@ mod tests { assert_eq!(v.len(), ProtocolHeader::packed_size()); let frame = ProtocolHeader::unpack(&v).unwrap(); - frame.validate(); + frame.validate(false).unwrap(); println!("ProtocolHeader: {:?}", frame); } @@ -2706,7 +2725,7 @@ mod tests { ]; let msg = RawMessage::unpack(&v).unwrap(); - msg.validate(); + msg.validate(false).unwrap(); println!("{:#?}", msg); } @@ -2723,7 +2742,7 @@ mod tests { ]; let msg = RawMessage::unpack(&v).unwrap(); - msg.validate(); + msg.validate(false).unwrap(); println!("{:#?}", msg); } @@ -2839,7 +2858,7 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; let rawmsg = RawMessage::unpack(&v).unwrap(); - rawmsg.validate(); + rawmsg.validate(false).unwrap(); let msg = Message::from_raw(&rawmsg).unwrap(); @@ -2871,7 +2890,7 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; let rawmsg = RawMessage::unpack(&v).unwrap(); - rawmsg.validate(); + rawmsg.validate(false).unwrap(); let msg = Message::from_raw(&rawmsg).unwrap(); diff --git a/utils/get_all_info/src/main.rs b/utils/get_all_info/src/main.rs index 43c297a..e71358a 100644 --- a/utils/get_all_info/src/main.rs +++ b/utils/get_all_info/src/main.rs @@ -359,9 +359,10 @@ impl Manager { for addr in get_if_addrs().unwrap() { if let IfAddr::V4(Ifv4Addr { - broadcast: Some(bcast), - .. - }) = addr.addr { + broadcast: Some(bcast), + .. + }) = addr.addr + { if addr.ip().is_loopback() { continue; } @@ -395,7 +396,7 @@ fn main() { } mgr.refresh(); - println!("\n\n\n\n"); + // println!("\n\n\n\n"); if let Ok(bulbs) = mgr.bulbs.lock() { let bulbs = bulbs.values(); for bulb in bulbs {