cleanup, show tlv errors
This commit is contained in:
parent
3b9bc6c959
commit
7a49efe6f6
|
@ -159,12 +159,6 @@ impl AccessorySocket {
|
|||
}
|
||||
send_data.extend_from_slice("\r\n".as_bytes());
|
||||
send_data.extend_from_slice(&body);
|
||||
let mut visible = String::new();
|
||||
for b in &send_data {
|
||||
let part: Vec<u8> = std::ascii::escape_default(*b).collect();
|
||||
visible.push_str(std::str::from_utf8(&part).unwrap());
|
||||
}
|
||||
log::info!("data as string: {visible}");
|
||||
|
||||
if let Some(encryption) = self.socket_encryption.as_mut() {
|
||||
let mut packets = Vec::new();
|
||||
|
@ -201,9 +195,6 @@ impl AccessorySocket {
|
|||
log::info!("encrypted {i} chunks!");
|
||||
}
|
||||
|
||||
log::info!("data: {send_data:X?}");
|
||||
log::info!("data len: {}", send_data.len());
|
||||
|
||||
self.socket.write_all(&send_data)?;
|
||||
|
||||
let mut buf = [0; 1024];
|
||||
|
|
|
@ -4,14 +4,14 @@ use hkdf::Hkdf;
|
|||
use sha2::Sha512;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
use thiserror::Error;
|
||||
use tlv8::{TlvEncode, TlvType};
|
||||
use tlv8::{HomekitState, TlvEncode, TlvType};
|
||||
use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
|
||||
use pairing_data::DevicePairingData;
|
||||
|
||||
use crate::{
|
||||
homekit_http::AccessorySocket,
|
||||
tlv8::{decode, FormatTlv, TlvEncodableData},
|
||||
tlv8::{decode, TlvEncodableData},
|
||||
};
|
||||
|
||||
mod pairing_data;
|
||||
|
@ -198,8 +198,6 @@ impl DevicePairingData {
|
|||
return Err(HomekitError::StateMismatch);
|
||||
}
|
||||
|
||||
log::info!("step3 response: {}", step3_response.as_tlv_string());
|
||||
|
||||
// 5.7.4 M4: Accessory -> iOS Device – ‘Verify Finish Responseʼ
|
||||
// When the accessory receives <M3>, it must perform the following steps:
|
||||
//
|
||||
|
@ -233,14 +231,12 @@ impl DevicePairingData {
|
|||
b"Control-Write-Encryption-Key",
|
||||
&mut controller_to_accessory_key,
|
||||
)?;
|
||||
log::info!("c2a key: {controller_to_accessory_key:?}");
|
||||
|
||||
let mut accessory_to_controller_key = [0; 32];
|
||||
Hkdf::<Sha512>::new(Some(b"Control-Salt"), shared_secret.as_bytes()).expand(
|
||||
b"Control-Read-Encryption-Key",
|
||||
&mut accessory_to_controller_key,
|
||||
)?;
|
||||
log::info!("a2c key: {accessory_to_controller_key:?}");
|
||||
|
||||
socket.set_encryption(controller_to_accessory_key, accessory_to_controller_key);
|
||||
|
||||
|
@ -265,15 +261,6 @@ impl DevicePairingData {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum HomekitState {
|
||||
M1 = 1,
|
||||
M2 = 2,
|
||||
M3 = 3,
|
||||
M4 = 4,
|
||||
M5 = 5,
|
||||
M6 = 6,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum HomekitError {
|
||||
#[error("io")]
|
||||
|
@ -283,7 +270,7 @@ pub enum HomekitError {
|
|||
#[error("no device pairing data stored")]
|
||||
NoPairingData,
|
||||
#[error("tlv error")]
|
||||
Tlv(#[from] tlv8::TlvError),
|
||||
Tlv(#[from] tlv8::TlvCodecError),
|
||||
#[error("mismatch with state response")]
|
||||
StateMismatch,
|
||||
#[error("Tlv not found")]
|
||||
|
|
|
@ -70,3 +70,79 @@ impl TryFrom<u8> for TlvType {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TlvError {
|
||||
Reserved,
|
||||
Unknown,
|
||||
Authentication,
|
||||
Backoff,
|
||||
MaxPeers,
|
||||
MaxTries,
|
||||
Unavailable,
|
||||
Busy,
|
||||
}
|
||||
|
||||
impl From<TlvError> for u8 {
|
||||
fn from(value: TlvError) -> Self {
|
||||
match value {
|
||||
TlvError::Reserved => 0x00,
|
||||
TlvError::Unknown => 0x01,
|
||||
TlvError::Authentication => 0x02,
|
||||
TlvError::Backoff => 0x03,
|
||||
TlvError::MaxPeers => 0x04,
|
||||
TlvError::MaxTries => 0x05,
|
||||
TlvError::Unavailable => 0x06,
|
||||
TlvError::Busy => 0x07,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TlvErrorDecodeError(pub u8);
|
||||
|
||||
impl TryFrom<u8> for TlvError {
|
||||
type Error = TlvErrorDecodeError;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0x00 => Ok(TlvError::Reserved),
|
||||
0x01 => Ok(TlvError::Unknown),
|
||||
0x02 => Ok(TlvError::Authentication),
|
||||
0x03 => Ok(TlvError::Backoff),
|
||||
0x04 => Ok(TlvError::MaxPeers),
|
||||
0x05 => Ok(TlvError::MaxTries),
|
||||
0x06 => Ok(TlvError::Unavailable),
|
||||
0x07 => Ok(TlvError::Busy),
|
||||
_ => Err(TlvErrorDecodeError(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum HomekitState {
|
||||
M1 = 1,
|
||||
M2 = 2,
|
||||
M3 = 3,
|
||||
M4 = 4,
|
||||
M5 = 5,
|
||||
M6 = 6,
|
||||
}
|
||||
|
||||
pub struct HomekitStateDecodeError(pub u8);
|
||||
|
||||
impl TryFrom<u8> for HomekitState {
|
||||
type Error = HomekitStateDecodeError;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
1 => Ok(Self::M1),
|
||||
2 => Ok(Self::M2),
|
||||
3 => Ok(Self::M3),
|
||||
4 => Ok(Self::M4),
|
||||
5 => Ok(Self::M5),
|
||||
6 => Ok(Self::M6),
|
||||
_ => Err(HomekitStateDecodeError(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
mod data_types;
|
||||
|
||||
use self::data_types::TlvError;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub use data_types::TlvType;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
pub use data_types::{HomekitState, TlvType};
|
||||
|
||||
mod data_types;
|
||||
|
||||
pub trait FormatTlv {
|
||||
fn as_tlv_string(&self) -> String;
|
||||
}
|
||||
|
@ -20,11 +20,38 @@ impl FormatTlv for (u8, Vec<u8>) {
|
|||
impl FormatTlv for (&u8, &Vec<u8>) {
|
||||
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())
|
||||
let tlv_type =
|
||||
TlvType::try_from(**tlv_type).map_err(|e| format!("Unknown TLV type: {}", e.0));
|
||||
match tlv_type {
|
||||
Ok(tlv_type) => match tlv_type {
|
||||
TlvType::Error => data
|
||||
.first()
|
||||
.map(|v| {
|
||||
format!(
|
||||
"Error: {}",
|
||||
TlvError::try_from(*v).map_or_else(
|
||||
|e| format!("Unknown error {:02X}", e.0),
|
||||
|v| format!("{v:?}"),
|
||||
)
|
||||
)
|
||||
})
|
||||
.unwrap_or(String::from("TLV error type with no data!")),
|
||||
TlvType::State => data
|
||||
.first()
|
||||
.map(|v| {
|
||||
format!(
|
||||
"State: {}",
|
||||
HomekitState::try_from(*v).map_or_else(
|
||||
|e| format!("Unknown state {:02X}", e.0),
|
||||
|v| format!("{v:?}"),
|
||||
)
|
||||
)
|
||||
})
|
||||
.unwrap_or(String::from("TLV error type with no data!")),
|
||||
_ => format!("{tlv_type:?}: {data:?} (length: {})", data.len()),
|
||||
},
|
||||
Err(tlv_type) => format!("{tlv_type}: {data:?} (length: {})", data.len()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +62,14 @@ impl FormatTlv for HashMap<u8, Vec<u8>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn decode(data: &[u8]) -> Result<HashMap<u8, Vec<u8>>, TlvError> {
|
||||
impl FormatTlv for Vec<(u8, Vec<u8>)> {
|
||||
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<HashMap<u8, Vec<u8>>, TlvCodecError> {
|
||||
let mut tlvs = HashMap::new();
|
||||
let mut data = data;
|
||||
|
||||
|
@ -43,17 +77,17 @@ pub fn decode(data: &[u8]) -> Result<HashMap<u8, Vec<u8>>, TlvError> {
|
|||
let tlv_len = (data[1] as usize) + 2;
|
||||
let current;
|
||||
if tlv_len > data.len() {
|
||||
return Err(TlvError::WrongLength);
|
||||
return Err(TlvCodecError::WrongLength);
|
||||
}
|
||||
|
||||
(current, data) = data.split_at(tlv_len);
|
||||
|
||||
if current.len() < 2 {
|
||||
return Err(TlvError::TooShort);
|
||||
return Err(TlvCodecError::TooShort);
|
||||
}
|
||||
|
||||
if current.len() < tlv_len {
|
||||
return Err(TlvError::WrongLength);
|
||||
return Err(TlvCodecError::WrongLength);
|
||||
}
|
||||
|
||||
let tlv_type = current[0];
|
||||
|
@ -64,11 +98,12 @@ pub fn decode(data: &[u8]) -> Result<HashMap<u8, Vec<u8>>, TlvError> {
|
|||
};
|
||||
tlvs.insert(tlv_type, tlv_data);
|
||||
}
|
||||
log::info!("{}", tlvs.as_tlv_string());
|
||||
Ok(tlvs)
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum TlvError {
|
||||
pub enum TlvCodecError {
|
||||
#[error("too short")]
|
||||
TooShort,
|
||||
#[error("wrong length")]
|
||||
|
|
Loading…
Reference in a new issue