diff --git a/homekit-controller/src/pairing_data/mod.rs b/homekit-controller/src/pairing_data/mod.rs index 098f80f..0cee57e 100644 --- a/homekit-controller/src/pairing_data/mod.rs +++ b/homekit-controller/src/pairing_data/mod.rs @@ -24,7 +24,7 @@ pub struct DevicePairingData { #[serde(rename = "Connection")] pub connection: ConnectionType, #[serde(rename = "accessories")] - pub accessories: Vec, + pub accessories: Option>, } #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/homekit-controller/src/tlv8/data_types.rs b/homekit-controller/src/tlv8/data_types.rs index 271e20a..96d7c05 100644 --- a/homekit-controller/src/tlv8/data_types.rs +++ b/homekit-controller/src/tlv8/data_types.rs @@ -1,3 +1,4 @@ +#[derive(Debug)] pub enum TlvType { Method, Identifier, @@ -41,3 +42,31 @@ impl From for u8 { } } } + +#[derive(Debug)] +pub struct TlvTypeDecodeError(pub u8); + +impl TryFrom for TlvType { + type Error = TlvTypeDecodeError; + + fn try_from(value: u8) -> Result>::Error> { + match value { + 0 => Ok(TlvType::Method), + 1 => Ok(TlvType::Identifier), + 2 => Ok(TlvType::Salt), + 3 => Ok(TlvType::PublicKey), + 4 => Ok(TlvType::Proof), + 5 => Ok(TlvType::EncryptedData), + 6 => Ok(TlvType::State), + 7 => Ok(TlvType::Error), + 8 => Ok(TlvType::RetryDelay), + 9 => Ok(TlvType::Certificate), + 10 => Ok(TlvType::Signature), + 11 => Ok(TlvType::Permissions), + 12 => Ok(TlvType::FragmentData), + 13 => Ok(TlvType::FragmentLast), + 14 => Ok(TlvType::SessionID), + _ => Err(TlvTypeDecodeError(value)), + } + } +} diff --git a/homekit-controller/src/tlv8/mod.rs b/homekit-controller/src/tlv8/mod.rs index ba5f43c..928c65f 100644 --- a/homekit-controller/src/tlv8/mod.rs +++ b/homekit-controller/src/tlv8/mod.rs @@ -6,6 +6,35 @@ pub use data_types::TlvType; use thiserror::Error; +pub trait FormatTlv { + fn as_tlv_string(&self) -> String; +} + +impl FormatTlv for (u8, Vec) { + fn as_tlv_string(&self) -> String { + let (tlv_type, data) = self; + (tlv_type, data).as_tlv_string() + } +} + +impl FormatTlv for (&u8, &Vec) { + fn as_tlv_string(&self) -> String { + let (tlv_type, data) = self; + let tlv_type = TlvType::try_from(**tlv_type).map_or_else( + |e| format!("Unknown TLV type: {}", e.0), + |v| format!("{v:?}"), + ); + format!("{tlv_type}: {data:?} (length: {})", data.len()) + } +} + +impl FormatTlv for HashMap> { + fn as_tlv_string(&self) -> String { + self.iter() + .fold(String::new(), |a, v| format!("{a}\n{}", v.as_tlv_string())) + } +} + pub fn decode(data: &[u8]) -> Result>, TlvError> { let mut tlvs = HashMap::new(); let mut data = data;