minor updates
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
//! - **Star Line format**: 64 bits, 250/500µs PWM, 433 MHz
|
||||
//!
|
||||
//! All decryption is done via [keeloq_common]; this module only orchestrates bit collection
|
||||
//! (delegated to the format-specific collectors) and tries each key.
|
||||
//! (delegated to the format-specific collectors) and tries each key in both byte orders
|
||||
//! (as stored, and byte-swapped) in case the source used big- or little-endian.
|
||||
|
||||
use super::common::DecodedSignal;
|
||||
use super::keeloq_common::{keeloq_decrypt, keeloq_normal_learning, reverse_key, reverse8};
|
||||
@@ -19,39 +20,32 @@ const KIA_V3_V4_BITS: usize = 68;
|
||||
const STAR_LINE_BITS: usize = 64;
|
||||
|
||||
/// Try to decode an unknown signal as KeeLoq using every keystore manufacturer key.
|
||||
/// Tries Kia V3/V4 format first (315/433 MHz), then Star Line format (433 MHz).
|
||||
/// Tries both Kia V3/V4 format (68-bit, 400/800µs) and Star Line format (64-bit, 250/500µs)
|
||||
/// regardless of frequency; each key is tried in both byte orders (LE and BE) until one validates.
|
||||
/// Returns `("Keeloq (keystore name)", decoded)` on first successful decrypt.
|
||||
pub fn try_decode(
|
||||
pairs: &[LevelDuration],
|
||||
frequency: u32,
|
||||
_frequency: u32,
|
||||
) -> Option<(String, DecodedSignal)> {
|
||||
let keys = keystore::keeloq_mf_keys_with_names();
|
||||
if keys.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Kia V3/V4 format: 400/800µs, 315/433 MHz
|
||||
let kia_freq_ok = [315_000_000u32, 433_920_000].iter().any(|&f| {
|
||||
let diff = if f > frequency { f - frequency } else { frequency - f };
|
||||
diff < (f / 50)
|
||||
});
|
||||
if kia_freq_ok {
|
||||
for invert in [false, true] {
|
||||
if let Some((buf, is_v3)) = kia_v3_v4::collect_kia_v3_v4_bits(pairs, invert) {
|
||||
if let Some((name, decoded)) = try_kia_v3_v4_format(&buf, is_v3, &keys) {
|
||||
return Some((format!("Keeloq ({})", name), decoded));
|
||||
}
|
||||
// Kia V3/V4 format: 400/800µs, 68 bits (try both polarities, all keys)
|
||||
for invert in [false, true] {
|
||||
if let Some((buf, is_v3)) = kia_v3_v4::collect_kia_v3_v4_bits(pairs, invert) {
|
||||
if let Some((name, decoded)) = try_kia_v3_v4_format(&buf, is_v3, &keys) {
|
||||
return Some((format!("Keeloq ({})", name), decoded));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Star Line format: 250/500µs, 433 MHz
|
||||
if frequency.abs_diff(433_920_000) < (433_920_000 / 50) {
|
||||
for invert in [false, true] {
|
||||
if let Some(data) = star_line::collect_star_line_bits(pairs, invert) {
|
||||
if let Some((name, decoded)) = try_star_line_format(data, &keys) {
|
||||
return Some((format!("Keeloq ({})", name), decoded));
|
||||
}
|
||||
// Star Line format: 250/500µs, 64 bits (try both polarities, all keys)
|
||||
for invert in [false, true] {
|
||||
if let Some(data) = star_line::collect_star_line_bits(pairs, invert) {
|
||||
if let Some((name, decoded)) = try_star_line_format(data, &keys) {
|
||||
return Some((format!("Keeloq ({})", name), decoded));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,27 +85,29 @@ fn try_kia_v3_v4_format(
|
||||
| (b[7] as u64);
|
||||
|
||||
for (name, mf_key) in keys {
|
||||
if *mf_key == 0 {
|
||||
continue;
|
||||
}
|
||||
let decrypted = keeloq_decrypt(encrypted, *mf_key);
|
||||
let dec_btn = ((decrypted >> 28) & 0x0F) as u8;
|
||||
let dec_serial_lsb = ((decrypted >> 16) & 0xFF) as u8;
|
||||
if dec_btn == button && dec_serial_lsb == our_serial_lsb {
|
||||
let counter = (decrypted & 0xFFFF) as u16;
|
||||
return Some((
|
||||
name.clone(),
|
||||
DecodedSignal {
|
||||
serial: Some(serial),
|
||||
button: Some(button),
|
||||
counter: Some(counter),
|
||||
crc_valid: true,
|
||||
data: key_data,
|
||||
data_count_bit: KIA_V3_V4_BITS,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
},
|
||||
));
|
||||
for key in [*mf_key, mf_key.swap_bytes()] {
|
||||
if key == 0 {
|
||||
continue;
|
||||
}
|
||||
let decrypted = keeloq_decrypt(encrypted, key);
|
||||
let dec_btn = ((decrypted >> 28) & 0x0F) as u8;
|
||||
let dec_serial_lsb = ((decrypted >> 16) & 0xFF) as u8;
|
||||
if dec_btn == button && dec_serial_lsb == our_serial_lsb {
|
||||
let counter = (decrypted & 0xFFFF) as u16;
|
||||
return Some((
|
||||
name.clone(),
|
||||
DecodedSignal {
|
||||
serial: Some(serial),
|
||||
button: Some(button),
|
||||
counter: Some(counter),
|
||||
crc_valid: true,
|
||||
data: key_data,
|
||||
data_count_bit: KIA_V3_V4_BITS,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
@@ -131,49 +127,51 @@ fn try_star_line_format(
|
||||
let serial_lsb = (serial & 0xFF) as u8;
|
||||
|
||||
for (name, mf_key) in keys {
|
||||
if *mf_key == 0 {
|
||||
continue;
|
||||
}
|
||||
// Simple learning
|
||||
let decrypt = keeloq_decrypt(key_hop, *mf_key);
|
||||
let dec_btn = (decrypt >> 24) as u8;
|
||||
let dec_serial_lsb = ((decrypt >> 16) & 0xFF) as u8;
|
||||
if dec_btn == btn && dec_serial_lsb == serial_lsb {
|
||||
let counter = (decrypt & 0xFFFF) as u16;
|
||||
return Some((
|
||||
name.clone(),
|
||||
DecodedSignal {
|
||||
serial: Some(serial),
|
||||
button: Some(btn),
|
||||
counter: Some(counter),
|
||||
crc_valid: true,
|
||||
data,
|
||||
data_count_bit: STAR_LINE_BITS,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
// Normal learning
|
||||
let man_key = keeloq_normal_learning(key_fix, *mf_key);
|
||||
let decrypt = keeloq_decrypt(key_hop, man_key);
|
||||
let dec_btn = (decrypt >> 24) as u8;
|
||||
let dec_serial_lsb = ((decrypt >> 16) & 0xFF) as u8;
|
||||
if dec_btn == btn && dec_serial_lsb == serial_lsb {
|
||||
let counter = (decrypt & 0xFFFF) as u16;
|
||||
return Some((
|
||||
name.clone(),
|
||||
DecodedSignal {
|
||||
serial: Some(serial),
|
||||
button: Some(btn),
|
||||
counter: Some(counter),
|
||||
crc_valid: true,
|
||||
data,
|
||||
data_count_bit: STAR_LINE_BITS,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
},
|
||||
));
|
||||
for key in [*mf_key, mf_key.swap_bytes()] {
|
||||
if key == 0 {
|
||||
continue;
|
||||
}
|
||||
// Simple learning
|
||||
let decrypt = keeloq_decrypt(key_hop, key);
|
||||
let dec_btn = (decrypt >> 24) as u8;
|
||||
let dec_serial_lsb = ((decrypt >> 16) & 0xFF) as u8;
|
||||
if dec_btn == btn && dec_serial_lsb == serial_lsb {
|
||||
let counter = (decrypt & 0xFFFF) as u16;
|
||||
return Some((
|
||||
name.clone(),
|
||||
DecodedSignal {
|
||||
serial: Some(serial),
|
||||
button: Some(btn),
|
||||
counter: Some(counter),
|
||||
crc_valid: true,
|
||||
data,
|
||||
data_count_bit: STAR_LINE_BITS,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
// Normal learning
|
||||
let man_key = keeloq_normal_learning(key_fix, key);
|
||||
let decrypt = keeloq_decrypt(key_hop, man_key);
|
||||
let dec_btn = (decrypt >> 24) as u8;
|
||||
let dec_serial_lsb = ((decrypt >> 16) & 0xFF) as u8;
|
||||
if dec_btn == btn && dec_serial_lsb == serial_lsb {
|
||||
let counter = (decrypt & 0xFFFF) as u16;
|
||||
return Some((
|
||||
name.clone(),
|
||||
DecodedSignal {
|
||||
serial: Some(serial),
|
||||
button: Some(btn),
|
||||
counter: Some(counter),
|
||||
crc_valid: true,
|
||||
data,
|
||||
data_count_bit: STAR_LINE_BITS,
|
||||
encoder_capable: true,
|
||||
extra: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user