fix build and readme
FAP Build / ufbt: Build for Momentum dev (push) Successful in 1m13s
FAP Build / ufbt: Build for Momentum release (push) Successful in 1m15s
FAP Build / ufbt: Build for OFW dev channel (push) Successful in 1m9s
FAP Build / ufbt: Build for OFW release channel (push) Successful in 1m8s
FAP Build / ufbt: Build for Unleashed dev (push) Successful in 1m5s
FAP Build / ufbt: Build for Unleashed release (push) Successful in 1m7s

This commit is contained in:
MX
2026-04-16 02:13:36 +03:00
parent 331f48b352
commit eb5dd515e4
3 changed files with 62 additions and 64 deletions
+5
View File
@@ -23,6 +23,7 @@ App is intended for educational and security purposes only, and has no signal tr
| Protocol | Decoder | Encoder | Signal Encoding | Modulation | Encryption | CRC | Frequency |
|:------------------------------|:--------|:--------|:--------|:--------|:--------|:--------|:--------|
| Fiat V0 | ✅ | ✅ | Manchester | AM | Rolling Code (Static Emu only) | ❌ | 433.92 |
| Fiat V1 | ✅ | ❌ | Manchester | AM | Rolling Code | ❌ | 433.92 |
| Ford V0 | ✅ | ✅ | Manchester | AM | Rolling Code | ✅ + Checksum | 315.00 / 433.92 |
| Kia V0 | ✅ | ✅ | PWM | FM | Rolling Code | CRC8 | 433.92 |
| Kia V1 | ✅ | ✅ | Manchester | AM | Rolling Code | CRC4 | 315.00 / 433.92 |
@@ -30,12 +31,16 @@ App is intended for educational and security purposes only, and has no signal tr
| Kia V3 / V4 | ✅ | ✅ | PWM | AM/FM | KeeLoq | CRC4 | 315.00 / 433.92 |
| Kia V5 | ✅ | ❌ | Manchester | FM | Rolling Code | ✅ | 433.92 |
| Kia V6 | ✅ | ✅ | Manchester | FM | AES128 | CRC8 | 433.92 |
| Kia V7 | ✅ | ✅ | Manchester | FM | Rolling Code | CRC8 | 433.92 |
| PSA (Peugeot/Citroen) | ✅ | ✅ | Manchester | AM/FM | XTEA/XOR | ✅ | 433.92 |
| Scher-Khan | ✅ | ❌ | PWM | FM | Magic Code | ❌ | 433.92 |
| StarLine | ✅ | ✅ | PWM | AM | KeeLoq | ❌ | 433.92 |
| Subaru | ✅ | ✅ | PWM | AM | Rolling Code | ❌ | 433.92 |
| Suzuki | ✅ | ✅ | PWM | FM | Rolling Code | CRC8 | 433.92 |
| VAG (VW/Audi/Seat/Skoda) | ✅ | ✅ | Manchester | AM | AUT64/XTEA | ❌ | 434.42 |
| Mazda V0 | ✅ | ✅ | Manchester | AM | Rolling Code | ❌ | 433.92 |
| Mitsubishi V0 | ✅ | ❌ | PWM | AM | Rolling Code | ❌ | 433.92 |
| Porsche/Touareg | ✅ | ❌ | PWM | AM | Rolling Code | ❌ | 433.92 |
_More Coming Soon_
+32 -36
View File
@@ -1,13 +1,13 @@
#include "kia_v7.h"
#include <string.h>
#define KIA_V7_UPLOAD_CAPACITY 0x3A4
#define KIA_V7_PREAMBLE_PAIRS 0x13F
#define KIA_V7_UPLOAD_CAPACITY 0x3A4
#define KIA_V7_PREAMBLE_PAIRS 0x13F
#define KIA_V7_PREAMBLE_MIN_PAIRS 16
#define KIA_V7_HEADER 0x4C
#define KIA_V7_TAIL_GAP_US 0x7D0
#define KIA_V7_KEY_BITS 64U
#define KIA_V7_DEFAULT_TX_REPEAT 10U
#define KIA_V7_HEADER 0x4C
#define KIA_V7_TAIL_GAP_US 0x7D0
#define KIA_V7_KEY_BITS 64U
#define KIA_V7_DEFAULT_TX_REPEAT 10U
static const SubGhzBlockConst kia_protocol_v7_const = {
.te_short = 250,
@@ -87,7 +87,8 @@ static uint64_t kia_v7_bytes_to_u64_be(const uint8_t bytes[8]) {
}
static bool kia_v7_is_short(uint32_t duration) {
return DURATION_DIFF(duration, kia_protocol_v7_const.te_short) < kia_protocol_v7_const.te_delta;
return DURATION_DIFF(duration, kia_protocol_v7_const.te_short) <
kia_protocol_v7_const.te_delta;
}
static bool kia_v7_is_long(uint32_t duration) {
@@ -113,8 +114,7 @@ static SubGhzProtocolStatus
SubGhzProtocolStatus status = SubGhzProtocolStatusOk;
FuriString* display = furi_string_alloc();
furi_string_printf(
display, "%s - %s", protocol_name, kia_v7_get_button_name(button));
furi_string_printf(display, "%s - %s", protocol_name, kia_v7_get_button_name(button));
if(!flipper_format_write_string_cstr(flipper_format, "Disp", furi_string_get_cstr(display))) {
status = SubGhzProtocolStatusErrorParserOthers;
@@ -173,17 +173,6 @@ static void kia_v7_decode_key_decoder(SubGhzProtocolDecoderKiaV7* instance) {
&instance->crc_valid);
}
#ifdef ENABLE_EMULATE_FEATURE
static void kia_v7_decode_key_encoder(SubGhzProtocolEncoderKiaV7* instance) {
kia_v7_decode_key_common(
&instance->generic,
&instance->decoded_button,
&instance->fixed_high_byte,
&instance->crc_calculated,
&instance->crc_raw,
&instance->crc_valid);
}
static uint64_t kia_v7_encode_key(
uint8_t fixed_high_byte,
uint32_t serial,
@@ -211,18 +200,28 @@ static uint64_t kia_v7_encode_key(
return kia_v7_bytes_to_u64_be(bytes);
}
#ifdef ENABLE_EMULATE_FEATURE
static void kia_v7_decode_key_encoder(SubGhzProtocolEncoderKiaV7* instance) {
kia_v7_decode_key_common(
&instance->generic,
&instance->decoded_button,
&instance->fixed_high_byte,
&instance->crc_calculated,
&instance->crc_raw,
&instance->crc_valid);
}
static bool kia_v7_encoder_get_upload(SubGhzProtocolEncoderKiaV7* instance) {
furi_check(instance);
const LevelDuration high_short =
level_duration_make(true, kia_protocol_v7_const.te_short);
const LevelDuration low_short =
level_duration_make(false, kia_protocol_v7_const.te_short);
const LevelDuration high_short = level_duration_make(true, kia_protocol_v7_const.te_short);
const LevelDuration low_short = level_duration_make(false, kia_protocol_v7_const.te_short);
const LevelDuration low_tail = level_duration_make(false, KIA_V7_TAIL_GAP_US);
const size_t max_size = KIA_V7_UPLOAD_CAPACITY;
const uint8_t bit_count =
(instance->tx_bit_count > 0U && instance->tx_bit_count <= 64U) ? instance->tx_bit_count : 64U;
const uint8_t bit_count = (instance->tx_bit_count > 0U && instance->tx_bit_count <= 64U) ?
instance->tx_bit_count :
64U;
size_t final_size = 0;
@@ -362,17 +361,15 @@ SubGhzProtocolStatus
flipper_format_rewind(flipper_format);
SubGhzProtocolStatus load_st = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
KIA_V7_KEY_BITS);
&instance->generic, flipper_format, KIA_V7_KEY_BITS);
if(load_st != SubGhzProtocolStatusOk) {
break;
}
instance->tx_bit_count =
(instance->generic.data_count_bit > 0U && instance->generic.data_count_bit <= 64U)
? (uint8_t)instance->generic.data_count_bit
: 64U;
(instance->generic.data_count_bit > 0U && instance->generic.data_count_bit <= 64U) ?
(uint8_t)instance->generic.data_count_bit :
64U;
kia_v7_decode_key_encoder(instance);
@@ -668,7 +665,8 @@ SubGhzProtocolStatus kia_protocol_decoder_v7_serialize(
return SubGhzProtocolStatusErrorParserOthers;
}
return kia_v7_write_display(flipper_format, instance->generic.protocol_name, instance->decoded_button);
return kia_v7_write_display(
flipper_format, instance->generic.protocol_name, instance->decoded_button);
}
SubGhzProtocolStatus
@@ -677,9 +675,7 @@ SubGhzProtocolStatus
SubGhzProtocolDecoderKiaV7* instance = context;
SubGhzProtocolStatus status = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
KIA_V7_KEY_BITS);
&instance->generic, flipper_format, KIA_V7_KEY_BITS);
if(status != SubGhzProtocolStatusOk) {
return status;
+25 -28
View File
@@ -13,7 +13,7 @@ static const SubGhzBlockConst subghz_protocol_mazda_v0_const = {
.min_count_bit_for_found = 64,
};
#define MAZDA_V0_UPLOAD_CAPACITY 0x184
#define MAZDA_V0_UPLOAD_CAPACITY 0x184
#define MAZDA_V0_GAP_US 0xCB20
#define MAZDA_V0_SYNC_BYTE 0xD7
#define MAZDA_V0_TAIL_BYTE 0x5A
@@ -68,14 +68,14 @@ static bool mazda_v0_encoder_add_level(
size_t* index,
bool level,
uint32_t duration);
static bool mazda_v0_append_byte(
SubGhzProtocolEncoderMazdaV0* instance,
size_t* index,
uint8_t value);
static bool
mazda_v0_append_byte(SubGhzProtocolEncoderMazdaV0* instance, size_t* index, uint8_t value);
static bool mazda_v0_build_upload(SubGhzProtocolEncoderMazdaV0* instance);
#endif
static SubGhzProtocolStatus
mazda_v0_write_display(FlipperFormat* flipper_format, const char* protocol_name, uint8_t button);
static SubGhzProtocolStatus mazda_v0_write_display(
FlipperFormat* flipper_format,
const char* protocol_name,
uint8_t button);
// =============================================================================
// PROTOCOL INTERFACE DEFINITIONS
@@ -137,7 +137,7 @@ static void mazda_v0_u64_to_bytes_be(uint64_t data, uint8_t bytes[8]) {
bytes[i] = (uint8_t)((data >> ((7 - i) * 8)) & 0xFF);
}
}
#ifdef ENABLE_EMULATE_FEATURE
static uint64_t mazda_v0_bytes_to_u64_be(const uint8_t bytes[8]) {
uint64_t data = 0;
for(size_t i = 0; i < 8; i++) {
@@ -145,13 +145,12 @@ static uint64_t mazda_v0_bytes_to_u64_be(const uint8_t bytes[8]) {
}
return data;
}
#endif
static uint8_t mazda_v0_calculate_checksum(uint32_t serial, uint8_t button, uint32_t counter) {
counter &= 0xFFFFFU;
return (uint8_t)(
((serial >> 24) & 0xFF) + ((serial >> 16) & 0xFF) + ((serial >> 8) & 0xFF) +
(serial & 0xFF) + ((counter >> 8) & 0xFF) + (counter & 0xFF) +
((((counter >> 16) & 0x0F) | ((button & 0x0F) << 4)) & 0xFF));
return (uint8_t)(((serial >> 24) & 0xFF) + ((serial >> 16) & 0xFF) + ((serial >> 8) & 0xFF) +
(serial & 0xFF) + ((counter >> 8) & 0xFF) + (counter & 0xFF) +
((((counter >> 16) & 0x0F) | ((button & 0x0F) << 4)) & 0xFF));
}
static const char* mazda_v0_get_button_name(uint8_t button) {
@@ -256,10 +255,8 @@ static bool mazda_v0_encoder_add_level(
return true;
}
static bool mazda_v0_append_byte(
SubGhzProtocolEncoderMazdaV0* instance,
size_t* index,
uint8_t value) {
static bool
mazda_v0_append_byte(SubGhzProtocolEncoderMazdaV0* instance, size_t* index, uint8_t value) {
if(*index + 16 > MAZDA_V0_UPLOAD_CAPACITY) {
return false;
}
@@ -333,13 +330,14 @@ static bool mazda_v0_build_upload(SubGhzProtocolEncoderMazdaV0* instance) {
}
#endif
static SubGhzProtocolStatus
mazda_v0_write_display(FlipperFormat* flipper_format, const char* protocol_name, uint8_t button) {
static SubGhzProtocolStatus mazda_v0_write_display(
FlipperFormat* flipper_format,
const char* protocol_name,
uint8_t button) {
SubGhzProtocolStatus status = SubGhzProtocolStatusOk;
FuriString* display = furi_string_alloc();
furi_string_printf(
display, "%s - %s", protocol_name, mazda_v0_get_button_name(button));
furi_string_printf(display, "%s - %s", protocol_name, mazda_v0_get_button_name(button));
if(!flipper_format_write_string_cstr(flipper_format, "Disp", furi_string_get_cstr(display))) {
status = SubGhzProtocolStatusErrorParserOthers;
@@ -468,8 +466,8 @@ SubGhzProtocolStatus
break;
}
uint32_t chk = mazda_v0_calculate_checksum(
instance->serial, instance->button, instance->count);
uint32_t chk =
mazda_v0_calculate_checksum(instance->serial, instance->button, instance->count);
flipper_format_rewind(flipper_format);
flipper_format_insert_or_update_uint32(flipper_format, "Checksum", &chk, 1);
@@ -551,9 +549,8 @@ void subghz_protocol_decoder_mazda_v0_feed(void* context, bool level, uint32_t d
switch(instance->decoder.parser_step) {
case MazdaV0DecoderStepReset:
if(level &&
((uint32_t)DURATION_DIFF(duration, subghz_protocol_mazda_v0_const.te_short) <
(uint32_t)subghz_protocol_mazda_v0_const.te_delta + 20U)) {
if(level && ((uint32_t)DURATION_DIFF(duration, subghz_protocol_mazda_v0_const.te_short) <
(uint32_t)subghz_protocol_mazda_v0_const.te_delta + 20U)) {
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
instance->decoder.parser_step = MazdaV0DecoderStepPreamble;
@@ -653,8 +650,8 @@ SubGhzProtocolStatus subghz_protocol_decoder_mazda_v0_serialize(
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
if(ret == SubGhzProtocolStatusOk) {
uint32_t chk = mazda_v0_calculate_checksum(
instance->serial, instance->button, instance->count);
uint32_t chk =
mazda_v0_calculate_checksum(instance->serial, instance->button, instance->count);
flipper_format_write_uint32(flipper_format, "Checksum", &chk, 1);
flipper_format_write_uint32(flipper_format, "Serial", &instance->serial, 1);