diff --git a/crates/windlass/src/application.rs b/crates/windlass/src/application.rs index 1fa3805..bcb4e70 100644 --- a/crates/windlass/src/application.rs +++ b/crates/windlass/src/application.rs @@ -59,11 +59,8 @@ impl Connection { return Ok(()); } - trace!("decoding part of identify response"); - let resp = IdentifyResponse::decode(payload)?; - self.dictionary - .receive_response(&mut self.transport, &resp, receive_time)?; + .receive_response(&mut self.transport, payload, receive_time)?; return Ok(()); }; @@ -106,57 +103,64 @@ impl DictionaryReceiveState { pub fn receive_response( &mut self, transport: &mut transport::Connection, - resp: &IdentifyResponseData<'_>, + payload: &mut &[u8], receive_time: Instant, ) -> Result<(), Error> { - match self { - Self::InProgress { start, so_far } => { - if (receive_time - *start).as_secs() >= 10 { - return Err(Error::IdentifyTimeout); - } - if (resp.offset as usize) != so_far.len() { - return Ok(()); - } - - so_far.extend(resp.data); - - if !resp.data.is_empty() { - trace!( - offset = resp.offset, - len = resp.data.len(), - "received more of dictionary" - ); - transport.push_message( - Identify::encode( - u32::try_from(so_far.len()) - .expect("identify data length overflowed u32!"), - 40, - ) - .payload - .content, - ); - - return Ok(()); - } - - // done receiving dictionary - trace!("done receiving dictionary, attempting decode"); - let mut decoder = flate2::read::ZlibDecoder::new(so_far.as_slice()); - let mut buf = Vec::new(); - decoder.read_to_end(&mut buf).map_err(Error::DictionaryIO)?; - let raw_dict: RawDictionary = - serde_json::from_slice(&buf).map_err(Error::DictionaryJson)?; - let dict = Dictionary::try_from(raw_dict).map_err(Error::DictionaryData)?; - - trace!(dict = ?dict, "dictionary in place"); - - *self = Self::Done(dict); - } - Self::Done(_) => (), + trace!("decoding part of identify response"); + let Self::InProgress { start, so_far } = self else { + return Ok(()); }; + let resp = IdentifyResponse::decode(payload)?; + + if (receive_time - *start).as_secs() >= 10 { + return Err(Error::IdentifyTimeout); + } + if (resp.offset as usize) != so_far.len() { + return Ok(()); + } + + so_far.extend(resp.data); + + if !resp.data.is_empty() { + trace!( + offset = resp.offset, + len = resp.data.len(), + "received more of dictionary" + ); + transport.push_message( + Identify::encode( + u32::try_from(so_far.len()).expect("identify data length overflowed u32!"), + 40, + ) + .payload + .content, + ); + + return Ok(()); + } + + // done receiving dictionary + trace!("done receiving dictionary, attempting decode"); + let dict = Self::decode_complete(so_far.as_slice())?; + trace!(dict = ?dict, "dictionary in place"); + *self = Self::Done(dict); + Ok(()) } + + fn decode_complete(data: &[u8]) -> Result { + let mut decoder = flate2::read::ZlibDecoder::new(data); + + let mut buf = Vec::new(); + decoder.read_to_end(&mut buf).map_err(Error::DictionaryIO)?; + + let raw_dict: RawDictionary = + serde_json::from_slice(&buf).map_err(Error::DictionaryJson)?; + let dict = Dictionary::try_from(raw_dict).map_err(Error::DictionaryData)?; + + Ok(dict) + } } #[derive(Error, Debug)] diff --git a/crates/windlass/src/macros.rs b/crates/windlass/src/macros.rs index c118ada..513ff77 100644 --- a/crates/windlass/src/macros.rs +++ b/crates/windlass/src/macros.rs @@ -111,8 +111,14 @@ macro_rules! mcu_message_impl { fn encode(&self) -> $crate::messages::FrontTrimmableBuffer { use $crate::encoding::Writable; let mut buf = Vec::with_capacity($crate::transport::MESSAGE_LENGTH_PAYLOAD_MAX); - buf.push(0); - buf.push(0); + if let Some(id) = $cmd_id { + $crate::encoding::encode_vlq_int(&mut buf, id); + } else { + // todo: assumes this will be replaced later + // not sure why we add two though + buf.push(0); + buf.push(0); + } $(self.$arg.write(&mut buf);)* $crate::messages::FrontTrimmableBuffer { content: buf, offset: 0 } }