From 246935fc646a82a3fccdb9ee85de19879199db9b Mon Sep 17 00:00:00 2001 From: RocketGod <57732082+RocketGod-git@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:52:02 -0800 Subject: [PATCH] VW / VAG / AUT64 added --- dist/proto_pirate.fap | Bin 49744 -> 52348 bytes protocols/protocol_items.c | 1 + protocols/protocol_items.h | 1 + protocols/vw.c | 363 +++++++++++++++++++++++++++++++ protocols/vw.h | 28 +++ scenes/protopirate_scene_about.c | 3 +- 6 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 protocols/vw.c create mode 100644 protocols/vw.h diff --git a/dist/proto_pirate.fap b/dist/proto_pirate.fap index 0892e0e2522ba96aa69ff230a059a084d26b2223..9a4dd2a643dad5089a75bf1d016079b5340a9b2d 100644 GIT binary patch delta 19775 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 KU7%jpD)ztTKke!O delta 17457 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 8) { + // use generic.data (bytes 1-8) + bit_index = bit - 8; + } else { + // use data_2 + if(bit >= 72) { + bit_index = bit - 64; // byte 0 = type + } + if(bit < 8) { + bit_index = bit; // byte 9 = check digit + } + bit_index |= 0x80; // mark for data_2 + } + + return bit_index; +} + +static void vw_add_bit(SubGhzProtocolDecoderVw* instance, bool level) { + if(instance->generic.data_count_bit >= subghz_protocol_vw_const.min_count_bit_for_found) { + return; + } + + uint8_t bit_index_full = subghz_protocol_vw_const.min_count_bit_for_found - 1 - instance->generic.data_count_bit; + uint8_t bit_index_masked = vw_get_bit_index(bit_index_full); + uint8_t bit_index = bit_index_masked & 0x7F; + + if(bit_index_masked & 0x80) { + // use data_2 + if(level) { + instance->data_2 |= (1ULL << bit_index); + } else { + instance->data_2 &= ~(1ULL << bit_index); + } + } else { + // use data + if(level) { + instance->generic.data |= (1ULL << bit_index); + } else { + instance->generic.data &= ~(1ULL << bit_index); + } + } + + instance->generic.data_count_bit++; + + if(instance->generic.data_count_bit >= subghz_protocol_vw_const.min_count_bit_for_found) { + if(instance->base.callback) { + instance->base.callback(&instance->base, instance->base.context); + } + } +} + +void* subghz_protocol_decoder_vw_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderVw* instance = malloc(sizeof(SubGhzProtocolDecoderVw)); + instance->base.protocol = &vw_protocol; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_vw_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderVw* instance = context; + free(instance); +} + +void subghz_protocol_decoder_vw_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderVw* instance = context; + instance->decoder.parser_step = VwDecoderStepReset; + instance->generic.data_count_bit = 0; + instance->generic.data = 0; + instance->data_2 = 0; + instance->manchester_state = ManchesterStateMid1; +} + +void subghz_protocol_decoder_vw_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderVw* instance = context; + + uint32_t te_short = subghz_protocol_vw_const.te_short; + uint32_t te_long = subghz_protocol_vw_const.te_long; + uint32_t te_delta = subghz_protocol_vw_const.te_delta; + uint32_t te_med = (te_long + te_short) / 2; + uint32_t te_end = te_long * 5; + + ManchesterEvent event = ManchesterEventReset; + + switch(instance->decoder.parser_step) { + case VwDecoderStepReset: + if(DURATION_DIFF(duration, te_short) < te_delta) { + instance->decoder.parser_step = VwDecoderStepFoundSync; + } + break; + + case VwDecoderStepFoundSync: + if(DURATION_DIFF(duration, te_short) < te_delta) { + // Stay - sync pattern repeats ~43 times + break; + } + + if(level && DURATION_DIFF(duration, te_long) < te_delta) { + instance->decoder.parser_step = VwDecoderStepFoundStart1; + break; + } + + instance->decoder.parser_step = VwDecoderStepReset; + break; + + case VwDecoderStepFoundStart1: + if(!level && DURATION_DIFF(duration, te_short) < te_delta) { + instance->decoder.parser_step = VwDecoderStepFoundStart2; + break; + } + + instance->decoder.parser_step = VwDecoderStepReset; + break; + + case VwDecoderStepFoundStart2: + if(level && DURATION_DIFF(duration, te_med) < te_delta) { + instance->decoder.parser_step = VwDecoderStepFoundStart3; + break; + } + + instance->decoder.parser_step = VwDecoderStepReset; + break; + + case VwDecoderStepFoundStart3: + if(DURATION_DIFF(duration, te_med) < te_delta) { + // Stay - med pattern repeats + break; + } + + if(level && DURATION_DIFF(duration, te_short) < te_delta) { + // Start data collection + vw_manchester_advance( + instance->manchester_state, + ManchesterEventReset, + &instance->manchester_state, + NULL); + vw_manchester_advance( + instance->manchester_state, + ManchesterEventShortHigh, + &instance->manchester_state, + NULL); + instance->generic.data_count_bit = 0; + instance->generic.data = 0; + instance->data_2 = 0; + instance->decoder.parser_step = VwDecoderStepFoundData; + break; + } + + instance->decoder.parser_step = VwDecoderStepReset; + break; + + case VwDecoderStepFoundData: + if(DURATION_DIFF(duration, te_short) < te_delta) { + event = level ? ManchesterEventShortHigh : ManchesterEventShortLow; + } + + if(DURATION_DIFF(duration, te_long) < te_delta) { + event = level ? ManchesterEventLongHigh : ManchesterEventLongLow; + } + + // Last bit can be arbitrarily long + if(instance->generic.data_count_bit == subghz_protocol_vw_const.min_count_bit_for_found - 1 && + !level && duration > te_end) { + event = ManchesterEventShortLow; + } + + if(event == ManchesterEventReset) { + subghz_protocol_decoder_vw_reset(instance); + } else { + bool new_level; + if(vw_manchester_advance( + instance->manchester_state, + event, + &instance->manchester_state, + &new_level)) { + vw_add_bit(instance, new_level); + } + } + break; + } +} + +uint8_t subghz_protocol_decoder_vw_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderVw* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_vw_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderVw* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus subghz_protocol_decoder_vw_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderVw* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_vw_const.min_count_bit_for_found); +} + +static const char* vw_get_button_name(uint8_t btn) { + switch(btn) { + case 0x1: return "UNLOCK"; + case 0x2: return "LOCK"; + case 0x3: return "Un+Lk"; + case 0x4: return "TRUNK"; + case 0x5: return "Un+Tr"; + case 0x6: return "Lk+Tr"; + case 0x7: return "Un+Lk+Tr"; + case 0x8: return "PANIC"; + default: return "Unknown"; + } +} + +void subghz_protocol_decoder_vw_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderVw* instance = context; + + uint8_t type = (instance->data_2 >> 8) & 0xFF; + uint8_t check = instance->data_2 & 0xFF; + uint8_t btn = (check >> 4) & 0xF; + + uint32_t key_high = (instance->generic.data >> 32) & 0xFFFFFFFF; + uint32_t key_low = instance->generic.data & 0xFFFFFFFF; + + furi_string_cat_printf( + output, + "%s %dbit\r\n" + "Key:%02X%08lX%08lX%02X\r\n" + "Type:%02X Btn:%X %s\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + type, + key_high, + key_low, + check, + type, + btn, + vw_get_button_name(btn)); +} \ No newline at end of file diff --git a/protocols/vw.h b/protocols/vw.h new file mode 100644 index 0000000..bdbaa01 --- /dev/null +++ b/protocols/vw.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VW_PROTOCOL_NAME "VW" + +extern const SubGhzProtocol vw_protocol; + +void* subghz_protocol_decoder_vw_alloc(SubGhzEnvironment* environment); +void subghz_protocol_decoder_vw_free(void* context); +void subghz_protocol_decoder_vw_reset(void* context); +void subghz_protocol_decoder_vw_feed(void* context, bool level, uint32_t duration); +uint8_t subghz_protocol_decoder_vw_get_hash_data(void* context); +SubGhzProtocolStatus subghz_protocol_decoder_vw_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); +SubGhzProtocolStatus subghz_protocol_decoder_vw_deserialize(void* context, FlipperFormat* flipper_format); +void subghz_protocol_decoder_vw_get_string(void* context, FuriString* output); \ No newline at end of file diff --git a/scenes/protopirate_scene_about.c b/scenes/protopirate_scene_about.c index 66c2084..7831fa9 100644 --- a/scenes/protopirate_scene_about.c +++ b/scenes/protopirate_scene_about.c @@ -9,11 +9,12 @@ #define SCROLL_SPEED 1 static const char* credits[] = { + "", "Protocols: L0rdDiakon", "Protocols: RocketGod", "Protocols: Trikk", - "Protocols: YougZ", "Protocols: Wootini", + "Protocols: YougZ", "App: RocketGod", "App: MMX", // can add more