v1.0.0
This commit is contained in:
@@ -30,6 +30,8 @@ pub struct DecodedSignal {
|
||||
pub data_count_bit: usize,
|
||||
/// Whether encoding is supported
|
||||
pub encoder_capable: bool,
|
||||
/// Protocol-specific extra data for encoding (e.g. VAG: vag_type + key_idx)
|
||||
pub extra: Option<u64>,
|
||||
}
|
||||
|
||||
impl DecodedSignal {
|
||||
@@ -43,6 +45,7 @@ impl DecodedSignal {
|
||||
data,
|
||||
data_count_bit: bit_count,
|
||||
encoder_capable: false,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@ impl FiatV0Decoder {
|
||||
data,
|
||||
data_count_bit: 71,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,6 +608,7 @@ impl ProtocolDecoder for FordV0Decoder {
|
||||
data: self.key1,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
};
|
||||
|
||||
self.data_low = 0;
|
||||
|
||||
@@ -84,6 +84,7 @@ impl KiaV0Decoder {
|
||||
data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ impl KiaV1Decoder {
|
||||
data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ impl KiaV2Decoder {
|
||||
data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ impl KiaV3V4Decoder {
|
||||
data: key_data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@ impl KiaV5Decoder {
|
||||
data: key,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: false, // V5 is decode-only
|
||||
extra: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,6 +538,7 @@ impl ProtocolDecoder for KiaV6Decoder {
|
||||
data: key_data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: false,
|
||||
extra: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -262,6 +262,7 @@ impl PsaDecoder {
|
||||
data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
}
|
||||
} else {
|
||||
DecodedSignal {
|
||||
@@ -272,6 +273,7 @@ impl PsaDecoder {
|
||||
data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: false,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ impl ScherKhanDecoder {
|
||||
data,
|
||||
data_count_bit: bit_count,
|
||||
encoder_capable: false,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ impl StarLineDecoder {
|
||||
data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,7 @@ impl SubaruDecoder {
|
||||
data: key,
|
||||
data_count_bit: 64,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ impl SuzukiDecoder {
|
||||
data,
|
||||
data_count_bit: MIN_COUNT_BIT,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+70
-45
@@ -451,41 +451,54 @@ impl VagDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Build encoder output for the given signal
|
||||
/// Build encoder output from decoded signal (uses decoded + extra; extra = vag_type | (key_idx<<8))
|
||||
fn encode_signal(&self, decoded: &DecodedSignal) -> Option<Vec<LevelDuration>> {
|
||||
if !self.decrypted {
|
||||
return None;
|
||||
}
|
||||
let extra = match decoded.extra {
|
||||
Some(e) => e,
|
||||
None => return None,
|
||||
};
|
||||
let vag_type_num = (extra & 0xFF) as u8;
|
||||
let vag_type = match vag_type_num {
|
||||
1 => VagType::Type1,
|
||||
2 => VagType::Type2,
|
||||
3 => VagType::Type3,
|
||||
4 => VagType::Type4,
|
||||
_ => return None,
|
||||
};
|
||||
let key_idx = ((extra >> 8) & 0xFF) as u8;
|
||||
|
||||
match self.vag_type {
|
||||
VagType::Type1 => self.encode_type1(decoded),
|
||||
VagType::Type2 => self.encode_type2(decoded),
|
||||
VagType::Type3 | VagType::Type4 => self.encode_type3_4(decoded),
|
||||
match vag_type {
|
||||
VagType::Type1 => Self::encode_type1(decoded, key_idx),
|
||||
VagType::Type2 => Self::encode_type2(decoded),
|
||||
VagType::Type3 | VagType::Type4 => Self::encode_type3_4(decoded, vag_type, key_idx),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode Type 1 (300µs, AUT64)
|
||||
fn encode_type1(&self, _decoded: &DecodedSignal) -> Option<Vec<LevelDuration>> {
|
||||
fn encode_type1(decoded: &DecodedSignal, key_idx: u8) -> Option<Vec<LevelDuration>> {
|
||||
let mut upload = Vec::with_capacity(700);
|
||||
|
||||
let btn_byte = self.btn;
|
||||
let serial = decoded.serial.unwrap_or(0);
|
||||
let btn = decoded.button.unwrap_or(0);
|
||||
let cnt = decoded.counter.unwrap_or(0) as u32;
|
||||
let type_byte = (decoded.data >> 56) as u8;
|
||||
let btn_byte = btn;
|
||||
let dispatch = Self::get_dispatch_byte(btn_byte, 1);
|
||||
let type_byte = (self.key1_high >> 24) as u8;
|
||||
|
||||
// Build plaintext block
|
||||
let mut block = [0u8; 8];
|
||||
block[0] = (self.serial >> 24) as u8;
|
||||
block[1] = (self.serial >> 16) as u8;
|
||||
block[2] = (self.serial >> 8) as u8;
|
||||
block[3] = self.serial as u8;
|
||||
block[4] = self.cnt as u8;
|
||||
block[5] = (self.cnt >> 8) as u8;
|
||||
block[6] = (self.cnt >> 16) as u8;
|
||||
block[0] = (serial >> 24) as u8;
|
||||
block[1] = (serial >> 16) as u8;
|
||||
block[2] = (serial >> 8) as u8;
|
||||
block[3] = serial as u8;
|
||||
block[4] = cnt as u8;
|
||||
block[5] = (cnt >> 8) as u8;
|
||||
block[6] = (cnt >> 16) as u8;
|
||||
block[7] = btn_byte;
|
||||
|
||||
// Encrypt with AUT64
|
||||
let key_idx = if self.key_idx != 0xFF { self.key_idx as usize } else { 0 };
|
||||
let key_idx = if key_idx != 0xFF { key_idx as usize } else { 0 };
|
||||
let store = keys::get_keystore();
|
||||
if let Some(key) = store.get_vag_key((key_idx + 1) as u8) {
|
||||
aut64::aut64_encrypt(key, &mut block);
|
||||
@@ -533,22 +546,25 @@ impl VagDecoder {
|
||||
}
|
||||
|
||||
/// Encode Type 2 (300µs, TEA)
|
||||
fn encode_type2(&self, _decoded: &DecodedSignal) -> Option<Vec<LevelDuration>> {
|
||||
fn encode_type2(decoded: &DecodedSignal) -> Option<Vec<LevelDuration>> {
|
||||
let mut upload = Vec::with_capacity(700);
|
||||
|
||||
let btn_byte = Self::btn_to_byte(self.btn, 2);
|
||||
let serial = decoded.serial.unwrap_or(0);
|
||||
let btn = decoded.button.unwrap_or(0);
|
||||
let cnt = decoded.counter.unwrap_or(0) as u32;
|
||||
let type_byte = (decoded.data >> 56) as u8;
|
||||
let btn_byte = Self::btn_to_byte(btn, 2);
|
||||
let dispatch = Self::get_dispatch_byte(btn_byte, 2);
|
||||
let type_byte = (self.key1_high >> 24) as u8;
|
||||
|
||||
// Build plaintext block
|
||||
let mut block = [0u8; 8];
|
||||
block[0] = (self.serial >> 24) as u8;
|
||||
block[1] = (self.serial >> 16) as u8;
|
||||
block[2] = (self.serial >> 8) as u8;
|
||||
block[3] = self.serial as u8;
|
||||
block[4] = self.cnt as u8;
|
||||
block[5] = (self.cnt >> 8) as u8;
|
||||
block[6] = (self.cnt >> 16) as u8;
|
||||
block[0] = (serial >> 24) as u8;
|
||||
block[1] = (serial >> 16) as u8;
|
||||
block[2] = (serial >> 8) as u8;
|
||||
block[3] = serial as u8;
|
||||
block[4] = cnt as u8;
|
||||
block[5] = (cnt >> 8) as u8;
|
||||
block[6] = (cnt >> 16) as u8;
|
||||
block[7] = btn_byte;
|
||||
|
||||
// Encrypt with TEA
|
||||
@@ -606,27 +622,30 @@ impl VagDecoder {
|
||||
}
|
||||
|
||||
/// Encode Type 3/4 (500µs, AUT64)
|
||||
fn encode_type3_4(&self, _decoded: &DecodedSignal) -> Option<Vec<LevelDuration>> {
|
||||
fn encode_type3_4(decoded: &DecodedSignal, vag_type: VagType, key_idx: u8) -> Option<Vec<LevelDuration>> {
|
||||
let mut upload = Vec::with_capacity(600);
|
||||
let vag_type_num = self.vag_type as u8;
|
||||
let vag_type_num = vag_type as u8;
|
||||
|
||||
let btn_byte = Self::btn_to_byte(self.btn, vag_type_num);
|
||||
let serial = decoded.serial.unwrap_or(0);
|
||||
let btn = decoded.button.unwrap_or(0);
|
||||
let cnt = decoded.counter.unwrap_or(0) as u32;
|
||||
let type_byte = (decoded.data >> 56) as u8;
|
||||
let btn_byte = Self::btn_to_byte(btn, vag_type_num);
|
||||
let dispatch = Self::get_dispatch_byte(btn_byte, vag_type_num);
|
||||
let type_byte = (self.key1_high >> 24) as u8;
|
||||
|
||||
let mut block = [0u8; 8];
|
||||
block[0] = (self.serial >> 24) as u8;
|
||||
block[1] = (self.serial >> 16) as u8;
|
||||
block[2] = (self.serial >> 8) as u8;
|
||||
block[3] = self.serial as u8;
|
||||
block[4] = self.cnt as u8;
|
||||
block[5] = (self.cnt >> 8) as u8;
|
||||
block[6] = (self.cnt >> 16) as u8;
|
||||
block[0] = (serial >> 24) as u8;
|
||||
block[1] = (serial >> 16) as u8;
|
||||
block[2] = (serial >> 8) as u8;
|
||||
block[3] = serial as u8;
|
||||
block[4] = cnt as u8;
|
||||
block[5] = (cnt >> 8) as u8;
|
||||
block[6] = (cnt >> 16) as u8;
|
||||
block[7] = btn_byte;
|
||||
|
||||
let key_idx = if self.key_idx != 0xFF {
|
||||
self.key_idx as usize
|
||||
} else if self.vag_type == VagType::Type4 { 2 } else { 1 };
|
||||
let key_idx = if key_idx != 0xFF {
|
||||
key_idx as usize
|
||||
} else if vag_type == VagType::Type4 { 2 } else { 1 };
|
||||
|
||||
let store = keys::get_keystore();
|
||||
if let Some(key) = store.get_vag_key((key_idx + 1) as u8) {
|
||||
@@ -758,9 +777,14 @@ impl VagDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Build DecodedSignal from internal state
|
||||
/// Build DecodedSignal from internal state (sets extra when decrypted for encode-from-capture)
|
||||
fn build_decoded_signal(&self) -> DecodedSignal {
|
||||
let key1 = ((self.key1_high as u64) << 32) | (self.key1_low as u64);
|
||||
let extra = if self.decrypted {
|
||||
Some((self.vag_type as u8 as u64) | ((self.key_idx as u64) << 8))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
DecodedSignal {
|
||||
serial: if self.decrypted { Some(self.serial) } else { None },
|
||||
@@ -770,6 +794,7 @@ impl VagDecoder {
|
||||
data: key1,
|
||||
data_count_bit: self.data_count_bit,
|
||||
encoder_capable: self.decrypted,
|
||||
extra,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1160,7 +1185,7 @@ impl ProtocolDecoder for VagDecoder {
|
||||
}
|
||||
|
||||
fn supports_encoding(&self) -> bool {
|
||||
self.decrypted
|
||||
true
|
||||
}
|
||||
|
||||
fn encode(&self, decoded: &DecodedSignal, _button: u8) -> Option<Vec<LevelDuration>> {
|
||||
|
||||
Reference in New Issue
Block a user