From 36c8dce72d9a95747211aa0cafd069ec26e02159 Mon Sep 17 00:00:00 2001 From: zero-mega Date: Thu, 19 Feb 2026 17:31:24 +0100 Subject: [PATCH] Fix VAG decoder --- protocols/vag.c | 411 +++++++++++++++++------------------------------- 1 file changed, 145 insertions(+), 266 deletions(-) diff --git a/protocols/vag.c b/protocols/vag.c index bd2dd41..efd6363 100644 --- a/protocols/vag.c +++ b/protocols/vag.c @@ -12,6 +12,29 @@ static const SubGhzBlockConst subghz_protocol_vag_const = { .min_count_bit_for_found = 80, }; +#define VAG_T12_TE_SHORT 300u +#define VAG_T12_TE_LONG 600u +#define VAG_T12_TE_DELTA 100u +#define VAG_T12_GAP_DELTA 200u +#define VAG_T12_PREAMBLE_MIN 151u + +#define VAG_T34_TE_SHORT 500u +#define VAG_T34_TE_LONG 1000u +#define VAG_T34_TE_DELTA 100u +#define VAG_T34_LONG_DELTA 200u +#define VAG_T34_SYNC 750u +#define VAG_T34_SYNC_DELTA 150u +#define VAG_T34_PREAMBLE_MIN 31u +#define VAG_T34_SYNC_PAIRS 3u + +#define VAG_DATA_GAP_MIN 4001u +#define VAG_TOTAL_BITS 80u +#define VAG_KEY1_BITS 64u +#define VAG_PREFIX_BITS 15u +#define VAG_BIT_LIMIT 96u +#define VAG_FRAME_PREFIX_T1 0x2F3Fu +#define VAG_FRAME_PREFIX_T2 0x2F1Cu + #define VAG_KEYS_COUNT 3 static int8_t protocol_vag_keys_loaded = -1; @@ -89,8 +112,6 @@ typedef struct SubGhzProtocolDecoderVAG { SubGhzBlockDecoder decoder; SubGhzBlockGeneric generic; - uint32_t parser_step; - uint32_t te_last; uint32_t data_low; uint32_t data_high; uint8_t bit_count; @@ -509,7 +530,7 @@ void subghz_protocol_decoder_vag_free(void* context) { void subghz_protocol_decoder_vag_reset(void* context) { furi_check(context); SubGhzProtocolDecoderVAG* instance = context; - instance->parser_step = VAGDecoderStepReset; + instance->decoder.parser_step = VAGDecoderStepReset; instance->decrypted = false; instance->serial = 0; instance->cnt = 0; @@ -522,132 +543,66 @@ void subghz_protocol_decoder_vag_feed(void* context, bool level, uint32_t durati furi_check(context); SubGhzProtocolDecoderVAG* instance = context; - uint32_t diff; - bool bit_value = false; - ManchesterEvent event; - - switch(instance->parser_step) { + switch(instance->decoder.parser_step) { case VAGDecoderStepReset: - if(!level) { - return; + if(!level) break; + if(DURATION_DIFF(duration, VAG_T12_TE_SHORT) < VAG_T12_TE_DELTA) { + instance->decoder.parser_step = VAGDecoderStepPreamble1; + } else if(DURATION_DIFF(duration, VAG_T34_TE_SHORT) < VAG_T34_TE_DELTA) { + instance->decoder.parser_step = VAGDecoderStepPreamble2; + } else { + break; } - - if(duration < 300) { - if((300 - duration) > 79) { - return; - } - goto init_pattern1; - } else if((duration - 300) > 79) { - if(duration < 500) { - diff = 500 - duration; - } else { - diff = duration - 500; - } - if(diff > 79) { - return; - } - instance->parser_step = VAGDecoderStepPreamble2; - goto init_common; - } - init_pattern1: - instance->parser_step = VAGDecoderStepPreamble1; - init_common: instance->data_low = 0; instance->data_high = 0; instance->header_count = 0; instance->mid_count = 0; instance->bit_count = 0; instance->vag_type = 0; - instance->te_last = duration; + instance->decoder.te_last = duration; manchester_advance( instance->manchester_state, ManchesterEventReset, &instance->manchester_state, NULL); - return; + break; case VAGDecoderStepPreamble1: - if(level) { - return; - } - - if(duration < 300) { - if((300 - duration) < 80) { - goto check_preamble1_prev; - } - instance->parser_step = VAGDecoderStepReset; - if(instance->header_count < 201) { - return; - } - duration = 600 - duration; - goto check_gap1; - } else { - if((duration - 300) < 80) { - goto check_preamble1_prev; - } - instance->parser_step = VAGDecoderStepReset; - if(instance->header_count < 201) { - return; - } - if(duration < 600) { - duration = 600 - duration; + if(level) break; + if(DURATION_DIFF(duration, VAG_T12_TE_SHORT) < VAG_T12_TE_DELTA) { + if(DURATION_DIFF(instance->decoder.te_last, VAG_T12_TE_SHORT) < VAG_T12_TE_DELTA) { + instance->decoder.te_last = duration; + instance->header_count++; } else { - duration = duration - 600; + instance->decoder.parser_step = VAGDecoderStepReset; } - check_gap1: - if(duration > 79) { - return; - } - if(instance->te_last < 300) { - diff = 300 - instance->te_last; - } else { - diff = instance->te_last - 300; - } - if(diff > 79) { - return; - } - instance->parser_step = VAGDecoderStepData1; - return; + break; + } + instance->decoder.parser_step = VAGDecoderStepReset; + if(instance->header_count < VAG_T12_PREAMBLE_MIN) break; + if(DURATION_DIFF(duration, VAG_T12_TE_LONG) >= VAG_T12_GAP_DELTA) break; + if(DURATION_DIFF(instance->decoder.te_last, VAG_T12_TE_SHORT) >= VAG_T12_TE_DELTA) break; + instance->decoder.parser_step = VAGDecoderStepData1; + break; + + case VAGDecoderStepData1: { + if(instance->bit_count >= VAG_BIT_LIMIT) { + instance->decoder.parser_step = VAGDecoderStepReset; + break; } - check_preamble1_prev: - if(instance->te_last < 300) { - diff = 300 - instance->te_last; - } else { - diff = instance->te_last - 300; + bool bit_value = false; + ManchesterEvent event = ManchesterEventReset; + bool got_pulse = false; + + if(DURATION_DIFF(duration, VAG_T12_TE_SHORT) < VAG_T12_TE_DELTA) { + event = level ? ManchesterEventShortLow : ManchesterEventShortHigh; + got_pulse = true; + } else if( + duration > VAG_T12_TE_SHORT + VAG_T12_TE_DELTA && + DURATION_DIFF(duration, VAG_T12_TE_LONG) < VAG_T12_GAP_DELTA) { + event = level ? ManchesterEventLongLow : ManchesterEventLongHigh; + got_pulse = true; } - if(diff > 79) { - instance->parser_step = VAGDecoderStepReset; - if(instance->header_count >= 201) { - } - return; - } - instance->te_last = duration; - instance->header_count++; - return; - case VAGDecoderStepData1: - if(instance->bit_count < 96) { - if(duration < 300) { - if((300 - duration) <= 79) { - event = level ? ManchesterEventShortLow : ManchesterEventShortHigh; - goto process_manchester1; - } - } else if((duration - 300) < 80) { - event = level ? ManchesterEventShortLow : ManchesterEventShortHigh; - goto process_manchester1; - } - - if(duration < 600) { - if((600 - duration) <= 79) { - event = level ? ManchesterEventLongLow : ManchesterEventLongHigh; - goto process_manchester1; - } - } else if((duration - 600) < 80) { - event = level ? ManchesterEventLongLow : ManchesterEventLongHigh; - goto process_manchester1; - } - - goto check_gap1_data; - - process_manchester1: + if(got_pulse && instance->bit_count < VAG_BIT_LIMIT) { if(manchester_advance( instance->manchester_state, event, &instance->manchester_state, &bit_value)) { uint32_t carry = (instance->data_low >> 31) & 1; @@ -655,44 +610,35 @@ void subghz_protocol_decoder_vag_feed(void* context, bool level, uint32_t durati instance->data_high = (instance->data_high << 1) | carry; instance->bit_count++; - if(instance->bit_count == 15) { - if(instance->data_low == 0x2F3F && instance->data_high == 0) { + if(instance->bit_count == VAG_PREFIX_BITS) { + if(instance->data_low == VAG_FRAME_PREFIX_T1 && instance->data_high == 0) { instance->data_low = 0; instance->data_high = 0; instance->bit_count = 0; instance->vag_type = 1; - } else if(instance->data_low == 0x2F1C && instance->data_high == 0) { + } else if( + instance->data_low == VAG_FRAME_PREFIX_T2 && instance->data_high == 0) { instance->data_low = 0; instance->data_high = 0; instance->bit_count = 0; instance->vag_type = 2; } - } else if(instance->bit_count == 64) { + } else if(instance->bit_count == VAG_KEY1_BITS) { instance->key1_low = ~instance->data_low; instance->key1_high = ~instance->data_high; instance->data_low = 0; instance->data_high = 0; } } - return; + break; } - check_gap1_data: - if(level) { - return; - } - if(duration < 6000) { - diff = 6000 - duration; - } else { - diff = duration - 6000; - } - if(diff >= 4000) { - return; - } - if(instance->bit_count == 80) { + if(level) break; + if(duration < VAG_DATA_GAP_MIN) break; + if(instance->bit_count == VAG_TOTAL_BITS) { instance->key2_low = (~instance->data_low) & 0xFFFF; instance->key2_high = 0; - instance->data_count_bit = 80; + instance->data_count_bit = VAG_TOTAL_BITS; FURI_LOG_I( TAG, "VAG decoded: Key1:%08lX%08lX Key2:%04X Type:%d", @@ -700,9 +646,7 @@ void subghz_protocol_decoder_vag_feed(void* context, bool level, uint32_t durati (unsigned long)instance->key1_low, (unsigned int)(instance->key2_low & 0xFFFF), instance->vag_type); - vag_parse_data(instance); - if(instance->base.callback) { instance->base.callback(&instance->base, instance->base.context); } @@ -710,168 +654,104 @@ void subghz_protocol_decoder_vag_feed(void* context, bool level, uint32_t durati instance->data_low = 0; instance->data_high = 0; instance->bit_count = 0; - instance->parser_step = VAGDecoderStepReset; + instance->decoder.parser_step = VAGDecoderStepReset; break; + } case VAGDecoderStepPreamble2: if(!level) { - if(duration < 500) { - diff = 500 - duration; + if(DURATION_DIFF(duration, VAG_T34_TE_SHORT) < VAG_T34_TE_DELTA && + DURATION_DIFF(instance->decoder.te_last, VAG_T34_TE_SHORT) < VAG_T34_TE_DELTA) { + instance->decoder.te_last = duration; + instance->header_count++; } else { - diff = duration - 500; + instance->decoder.parser_step = VAGDecoderStepReset; } - if(diff < 80) { - if(instance->te_last < 500) { - diff = 500 - instance->te_last; - } else { - diff = instance->te_last - 500; - } - if(diff < 80) { - instance->te_last = duration; - instance->header_count++; - return; - } - } - instance->parser_step = VAGDecoderStepReset; - return; + break; } - - if(instance->header_count < 41) { - return; - } - - if(duration < 1000) { - diff = 1000 - duration; - } else { - diff = duration - 1000; - } - if(diff > 79) { - return; - } - - if(instance->te_last < 500) { - diff = 500 - instance->te_last; - } else { - diff = instance->te_last - 500; - } - if(diff > 79) { - return; - } - - instance->te_last = duration; - instance->parser_step = VAGDecoderStepSync2A; + if(instance->header_count < VAG_T34_PREAMBLE_MIN) break; + if(DURATION_DIFF(duration, VAG_T34_TE_LONG) >= VAG_T34_LONG_DELTA) break; + if(DURATION_DIFF(instance->decoder.te_last, VAG_T34_TE_SHORT) >= VAG_T34_TE_DELTA) break; + instance->decoder.te_last = duration; + instance->decoder.parser_step = VAGDecoderStepSync2A; break; case VAGDecoderStepSync2A: - if(!level) { - if(duration < 500) { - diff = 500 - duration; - } else { - diff = duration - 500; - } - if(diff < 80) { - if(instance->te_last < 1000) { - diff = 1000 - instance->te_last; - } else { - diff = instance->te_last - 1000; - } - if(diff < 80) { - instance->te_last = duration; - instance->parser_step = VAGDecoderStepSync2B; - break; - } - } + if(!level && + DURATION_DIFF(duration, VAG_T34_TE_SHORT) < VAG_T34_TE_DELTA && + DURATION_DIFF(instance->decoder.te_last, VAG_T34_TE_LONG) < VAG_T34_LONG_DELTA) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = VAGDecoderStepSync2B; + } else { + instance->decoder.parser_step = VAGDecoderStepReset; } - instance->parser_step = VAGDecoderStepReset; break; case VAGDecoderStepSync2B: - if(level) { - if(duration < 750) { - diff = 750 - duration; - } else { - diff = duration - 750; - } - if(diff < 80) { - instance->te_last = duration; - instance->parser_step = VAGDecoderStepSync2C; - break; - } + if(level && DURATION_DIFF(duration, VAG_T34_SYNC) < VAG_T34_SYNC_DELTA) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = VAGDecoderStepSync2C; + } else { + instance->decoder.parser_step = VAGDecoderStepReset; } - instance->parser_step = VAGDecoderStepReset; break; case VAGDecoderStepSync2C: - if(!level) { - if(duration < 750) { - diff = 750 - duration; - } else { - diff = duration - 750; - } - if(diff <= 79) { - if(instance->te_last < 750) { - diff = 750 - instance->te_last; - } else { - diff = instance->te_last - 750; - } - if(diff <= 79) { - instance->mid_count++; - instance->parser_step = VAGDecoderStepSync2B; - - if(instance->mid_count == 3) { - instance->data_low = 1; - instance->data_high = 0; - instance->bit_count = 1; - manchester_advance( - instance->manchester_state, - ManchesterEventReset, - &instance->manchester_state, - NULL); - instance->parser_step = VAGDecoderStepData2; - } - break; - } + if(!level && + DURATION_DIFF(duration, VAG_T34_SYNC) < VAG_T34_SYNC_DELTA && + DURATION_DIFF(instance->decoder.te_last, VAG_T34_SYNC) < VAG_T34_SYNC_DELTA) { + instance->mid_count++; + instance->decoder.parser_step = VAGDecoderStepSync2B; + if(instance->mid_count == VAG_T34_SYNC_PAIRS) { + instance->data_low = 1; + instance->data_high = 0; + instance->bit_count = 1; + manchester_advance( + instance->manchester_state, + ManchesterEventReset, + &instance->manchester_state, + NULL); + instance->decoder.parser_step = VAGDecoderStepData2; } + } else { + instance->decoder.parser_step = VAGDecoderStepReset; } - instance->parser_step = VAGDecoderStepReset; break; - case VAGDecoderStepData2: - if(duration >= 380 && duration <= 620) { + case VAGDecoderStepData2: { + bool bit_value = false; + ManchesterEvent event = ManchesterEventReset; + bool got_pulse = false; + + if(DURATION_DIFF(duration, VAG_T34_TE_SHORT) < VAG_T34_TE_DELTA) { event = level ? ManchesterEventShortLow : ManchesterEventShortHigh; - goto process_manchester2; - } - - if(duration >= 880 && duration <= 1120) { + got_pulse = true; + } else if(DURATION_DIFF(duration, VAG_T34_TE_LONG) < VAG_T34_LONG_DELTA) { event = level ? ManchesterEventLongLow : ManchesterEventLongHigh; - goto process_manchester2; + got_pulse = true; } - goto check_complete2; + if(got_pulse) { + if(manchester_advance( + instance->manchester_state, event, &instance->manchester_state, &bit_value)) { + uint32_t carry = (instance->data_low >> 31) & 1; + instance->data_low = (instance->data_low << 1) | (bit_value ? 1 : 0); + instance->data_high = (instance->data_high << 1) | carry; + instance->bit_count++; - process_manchester2: - if(manchester_advance( - instance->manchester_state, event, &instance->manchester_state, &bit_value)) { - uint32_t carry = (instance->data_low >> 31) & 1; - instance->data_low = (instance->data_low << 1) | (bit_value ? 1 : 0); - instance->data_high = (instance->data_high << 1) | carry; - instance->bit_count++; - - if(instance->bit_count == 64) { - instance->key1_low = instance->data_low; - instance->key1_high = instance->data_high; - instance->data_low = 0; - instance->data_high = 0; + if(instance->bit_count == VAG_KEY1_BITS) { + instance->key1_low = instance->data_low; + instance->key1_high = instance->data_high; + instance->data_low = 0; + instance->data_high = 0; + } } } - check_complete2: - if(instance->bit_count != 80) { - break; - } + if(instance->bit_count != VAG_TOTAL_BITS) break; instance->key2_low = instance->data_low & 0xFFFF; instance->key2_high = 0; - instance->data_count_bit = 80; + instance->data_count_bit = VAG_TOTAL_BITS; instance->vag_type = 3; FURI_LOG_I( TAG, @@ -880,20 +760,19 @@ void subghz_protocol_decoder_vag_feed(void* context, bool level, uint32_t durati (unsigned long)instance->key1_low, (unsigned int)(instance->key2_low & 0xFFFF), instance->vag_type); - vag_parse_data(instance); - if(instance->base.callback) { instance->base.callback(&instance->base, instance->base.context); } instance->data_low = 0; instance->data_high = 0; instance->bit_count = 0; - instance->parser_step = VAGDecoderStepReset; + instance->decoder.parser_step = VAGDecoderStepReset; break; + } default: - instance->parser_step = VAGDecoderStepReset; + instance->decoder.parser_step = VAGDecoderStepReset; break; } }