From 230b42f867120b47f025f54ca894b88eb8786d19 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:33:49 +0300 Subject: [PATCH 01/19] Fix Typos --- lib/subghz/protocols/alutech_at_4n.h | 2 +- lib/subghz/protocols/dooya.c | 4 ++-- lib/subghz/protocols/public_api.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/subghz/protocols/alutech_at_4n.h b/lib/subghz/protocols/alutech_at_4n.h index 189f2f0d8b4..871ece0ad69 100644 --- a/lib/subghz/protocols/alutech_at_4n.h +++ b/lib/subghz/protocols/alutech_at_4n.h @@ -1,7 +1,7 @@ #pragma once #include "base.h" -#define SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME "Alutech at-4n" +#define SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME "Alutech AT-4N" typedef struct SubGhzProtocolDecoderAlutech_at_4n SubGhzProtocolDecoderAlutech_at_4n; typedef struct SubGhzProtocolEncoderAlutech_at_4n SubGhzProtocolEncoderAlutech_at_4n; diff --git a/lib/subghz/protocols/dooya.c b/lib/subghz/protocols/dooya.c index 47e95209e54..816847840fc 100644 --- a/lib/subghz/protocols/dooya.c +++ b/lib/subghz/protocols/dooya.c @@ -308,7 +308,7 @@ void subghz_protocol_decoder_dooya_feed(void* context, bool level, uint32_t dura * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance */ -static void subghz_protocol_somfy_telis_check_remote_controller(SubGhzBlockGeneric* instance) { +static void subghz_protocol_dooya_check_remote_controller(SubGhzBlockGeneric* instance) { /* * serial s/m ch key * long press down X * E1DC030533, 40b 111000011101110000000011 0000 0101 0011 0011 @@ -416,7 +416,7 @@ void subghz_protocol_decoder_dooya_get_string(void* context, FuriString* output) furi_assert(context); SubGhzProtocolDecoderDooya* instance = context; - subghz_protocol_somfy_telis_check_remote_controller(&instance->generic); + subghz_protocol_dooya_check_remote_controller(&instance->generic); furi_string_cat_printf( output, diff --git a/lib/subghz/protocols/public_api.h b/lib/subghz/protocols/public_api.h index 174f175cdfa..a5a980b3bba 100644 --- a/lib/subghz/protocols/public_api.h +++ b/lib/subghz/protocols/public_api.h @@ -31,7 +31,7 @@ bool subghz_protocol_secplus_v2_create_data( * @param flipper_format Pointer to a FlipperFormat instance * @param serial Serial number, 28 bit * @param btn Button number, 4 bit - * @param cnt Container value, 16 bit + * @param cnt Counter value, 16 bit * @param manufacture_name Name of manufacturer's key * @param preset Modulation, SubGhzRadioPreset * @return true On success From b1ea81ff70c793c9f4d340fff5ef0406537d138b Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:34:45 +0300 Subject: [PATCH 02/19] Tune decoders --- lib/subghz/protocols/came.c | 5 ++++- lib/subghz/protocols/holtek_ht12x.c | 6 ++++-- lib/subghz/protocols/raw.c | 6 +++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index bbe3e487fe0..c3d9c8662d9 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -244,8 +244,11 @@ void subghz_protocol_decoder_came_feed(void* context, bool level, uint32_t durat switch(instance->decoder.parser_step) { case CameDecoderStepReset: if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_const.te_short * 56) < - subghz_protocol_came_const.te_delta * 47)) { + subghz_protocol_came_const.te_delta * 63)) { + // 17920 us + 7050 us = 24970 us max possible value old one + // delta = 150 us x 63 = 9450 us + 17920 us = 27370 us max possible value //Found header CAME + // 26700 us or 24000 us max possible values instance->decoder.parser_step = CameDecoderStepFoundStartBit; } break; diff --git a/lib/subghz/protocols/holtek_ht12x.c b/lib/subghz/protocols/holtek_ht12x.c index 302b78598b9..be2dfd406d7 100644 --- a/lib/subghz/protocols/holtek_ht12x.c +++ b/lib/subghz/protocols/holtek_ht12x.c @@ -234,8 +234,10 @@ void subghz_protocol_decoder_holtek_th12x_feed(void* context, bool level, uint32 switch(instance->decoder.parser_step) { case Holtek_HT12XDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_short * 36) < - subghz_protocol_holtek_th12x_const.te_delta * 36)) { + if((!level) && (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_short * 28) < + subghz_protocol_holtek_th12x_const.te_delta * 20)) { + // 18720 us old max value + // 12960 us corrected max value //Found Preambula instance->decoder.parser_step = Holtek_HT12XDecoderStepFoundStartBit; } diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index d7b31be3791..96908130e9e 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -245,8 +245,8 @@ void subghz_protocol_decoder_raw_reset(void* context) { void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t duration) { furi_check(context); SubGhzProtocolDecoderRAW* instance = context; - - if(!instance->pause && (instance->upload_raw != NULL)) { + // Add check if we got duration higher than 1 second, we skipping it, temp fix + if((!instance->pause && (instance->upload_raw != NULL)) && (duration < ((uint32_t)1000000))) { if(duration > subghz_protocol_raw_const.te_short) { if(instance->last_level != level) { instance->last_level = (level ? true : false); @@ -273,7 +273,7 @@ void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output) { furi_check(context); //SubGhzProtocolDecoderRAW* instance = context; UNUSED(context); - furi_string_cat_printf(output, "RAW Date"); + furi_string_cat_printf(output, "RAW Data"); } void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { From 9d6fa1aa678ad2582802180be79492a4e6b4685e Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:36:19 +0300 Subject: [PATCH 03/19] Better parsing, show more data in existing protocols --- lib/subghz/protocols/magellan.c | 118 ++++++++++++++++++++++++------ lib/subghz/protocols/marantec.c | 34 ++++++++- lib/subghz/protocols/marantec.h | 8 ++ lib/subghz/protocols/phoenix_v2.c | 67 +++++++++++++++-- lib/subghz/protocols/scher_khan.c | 42 +++++++++-- 5 files changed, 232 insertions(+), 37 deletions(-) diff --git a/lib/subghz/protocols/magellan.c b/lib/subghz/protocols/magellan.c index 1b8eccc36e3..2402f1464ee 100644 --- a/lib/subghz/protocols/magellan.c +++ b/lib/subghz/protocols/magellan.c @@ -359,15 +359,38 @@ static void subghz_protocol_magellan_check_remote_controller(SubGhzBlockGeneric* * * 0x1275EC => 0x12-event codes, 0x75EC-serial (dec 117236) * -* event codes -* bit_0: 1-Open/Motion, 0-close/ok -* bit_1: 1-Tamper On (alarm), 0-Tamper Off (ok) -* bit_2: ? -* bit_3: 1-power on -* bit_4: model type - wireless reed -* bit_5: model type - motion sensor -* bit_6: ? -* bit_7: ? +* Event codes consist of two parts: +* - The upper nibble (bits 7-4) represents the event type: +* - 0x00: Nothing +* - 0x01: Door +* - 0x02: Motion +* - 0x03: Smoke Alarm +* - 0x04: REM1 +* - 0x05: REM1 with subtype Off1 +* - 0x06: REM2 +* - 0x07: REM2 with subtype Off1 +* - Others: Unknown +* - The lower nibble (bits 3-0) represents the event subtype, which varies based on the model type: +* - If the model type is greater than 0x03 (e.g., REM1 or REM2): +* - 0x00: Arm1 +* - 0x01: Btn1 +* - 0x02: Btn2 +* - 0x03: Btn3 +* - 0x08: Reset +* - 0x09: LowBatt +* - 0x0A: BattOk +* - 0x0B: Learn +* - Others: Unknown +* - Otherwise: +* - 0x00: Sealed +* - 0x01: Alarm +* - 0x02: Tamper +* - 0x03: Alarm + Tamper +* - 0x08: Reset +* - 0x09: LowBatt +* - 0x0A: BattOk +* - 0x0B: Learn +* - Others: Unknown * */ uint64_t data_rev = subghz_protocol_blocks_reverse_key(instance->data >> 8, 24); @@ -376,18 +399,71 @@ static void subghz_protocol_magellan_check_remote_controller(SubGhzBlockGeneric* } static void subghz_protocol_magellan_get_event_serialize(uint8_t event, FuriString* output) { - furi_string_cat_printf( - output, - "%s%s%s%s%s%s%s%s", - ((event >> 4) & 0x1 ? (event & 0x1 ? " Open" : " Close") : - (event & 0x1 ? " Motion" : " Ok")), - ((event >> 1) & 0x1 ? ", Tamper On\n(Alarm)" : ""), - ((event >> 2) & 0x1 ? ", ?" : ""), - ((event >> 3) & 0x1 ? ", Power On" : ""), - ((event >> 4) & 0x1 ? ", MT:Wireless_Reed" : ""), - ((event >> 5) & 0x1 ? ", MT:Motion_Sensor" : ""), - ((event >> 6) & 0x1 ? ", ?" : ""), - ((event >> 7) & 0x1 ? ", ?" : "")); + const char* event_type; + const char* event_subtype; + + switch((event >> 4) & 0x0F) { + case 0x00: + event_type = "Nothing"; + break; + case 0x01: + event_type = "Door"; + break; + case 0x02: + event_type = "Motion"; + break; + case 0x03: + event_type = "Smoke Alarm"; + break; + case 0x04: + event_type = "REM1"; + break; + case 0x05: + event_type = "REM1"; + event_subtype = "Off1"; + furi_string_cat_printf(output, "%s - %s", event_type, event_subtype); + return; + case 0x06: + event_type = "REM2"; + event_subtype = "Off1"; + furi_string_cat_printf(output, "%s - %s", event_type, event_subtype); + return; + default: + event_type = "Unknown"; + break; + } + + switch(event & 0x0F) { + case 0x00: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Arm1" : "Sealed"; + break; + case 0x01: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Btn1" : "Alarm"; + break; + case 0x02: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Btn2" : "Tamper"; + break; + case 0x03: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Btn3" : "Alarm + Tamper"; + break; + case 0x08: + event_subtype = "Reset"; + break; + case 0x09: + event_subtype = "LowBatt"; + break; + case 0x0A: + event_subtype = "BattOk"; + break; + case 0x0B: + event_subtype = "Learn"; + break; + default: + event_subtype = "Unknown"; + break; + } + + furi_string_cat_printf(output, "%s - %s", event_type, event_subtype); } uint8_t subghz_protocol_decoder_magellan_get_hash_data(void* context) { diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index fc4aa0dca4e..edb17663596 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -165,7 +165,7 @@ static void subghz_protocol_encoder_marantec_get_upload(SubGhzProtocolEncoderMar } uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) { - uint8_t crc = 0x08; + uint8_t crc = 0x01; size_t i, j; for(i = 0; i < len; i++) { crc ^= data[i]; @@ -184,6 +184,18 @@ uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) { * @param instance Pointer to a SubGhzBlockGeneric* instance */ static void subghz_protocol_marantec_remote_controller(SubGhzBlockGeneric* instance) { + // Key samples + // 1307EDF6486C5 = 000 100110000 01111110110111110110 0100 10000110 11000101 + // 1303EFAFD8683 = 000 100110000 00111110111110101111 1101 10000110 10000011 + + // From unittests + // 1300710DF869F + + // const serial button serial crc + // 130 7EDF6 4 86 C5 + // 130 3EFAF D 86 83 + // 130 0710D F 86 9F + instance->btn = (instance->data >> 16) & 0xF; instance->serial = ((instance->data >> 12) & 0xFFFFFF00) | ((instance->data >> 8) & 0xFF); } @@ -367,16 +379,30 @@ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* outp SubGhzProtocolDecoderMarantec* instance = context; subghz_protocol_marantec_remote_controller(&instance->generic); + uint8_t tdata[6] = { + instance->generic.data >> 48, + instance->generic.data >> 40, + instance->generic.data >> 32, + instance->generic.data >> 24, + instance->generic.data >> 16, + instance->generic.data >> 8}; + + uint8_t crc = subghz_protocol_marantec_crc8(tdata, sizeof(tdata)); + bool crc_ok = (crc == (instance->generic.data & 0xFF)); + furi_string_cat_printf( output, "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%07lX \r\n" - "Btn:%X\r\n", + "Key: 0x%lX%08lX\r\n" + "Sn: 0x%07lX \r\n" + "CRC: 0x%02X - %s\r\n" + "Btn: %X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), (uint32_t)(instance->generic.data & 0xFFFFFFFF), instance->generic.serial, + crc, + crc_ok ? "Valid" : "Invalid", instance->generic.btn); } diff --git a/lib/subghz/protocols/marantec.h b/lib/subghz/protocols/marantec.h index 485c563b2fb..9a7b55b7edb 100644 --- a/lib/subghz/protocols/marantec.h +++ b/lib/subghz/protocols/marantec.h @@ -107,3 +107,11 @@ SubGhzProtocolStatus * @param output Resulting text */ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output); + +/** + * Calculate CRC8 for Marantec protocol. + * @param data Pointer to the data buffer + * @param len Length of the data buffer + * @return CRC8 value + */ +uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len); diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index 2fabed73d5e..5665fd29679 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -7,7 +7,6 @@ #include "../blocks/math.h" #define TAG "SubGhzProtocolPhoenixV2" - //transmission only static mode static const SubGhzBlockConst subghz_protocol_phoenix_v2_const = { @@ -91,6 +90,9 @@ void subghz_protocol_encoder_phoenix_v2_free(void* context) { free(instance); } +// Pre define functions +static void subghz_protocol_phoenix_v2_check_remote_controller(SubGhzBlockGeneric* instance); + /** * Generating an upload from data. * @param instance Pointer to a SubGhzProtocolEncoderPhoenix_V2 instance @@ -107,6 +109,7 @@ static bool } else { instance->encoder.size_upload = size_upload; } + //Send header instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)subghz_protocol_phoenix_v2_const.te_short * 60); @@ -153,6 +156,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorEncoderGetUpload; break; } + instance->encoder.is_running = true; } while(false); @@ -274,16 +278,66 @@ void subghz_protocol_decoder_phoenix_v2_feed(void* context, bool level, uint32_t } } +static uint16_t subghz_protocol_phoenix_v2_decrypt_counter(uint64_t full_key) { + uint16_t encrypted_value = (uint16_t)((full_key >> 40) & 0xFFFF); + + uint8_t byte1 = (uint8_t)(encrypted_value >> 8); // First encrypted counter byte + uint8_t byte2 = (uint8_t)(encrypted_value & 0xFF); // Second encrypted counter byte + + uint8_t xor_key1 = (uint8_t)(full_key >> 24); // First byte of serial + uint8_t xor_key2 = (uint8_t)((full_key >> 16) & 0xFF); // Second byte of serial + + for(int i = 0; i < 16; i++) { + // Store the most significant bit (MSB) of byte1. + // The check `(msb_of_byte1 == 0)` will determine if we apply the XOR keys. + uint8_t msb_of_byte1 = byte1 & 0x80; + + // Store the least significant bit (LSB) of byte2. + uint8_t lsb_of_byte2 = byte2 & 1; + + // Perform a bit shuffle between the two bytes + byte2 = (byte2 >> 1) | msb_of_byte1; + byte1 = (byte1 << 1) | lsb_of_byte2; + + // Conditionally apply the XOR keys based on the original MSB of byte1. + if(msb_of_byte1 == 0) { + byte1 ^= xor_key1; + // The mask `& 0x7F` clears the MSB of byte2 after the XOR. + byte2 = (byte2 ^ xor_key2) & 0x7F; + } + } + + return (uint16_t)byte2 << 8 | byte1; +} + /** * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance */ static void subghz_protocol_phoenix_v2_check_remote_controller(SubGhzBlockGeneric* instance) { + // 2022.08 - @Skorpionm + // 2025.07 - @xMasterX & @RocketGod-git + // Fully supported now, with button switch and add manually + // + // Key samples + // Full key example: 0xC63E01B9615720 - after subghz_protocol_blocks_reverse_key was applied + // Serial - B9615720 + // Button - 01 + // Encrypted -> Decrypted counters + // C63E - 025C + // BCC1 - 025D + // 3341 - 025E + // 49BE - 025F + // 99D3 - 0260 + // E32C - 0261 + uint64_t data_rev = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit + 4); + instance->serial = data_rev & 0xFFFFFFFF; - instance->cnt = (data_rev >> 40) & 0xFFFF; + instance->cnt = subghz_protocol_phoenix_v2_decrypt_counter(data_rev); instance->btn = (data_rev >> 32) & 0xF; + // encrypted cnt is (data_rev >> 40) & 0xFFFF } uint8_t subghz_protocol_decoder_phoenix_v2_get_hash_data(void* context) { @@ -318,14 +372,15 @@ void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* ou subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic); furi_string_cat_printf( output, - "%s %dbit\r\n" - "Key:%02lX%08lX\r\n" + "V2 Phoenix %dbit\r\n" + "Key:%05lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%X\r\n", - instance->generic.protocol_name, + "Cnt: 0x%04lX\r\n" + "Btn: %X\r\n", instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, (uint32_t)(instance->generic.data & 0xFFFFFFFF), instance->generic.serial, + instance->generic.cnt, instance->generic.btn); } diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index bf8de10c96f..f1c41bd1e4a 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -219,18 +219,48 @@ static void subghz_protocol_scher_khan_check_remote_controller( */ switch(instance->data_count_bit) { - // case 35: //MAGIC CODE, Static - // instance->protocol_name = "MAGIC CODE, Static"; - // break; + case 35: //MAGIC CODE, Static + *protocol_name = "MAGIC CODE, Static"; + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + break; case 51: //MAGIC CODE, Dynamic *protocol_name = "MAGIC CODE, Dynamic"; instance->serial = ((instance->data >> 24) & 0xFFFFFF0) | ((instance->data >> 20) & 0x0F); instance->btn = (instance->data >> 24) & 0x0F; instance->cnt = instance->data & 0xFFFF; break; - // case 57: //MAGIC CODE PRO / PRO2 - // instance->protocol_name = "MAGIC CODE PRO / PRO2"; - // break; + case 57: //MAGIC CODE PRO / PRO2 + *protocol_name = "MAGIC CODE PRO/PRO2"; + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + break; + case 63: //MAGIC CODE, Dynamic Response + *protocol_name = "MAGIC CODE, Response"; + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + break; + case 64: //MAGICAR, Response ??? + *protocol_name = "MAGICAR, Response"; + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + break; + case 81: //MAGIC CODE PRO / PRO2 Response ??? + *protocol_name = "MAGIC CODE PRO,\n Response"; + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + break; + case 82: //MAGIC CODE PRO / PRO2 Response ??? + *protocol_name = "MAGIC CODE PRO,\n Response"; + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + break; default: *protocol_name = "Unknown"; From 0f8d01147dc104df4017559301f3c80fa515b9a0 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:37:24 +0300 Subject: [PATCH 04/19] Add new protocols --- lib/subghz/protocols/feron.c | 350 ++++++++++++++++++++++ lib/subghz/protocols/feron.h | 109 +++++++ lib/subghz/protocols/gangqi.c | 404 +++++++++++++++++++++++++ lib/subghz/protocols/gangqi.h | 109 +++++++ lib/subghz/protocols/hay21.c | 269 +++++++++++++++++ lib/subghz/protocols/hay21.h | 74 +++++ lib/subghz/protocols/hollarm.c | 406 +++++++++++++++++++++++++ lib/subghz/protocols/hollarm.h | 109 +++++++ lib/subghz/protocols/honeywell.c | 371 +++++++++++++++++++++++ lib/subghz/protocols/honeywell.h | 61 ++++ lib/subghz/protocols/legrand.c | 378 ++++++++++++++++++++++++ lib/subghz/protocols/legrand.h | 117 ++++++++ lib/subghz/protocols/marantec24.c | 346 ++++++++++++++++++++++ lib/subghz/protocols/marantec24.h | 109 +++++++ lib/subghz/protocols/protocol_items.c | 9 + lib/subghz/protocols/protocol_items.h | 9 + lib/subghz/protocols/revers_rb2.c | 408 ++++++++++++++++++++++++++ lib/subghz/protocols/revers_rb2.h | 109 +++++++ lib/subghz/protocols/roger.c | 339 +++++++++++++++++++++ lib/subghz/protocols/roger.h | 109 +++++++ 20 files changed, 4195 insertions(+) create mode 100644 lib/subghz/protocols/feron.c create mode 100644 lib/subghz/protocols/feron.h create mode 100644 lib/subghz/protocols/gangqi.c create mode 100644 lib/subghz/protocols/gangqi.h create mode 100644 lib/subghz/protocols/hay21.c create mode 100644 lib/subghz/protocols/hay21.h create mode 100644 lib/subghz/protocols/hollarm.c create mode 100644 lib/subghz/protocols/hollarm.h create mode 100644 lib/subghz/protocols/honeywell.c create mode 100644 lib/subghz/protocols/honeywell.h create mode 100644 lib/subghz/protocols/legrand.c create mode 100644 lib/subghz/protocols/legrand.h create mode 100644 lib/subghz/protocols/marantec24.c create mode 100644 lib/subghz/protocols/marantec24.h create mode 100644 lib/subghz/protocols/revers_rb2.c create mode 100644 lib/subghz/protocols/revers_rb2.h create mode 100644 lib/subghz/protocols/roger.c create mode 100644 lib/subghz/protocols/roger.h diff --git a/lib/subghz/protocols/feron.c b/lib/subghz/protocols/feron.c new file mode 100644 index 00000000000..1096f07a77a --- /dev/null +++ b/lib/subghz/protocols/feron.c @@ -0,0 +1,350 @@ +#include "feron.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolFeron" + +static const SubGhzBlockConst subghz_protocol_feron_const = { + .te_short = 350, + .te_long = 750, + .te_delta = 150, + .min_count_bit_for_found = 32, +}; + +struct SubGhzProtocolDecoderFeron { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderFeron { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + FeronDecoderStepReset = 0, + FeronDecoderStepSaveDuration, + FeronDecoderStepCheckDuration, +} FeronDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_feron_decoder = { + .alloc = subghz_protocol_decoder_feron_alloc, + .free = subghz_protocol_decoder_feron_free, + + .feed = subghz_protocol_decoder_feron_feed, + .reset = subghz_protocol_decoder_feron_reset, + + .get_hash_data = subghz_protocol_decoder_feron_get_hash_data, + .serialize = subghz_protocol_decoder_feron_serialize, + .deserialize = subghz_protocol_decoder_feron_deserialize, + .get_string = subghz_protocol_decoder_feron_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_feron_encoder = { + .alloc = subghz_protocol_encoder_feron_alloc, + .free = subghz_protocol_encoder_feron_free, + + .deserialize = subghz_protocol_encoder_feron_deserialize, + .stop = subghz_protocol_encoder_feron_stop, + .yield = subghz_protocol_encoder_feron_yield, +}; + +const SubGhzProtocol subghz_protocol_feron = { + .name = SUBGHZ_PROTOCOL_FERON_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_feron_decoder, + .encoder = &subghz_protocol_feron_encoder, +}; + +void* subghz_protocol_encoder_feron_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderFeron* instance = malloc(sizeof(SubGhzProtocolEncoderFeron)); + + instance->base.protocol = &subghz_protocol_feron; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 256; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_feron_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderFeron* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderFeron instance + */ +static void subghz_protocol_encoder_feron_get_upload(SubGhzProtocolEncoderFeron* instance) { + furi_assert(instance); + size_t index = 0; + + // Send key and GAP + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // Send bit 1 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_feron_const.te_long); + if(i == 1) { + //Send 500/500 and gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_feron_const.te_short + 150); + instance->encoder.upload[index++] = level_duration_make( + true, (uint32_t)subghz_protocol_feron_const.te_short + 150); + // Gap + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_long * 6); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_short); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_feron_const.te_short); + if(i == 1) { + //Send 500/500 and gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_feron_const.te_short + 150); + instance->encoder.upload[index++] = level_duration_make( + true, (uint32_t)subghz_protocol_feron_const.te_short + 150); + // Gap + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_long * 6); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_long); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_feron_check_remote_controller(SubGhzBlockGeneric* instance) { + instance->serial = instance->data >> 16; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_feron_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderFeron* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_feron_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_feron_check_remote_controller(&instance->generic); + subghz_protocol_encoder_feron_get_upload(instance); + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_feron_stop(void* context) { + SubGhzProtocolEncoderFeron* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_feron_yield(void* context) { + SubGhzProtocolEncoderFeron* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + +void* subghz_protocol_decoder_feron_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderFeron* instance = malloc(sizeof(SubGhzProtocolDecoderFeron)); + instance->base.protocol = &subghz_protocol_feron; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_feron_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + free(instance); +} + +void subghz_protocol_decoder_feron_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + instance->decoder.parser_step = FeronDecoderStepReset; +} + +void subghz_protocol_decoder_feron_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + + // Feron Decoder + // 2025.04 - @xMasterX (MMX) + + // Key samples + /* + 0110001100111000 1000010101111010 - ON + 0110001100111000 1000010001111011 - OFF + + 0110001100111000 1000011001111001 - brightness up + 0110001100111000 1000011101111000 - brightness down + + 0110001100111000 1000001001111101 - scroll mode command + + ------------------------------------------ + 0110001100111000 0111000010001111 - R + 0110001100111000 0001101011100101 - B + 0110001100111000 0100000010111111 - G + */ + + switch(instance->decoder.parser_step) { + case FeronDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_feron_const.te_long * 6) < + subghz_protocol_feron_const.te_delta * 4)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = FeronDecoderStepSaveDuration; + } + break; + case FeronDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = FeronDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = FeronDecoderStepReset; + } + break; + case FeronDecoderStepCheckDuration: + if(!level) { + // Bit 0 is short and long timing = 350us HIGH (te_last) and 750us LOW + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_short) < + subghz_protocol_feron_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_feron_const.te_long) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = FeronDecoderStepSaveDuration; + // Bit 1 is long and short timing = 750us HIGH (te_last) and 350us LOW + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_long) < + subghz_protocol_feron_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_feron_const.te_short) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = FeronDecoderStepSaveDuration; + } else if( + // End of the key 500Low(we are here)/500High us + DURATION_DIFF( + duration, (uint16_t)(subghz_protocol_feron_const.te_short + (uint16_t)150)) < + subghz_protocol_feron_const.te_delta) { + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_short) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_long) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + // If got 32 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_feron_const.min_count_bit_for_found) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = FeronDecoderStepReset; + } else { + instance->decoder.parser_step = FeronDecoderStepReset; + } + } else { + instance->decoder.parser_step = FeronDecoderStepReset; + } + break; + } +} + +uint8_t subghz_protocol_decoder_feron_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_feron_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_feron_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_feron_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_feron_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + + subghz_protocol_feron_check_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%08lX\r\n" + "Serial: 0x%04lX\r\n" + "Command: 0x%04lX\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + instance->generic.serial, + (uint32_t)(instance->generic.data & 0xFFFF)); +} diff --git a/lib/subghz/protocols/feron.h b/lib/subghz/protocols/feron.h new file mode 100644 index 00000000000..97f0eb6fe8c --- /dev/null +++ b/lib/subghz/protocols/feron.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_FERON_NAME "Feron" + +typedef struct SubGhzProtocolDecoderFeron SubGhzProtocolDecoderFeron; +typedef struct SubGhzProtocolEncoderFeron SubGhzProtocolEncoderFeron; + +extern const SubGhzProtocolDecoder subghz_protocol_feron_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_feron_encoder; +extern const SubGhzProtocol subghz_protocol_feron; + +/** + * Allocate SubGhzProtocolEncoderFeron. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderFeron* pointer to a SubGhzProtocolEncoderFeron instance + */ +void* subghz_protocol_encoder_feron_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderFeron. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + */ +void subghz_protocol_encoder_feron_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_feron_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + */ +void subghz_protocol_encoder_feron_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_feron_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderFeron. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderFeron* pointer to a SubGhzProtocolDecoderFeron instance + */ +void* subghz_protocol_decoder_feron_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + */ +void subghz_protocol_decoder_feron_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + */ +void subghz_protocol_decoder_feron_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_feron_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_feron_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_feron_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_feron_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @param output Resulting text + */ +void subghz_protocol_decoder_feron_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c new file mode 100644 index 00000000000..aca22cfd781 --- /dev/null +++ b/lib/subghz/protocols/gangqi.c @@ -0,0 +1,404 @@ +#include "gangqi.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolGangQi" + +static const SubGhzBlockConst subghz_protocol_gangqi_const = { + .te_short = 500, + .te_long = 1200, + .te_delta = 200, + .min_count_bit_for_found = 34, +}; + +struct SubGhzProtocolDecoderGangQi { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderGangQi { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + GangQiDecoderStepReset = 0, + GangQiDecoderStepSaveDuration, + GangQiDecoderStepCheckDuration, +} GangQiDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_gangqi_decoder = { + .alloc = subghz_protocol_decoder_gangqi_alloc, + .free = subghz_protocol_decoder_gangqi_free, + + .feed = subghz_protocol_decoder_gangqi_feed, + .reset = subghz_protocol_decoder_gangqi_reset, + + .get_hash_data = subghz_protocol_decoder_gangqi_get_hash_data, + .serialize = subghz_protocol_decoder_gangqi_serialize, + .deserialize = subghz_protocol_decoder_gangqi_deserialize, + .get_string = subghz_protocol_decoder_gangqi_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_gangqi_encoder = { + .alloc = subghz_protocol_encoder_gangqi_alloc, + .free = subghz_protocol_encoder_gangqi_free, + + .deserialize = subghz_protocol_encoder_gangqi_deserialize, + .stop = subghz_protocol_encoder_gangqi_stop, + .yield = subghz_protocol_encoder_gangqi_yield, +}; + +const SubGhzProtocol subghz_protocol_gangqi = { + .name = SUBGHZ_PROTOCOL_GANGQI_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_gangqi_decoder, + .encoder = &subghz_protocol_gangqi_encoder, +}; + +void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderGangQi* instance = malloc(sizeof(SubGhzProtocolEncoderGangQi)); + + instance->base.protocol = &subghz_protocol_gangqi; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 256; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_gangqi_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderGangQi* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderGangQi instance + */ +static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQi* instance) { + furi_assert(instance); + + // Generate new key + uint16_t serial = (uint16_t)((instance->generic.data >> 18) & 0xFFFF); + uint8_t const_and_button = (uint8_t)(0xD0 | instance->generic.btn); + uint8_t serial_high = (uint8_t)(serial >> 8); + uint8_t serial_low = (uint8_t)(serial & 0xFF); + uint8_t bytesum = (uint8_t)(0xC8 - serial_high - serial_low - const_and_button); + + instance->generic.data = (instance->generic.data >> 14) << 14 | (instance->generic.btn << 10) | + (bytesum << 2); + + size_t index = 0; + + // Send key and GAP between parcels + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // Send bit 1 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + + subghz_protocol_gangqi_const.te_delta); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_short); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + + subghz_protocol_gangqi_const.te_delta); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data and parsing serial number + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_gangqi_remote_controller(SubGhzBlockGeneric* instance) { + instance->btn = (instance->data >> 10) & 0xF; + instance->serial = (instance->data & 0xFFFFF0000) >> 16; + + // GangQi Decoder + // 09.2024 - @xMasterX (MMX) (last update - bytesum calculation at 02.2025) + // Thanks @Skorpionm for support! + // Thanks @Drone1950 and @mishamyte (who spent 2 weeks on this) for making this work properly + + // Example of correct bytesum calculation + // 0xC8 - serial_high - serial_low - constant_and_button +} + +SubGhzProtocolStatus + subghz_protocol_encoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderGangQi* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_gangqi_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_gangqi_remote_controller(&instance->generic); + subghz_protocol_encoder_gangqi_get_upload(instance); + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + uint8_t key_data[sizeof(uint64_t)] = {0}; + for(size_t i = 0; i < sizeof(uint64_t); i++) { + key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; + } + if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Unable to add Key"); + break; + } + + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_gangqi_stop(void* context) { + SubGhzProtocolEncoderGangQi* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_gangqi_yield(void* context) { + SubGhzProtocolEncoderGangQi* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + +void* subghz_protocol_decoder_gangqi_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderGangQi* instance = malloc(sizeof(SubGhzProtocolDecoderGangQi)); + instance->base.protocol = &subghz_protocol_gangqi; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_gangqi_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + free(instance); +} + +void subghz_protocol_decoder_gangqi_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + instance->decoder.parser_step = GangQiDecoderStepReset; +} + +void subghz_protocol_decoder_gangqi_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + + switch(instance->decoder.parser_step) { + case GangQiDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_long * 2) < + subghz_protocol_gangqi_const.te_delta * 3)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = GangQiDecoderStepSaveDuration; + } + break; + case GangQiDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = GangQiDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = GangQiDecoderStepReset; + } + break; + case GangQiDecoderStepCheckDuration: + if(!level) { + // Bit 0 is short and long timing + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gangqi_const.te_short) < + subghz_protocol_gangqi_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_long) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = GangQiDecoderStepSaveDuration; + // Bit 1 is long and short timing + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gangqi_const.te_long) < + subghz_protocol_gangqi_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = GangQiDecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short * 4) < + subghz_protocol_gangqi_const.te_delta) { + //Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes) + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_gangqi_const.te_short) < + subghz_protocol_gangqi_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short * 4) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gangqi_const.te_long) < + subghz_protocol_gangqi_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short * 4) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + // If got 34 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_gangqi_const.min_count_bit_for_found) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = GangQiDecoderStepReset; + } else { + instance->decoder.parser_step = GangQiDecoderStepReset; + } + } else { + instance->decoder.parser_step = GangQiDecoderStepReset; + } + break; + } +} + +/** + * Get button name. + * @param btn Button number, 4 bit + */ +static const char* subghz_protocol_gangqi_get_button_name(uint8_t btn) { + const char* name_btn[16] = { + "Unknown", + "Exit settings", + "Volume setting", + "0x3", + "Vibro sens. setting", + "Settings mode", + "Ringtone setting", + "Ring", // D + "0x8", + "0x9", + "0xA", + "Alarm", // C + "0xC", + "Arm", // A + "Disarm", // B + "0xF"}; + return btn <= 0xf ? name_btn[btn] : name_btn[0]; +} + +uint8_t subghz_protocol_decoder_gangqi_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_gangqi_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_gangqi_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_gangqi_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + + // Parse serial + subghz_protocol_gangqi_remote_controller(&instance->generic); + + // Get byte sum + uint16_t serial = (uint16_t)((instance->generic.data >> 18) & 0xFFFF); + uint8_t const_and_button = (uint8_t)(0xD0 | instance->generic.btn); + uint8_t serial_high = (uint8_t)(serial >> 8); + uint8_t serial_low = (uint8_t)(serial & 0xFF); + // Type 1 is what original remotes use, type 2 is "backdoor" sum that receiver accepts too + uint8_t sum_type1 = (uint8_t)(0xC8 - serial_high - serial_low - const_and_button); + uint8_t sum_type2 = (uint8_t)(0x02 + serial_high + serial_low + const_and_button); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%X%08lX\r\n" + "Serial: 0x%05lX\r\n" + "Sum: 0x%02X Sum2: 0x%02X\r\n" + "Btn: 0x%01X - %s\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint8_t)(instance->generic.data >> 32), + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + instance->generic.serial, + sum_type1, + sum_type2, + instance->generic.btn, + subghz_protocol_gangqi_get_button_name(instance->generic.btn)); +} diff --git a/lib/subghz/protocols/gangqi.h b/lib/subghz/protocols/gangqi.h new file mode 100644 index 00000000000..e90f4e7c364 --- /dev/null +++ b/lib/subghz/protocols/gangqi.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_GANGQI_NAME "GangQi" + +typedef struct SubGhzProtocolDecoderGangQi SubGhzProtocolDecoderGangQi; +typedef struct SubGhzProtocolEncoderGangQi SubGhzProtocolEncoderGangQi; + +extern const SubGhzProtocolDecoder subghz_protocol_gangqi_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_gangqi_encoder; +extern const SubGhzProtocol subghz_protocol_gangqi; + +/** + * Allocate SubGhzProtocolEncoderGangQi. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderGangQi* pointer to a SubGhzProtocolEncoderGangQi instance + */ +void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderGangQi. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + */ +void subghz_protocol_encoder_gangqi_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + */ +void subghz_protocol_encoder_gangqi_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_gangqi_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderGangQi. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderGangQi* pointer to a SubGhzProtocolDecoderGangQi instance + */ +void* subghz_protocol_decoder_gangqi_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + */ +void subghz_protocol_decoder_gangqi_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + */ +void subghz_protocol_decoder_gangqi_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_gangqi_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_gangqi_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_gangqi_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @param output Resulting text + */ +void subghz_protocol_decoder_gangqi_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/hay21.c b/lib/subghz/protocols/hay21.c new file mode 100644 index 00000000000..f4e1094962f --- /dev/null +++ b/lib/subghz/protocols/hay21.c @@ -0,0 +1,269 @@ +#include "hay21.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolHay21" + +static const SubGhzBlockConst subghz_protocol_hay21_const = { + .te_short = 300, + .te_long = 700, + .te_delta = 150, + .min_count_bit_for_found = 21, +}; + +struct SubGhzProtocolDecoderHay21 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderHay21 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + Hay21DecoderStepReset = 0, + Hay21DecoderStepSaveDuration, + Hay21DecoderStepCheckDuration, +} Hay21DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_hay21_decoder = { + .alloc = subghz_protocol_decoder_hay21_alloc, + .free = subghz_protocol_decoder_hay21_free, + + .feed = subghz_protocol_decoder_hay21_feed, + .reset = subghz_protocol_decoder_hay21_reset, + + .get_hash_data = subghz_protocol_decoder_hay21_get_hash_data, + .serialize = subghz_protocol_decoder_hay21_serialize, + .deserialize = subghz_protocol_decoder_hay21_deserialize, + .get_string = subghz_protocol_decoder_hay21_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_hay21_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol subghz_protocol_hay21 = { + .name = SUBGHZ_PROTOCOL_HAY21_NAME, + .type = SubGhzProtocolTypeDynamic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &subghz_protocol_hay21_decoder, + .encoder = &subghz_protocol_hay21_encoder, +}; + +/** + * Analysis of received data and parsing serial number + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_hay21_remote_controller(SubGhzBlockGeneric* instance) { + instance->btn = (instance->data >> 13) & 0xFF; + instance->serial = (instance->data >> 5) & 0xFF; + instance->cnt = (instance->data >> 1) & 0xF; + + // Hay21 Decoder + // 09.2024 - @xMasterX (MMX) + + // Key samples (inverted) + // button serial CNT (goes lower since 0/1 are inverted) + //14A84A = 000 10100101 01000010 0101 0 (cnt 5) + //14A848 = 000 10100101 01000010 0100 0 (cnt 4) + //14A846 = 000 10100101 01000010 0011 0 (cnt 3) + //14A844 = 000 10100101 01000010 0010 0 (cnt 2) + //14A842 = 000 10100101 01000010 0001 0 (cnt 1) + //14A840 = 000 10100101 01000010 0000 0 (cnt 0) + //14A85E = 000 10100101 01000010 1111 0 (cnt F) + //14A85C = 000 10100101 01000010 1110 0 (cnt E) + //14A85A = 000 10100101 01000010 1101 0 (cnt D) + //14A858 = 000 10100101 01000010 1100 0 (cnt C) + //14A856 = 000 10100101 01000010 1011 0 (cnt B) + // 0xA5 (Labeled as On/Off on the remote board) + // 0x3C (Labeled as Mode on the remote board) + // 0x42 (Serial) + // BTN Serial CNT + //078854 = 000 00111100 01000010 1010 0 (cnt A) + //078852 = 000 00111100 01000010 1001 0 (cnt 9) + //078850 = 000 00111100 01000010 1000 0 (cnt 8) + //07884E = 000 00111100 01000010 0111 0 (cnt 7) + // Inverted back + //1877B9 = 000 11000011 10111101 1100 1 + //1877BB = 000 11000011 10111101 1101 1 + //1877BD = 000 11000011 10111101 1110 1 + //0B57BF = 000 01011010 10111101 1111 1 +} + +void* subghz_protocol_decoder_hay21_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderHay21* instance = malloc(sizeof(SubGhzProtocolDecoderHay21)); + instance->base.protocol = &subghz_protocol_hay21; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_hay21_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + free(instance); +} + +void subghz_protocol_decoder_hay21_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + instance->decoder.parser_step = Hay21DecoderStepReset; +} + +void subghz_protocol_decoder_hay21_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + + switch(instance->decoder.parser_step) { + case Hay21DecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_hay21_const.te_long * 6) < + subghz_protocol_hay21_const.te_delta * 3)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = Hay21DecoderStepSaveDuration; + } + break; + case Hay21DecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = Hay21DecoderStepCheckDuration; + } else { + instance->decoder.parser_step = Hay21DecoderStepReset; + } + break; + case Hay21DecoderStepCheckDuration: + if(!level) { + // Bit 1 is long + short timing + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_long) < + subghz_protocol_hay21_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hay21_const.te_short) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = Hay21DecoderStepSaveDuration; + // Bit 0 is short + long timing + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_short) < + subghz_protocol_hay21_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hay21_const.te_long) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = Hay21DecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_hay21_const.te_long * 6) < + subghz_protocol_hay21_const.te_delta * 2) { + //Found next GAP and add bit 0 or 1 + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_long) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_short) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + // If got 21 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_hay21_const.min_count_bit_for_found) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = Hay21DecoderStepReset; + } else { + instance->decoder.parser_step = Hay21DecoderStepReset; + } + } else { + instance->decoder.parser_step = Hay21DecoderStepReset; + } + break; + } +} + +/** + * Get button name. + * @param btn Button number, 4 bit + */ +static const char* subghz_protocol_hay21_get_button_name(uint8_t btn) { + const char* btn_name; + switch(btn) { + case 0x5A: + btn_name = "On/Off"; + break; + case 0xC3: + btn_name = "Mode"; + break; + case 0x88: + btn_name = "Hold"; + break; + default: + btn_name = "Unknown"; + break; + } + return btn_name; +} + +uint8_t subghz_protocol_decoder_hay21_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_hay21_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_hay21_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_hay21_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_hay21_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + + // Parse serial, button, counter + subghz_protocol_hay21_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s - %dbit\r\n" + "Key: 0x%06lX\r\n" + "Serial: 0x%02X\r\n" + "Btn: 0x%01X - %s\r\n" + "Cnt: 0x%01X\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + (uint8_t)(instance->generic.serial & 0xFF), + instance->generic.btn, + subghz_protocol_hay21_get_button_name(instance->generic.btn), + (uint8_t)(instance->generic.cnt & 0xF)); +} diff --git a/lib/subghz/protocols/hay21.h b/lib/subghz/protocols/hay21.h new file mode 100644 index 00000000000..22720d7ddcd --- /dev/null +++ b/lib/subghz/protocols/hay21.h @@ -0,0 +1,74 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_HAY21_NAME "Hay21" + +typedef struct SubGhzProtocolDecoderHay21 SubGhzProtocolDecoderHay21; +typedef struct SubGhzProtocolEncoderHay21 SubGhzProtocolEncoderHay21; + +extern const SubGhzProtocolDecoder subghz_protocol_hay21_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_hay21_encoder; +extern const SubGhzProtocol subghz_protocol_hay21; + +/** + * Allocate SubGhzProtocolDecoderHay21. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderHay21* pointer to a SubGhzProtocolDecoderHay21 instance + */ +void* subghz_protocol_decoder_hay21_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + */ +void subghz_protocol_decoder_hay21_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + */ +void subghz_protocol_decoder_hay21_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_hay21_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_hay21_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_hay21_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_hay21_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_hay21_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/hollarm.c b/lib/subghz/protocols/hollarm.c new file mode 100644 index 00000000000..cbc1bd5d922 --- /dev/null +++ b/lib/subghz/protocols/hollarm.c @@ -0,0 +1,406 @@ +#include "hollarm.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolHollarm" + +static const SubGhzBlockConst subghz_protocol_hollarm_const = { + .te_short = 200, + .te_long = 1000, + .te_delta = 200, + .min_count_bit_for_found = 42, +}; + +struct SubGhzProtocolDecoderHollarm { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderHollarm { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + HollarmDecoderStepReset = 0, + HollarmDecoderStepSaveDuration, + HollarmDecoderStepCheckDuration, +} HollarmDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_hollarm_decoder = { + .alloc = subghz_protocol_decoder_hollarm_alloc, + .free = subghz_protocol_decoder_hollarm_free, + + .feed = subghz_protocol_decoder_hollarm_feed, + .reset = subghz_protocol_decoder_hollarm_reset, + + .get_hash_data = subghz_protocol_decoder_hollarm_get_hash_data, + .serialize = subghz_protocol_decoder_hollarm_serialize, + .deserialize = subghz_protocol_decoder_hollarm_deserialize, + .get_string = subghz_protocol_decoder_hollarm_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_hollarm_encoder = { + .alloc = subghz_protocol_encoder_hollarm_alloc, + .free = subghz_protocol_encoder_hollarm_free, + + .deserialize = subghz_protocol_encoder_hollarm_deserialize, + .stop = subghz_protocol_encoder_hollarm_stop, + .yield = subghz_protocol_encoder_hollarm_yield, +}; + +const SubGhzProtocol subghz_protocol_hollarm = { + .name = SUBGHZ_PROTOCOL_HOLLARM_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_hollarm_decoder, + .encoder = &subghz_protocol_hollarm_encoder, +}; + +void* subghz_protocol_encoder_hollarm_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderHollarm* instance = malloc(sizeof(SubGhzProtocolEncoderHollarm)); + + instance->base.protocol = &subghz_protocol_hollarm; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 256; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_hollarm_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderHollarm* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderHollarm instance + */ +static void subghz_protocol_encoder_hollarm_get_upload(SubGhzProtocolEncoderHollarm* instance) { + furi_assert(instance); + + // Generate new key + uint64_t new_key = (instance->generic.data >> 12) << 12 | (instance->generic.btn << 8); + + uint8_t bytesum = ((new_key >> 32) & 0xFF) + ((new_key >> 24) & 0xFF) + + ((new_key >> 16) & 0xFF) + ((new_key >> 8) & 0xFF); + + instance->generic.data = (new_key | bytesum); + + size_t index = 0; + + // Send key and GAP between parcels + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + // Read and prepare levels with 2 bit (was saved for better parsing) to the left offset to fit with the original remote transmission + if(bit_read((instance->generic.data << 2), i - 1)) { + // Send bit 1 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_hollarm_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_hollarm_const.te_short * 12); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_hollarm_const.te_short * 8); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_hollarm_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_hollarm_const.te_short * 12); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_hollarm_const.te_long); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data and parsing serial number + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_hollarm_remote_controller(SubGhzBlockGeneric* instance) { + instance->btn = (instance->data >> 8) & 0xF; + instance->serial = (instance->data & 0xFFFFFFF0000) >> 16; + + // Hollarm Decoder + // 09.2024 - @xMasterX (MMX) + // Thanks @Skorpionm for support! + + // F0B93422FF = FF 8bit Sum + // F0B93421FE = FE 8bit Sum + // F0B9342401 = 01 8bit Sum + // F0B9342805 = 05 8bit Sum + + // Serial (moved 2bit to right) | Btn | 8b previous 4 bytes sum + // 00001111000010111001001101000010 0010 11111111 btn = (0x2) + // 00001111000010111001001101000010 0001 11111110 btn = (0x1) + // 00001111000010111001001101000010 0100 00000001 btn = (0x4) + // 00001111000010111001001101000010 1000 00000101 btn = (0x8) +} + +SubGhzProtocolStatus + subghz_protocol_encoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderHollarm* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_hollarm_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_hollarm_remote_controller(&instance->generic); + subghz_protocol_encoder_hollarm_get_upload(instance); + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + uint8_t key_data[sizeof(uint64_t)] = {0}; + for(size_t i = 0; i < sizeof(uint64_t); i++) { + key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; + } + if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Unable to add Key"); + break; + } + + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_hollarm_stop(void* context) { + SubGhzProtocolEncoderHollarm* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_hollarm_yield(void* context) { + SubGhzProtocolEncoderHollarm* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + +void* subghz_protocol_decoder_hollarm_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderHollarm* instance = malloc(sizeof(SubGhzProtocolDecoderHollarm)); + instance->base.protocol = &subghz_protocol_hollarm; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_hollarm_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + free(instance); +} + +void subghz_protocol_decoder_hollarm_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + instance->decoder.parser_step = HollarmDecoderStepReset; +} + +void subghz_protocol_decoder_hollarm_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + + switch(instance->decoder.parser_step) { + case HollarmDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_short * 12) < + subghz_protocol_hollarm_const.te_delta * 2)) { + //Found GAP between parcels + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = HollarmDecoderStepSaveDuration; + } + break; + case HollarmDecoderStepSaveDuration: + // Save HIGH level timing for next step + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = HollarmDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = HollarmDecoderStepReset; + } + break; + case HollarmDecoderStepCheckDuration: + if(!level) { + // Bit 0 is short 200us HIGH + long 1000us LOW timing + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hollarm_const.te_short) < + subghz_protocol_hollarm_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_long) < + subghz_protocol_hollarm_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = HollarmDecoderStepSaveDuration; + // Bit 1 is short 200us HIGH + short x8 = 1600us LOW timing + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hollarm_const.te_short) < + subghz_protocol_hollarm_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_short * 8) < + subghz_protocol_hollarm_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = HollarmDecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_short * 12) < + subghz_protocol_hollarm_const.te_delta) { + // When next GAP is found add bit 0 and do check for read finish + // (we have 42 high level pulses, last or first one may be a stop/start bit but we will parse it as zero) + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + + // If got 42 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_hollarm_const.min_count_bit_for_found) { + // Saving with 2bit to the right offset for proper parsing + instance->generic.data = (instance->decoder.decode_data >> 2); + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + + uint8_t bytesum = ((instance->generic.data >> 32) & 0xFF) + + ((instance->generic.data >> 24) & 0xFF) + + ((instance->generic.data >> 16) & 0xFF) + + ((instance->generic.data >> 8) & 0xFF); + + if(bytesum != (instance->generic.data & 0xFF)) { + // Check if the key is valid by verifying the sum + instance->generic.data = 0; + instance->generic.data_count_bit = 0; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = HollarmDecoderStepReset; + break; + } + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = HollarmDecoderStepReset; + } else { + instance->decoder.parser_step = HollarmDecoderStepReset; + } + } else { + instance->decoder.parser_step = HollarmDecoderStepReset; + } + break; + } +} + +/** + * Get button name. + * @param btn Button number, 4 bit + */ +static const char* subghz_protocol_hollarm_get_button_name(uint8_t btn) { + const char* name_btn[16] = { + "Unknown", + "Disarm", // B (2) + "Arm", // A (1) + "0x3", + "Ringtone/Alarm", // C (3) + "0x5", + "0x6", + "0x7", + "Ring", // D (4) + "Settings mode", + "Exit settings", + "Vibro sens. setting", + "Not used\n(in settings)", + "Volume setting", + "0xE", + "0xF"}; + return btn <= 0xf ? name_btn[btn] : name_btn[0]; +} + +uint8_t subghz_protocol_decoder_hollarm_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_hollarm_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_hollarm_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_hollarm_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + + // Parse serial + subghz_protocol_hollarm_remote_controller(&instance->generic); + // Get byte sum + uint8_t bytesum = + ((instance->generic.data >> 32) & 0xFF) + ((instance->generic.data >> 24) & 0xFF) + + ((instance->generic.data >> 16) & 0xFF) + ((instance->generic.data >> 8) & 0xFF); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%02lX%08lX\r\n" + "Serial: 0x%06lX Sum: %02X\r\n" + "Btn: 0x%01X - %s\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)instance->generic.data, + instance->generic.serial, + bytesum, + instance->generic.btn, + subghz_protocol_hollarm_get_button_name(instance->generic.btn)); +} diff --git a/lib/subghz/protocols/hollarm.h b/lib/subghz/protocols/hollarm.h new file mode 100644 index 00000000000..8749198a102 --- /dev/null +++ b/lib/subghz/protocols/hollarm.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_HOLLARM_NAME "Hollarm" + +typedef struct SubGhzProtocolDecoderHollarm SubGhzProtocolDecoderHollarm; +typedef struct SubGhzProtocolEncoderHollarm SubGhzProtocolEncoderHollarm; + +extern const SubGhzProtocolDecoder subghz_protocol_hollarm_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_hollarm_encoder; +extern const SubGhzProtocol subghz_protocol_hollarm; + +/** + * Allocate SubGhzProtocolEncoderHollarm. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderHollarm* pointer to a SubGhzProtocolEncoderHollarm instance + */ +void* subghz_protocol_encoder_hollarm_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderHollarm. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + */ +void subghz_protocol_encoder_hollarm_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + */ +void subghz_protocol_encoder_hollarm_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_hollarm_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderHollarm. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderHollarm* pointer to a SubGhzProtocolDecoderHollarm instance + */ +void* subghz_protocol_decoder_hollarm_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + */ +void subghz_protocol_decoder_hollarm_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + */ +void subghz_protocol_decoder_hollarm_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_hollarm_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_hollarm_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_hollarm_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @param output Resulting text + */ +void subghz_protocol_decoder_hollarm_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/honeywell.c b/lib/subghz/protocols/honeywell.c new file mode 100644 index 00000000000..e76bb2822be --- /dev/null +++ b/lib/subghz/protocols/honeywell.c @@ -0,0 +1,371 @@ +#include "honeywell.h" +#include + +//Created by HTotoo 2023-10-30 +//Got a lot of help from LiQuiDz. +//Protocol decoding help from: https://github.com/merbanan/rtl_433/blob/master/src/devices/honeywell.c + +/* +64 bit packets, repeated multiple times per open/close event. + +Protocol whitepaper: "DEFCON 22: Home Insecurity" by Logan Lamb. + +Data layout: + + PP PP C IIIII EE SS SS + +- P: 16bit Preamble and sync bit (always ff fe) +- C: 4bit Channel +- I: 20bit Device serial number / or counter value +- E: 8bit Event, where 0x80 = Open/Close, 0x04 = Heartbeat / or id +- S: 16bit CRC +*/ + +#define TAG "SubGhzProtocolHoneywell" + +uint16_t subghz_protocol_honeywell_crc16( + uint8_t const message[], + unsigned nBytes, + uint16_t polynomial, + uint16_t init) { + uint16_t remainder = init; + unsigned byte, bit; + + for(byte = 0; byte < nBytes; ++byte) { + remainder ^= message[byte] << 8; + for(bit = 0; bit < 8; ++bit) { + if(remainder & 0x8000) { + remainder = (remainder << 1) ^ polynomial; + } else { + remainder = (remainder << 1); + } + } + } + return remainder; +} + +void subghz_protocol_decoder_honeywell_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHoneywell* instance = context; + free(instance); +} + +void subghz_protocol_decoder_honeywell_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHoneywell* instance = context; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; +} + +void subghz_protocol_decoder_honeywell_addbit(void* context, bool data) { + SubGhzProtocolDecoderHoneywell* instance = context; + instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; + instance->decoder.decode_count_bit++; + + if(instance->decoder.decode_count_bit < 62) return; + + uint16_t preamble = (instance->decoder.decode_data >> 48) & 0xFFFF; + //can be multiple, since flipper can't read it well.. + if(preamble == 0b0011111111111110 || preamble == 0b0111111111111110 || + preamble == 0b1111111111111110) { + uint8_t datatocrc[4]; + datatocrc[0] = (instance->decoder.decode_data >> 40) & 0xFFFF; + datatocrc[1] = (instance->decoder.decode_data >> 32) & 0xFFFF; + datatocrc[2] = (instance->decoder.decode_data >> 24) & 0xFFFF; + datatocrc[3] = (instance->decoder.decode_data >> 16) & 0xFFFF; + uint8_t channel = (instance->decoder.decode_data >> 44) & 0xF; + uint16_t crc_calc = 0; + if(channel == 0x2 || channel == 0x4 || channel == 0xA) { + // 2GIG brand + crc_calc = subghz_protocol_honeywell_crc16(datatocrc, 4, 0x8050, 0); + } else if(channel == 0x8) { + crc_calc = subghz_protocol_honeywell_crc16(datatocrc, 4, 0x8005, 0); + } else { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + return; + } + uint16_t crc = instance->decoder.decode_data & 0xFFFF; + if(crc == crc_calc) { + //the data is good. process it. + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = + instance->decoder + .decode_count_bit; //maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + } else { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + return; + } + } else if(instance->decoder.decode_count_bit >= 64) { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + return; + } +} + +void subghz_protocol_decoder_honeywell_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderHoneywell* instance = context; + + ManchesterEvent event = ManchesterEventReset; + if(!level) { + if(DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_short) < + subghz_protocol_honeywell_const.te_delta) { + event = ManchesterEventShortLow; + } else if( + DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_long) < + subghz_protocol_honeywell_const.te_delta * 2) { + event = ManchesterEventLongLow; + } + } else { + if(DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_short) < + subghz_protocol_honeywell_const.te_delta) { + event = ManchesterEventShortHigh; + } else if( + DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_long) < + subghz_protocol_honeywell_const.te_delta * 2) { + event = ManchesterEventLongHigh; + } + } + if(event != ManchesterEventReset) { + bool data; + bool data_ok = manchester_advance( + instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); + if(data_ok) { + subghz_protocol_decoder_honeywell_addbit(instance, data); + } + } else { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + } +} + +uint8_t subghz_protocol_decoder_honeywell_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHoneywell* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_honeywell_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderHoneywell* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_honeywell_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderHoneywell* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_honeywell_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_honeywell_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderHoneywell* instance = context; + + // Parse here and not in decode to avoid visual glitches when loading from file + instance->generic.serial = (instance->generic.data >> 24) & 0xFFFFF; + instance->generic.btn = (instance->generic.data >> 16) & + 0xFF; //not exactly button, but can contain btn data too. + + uint8_t channel = (instance->generic.data >> 44) & 0xF; + uint8_t contact = (instance->generic.btn & 0x80) >> 7; + uint8_t tamper = (instance->generic.btn & 0x40) >> 6; + uint8_t reed = (instance->generic.btn & 0x20) >> 5; + uint8_t alarm = (instance->generic.btn & 0x10) >> 4; + uint8_t battery_low = (instance->generic.btn & 0x08) >> 3; + uint8_t heartbeat = (instance->generic.btn & 0x04) >> 2; + + furi_string_cat_printf( + output, + "%s\r\n%dbit " + "Sn:%07lu\r\nCh:%u Bat:%d Hb: %d\r\n" + "L1: %u, L2: %u, L3: %u, L4: %u\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + instance->generic.serial, + channel, + battery_low, + heartbeat, + contact, + reed, + alarm, + tamper); +} + +void* subghz_protocol_decoder_honeywell_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderHoneywell* instance = malloc(sizeof(SubGhzProtocolDecoderHoneywell)); + instance->base.protocol = &subghz_protocol_honeywell; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void* subghz_protocol_encoder_honeywell_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderHoneywell* instance = malloc(sizeof(SubGhzProtocolEncoderHoneywell)); + + instance->base.protocol = &subghz_protocol_honeywell; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 3; + instance->encoder.size_upload = 64 * 2 + 10; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_honeywell_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderHoneywell* instance = context; + free(instance->encoder.upload); + free(instance); +} +static LevelDuration + subghz_protocol_encoder_honeywell_add_duration_to_upload(ManchesterEncoderResult result) { + LevelDuration data = {.duration = 0, .level = 0}; + switch(result) { + case ManchesterEncoderResultShortLow: + data.duration = subghz_protocol_honeywell_const.te_short; + data.level = false; + break; + case ManchesterEncoderResultLongLow: + data.duration = subghz_protocol_honeywell_const.te_long; + data.level = false; + break; + case ManchesterEncoderResultLongHigh: + data.duration = subghz_protocol_honeywell_const.te_long; + data.level = true; + break; + case ManchesterEncoderResultShortHigh: + data.duration = subghz_protocol_honeywell_const.te_short; + data.level = true; + break; + + default: + furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); + break; + } + return level_duration_make(data.level, data.duration); +} + +static void + subghz_protocol_encoder_honeywell_get_upload(SubGhzProtocolEncoderHoneywell* instance) { + furi_assert(instance); + size_t index = 0; + + ManchesterEncoderState enc_state; + manchester_encoder_reset(&enc_state); + ManchesterEncoderResult result; + + for(uint8_t i = 63; i > 0; i--) { + if(!manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result)) { + instance->encoder.upload[index++] = + subghz_protocol_encoder_honeywell_add_duration_to_upload(result); + manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result); + } + instance->encoder.upload[index++] = + subghz_protocol_encoder_honeywell_add_duration_to_upload(result); + } + instance->encoder.upload[index] = subghz_protocol_encoder_honeywell_add_duration_to_upload( + manchester_encoder_finish(&enc_state)); + if(level_duration_get_level(instance->encoder.upload[index])) { + index++; + } + instance->encoder.size_upload = index; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_honeywell_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderHoneywell* instance = context; + SubGhzProtocolStatus res = SubGhzProtocolStatusError; + do { + if(SubGhzProtocolStatusOk != + subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + FURI_LOG_E(TAG, "Deserialize error"); + break; + } + + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_encoder_honeywell_get_upload(instance); + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + + instance->encoder.is_running = true; + + res = SubGhzProtocolStatusOk; + } while(false); + + return res; +} + +void subghz_protocol_encoder_honeywell_stop(void* context) { + SubGhzProtocolEncoderHoneywell* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_honeywell_yield(void* context) { + SubGhzProtocolEncoderHoneywell* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + return ret; +} + +const SubGhzProtocolDecoder subghz_protocol_honeywell_decoder = { + .alloc = subghz_protocol_decoder_honeywell_alloc, + .free = subghz_protocol_decoder_honeywell_free, + .feed = subghz_protocol_decoder_honeywell_feed, + .reset = subghz_protocol_decoder_honeywell_reset, + .get_hash_data = subghz_protocol_decoder_honeywell_get_hash_data, + .serialize = subghz_protocol_decoder_honeywell_serialize, + .deserialize = subghz_protocol_decoder_honeywell_deserialize, + .get_string = subghz_protocol_decoder_honeywell_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_honeywell_encoder = { + .alloc = subghz_protocol_encoder_honeywell_alloc, + .free = subghz_protocol_encoder_honeywell_free, + .deserialize = subghz_protocol_encoder_honeywell_deserialize, + .stop = subghz_protocol_encoder_honeywell_stop, + .yield = subghz_protocol_encoder_honeywell_yield, +}; + +const SubGhzProtocol subghz_protocol_honeywell = { + .name = SUBGHZ_PROTOCOL_HONEYWELL_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + .encoder = &subghz_protocol_honeywell_encoder, + .decoder = &subghz_protocol_honeywell_decoder, + +}; diff --git a/lib/subghz/protocols/honeywell.h b/lib/subghz/protocols/honeywell.h new file mode 100644 index 00000000000..8aa35ce6cc4 --- /dev/null +++ b/lib/subghz/protocols/honeywell.h @@ -0,0 +1,61 @@ +#pragma once + +#include + +#include +#include +#include +#include "base.h" +#include "../blocks/generic.h" +#include +#include +#include + +#define SUBGHZ_PROTOCOL_HONEYWELL_NAME "Honeywell Sec" + +typedef struct SubGhzProtocolDecoderHoneywell SubGhzProtocolDecoderHoneywell; +typedef struct SubGhzProtocolEncoderHoneywell SubGhzProtocolEncoderHoneywell; + +extern const SubGhzProtocolDecoder subghz_protocol_honeywell_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_honeywell_encoder; +extern const SubGhzProtocol subghz_protocol_honeywell; + +void* subghz_protocol_decoder_honeywell_alloc(SubGhzEnvironment* environment); + +void subghz_protocol_decoder_honeywell_free(void* context); + +void subghz_protocol_decoder_honeywell_reset(void* context); + +void subghz_protocol_decoder_honeywell_feed(void* context, bool level, uint32_t duration); + +uint8_t subghz_protocol_decoder_honeywell_get_hash_data(void* context); + +SubGhzProtocolStatus subghz_protocol_decoder_honeywell_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +SubGhzProtocolStatus + subghz_protocol_decoder_honeywell_deserialize(void* context, FlipperFormat* flipper_format); + +void subghz_protocol_decoder_honeywell_get_string(void* context, FuriString* output); + +static const SubGhzBlockConst subghz_protocol_honeywell_const = { + .te_long = 280, + .te_short = 143, + .te_delta = 51, + .min_count_bit_for_found = 62, +}; + +struct SubGhzProtocolDecoderHoneywell { + SubGhzProtocolDecoderBase base; + SubGhzBlockGeneric generic; + SubGhzBlockDecoder decoder; + ManchesterState manchester_saved_state; +}; + +struct SubGhzProtocolEncoderHoneywell { + SubGhzProtocolEncoderBase base; + SubGhzBlockGeneric generic; + SubGhzProtocolBlockEncoder encoder; +}; diff --git a/lib/subghz/protocols/legrand.c b/lib/subghz/protocols/legrand.c new file mode 100644 index 00000000000..9459fa2e71a --- /dev/null +++ b/lib/subghz/protocols/legrand.c @@ -0,0 +1,378 @@ +#include "legrand.h" + +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolLegrand" + +static const SubGhzBlockConst subghz_protocol_legrand_const = { + .te_short = 375, + .te_long = 1125, + .te_delta = 150, + .min_count_bit_for_found = 18, +}; + +struct SubGhzProtocolDecoderLegrand { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + + uint32_t te; + uint32_t last_data; +}; + +struct SubGhzProtocolEncoderLegrand { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; + + uint32_t te; +}; + +typedef enum { + LegrandDecoderStepReset = 0, + LegrandDecoderStepFirstBit, + LegrandDecoderStepSaveDuration, + LegrandDecoderStepCheckDuration, +} LegrandDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_legrand_decoder = { + .alloc = subghz_protocol_decoder_legrand_alloc, + .free = subghz_protocol_decoder_legrand_free, + + .feed = subghz_protocol_decoder_legrand_feed, + .reset = subghz_protocol_decoder_legrand_reset, + + .get_hash_data = subghz_protocol_decoder_legrand_get_hash_data, + .serialize = subghz_protocol_decoder_legrand_serialize, + .deserialize = subghz_protocol_decoder_legrand_deserialize, + .get_string = subghz_protocol_decoder_legrand_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_legrand_encoder = { + .alloc = subghz_protocol_encoder_legrand_alloc, + .free = subghz_protocol_encoder_legrand_free, + + .deserialize = subghz_protocol_encoder_legrand_deserialize, + .stop = subghz_protocol_encoder_legrand_stop, + .yield = subghz_protocol_encoder_legrand_yield, +}; + +const SubGhzProtocol subghz_protocol_legrand = { + .name = SUBGHZ_PROTOCOL_LEGRAND_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_legrand_decoder, + .encoder = &subghz_protocol_legrand_encoder, +}; + +void* subghz_protocol_encoder_legrand_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderLegrand* instance = malloc(sizeof(SubGhzProtocolEncoderLegrand)); + + instance->base.protocol = &subghz_protocol_legrand; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = subghz_protocol_legrand_const.min_count_bit_for_found * 2 + 1; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_legrand_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderLegrand* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderLegrand instance + * @return true On success + */ +static bool subghz_protocol_encoder_legrand_get_upload(SubGhzProtocolEncoderLegrand* instance) { + furi_assert(instance); + + size_t size_upload = (instance->generic.data_count_bit * 2) + 1; + if(size_upload != instance->encoder.size_upload) { + FURI_LOG_E(TAG, "Invalid data bit count"); + return false; + } + + size_t index = 0; + + // Send sync + instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te * 16); + + // Send key data + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // send bit 1 + instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te); + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te * 3); + } else { + // send bit 0 + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)instance->te * 3); + instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); + } + } + + return true; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_legrand_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderLegrand* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_legrand_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + ret = SubGhzProtocolStatusErrorParserOthers; + break; + } + if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { + FURI_LOG_E(TAG, "Missing TE"); + ret = SubGhzProtocolStatusErrorParserTe; + break; + } + // optional parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + if(!subghz_protocol_encoder_legrand_get_upload(instance)) { + ret = SubGhzProtocolStatusErrorEncoderGetUpload; + break; + } + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_legrand_stop(void* context) { + SubGhzProtocolEncoderLegrand* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_legrand_yield(void* context) { + SubGhzProtocolEncoderLegrand* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + +void* subghz_protocol_decoder_legrand_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderLegrand* instance = malloc(sizeof(SubGhzProtocolDecoderLegrand)); + instance->base.protocol = &subghz_protocol_legrand; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_legrand_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + free(instance); +} + +void subghz_protocol_decoder_legrand_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + instance->decoder.parser_step = LegrandDecoderStepReset; + instance->last_data = 0; +} + +void subghz_protocol_decoder_legrand_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + + switch(instance->decoder.parser_step) { + case LegrandDecoderStepReset: + if(!level && DURATION_DIFF(duration, subghz_protocol_legrand_const.te_short * 16) < + subghz_protocol_legrand_const.te_delta * 8) { + instance->decoder.parser_step = LegrandDecoderStepFirstBit; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->te = 0; + } + break; + case LegrandDecoderStepFirstBit: + if(level) { + if(DURATION_DIFF(duration, subghz_protocol_legrand_const.te_short) < + subghz_protocol_legrand_const.te_delta) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->te += duration * 4; // long low that is part of sync, then short high + } + + if(DURATION_DIFF(duration, subghz_protocol_legrand_const.te_long) < + subghz_protocol_legrand_const.te_delta * 3) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->te += duration / 3 * 4; // short low that is part of sync, then long high + } + + if(instance->decoder.decode_count_bit > 0) { + // advance to the next step if either short or long is found + instance->decoder.parser_step = LegrandDecoderStepSaveDuration; + break; + } + } + + instance->decoder.parser_step = LegrandDecoderStepReset; + break; + case LegrandDecoderStepSaveDuration: + if(!level) { + instance->decoder.te_last = duration; + instance->te += duration; + instance->decoder.parser_step = LegrandDecoderStepCheckDuration; + break; + } + + instance->decoder.parser_step = LegrandDecoderStepReset; + break; + case LegrandDecoderStepCheckDuration: + if(level) { + uint8_t found = 0; + + if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_legrand_const.te_long) < + subghz_protocol_legrand_const.te_delta * 3 && + DURATION_DIFF(duration, subghz_protocol_legrand_const.te_short) < + subghz_protocol_legrand_const.te_delta) { + found = 1; + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + + if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_legrand_const.te_short) < + subghz_protocol_legrand_const.te_delta && + DURATION_DIFF(duration, subghz_protocol_legrand_const.te_long) < + subghz_protocol_legrand_const.te_delta * 3) { + found = 1; + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + + if(found) { + instance->te += duration; + + if(instance->decoder.decode_count_bit < + subghz_protocol_legrand_const.min_count_bit_for_found) { + instance->decoder.parser_step = LegrandDecoderStepSaveDuration; + break; + } + + // enough bits for a packet found, save it only if there was a previous packet + // with the same data + if(instance->last_data && (instance->last_data == instance->decoder.decode_data)) { + instance->te /= instance->decoder.decode_count_bit * 4; + + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + + if(instance->base.callback) { + instance->base.callback(&instance->base, instance->base.context); + } + } + instance->last_data = instance->decoder.decode_data; + // fallthrough to reset, the next bit is expected to be a sync + // it also takes care of resetting the decoder state + } + } + + instance->decoder.parser_step = LegrandDecoderStepReset; + break; + } +} + +uint8_t subghz_protocol_decoder_legrand_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_legrand_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + SubGhzProtocolStatus ret = + subghz_block_generic_serialize(&instance->generic, flipper_format, preset); + if((ret == SubGhzProtocolStatusOk) && + !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) { + FURI_LOG_E(TAG, "Unable to add TE"); + ret = SubGhzProtocolStatusErrorParserTe; + } + return ret; +} + +SubGhzProtocolStatus + subghz_protocol_decoder_legrand_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_legrand_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + ret = SubGhzProtocolStatusErrorParserOthers; + break; + } + if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { + FURI_LOG_E(TAG, "Missing TE"); + ret = SubGhzProtocolStatusErrorParserTe; + break; + } + } while(false); + + return ret; +} + +void subghz_protocol_decoder_legrand_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + + furi_string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%05lX\r\n" + "Te:%luus\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFF), + instance->te); +} diff --git a/lib/subghz/protocols/legrand.h b/lib/subghz/protocols/legrand.h new file mode 100644 index 00000000000..0948ddb8b04 --- /dev/null +++ b/lib/subghz/protocols/legrand.h @@ -0,0 +1,117 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_LEGRAND_NAME "Legrand" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SubGhzProtocolDecoderLegrand SubGhzProtocolDecoderLegrand; +typedef struct SubGhzProtocolEncoderLegrand SubGhzProtocolEncoderLegrand; + +extern const SubGhzProtocolDecoder subghz_protocol_legrand_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_legrand_encoder; +extern const SubGhzProtocol subghz_protocol_legrand; + +/** + * Allocate SubGhzProtocolEncoderLegrand. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderLegrand* pointer to a SubGhzProtocolEncoderLegrand instance + */ +void* subghz_protocol_encoder_legrand_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderLegrand. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + */ +void subghz_protocol_encoder_legrand_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_legrand_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + */ +void subghz_protocol_encoder_legrand_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_legrand_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderLegrand. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderLegrand* pointer to a SubGhzProtocolDecoderLegrand instance + */ +void* subghz_protocol_decoder_legrand_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + */ +void subghz_protocol_decoder_legrand_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + */ +void subghz_protocol_decoder_legrand_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_legrand_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_legrand_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_legrand_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_legrand_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @param output Resulting text + */ +void subghz_protocol_decoder_legrand_get_string(void* context, FuriString* output); + +#ifdef __cplusplus +} +#endif diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c new file mode 100644 index 00000000000..ac602fc965c --- /dev/null +++ b/lib/subghz/protocols/marantec24.c @@ -0,0 +1,346 @@ +#include "marantec24.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolMarantec24" + +static const SubGhzBlockConst subghz_protocol_marantec24_const = { + .te_short = 800, + .te_long = 1600, + .te_delta = 200, + .min_count_bit_for_found = 24, +}; + +struct SubGhzProtocolDecoderMarantec24 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderMarantec24 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + Marantec24DecoderStepReset = 0, + Marantec24DecoderStepSaveDuration, + Marantec24DecoderStepCheckDuration, +} Marantec24DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_marantec24_decoder = { + .alloc = subghz_protocol_decoder_marantec24_alloc, + .free = subghz_protocol_decoder_marantec24_free, + + .feed = subghz_protocol_decoder_marantec24_feed, + .reset = subghz_protocol_decoder_marantec24_reset, + + .get_hash_data = subghz_protocol_decoder_marantec24_get_hash_data, + .serialize = subghz_protocol_decoder_marantec24_serialize, + .deserialize = subghz_protocol_decoder_marantec24_deserialize, + .get_string = subghz_protocol_decoder_marantec24_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_marantec24_encoder = { + .alloc = subghz_protocol_encoder_marantec24_alloc, + .free = subghz_protocol_encoder_marantec24_free, + + .deserialize = subghz_protocol_encoder_marantec24_deserialize, + .stop = subghz_protocol_encoder_marantec24_stop, + .yield = subghz_protocol_encoder_marantec24_yield, +}; + +const SubGhzProtocol subghz_protocol_marantec24 = { + .name = SUBGHZ_PROTOCOL_MARANTEC24_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_marantec24_decoder, + .encoder = &subghz_protocol_marantec24_encoder, +}; + +void* subghz_protocol_encoder_marantec24_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderMarantec24* instance = malloc(sizeof(SubGhzProtocolEncoderMarantec24)); + + instance->base.protocol = &subghz_protocol_marantec24; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 256; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_marantec24_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderMarantec24* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +static void + subghz_protocol_encoder_marantec24_get_upload(SubGhzProtocolEncoderMarantec24* instance) { + furi_assert(instance); + size_t index = 0; + + // Send key and GAP + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // Send bit 1 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_marantec24_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + + subghz_protocol_marantec24_const.te_short); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_marantec24_const.te_long * 2); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_marantec24_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + + subghz_protocol_marantec24_const.te_short); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_marantec24_const.te_short * 3); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_marantec24_check_remote_controller(SubGhzBlockGeneric* instance) { + instance->serial = instance->data >> 4; + instance->btn = instance->data & 0xF; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderMarantec24* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_marantec24_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_marantec24_check_remote_controller(&instance->generic); + subghz_protocol_encoder_marantec24_get_upload(instance); + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_marantec24_stop(void* context) { + SubGhzProtocolEncoderMarantec24* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_marantec24_yield(void* context) { + SubGhzProtocolEncoderMarantec24* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + +void* subghz_protocol_decoder_marantec24_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderMarantec24* instance = malloc(sizeof(SubGhzProtocolDecoderMarantec24)); + instance->base.protocol = &subghz_protocol_marantec24; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_marantec24_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + free(instance); +} + +void subghz_protocol_decoder_marantec24_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + instance->decoder.parser_step = Marantec24DecoderStepReset; +} + +void subghz_protocol_decoder_marantec24_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + + // Marantec24 Decoder + // 2024 - @xMasterX (MMX) + + // 2025 update - The protocol is not real marantec, + // it comes from chinese remote that pretends to be replica of original marantec, actually it was a cloner + // which had some thing written on it, which is uknown, but since its pretentding to be marantec, + // it was decided to keep the name of the protocol as marantec24 (24 bits) + + // Key samples + // 101011000000010111001000 = AC05C8 + // 101011000000010111000100 = AC05C4 + // 101011000000010111001100 = AC05CC + // 101011000000010111000000 = AC05C0 + + switch(instance->decoder.parser_step) { + case Marantec24DecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 9) < + subghz_protocol_marantec24_const.te_delta * 4)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = Marantec24DecoderStepSaveDuration; + } + break; + case Marantec24DecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = Marantec24DecoderStepCheckDuration; + } else { + instance->decoder.parser_step = Marantec24DecoderStepReset; + } + break; + case Marantec24DecoderStepCheckDuration: + if(!level) { + // Bit 0 is long and short x2 timing = 1600us HIGH (te_last) and 2400us LOW + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_marantec24_const.te_long) < + subghz_protocol_marantec24_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_short * 3) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = Marantec24DecoderStepSaveDuration; + // Bit 1 is short and long x2 timing = 800us HIGH (te_last) and 3200us LOW + } else if( + (DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_marantec24_const.te_short) < + subghz_protocol_marantec24_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 2) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = Marantec24DecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 9) < + subghz_protocol_marantec24_const.te_delta * 4) { + //Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes) + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_marantec24_const.te_long) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_marantec24_const.te_short) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + // If got 24 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_marantec24_const.min_count_bit_for_found) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = Marantec24DecoderStepReset; + } else { + instance->decoder.parser_step = Marantec24DecoderStepReset; + } + } else { + instance->decoder.parser_step = Marantec24DecoderStepReset; + } + break; + } +} + +uint8_t subghz_protocol_decoder_marantec24_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_marantec24_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_marantec24_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_marantec24_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + + subghz_protocol_marantec24_check_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%06lX\r\n" + "Serial: 0x%05lX\r\n" + "Btn: %01X", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFF), + instance->generic.serial, + instance->generic.btn); +} diff --git a/lib/subghz/protocols/marantec24.h b/lib/subghz/protocols/marantec24.h new file mode 100644 index 00000000000..862eb7e2a93 --- /dev/null +++ b/lib/subghz/protocols/marantec24.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_MARANTEC24_NAME "Marantec24" + +typedef struct SubGhzProtocolDecoderMarantec24 SubGhzProtocolDecoderMarantec24; +typedef struct SubGhzProtocolEncoderMarantec24 SubGhzProtocolEncoderMarantec24; + +extern const SubGhzProtocolDecoder subghz_protocol_marantec24_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_marantec24_encoder; +extern const SubGhzProtocol subghz_protocol_marantec24; + +/** + * Allocate SubGhzProtocolEncoderMarantec24. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderMarantec24* pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +void* subghz_protocol_encoder_marantec24_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderMarantec24. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +void subghz_protocol_encoder_marantec24_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +void subghz_protocol_encoder_marantec24_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_marantec24_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderMarantec24. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderMarantec24* pointer to a SubGhzProtocolDecoderMarantec24 instance + */ +void* subghz_protocol_decoder_marantec24_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + */ +void subghz_protocol_decoder_marantec24_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + */ +void subghz_protocol_decoder_marantec24_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_marantec24_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_marantec24_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_marantec24_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_marantec24_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/protocol_items.c b/lib/subghz/protocols/protocol_items.c index d7a14cd1cb8..465585d776a 100644 --- a/lib/subghz/protocols/protocol_items.c +++ b/lib/subghz/protocols/protocol_items.c @@ -44,7 +44,16 @@ const SubGhzProtocol* const subghz_protocol_registry_items[] = { &subghz_protocol_kinggates_stylo_4k, &subghz_protocol_bin_raw, &subghz_protocol_mastercode, + &subghz_protocol_honeywell, + &subghz_protocol_legrand, &subghz_protocol_dickert_mahs, + &subghz_protocol_gangqi, + &subghz_protocol_marantec24, + &subghz_protocol_hollarm, + &subghz_protocol_hay21, + &subghz_protocol_revers_rb2, + &subghz_protocol_feron, + &subghz_protocol_roger, }; const SubGhzProtocolRegistry subghz_protocol_registry = { diff --git a/lib/subghz/protocols/protocol_items.h b/lib/subghz/protocols/protocol_items.h index ae531c3f9b6..4f63b030eeb 100644 --- a/lib/subghz/protocols/protocol_items.h +++ b/lib/subghz/protocols/protocol_items.h @@ -45,4 +45,13 @@ #include "kinggates_stylo_4k.h" #include "bin_raw.h" #include "mastercode.h" +#include "honeywell.h" +#include "legrand.h" #include "dickert_mahs.h" +#include "gangqi.h" +#include "marantec24.h" +#include "hollarm.h" +#include "hay21.h" +#include "revers_rb2.h" +#include "feron.h" +#include "roger.h" diff --git a/lib/subghz/protocols/revers_rb2.c b/lib/subghz/protocols/revers_rb2.c new file mode 100644 index 00000000000..510e2698a98 --- /dev/null +++ b/lib/subghz/protocols/revers_rb2.c @@ -0,0 +1,408 @@ +#include "revers_rb2.h" +#include +#include +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolRevers_RB2" + +static const SubGhzBlockConst subghz_protocol_revers_rb2_const = { + .te_short = 250, + .te_long = 500, + .te_delta = 160, + .min_count_bit_for_found = 64, +}; + +struct SubGhzProtocolDecoderRevers_RB2 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + ManchesterState manchester_saved_state; + uint16_t header_count; +}; + +struct SubGhzProtocolEncoderRevers_RB2 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + Revers_RB2DecoderStepReset = 0, + Revers_RB2DecoderStepHeader, + Revers_RB2DecoderStepDecoderData, +} Revers_RB2DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_revers_rb2_decoder = { + .alloc = subghz_protocol_decoder_revers_rb2_alloc, + .free = subghz_protocol_decoder_revers_rb2_free, + + .feed = subghz_protocol_decoder_revers_rb2_feed, + .reset = subghz_protocol_decoder_revers_rb2_reset, + + .get_hash_data = subghz_protocol_decoder_revers_rb2_get_hash_data, + .serialize = subghz_protocol_decoder_revers_rb2_serialize, + .deserialize = subghz_protocol_decoder_revers_rb2_deserialize, + .get_string = subghz_protocol_decoder_revers_rb2_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_revers_rb2_encoder = { + .alloc = subghz_protocol_encoder_revers_rb2_alloc, + .free = subghz_protocol_encoder_revers_rb2_free, + + .deserialize = subghz_protocol_encoder_revers_rb2_deserialize, + .stop = subghz_protocol_encoder_revers_rb2_stop, + .yield = subghz_protocol_encoder_revers_rb2_yield, +}; + +const SubGhzProtocol subghz_protocol_revers_rb2 = { + .name = SUBGHZ_PROTOCOL_REVERSRB2_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_revers_rb2_decoder, + .encoder = &subghz_protocol_revers_rb2_encoder, +}; + +void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderRevers_RB2* instance = malloc(sizeof(SubGhzProtocolEncoderRevers_RB2)); + + instance->base.protocol = &subghz_protocol_revers_rb2; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 256; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_revers_rb2_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderRevers_RB2* instance = context; + free(instance->encoder.upload); + free(instance); +} + +static LevelDuration + subghz_protocol_encoder_revers_rb2_add_duration_to_upload(ManchesterEncoderResult result) { + LevelDuration data = {.duration = 0, .level = 0}; + switch(result) { + case ManchesterEncoderResultShortLow: + data.duration = subghz_protocol_revers_rb2_const.te_short; + data.level = false; + break; + case ManchesterEncoderResultLongLow: + data.duration = subghz_protocol_revers_rb2_const.te_long; + data.level = false; + break; + case ManchesterEncoderResultLongHigh: + data.duration = subghz_protocol_revers_rb2_const.te_long; + data.level = true; + break; + case ManchesterEncoderResultShortHigh: + data.duration = subghz_protocol_revers_rb2_const.te_short; + data.level = true; + break; + + default: + furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); + break; + } + return level_duration_make(data.level, data.duration); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +static void + subghz_protocol_encoder_revers_rb2_get_upload(SubGhzProtocolEncoderRevers_RB2* instance) { + furi_assert(instance); + size_t index = 0; + + ManchesterEncoderState enc_state; + manchester_encoder_reset(&enc_state); + ManchesterEncoderResult result; + + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(!manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result)) { + instance->encoder.upload[index++] = + subghz_protocol_encoder_revers_rb2_add_duration_to_upload(result); + manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result); + } + instance->encoder.upload[index++] = + subghz_protocol_encoder_revers_rb2_add_duration_to_upload(result); + } + instance->encoder.upload[index] = subghz_protocol_encoder_revers_rb2_add_duration_to_upload( + manchester_encoder_finish(&enc_state)); + if(level_duration_get_level(instance->encoder.upload[index])) { + index++; + } + instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)320); + instance->encoder.size_upload = index; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_revers_rb2_remote_controller(SubGhzBlockGeneric* instance) { + // Revers RB2 / RB2M Decoder + // 02.2025 - @xMasterX (MMX) + instance->serial = (((instance->data << 16) >> 16) >> 10); +} + +SubGhzProtocolStatus + subghz_protocol_encoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderRevers_RB2* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_revers_rb2_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_revers_rb2_remote_controller(&instance->generic); + subghz_protocol_encoder_revers_rb2_get_upload(instance); + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_revers_rb2_stop(void* context) { + SubGhzProtocolEncoderRevers_RB2* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_revers_rb2_yield(void* context) { + SubGhzProtocolEncoderRevers_RB2* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + +void* subghz_protocol_decoder_revers_rb2_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderRevers_RB2* instance = malloc(sizeof(SubGhzProtocolDecoderRevers_RB2)); + instance->base.protocol = &subghz_protocol_revers_rb2; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_revers_rb2_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + free(instance); +} + +void subghz_protocol_decoder_revers_rb2_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); +} + +void subghz_protocol_decoder_revers_rb2_addbit(void* context, bool data) { + SubGhzProtocolDecoderRevers_RB2* instance = context; + instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; + instance->decoder.decode_count_bit++; + + if(instance->decoder.decode_count_bit >= 65) { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + return; + } + + if(instance->decoder.decode_count_bit < + subghz_protocol_revers_rb2_const.min_count_bit_for_found) { + return; + } + + // Revers RB2 / RB2M Decoder + // 02.2025 - @xMasterX (MMX) + + uint16_t preamble = (instance->decoder.decode_data >> 48) & 0xFF; + uint16_t stop_code = (instance->decoder.decode_data & 0x3FF); + + if(preamble == 0xFF && stop_code == 0x200) { + //Found header and stop code + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); + } +} + +void subghz_protocol_decoder_revers_rb2_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + ManchesterEvent event = ManchesterEventReset; + + switch(instance->decoder.parser_step) { + case Revers_RB2DecoderStepReset: + if((!level) && + (DURATION_DIFF(duration, 600) < subghz_protocol_revers_rb2_const.te_delta)) { + instance->decoder.parser_step = Revers_RB2DecoderStepHeader; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); + } + break; + case Revers_RB2DecoderStepHeader: + if(!level) { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + if(instance->decoder.te_last == 1) { + instance->header_count++; + } + instance->decoder.te_last = level; + } else { + instance->header_count = 0; + instance->decoder.te_last = 0; + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } else { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + if(instance->decoder.te_last == 0) { + instance->header_count++; + } + instance->decoder.te_last = level; + } else { + instance->header_count = 0; + instance->decoder.te_last = 0; + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } + + if(instance->header_count == 4) { + instance->header_count = 0; + instance->decoder.decode_data = 0xF; + instance->decoder.decode_count_bit = 4; + instance->decoder.parser_step = Revers_RB2DecoderStepDecoderData; + } + break; + case Revers_RB2DecoderStepDecoderData: + if(!level) { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventShortLow; + } else if( + DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_long) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventLongLow; + } else { + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } else { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventShortHigh; + } else if( + DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_long) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventLongHigh; + } else { + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } + if(event != ManchesterEventReset) { + bool data; + bool data_ok = manchester_advance( + instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); + + if(data_ok) { + subghz_protocol_decoder_revers_rb2_addbit(instance, data); + } + } + break; + } +} + +uint8_t subghz_protocol_decoder_revers_rb2_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_revers_rb2_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_revers_rb2_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_revers_rb2_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + subghz_protocol_revers_rb2_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key:%lX%08lX\r\n" + "Sn:0x%08lX \r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + instance->generic.serial); +} diff --git a/lib/subghz/protocols/revers_rb2.h b/lib/subghz/protocols/revers_rb2.h new file mode 100644 index 00000000000..7ccd2a9a217 --- /dev/null +++ b/lib/subghz/protocols/revers_rb2.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_REVERSRB2_NAME "Revers_RB2" + +typedef struct SubGhzProtocolDecoderRevers_RB2 SubGhzProtocolDecoderRevers_RB2; +typedef struct SubGhzProtocolEncoderRevers_RB2 SubGhzProtocolEncoderRevers_RB2; + +extern const SubGhzProtocolDecoder subghz_protocol_revers_rb2_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_revers_rb2_encoder; +extern const SubGhzProtocol subghz_protocol_revers_rb2; + +/** + * Allocate SubGhzProtocolEncoderRevers_RB2. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderRevers_RB2* pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +void subghz_protocol_encoder_revers_rb2_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +void subghz_protocol_encoder_revers_rb2_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_revers_rb2_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderRevers_RB2. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderRevers_RB2* pointer to a SubGhzProtocolDecoderRevers_RB2 instance + */ +void* subghz_protocol_decoder_revers_rb2_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + */ +void subghz_protocol_decoder_revers_rb2_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + */ +void subghz_protocol_decoder_revers_rb2_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_revers_rb2_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_revers_rb2_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_revers_rb2_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_revers_rb2_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/roger.c b/lib/subghz/protocols/roger.c new file mode 100644 index 00000000000..8d98d98937b --- /dev/null +++ b/lib/subghz/protocols/roger.c @@ -0,0 +1,339 @@ +#include "roger.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolRoger" + +static const SubGhzBlockConst subghz_protocol_roger_const = { + .te_short = 500, + .te_long = 1000, + .te_delta = 270, + .min_count_bit_for_found = 28, +}; + +struct SubGhzProtocolDecoderRoger { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderRoger { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + RogerDecoderStepReset = 0, + RogerDecoderStepSaveDuration, + RogerDecoderStepCheckDuration, +} RogerDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_roger_decoder = { + .alloc = subghz_protocol_decoder_roger_alloc, + .free = subghz_protocol_decoder_roger_free, + + .feed = subghz_protocol_decoder_roger_feed, + .reset = subghz_protocol_decoder_roger_reset, + + .get_hash_data = subghz_protocol_decoder_roger_get_hash_data, + .serialize = subghz_protocol_decoder_roger_serialize, + .deserialize = subghz_protocol_decoder_roger_deserialize, + .get_string = subghz_protocol_decoder_roger_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_roger_encoder = { + .alloc = subghz_protocol_encoder_roger_alloc, + .free = subghz_protocol_encoder_roger_free, + + .deserialize = subghz_protocol_encoder_roger_deserialize, + .stop = subghz_protocol_encoder_roger_stop, + .yield = subghz_protocol_encoder_roger_yield, +}; + +const SubGhzProtocol subghz_protocol_roger = { + .name = SUBGHZ_PROTOCOL_ROGER_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | + SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | + SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_roger_decoder, + .encoder = &subghz_protocol_roger_encoder, +}; + +void* subghz_protocol_encoder_roger_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderRoger* instance = malloc(sizeof(SubGhzProtocolEncoderRoger)); + + instance->base.protocol = &subghz_protocol_roger; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 256; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_roger_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderRoger* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderRoger instance + */ +static void subghz_protocol_encoder_roger_get_upload(SubGhzProtocolEncoderRoger* instance) { + furi_assert(instance); + size_t index = 0; + + // Send key and GAP + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // Send bit 1 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_roger_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_roger_const.te_short * 19); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_roger_const.te_short); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_roger_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_roger_const.te_short * 19); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_roger_const.te_long); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_roger_check_remote_controller(SubGhzBlockGeneric* instance) { + // Roger Decoder + // 2025.07 - @xMasterX (MMX) + + // Key samples + // 0010001111111001 0001 00100000 // S/N: 0x23F9 Btn: 0x1 End: 0x20 + // 0010001111111001 0010 00100011 // S/N: 0x23F9 Btn: 0x2 End: 0x23 + // 0101011001010110 0001 00000001 // S/N: 0x5656 Btn: 0x1 End: 0x01 + // 0101011001010110 0010 00000010 // S/N: 0x5656 Btn: 0x2 End: 0x02 + // 0000110111111110 0001 00000001 // S/N: 0x0DFE Btn: 0x1 End: 0x01 + // 0000110111111110 0100 00000100 // S/N: 0x0DFE Btn: 0x4 End: 0x04 + // 0000110111111110 0010 00000010 // S/N: 0x0DFE Btn: 0x2 End: 0x02 + // 0000110111111110 1000 00001000 // S/N: 0x0DFE Btn: 0x8 End: 0x08 + + instance->serial = instance->data >> 12; + instance->btn = (instance->data >> 8) & 0xF; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_roger_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderRoger* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_roger_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_roger_check_remote_controller(&instance->generic); + subghz_protocol_encoder_roger_get_upload(instance); + + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_roger_stop(void* context) { + SubGhzProtocolEncoderRoger* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_roger_yield(void* context) { + SubGhzProtocolEncoderRoger* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { + instance->encoder.is_running = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + +void* subghz_protocol_decoder_roger_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderRoger* instance = malloc(sizeof(SubGhzProtocolDecoderRoger)); + instance->base.protocol = &subghz_protocol_roger; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_roger_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + free(instance); +} + +void subghz_protocol_decoder_roger_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + instance->decoder.parser_step = RogerDecoderStepReset; +} + +void subghz_protocol_decoder_roger_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + + switch(instance->decoder.parser_step) { + case RogerDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_roger_const.te_short * 19) < + subghz_protocol_roger_const.te_delta * 5)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = RogerDecoderStepSaveDuration; + } + break; + case RogerDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = RogerDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = RogerDecoderStepReset; + } + break; + case RogerDecoderStepCheckDuration: + if(!level) { + // Bit 1 is long and short timing = 1000us HIGH (te_last) and 500us LOW + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_long) < + subghz_protocol_roger_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_roger_const.te_short) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = RogerDecoderStepSaveDuration; + // Bit 0 is short and long timing = 500us HIGH (te_last) and 1000us LOW + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_short) < + subghz_protocol_roger_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_roger_const.te_long) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = RogerDecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_roger_const.te_short * 19) < + subghz_protocol_roger_const.te_delta * 5) { + //Found next GAP and add bit 1 or 0 + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_long) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_short) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + // If got full 28 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_roger_const.min_count_bit_for_found) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = RogerDecoderStepReset; + } else { + instance->decoder.parser_step = RogerDecoderStepReset; + } + } else { + instance->decoder.parser_step = RogerDecoderStepReset; + } + break; + } +} + +uint8_t subghz_protocol_decoder_roger_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_roger_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_roger_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_roger_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_roger_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + + subghz_protocol_roger_check_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%07lX\r\n" + "Serial: 0x%04lX\r\n" + "End: 0x%02lX\r\n" + "Btn: %01X", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFFF), + instance->generic.serial, + (uint32_t)(instance->generic.data & 0xFF), + instance->generic.btn); +} diff --git a/lib/subghz/protocols/roger.h b/lib/subghz/protocols/roger.h new file mode 100644 index 00000000000..c279164f955 --- /dev/null +++ b/lib/subghz/protocols/roger.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_ROGER_NAME "Roger" + +typedef struct SubGhzProtocolDecoderRoger SubGhzProtocolDecoderRoger; +typedef struct SubGhzProtocolEncoderRoger SubGhzProtocolEncoderRoger; + +extern const SubGhzProtocolDecoder subghz_protocol_roger_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_roger_encoder; +extern const SubGhzProtocol subghz_protocol_roger; + +/** + * Allocate SubGhzProtocolEncoderRoger. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderRoger* pointer to a SubGhzProtocolEncoderRoger instance + */ +void* subghz_protocol_encoder_roger_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderRoger. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + */ +void subghz_protocol_encoder_roger_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_roger_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + */ +void subghz_protocol_encoder_roger_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_roger_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderRoger. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderRoger* pointer to a SubGhzProtocolDecoderRoger instance + */ +void* subghz_protocol_decoder_roger_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + */ +void subghz_protocol_decoder_roger_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + */ +void subghz_protocol_decoder_roger_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_roger_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_roger_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus subghz_protocol_decoder_roger_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_roger_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @param output Resulting text + */ +void subghz_protocol_decoder_roger_get_string(void* context, FuriString* output); From 965ee5b104fb33530b426c5143425a069ab621ed Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 30 Jul 2025 01:26:25 +0300 Subject: [PATCH 05/19] Update keeloqs --- .../resources/subghz/assets/keeloq_mfcodes | 119 +++++++++--------- 1 file changed, 63 insertions(+), 56 deletions(-) diff --git a/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes b/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes index 39d9b3e3c95..b77080f8bbf 100644 --- a/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes +++ b/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes @@ -1,59 +1,66 @@ Filetype: Flipper SubGhz Keystore File Version: 0 Encryption: 1 -IV: 43 68 65 63 6B 20 70 61 73 73 65 64 20 4F 77 4F -00A92D8AE07E4998E826AF5C89AD659BD8C2BC6A40DA78B1AC05CF5B066243ED -A3C71FA36145D0EE56D78C05DDDDA97E487BCDCA6BDAC2C6F87402A0B20EE3CB -B9BDFBD18A63503580C18ABF84101B33D7F720900201510086EB3F0C1F533564 -EAB736F80371447008CC3BE3CE952CE429E7BF743A70C7CC62FF415B9E38467B -9C50D75C6E4A82F49AF285EC3545E58F8815FF4FCF5C9FFFCF0151FB693413FF13B594C8A28077450C8E561B0272C264 -A54C7E6DD1CAE0758F7A123B187C6EDA5BF3789969FE1E5F5A167E2DA7719671 -1461891D4AB3500B5BC0859166377CE098C04AAF6FD721F9C58A155F23F8E75A -BD1FD5645367BA76D8A87C271FF71E71C407B276BB0B165AF8CF6317250B77A6 -B18718EA6EB53CCDF9C26FC46E36D17234D93EF578376123B1F3F9953302CF62 -B633458C1948BC65357904F901F6DD5CD9D795887C176C6AA48E477F0EB693DB -B1352AC0DE8EBDD838F5DF7E040B062CF8FBB73180F3E712C5B2BDBFE1257A2C18694C51F242BCEA62DF317708771AA1 -842294FA0BACCD5B7710F002E40E4BB6142BC7C3125B2E56D4431FD8D6DD1CCE3397A4EB502B9E4248FA68CE8013E93D -5379E56AD483C0F870D9446C9CDE65ACA40C3A699D0653EC2F356A076D72D6C2 -8FD394F533CD2B03AE247B18F4A5214ED0AF64892F497362129FEF5837012BE4 -FA8BAB9CD11B306F9FCD924B3A66C678A0316F048A30312B5FA69B9E86EDD8C9 -35D6E447F3B8BA11331805027BCA1D972E9B29E07F1D2993C974DCAF5EE1EB76 -5FBF06E449C471D0AE2DECD141B937666C30EE72273CF58A99E19DCF5D2F69A703F17880B5FB1873480AFA82E2CE7674 -06C1463057544BDB86BD91B3BCC507FD3A5939CFF3315AFD252511FE4F6109EC -9AB5C03053AF5836E71FE27D0CD74515C967273EB240B7C37825B94D9D9F08AC -66EB1C65F32D5DBDC37B5FF7ACD7C4273B88298E8F0BED08F533F41F38DE651010686B79623804F67398B020E109B9A4 -7B1846759EDD928EF35B2E8FB7E3FFFE545C9A8B349476A9CE2BDDE55CE0E97F53002A543D0FB738CA67490501629296 -EB61CB652F414A70441ADACA46DBCC78A5AAC7A2ED4527AA2A93995482985867 -1E119E453C38C3242EFE3D9A3BBB3D257D91D15710C47811C1ADA934515DBD9E -6D8B689C37F7CFD52123BA77B6A4FABB16C3D22BF66FB78B4387BDBC975A3EE5 -997A46848917B76A1D728DA8C3A072F16F020AF50070BAD91AC2D841FA9805C1 -C51BFD0B93FECC7234D342F1DA785736A9229A21ACA8C9AA171906AA8916856F -86188B0DF2C25CA48DC0ED0B4524C17D93585873877FAFBBB55EB24A1D6FDABC -8178B7DFF235094BDCA1E5D72E48B113F2290C0FEBC95CF842013AB9CD84E0AD -25AEF7C490788DCC142CBC96FBCAB598B7EA1D15B7DE4ABBF75DE70832B519E4 -8C5FB85C16C5C833E1D8CE13A9432009D98B0D1639EB0C7C86D0AF4ACD7EB694 -AC9422E946BB8482CFD808B8E17BE01D9F5D9AB49E1192174A04BB0F032F2182 -793EEE939544D18C547E2198FA6F4A72D518C15C14146FC6CAD6AB642A3C9824 -C910617B5DC2C3137E96AC1869B7C5E90A1585181CC1B585C4CACC2624B7A72A -0AAEBC3463300A0391C2B2B14865A68EF44EAE8B1C2462B2730E28B25881B6462B3CCA631DC8A750F97EF5003E6B3060 -0861D4A3FE5970BB36BF8B525C69009212520A3B79F48ACEC6CB8F6DF96D913F -6327F56523F609D4ABC552912EF808E5919EA42104137AD206EF93AA4B34C097 -F88B71DAE547754731CD1C45ACBC355E52FE6D7B984A27B454DD7E8BFF12A023 -824025D56ED8B11BB65722F8C04168767D059BEB156B183D718CFB6AA38B9D81 -66E60820D0A6C452D9E209FB56FE3F49CAEFCBDC6116177063E0759FA11FDC8F -52D6ACA1A6928C52462BABD9A76628B25A2B913FC5BE316A9248C90B6F952529 -6FF5E9DAC956EF849FB58C11948C6F00743E157A8C2C631769EFCD80BAA3C048E10E682437EB53ED906C3060CCC7FECC -42757F22BDC1059154C41EDEE74E227E6D980F39939D3AA78FEC3F4DC303BE87 -689C2694447C4FF56C85B60E9FA66CD70A7EB9703A7C0202AD34374E9B290178 -E1A8E0ACF1E30714A7E580CA6380879C48992BA93A1637F24A66E15A03509B96 -5E1176A42E6C0DCF80E7B445372E3C054875A39D5F7A8B9C35985EDB46F65BB0 -12A6349CB3EC6D79B3C85052D6155730A036AF7F54BCD8CC9EC8F36557005D5E -B6D3D039D8B6D6F298665B16EBCB908D5F64D37C31F583C4F660AC0535DEC2DD -327BEE9B3E7A989B49787DE9D0C573C97343D79527FA6F442F8BDA0B9336E666 -1BDEDA4766FB3EFC1867836267E632B12020262B1EABA4BD31F9AB20DE49632A -8DE80C00CAD7F6E555713414DE8CE56B1C8603777F38F553F528907FA25E153EA5D3459739C66B46F6854A75F19A1511 -3A07DD2876F794FDF920F5D7B50A6D15C618FCF02F064E5AD5871C5B098EE8EC -66B7166156874006B35AF6997F61B84F016868FBAD283304B256F3DA065E65E3 -1E6D841D11C065F88B3F52EF60862E579E717E6AEFABF6A79FCF90D0810B35BB -B3B168E2532A6B659503736AA8933FB01A88DB9EA339C1C19EF7566600312B26 -974628362FD1951C207BDC3F5363F2747BAFA14ED7155772ADAA2FE8D1F7DC702F8DDB8CB4C17DBA803EC0DB6CDA43AC +IV: 48 69 69 69 2C 20 4D 69 73 68 61 21 21 30 31 21 +5914BA15A974B44BBF5886001E9CA8C05FED2B9A46D16F862484BC4760201A72 +885AB8E254F1403894740B50C6943A5F0A426C79CD8FA11D16915455E6B9ACE8 +48106C10911CC932FCAB49A793B6777DE845AA0D383E1B8D9FAE04E4F943FC60 +C1B81F527CF227F8A8D342BBB86EFBD95C99BFE3E3F55FFF19CF66C03CDB8779 +3DAB5A367DC19D412E9D71A89852E246DDEC0E97D7F7CE77DEE4043D9A99A1DEC4BDCA38B728CDC7BCB9E112044DCB8B +8E718417DD703259B6EBBB799EC8ED428C6D65115023C1421C349DDB70359929 +DB110804D813EB3D2F04F5723305CFA13778D46DD261D246B05DB257535C9520 +135BEFEEBEBF17665C27951E43639A82AD5B15EFAD7D1D776ACF1070E5E81F9C +996528B0D85E81D1AB47FECB2A5C2B63AFF35281EE41E316D26E34BB7E0E5EFE +BA220B2E219DE8045F6C5C4D8B4CABFB9944252ACB82755907C44E09071A0F90 +C4509ACDC858711F42B96AA40B0FEC58566E71D91E1D167835B97D13A9C6B4FD63F62D911E17C15081ED1FFBA00E08D0 +499D1031FDC6B5D6109D4A9046599FEC77F1DB26FCA809235803CE5F670F2BF1622042AB04F768CB4BBB8E93595B229A +43107EA4D34AC00BD05F45CF7AB077742C06A3619B3E258389EFF2D8ED057570 +A2ED253FB0CE66CDE2FF3921BE78662A97A23C344A83493D36CE6CC5ACC3A821 +963B48D299D6935B228A3BFCB86CF75F11A30850A19E014E31E6559F7A9A7DA8 +35D23E9D1D85AA0273A13B887EFBE9F55DD2E6C85B14F7E1100A66892F2A05BE +F3134F0E2545623B439D581F2A42F6F4CE0512622B6E53937DFBE353C26DF2E7E69871412C0221D8CCCBB1948715CB3C +C7E5A6E301B8E18BD3B15748A2A74AA1A939073FFE2F4A126213C49567D5BE44 +6E60F1421A27CEA2521C1EFE014EE2036F706ED734C12A794EBE3EFFACEA59C4 +9B60C596CE660E6A582AEC2C2804188EDD3C7636A3BC0E423A8D969F083319BB5AB90BE0DF3470BADB8D23E5AE0832EC +001C3E6E3A36954427626FC4F2CC9DA39983C945F745EC9F25B11814D8EDB233AFFA0FD3C0B9B4D22EAFA951E734FBFD +C03C3CC316F88E71C2A41B4B947FDF3FFCB46E103AFC420B820D757DCF7C46B6 +5430C52B29FDE8A436C745C1821BA6CDE9FB42C297C0407F1BC185B137485ABB +F9EE48BC297FE3866E2BFBFEC341CFD57150088F88A06725ADFCAD891F9FF9F1 +E0BB992BDBFA5A2369A1DAEF6316F1779C16A33FE03F1A4A42C86B7FAA80A8B1 +747863CCE4A663B2C4C7533733CCD604C271C8BF65066E219C427C7208DCA9D5 +8C05EF25D017E06ED6D2818B4EAC50E56727FA84039FFE119837C2E5933EB3CD +17C31C9451349E42F010F0E7540D71567485FC7D5E9CFCFEAB0E7AA3FEA8E3AE +76D5BF46CE39C37F09549D281C5FDB5EC12CAA73152E3B295E439091365EEEF1 +0B7B9F563A09D953BC6DD141A1313B9CCB52CE5406ED727DE965CE920F0CA5DC +78C9F207EBE8942DCF78A345A8E56B9C6C75D63C110250377D6C04DBB4DC15EA +3518584CFE8238E0AFA1E6F4CDF1E1A2A6349A7D2D641404067BA482DA4C6345 +F3CD339419BFF39EFF2F2F0E7C06BB0537B238427345011436EF4F28D2FB4D02 +96A25E27313CC92A48B515143643D235C28DDCB53AECCFCFC7792A417FC78CCC +11D553C6363F1C53B0074DF36C5256C9695CEA3006AC8737689694848C14FE93F15925BE58AB9D063D06FD87C0F7E637 +81BE95390E912466EAA1465BA7E316D662D7FDCE4DA91D79551247BCBE0FD66E +D2DA1301B149C17E4E579266D0AD810E8043AC1F16781F7743FAFB61B0A74D14 +C4921F5E174C988212CB46362FABB6B99599537C4E5B983016463ACF11AFA9F9 +F1333F4B1706326B776A6701E4457A18A0E262EDEC1758D3A696741094EAE7C8 +6F3647542899B48A53A829FF3CE82B22A75AA9AB3D3E01BF33C6B3D1F0C9BF3D +C42ACCF63F19E529E0D6A9AD9D2505F103D734248DAC0E9F2FCA35EC3F86C0A3 +1C0370E20EDBF342A76B1B65F0DB7C66F870ABB56E848159A0DB6585749F57B36EF4E18F730B5D0A2732C03ED74ECF72 +C61D01023FBDD674B09C6FFDB38A6F152F3B5C3203AFE4CA014C28600670922C +6C5507A0AF35860EA2EAD029A6ED19AEFE2AD90B15B2EEFD65B1F14747C1EA66 +1C908E924A1BE763868ADB985DE4BB157CEF7BA96E58CED46BE08816E7D92239 +A3E883AC3AE22373815F2C02F6B808B0DD36FCE27BDF22C262FDBFC5D1B03153 +7CC9A80338315C477B55B4024324F2EAA56A770675F2229D32B44E304214059D +D9CF90A9C4B60860355301A842323D8E207473D4A5631067E5DF2BFFD5A0E38E +824D256362207A507DD40C13D765B1BA172C1E2AAA09DB164028CE094BFF33A8 +8F04BFBD27084AC2FEA04D18F88E98E3F4AE979B40343E2D55C20173EB5030B6 +D28B98D9030AC29D79B974FCDF176C19EF6998DB776D5A8B067F1F6908B951F7 +B7AA60298EB22D45A182A6E8BC76C7AD04334BE7D26746455C5CA44BC7D34B38 +C79E0C38724D4ED317A0507C3981DC4E3AFA84F039FF9595FDE4C4C81F3332A3 +F30A3803C59558A0FD41B15E45B133B901E0C66D898B10A2EF5189BC36EAE904 +3F2CFFEE683A76EB9FDD84E99CE0C0FCFFC1B5ECA9C8677CACA2F6E33A773823 +EDBC9BF637AFFB3F8BC0A90A4B8F56D452F64949E865855DC51882B6F0889E64 +C4234CE6419E399A6415EBC80FEF6049A3EF345D4D0692784BB58626241291A37C080BCEEFB71B135368E4E3790C93B3 +C1231A97B5642D908BD9524B482801A63F6AF3E25EF69F51C495EABF5C967238 +651FF3C3EB76F90CD8BC02A0884E4C830A2794F8CE2467CC2FA2E74D081D6567 +65CCA76B05D06AC1346B23BFE435864B648247075385B74AAE53C4006560854F +2C19A88D52E56B9E09574F3B0B05A1AB3F417D47F78DCEDB9F6593EE01FD9540 +D46CF8835857552C4E77C8B37D79A6DE133ECEFD234CCD2278C78872EBAFFF2DAD0571FEFDA998031A235673CF6F2EA2 From e976b149562f5a44c7af3b724ab3abf867c5a504 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 30 Jul 2025 01:26:37 +0300 Subject: [PATCH 06/19] Add unit tests & raws --- .../resources/unit_tests/subghz/feron.sub | 7 ++ .../resources/unit_tests/subghz/feron_raw.sub | 31 +++++ .../resources/unit_tests/subghz/gang_qi.sub | 7 ++ .../unit_tests/subghz/gangqi_raw.sub | 10 ++ .../resources/unit_tests/subghz/hay21_raw.sub | 10 ++ .../resources/unit_tests/subghz/hollarm.sub | 7 ++ .../unit_tests/subghz/hollarm_raw.sub | 10 ++ .../unit_tests/subghz/legrand_2E37F.sub | 8 ++ .../unit_tests/subghz/legrand_2E37F_raw.sub | 22 ++++ .../unit_tests/subghz/marantec24.sub | 7 ++ .../unit_tests/subghz/marantec24_raw.sub | 14 +++ .../unit_tests/subghz/revers_rb2.sub | 7 ++ .../unit_tests/subghz/revers_rb2_raw.sub | 17 +++ .../resources/unit_tests/subghz/roger.sub | 7 ++ .../resources/unit_tests/subghz/roger_raw.sub | 23 ++++ .../unit_tests/tests/subghz/subghz_test.c | 113 ++++++++++++++++++ 16 files changed, 300 insertions(+) create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/feron.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/feron_raw.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/gang_qi.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/hay21_raw.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/hollarm.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/hollarm_raw.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F_raw.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/marantec24_raw.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2_raw.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/roger.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/roger_raw.sub diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/feron.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/feron.sub new file mode 100644 index 00000000000..14c293ca81c --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/feron.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Feron +Bit: 32 +Key: 00 00 00 00 63 38 84 7B diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/feron_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/feron_raw.sub new file mode 100644 index 00000000000..16249dce5d9 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/feron_raw.sub @@ -0,0 +1,31 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 329 -296 295 -66 163 -98 2441 -66 9337 -5690 131 -2574 65 -692 65 -460 165 -230 329 -266 131 -134 97 -400 197 -66 197 -66 12303 -5844 97 -200 167 -102 197 -334 297 -100 559 -166 133 -132 3425 -98 99 -13334 65 -66 129 -822 99 -598 133 -366 131 -68 163 -100 131 -66 99 -98 361 -130 63 -296 2175 -100 163 -100 1095 -100 859 -7534 165 -5584 99 -198 99 -1066 99 -232 99 -266 67 -66 99 -132 97 -564 131 -66 197 -132 231 -98 261 -560 195 -166 885 -98 1579 -198 729 -134 431 -68 5783 -5922 131 -992 65 -166 1459 -262 65 -526 97 -100 163 -230 65 -362 197 -958 99 -634 99 -132 65 -234 99 -394 527 -132 461 -130 323 -18704 231 -564 99 -600 133 -98 1359 -66 165 -166 133 -232 1657 -98 1907 -132 4497 -496 99 -66 167 -100 133 -168 233 -264 167 -66 863 -296 399 -68 2453 -134 635 -66 331 -200 395 -134 7025 -4436 165 -528 99 -298 229 -162 97 -362 197 -524 361 -428 65 -66 99 -166 199 -66 67 -198 165 -466 99 -428 263 -330 361 -132 293 -296 225 -66 3753 -66 291 -66 133 -66 6907 -4898 63 -558 65 -918 99 -100 623 -132 359 -100 457 -98 97 -98 363 -100 559 -132 297 -166 129 -296 97 -262 99 -722 297 -196 1187 -266 199 -168 133 -68 597 -66 301 -132 429 -64 6665 -5372 65 -1054 329 -200 167 -100 629 -100 293 -200 165 -100 133 -132 133 -332 197 -100 233 -496 65 -166 561 -232 165 -296 1127 -64 2753 -66 755 -164 12059 -360 65 -266 99 -66 65 -2612 99 -1780 97 -164 1083 -330 197 -100 397 -66 2095 -98 793 -102 65 -100 10223 -594 65 -232 97 -984 131 -296 99 -166 99 -664 197 -66 261 -230 97 -68 1683 -266 691 -98 335 -66 133 -8384 99 -2300 97 -1710 165 -230 229 -426 97 -134 359 -300 555 -164 193 -132 99 -132 163 -100 497 -298 823 -12964 99 -1874 97 -132 97 -262 97 -328 133 -100 231 -198 131 -132 195 -460 63 -198 131 -66 195 -66 1791 -100 97 -66 131 -64 955 -66 559 -98 233 -66 4633 -5270 263 -100 131 -198 99 -164 331 -132 303 -134 133 -430 233 -1192 67 -498 99 -302 233 -300 597 -66 99 -132 1261 -134 65 -5292 63 -756 131 -884 131 -130 231 -98 197 -198 195 -66 97 -592 261 -298 163 -922 163 -164 65 -656 131 -68 231 -66 99 -430 1295 -68 529 -100 1263 -68 1687 -14880 99 -236 65 -566 163 -758 99 -68 461 -98 559 -130 165 -162 995 -100 1787 -196 195 -524 295 -66 821 -66 5703 -3860 63 -3736 523 -166 161 -64 97 -132 163 -164 257 -164 197 -656 229 -1420 +RAW_Data: 99 -598 97 -168 297 -132 199 -232 629 -132 131 -100 97 -266 499 -66 597 -166 229 -66 429 -68 3463 -3518 97 -2346 265 -66 433 -66 503 -464 65 -68 987 -98 131 -98 557 -66 1583 -66 431 -100 1097 -134 5651 -6742 99 -830 197 -102 233 -398 67 -66 197 -168 267 -366 197 -332 363 -364 131 -2374 329 -66 331 -200 133 -100 333 -134 299 -66 4079 -5972 101 -1558 393 -230 331 -330 63 -98 65 -328 131 -426 133 -66 197 -196 65 -1352 65 -590 97 -230 161 -96 163 -230 329 -198 97 -134 1525 -66 433 -168 1455 -230 6225 -2024 99 -266 99 -268 133 -264 297 -100 167 -168 233 -168 267 -660 369 -234 337 -300 97 -132 263 -134 1133 -200 137 -136 265 -166 167 -232 99 -300 167 -66 99 -200 197 -462 131 -432 99 -300 165 -862 197 -496 531 -332 231 -132 1015 -100 427 -100 197 -1018 99 -66 97 -200 199 -168 199 -100 465 -100 197 -68 65 -132 3155 -66 12365 -328 131 -696 133 -896 265 -472 165 -132 133 -232 129 -68 165 -66 723 -564 529 -66 1491 -266 99 -132 397 -66 501 -6672 65 -1580 97 -1420 199 -166 265 -134 699 -168 133 -100 663 -66 637 -68 2119 -66 697 -66 1027 -66 3319 -7648 97 -162 293 -460 197 -230 591 -166 227 -98 65 -262 329 -198 163 -128 97 -328 131 -426 229 -368 299 -202 265 -168 331 -100 729 -68 1597 -66 133 -66 961 -68 231 -166 99 -234 5397 -5158 65 -1328 97 -502 99 -166 199 -198 131 -68 199 -264 231 -436 163 -332 199 -100 131 -166 165 -168 97 -100 133 -600 165 -1754 99 -66 195 -228 263 -164 297 -232 365 -200 499 -66 297 -66 1625 -66 399 -166 5011 -6110 97 -1482 65 -264 367 -166 65 -68 465 -892 197 -330 231 -430 133 -12408 129 -5982 295 -562 165 -132 1033 -66 997 -66 799 -66 297 -196 959 -100 729 -66 2115 -66 2639 -5752 99 -802 365 -232 97 -362 97 -2510 131 -534 99 -296 131 -268 1161 -66 131 -66 1057 -100 1325 -66 463 -4028 97 -364 65 -728 197 -234 99 -100 97 -100 65 -132 265 -428 333 -628 195 -262 99 -228 131 -1766 163 -562 297 -132 465 -302 165 -100 133 -198 365 -132 465 -66 1787 -4594 65 -2792 65 -164 131 -66 131 -98 197 -296 131 -332 165 -330 693 -298 101 -366 265 -1892 65 -134 65 -164 201 -200 65 -266 265 -232 133 -200 235 -200 1001 -68 991 -66 597 -100 963 -200 2913 -9784 65 -426 229 -954 131 -398 531 -198 97 -98 163 -130 131 -326 359 -100 2367 -168 691 -100 13125 -362 65 -394 197 -332 133 -200 299 -366 167 -264 299 -132 835 -234 2493 -132 +RAW_Data: 99 -134 565 -334 231 -134 167 -200 1425 -132 3943 -3864 563 -66 233 -2296 99 -198 165 -234 199 -298 263 -134 131 -530 299 -398 233 -1336 165 -166 65 -132 99 -232 295 -130 99 -328 97 -132 97 -66 97 -132 65 -262 2145 -132 195 -196 65 -362 231 -196 261 -98 65 -198 229 -132 229 -196 793 -66 555 -100 297 -66 493 -230 359 -100 195 -296 229 -66 99 -166 10343 -3654 165 -1392 65 -834 65 -132 495 -100 395 -232 331 -360 265 -132 1681 -5474 165 -2122 65 -200 65 -232 99 -1132 65 -200 165 -102 133 -68 199 -100 663 -234 165 -298 163 -68 1597 -98 1199 -66 197 -332 5539 -1934 65 -3354 133 -168 167 -2354 101 -930 65 -1266 131 -298 99 -1328 259 -232 563 -200 297 -100 65 -132 131 -66 1681 -100 267 -98 331 -168 299 -132 629 -66 5981 -2810 165 -3282 99 -132 227 -98 163 -430 231 -330 293 -66 65 -164 99 -958 65 -134 67 -432 99 -1426 297 -264 295 -132 363 -332 97 -366 133 -98 2869 -102 1755 -100 2911 -7466 261 -196 193 -260 259 -298 135 -66 133 -400 199 -266 195 -334 97 -268 365 -864 129 -1132 395 -300 395 -132 933 -200 367 -134 997 -66 233 -198 5415 -5556 65 -1292 65 -68 131 -268 165 -264 231 -1792 65 -764 65 -1394 299 -396 451 -854 323 -808 97 -62 227 -838 231 -868 635 -460 669 -402 275 -810 271 -838 681 -398 711 -388 691 -392 275 -832 279 -780 311 -774 741 -376 285 -776 321 -762 325 -776 297 -776 765 -324 345 -752 345 -724 341 -756 767 -326 773 -334 743 -340 771 -348 313 -770 741 -350 753 -556 497 -4666 359 -736 779 -318 759 -326 351 -758 347 -726 339 -760 767 -322 775 -334 351 -734 341 -732 769 -318 781 -326 777 -334 355 -724 349 -740 347 -724 775 -324 349 -734 353 -734 355 -756 347 -724 771 -326 347 -758 345 -732 353 -732 755 -350 771 -320 765 -322 763 -356 317 -758 755 -352 755 -524 557 -4642 323 -746 795 -320 773 -296 389 -722 347 -726 375 -724 767 -324 779 -332 355 -724 347 -724 775 -326 779 -334 747 -338 357 -730 355 -728 355 -756 743 -350 355 -722 353 -720 349 -754 345 -758 743 -346 331 -756 323 -744 361 -752 761 -322 773 -332 747 -336 779 -310 343 -764 735 -348 773 -516 561 -4620 349 -744 781 -320 763 -330 351 -756 347 -724 341 -758 769 -324 775 -332 351 -736 341 -734 771 -324 777 -322 773 -332 355 -724 349 -724 377 -724 769 -324 347 -758 345 -734 351 -732 351 -722 791 -320 351 -726 359 -736 321 -768 753 -322 801 -330 753 -334 755 -336 353 -732 765 -354 727 -548 +RAW_Data: 545 -4646 351 -738 755 -322 801 -296 389 -722 347 -740 347 -726 773 -326 777 -334 355 -730 355 -730 779 -308 777 -346 743 -348 321 -758 353 -722 351 -750 769 -314 333 -742 351 -740 361 -720 363 -754 761 -322 345 -756 347 -724 339 -756 767 -324 775 -332 745 -338 779 -310 357 -728 777 -348 739 -550 513 -4672 323 -776 749 -320 763 -328 353 -758 347 -740 347 -726 771 -326 777 -334 355 -724 349 -758 743 -326 777 -332 747 -340 351 -732 343 -736 351 -756 755 -320 371 -724 375 -724 335 -746 337 -746 771 -326 349 -756 347 -722 341 -756 767 -326 775 -332 747 -338 777 -310 343 -766 745 -346 759 -546 509 -4650 345 -770 743 -324 785 -326 347 -758 345 -734 349 -734 769 -344 763 -296 373 -744 333 -754 765 -322 777 -332 745 -340 351 -732 343 -734 351 -756 753 -322 367 -724 341 -760 335 -748 337 -756 767 -324 345 -756 345 -734 351 -732 767 -314 797 -296 769 -322 801 -296 353 -756 777 -332 747 -536 537 -4634 359 -742 777 -320 763 -328 349 -756 347 -726 339 -756 767 -322 775 -334 355 -732 355 -728 779 -310 757 -338 757 -342 351 -732 343 -734 353 -758 753 -322 367 -724 341 -760 335 -748 337 -756 765 -324 347 -736 351 -724 377 -726 769 -324 777 -334 747 -338 779 -310 343 -764 739 -330 769 -546 523 -4664 343 -758 743 -346 761 -324 347 -752 335 -754 333 -746 769 -324 775 -334 351 -734 341 -734 773 -324 775 -322 779 -332 355 -722 349 -740 347 -724 773 -324 351 -756 347 -724 339 -758 337 -748 769 -322 347 -756 347 -722 341 -756 767 -324 777 -332 747 -338 779 -310 341 -766 771 -298 767 -548 523 -4658 329 -770 777 -320 755 -328 349 -756 347 -740 347 -726 773 -324 777 -332 357 -722 349 -754 743 -326 779 -334 745 -342 351 -734 349 -752 347 -722 781 -312 333 -780 321 -742 361 -752 331 -752 763 -324 343 -756 347 -734 351 -734 767 -322 765 -352 753 -346 753 -296 373 -750 763 -322 775 -530 535 -4632 359 -736 779 -320 761 -328 351 -732 351 -758 347 -724 775 -326 781 -330 355 -724 349 -756 743 -326 779 -334 745 -340 351 -732 341 -762 317 -776 749 -320 367 -722 339 -758 337 -746 337 -746 773 -326 347 -736 351 -754 347 -726 771 -324 779 -332 747 -340 779 -310 343 -768 745 -348 753 -516 543 -4650 383 -716 769 -348 753 -326 343 -750 333 -754 335 -744 769 -324 775 -334 351 -734 343 -736 771 -324 775 -322 775 -332 351 -734 353 -722 349 -754 755 -318 337 -768 319 -766 325 -746 361 -752 763 -320 345 -756 345 -726 +RAW_Data: 337 -746 771 -324 777 -334 743 -340 769 -352 311 -768 741 -324 781 -520 561 -4636 359 -736 777 -320 757 -326 349 -756 347 -724 341 -758 769 -324 777 -332 351 -734 341 -734 773 -324 779 -320 773 -332 349 -734 353 -722 349 -756 753 -352 301 -766 319 -768 325 -746 365 -752 761 -322 345 -724 377 -734 351 -732 767 -316 761 -332 767 -322 769 -330 351 -766 745 -336 777 -512 541 -4668 325 -742 779 -320 761 -330 351 -756 347 -740 347 -724 773 -324 779 -332 355 -730 355 -726 777 -346 755 -308 777 -346 319 -760 309 -764 347 -752 751 -320 367 -724 375 -722 337 -746 337 -746 771 -326 349 -756 347 -724 339 -756 767 -324 775 -330 745 -340 769 -322 341 -766 743 -322 781 -552 529 -4628 359 -736 781 -318 759 -328 351 -734 341 -766 323 -746 779 -322 761 -328 351 -766 353 -724 777 -330 751 -336 753 -336 355 -728 355 -726 355 -756 741 -352 353 -722 351 -722 347 -752 349 -738 777 -320 361 -724 339 -756 335 -746 769 -326 775 -334 747 -338 755 -340 357 -724 783 -330 747 -538 539 -4658 347 -750 753 -320 763 -330 351 -732 353 -756 347 -724 775 -326 781 -332 355 -724 347 -756 741 -326 779 -334 747 -340 351 -734 349 -752 347 -722 779 -312 333 -780 323 -740 361 -752 331 -754 763 -320 345 -756 345 -724 339 -746 771 -324 779 -332 747 -338 769 -320 343 -766 741 -348 753 -556 531 -4624 349 -776 747 -320 765 -328 351 -758 347 -726 339 -758 767 -324 777 -332 351 -732 343 -732 771 -318 781 -324 777 -332 355 -722 349 -722 379 -734 745 -340 351 -732 345 -734 349 -760 323 -746 793 -322 341 -722 379 -722 339 -744 771 -324 775 -334 745 -340 757 -340 355 -728 779 -346 741 -548 511 -4676 323 -744 777 -318 763 -328 351 -758 347 -724 377 -722 767 -326 777 -332 355 -732 353 -724 777 -332 745 -338 777 -310 343 -734 349 -744 353 -742 759 -322 371 -734 351 -732 345 -734 353 -756 755 -322 367 -724 341 -770 349 -734 767 -318 765 -332 765 -320 761 -328 351 -756 745 -362 747 -536 537 -4662 317 -778 747 -322 797 -294 389 -724 347 -728 337 -746 771 -326 777 -334 351 -734 343 -734 777 -326 773 -322 775 -330 355 -724 349 -732 351 -732 767 -352 333 -736 351 -738 325 -780 331 -752 763 -322 345 -736 351 -758 345 -724 769 -324 777 -332 743 -340 769 -356 317 -752 769 -314 787 -514 539 -4638 345 -768 773 -320 753 -326 351 -760 347 -712 379 -724 773 -322 777 -334 351 -734 355 -718 789 -320 769 -324 759 -348 323 -758 355 -720 351 -720 +RAW_Data: 801 -314 333 -740 351 -740 361 -720 363 -754 761 -322 345 -726 377 -724 337 -746 769 -324 777 -334 743 -340 769 -320 343 -768 739 -324 783 -552 529 -4634 359 -736 779 -320 757 -326 351 -760 345 -722 341 -756 767 -322 777 -334 349 -736 353 -720 763 -354 759 -320 755 -350 331 -740 353 -740 327 -748 793 -320 341 -758 345 -722 337 -746 339 -746 773 -324 349 -756 345 -724 341 -756 767 -326 775 -334 745 -338 777 -310 343 -764 771 -296 767 -548 523 -4650 347 -742 781 -320 765 -328 351 -732 351 -758 347 -724 777 -326 779 -332 353 -724 349 -754 741 -326 779 -334 745 -342 351 -732 349 -754 347 -722 779 -348 299 -778 321 -742 363 -718 363 -754 763 -322 343 -758 345 -732 351 -732 769 -354 725 -350 755 -348 737 -350 353 -722 763 -354 757 -510 543 -4652 353 -742 791 -288 773 -330 351 -734 387 -722 347 -724 775 -326 781 -330 355 -732 355 -730 745 -342 777 -346 755 -310 357 -726 355 -724 353 -758 755 -348 355 -722 351 -722 349 -756 345 -756 747 -346 329 -752 321 -746 361 -752 763 -322 773 -332 751 -336 745 -342 341 -768 749 -346 753 -514 543 -4656 349 -756 755 -318 789 -316 333 -744 353 -742 359 -718 791 -320 773 -332 357 -724 349 -740 779 -296 785 -334 755 -336 353 -732 341 -736 353 -750 753 -320 369 -724 375 -712 375 -712 375 -736 749 -338 353 -730 343 -734 349 -754 753 -320 801 -294 779 -338 777 -310 341 -764 771 -296 799 -514 523 -4664 347 -756 745 -346 757 -318 349 -756 335 -756 335 -746 767 -324 777 -332 353 -730 343 -732 771 -326 775 -324 777 -332 357 -724 347 -726 375 -736 747 -338 353 -732 341 -734 349 -756 325 -744 793 -320 343 -726 377 -724 337 -746 769 -324 777 -334 747 -338 767 -322 341 -766 741 -322 785 -518 563 -4622 349 -744 783 -320 761 -326 353 -756 347 -724 375 -724 767 -324 777 -334 355 -724 349 -740 745 -330 779 -336 747 -342 353 -732 351 -722 383 -718 781 -314 333 -742 353 -742 361 -716 363 -754 765 -322 345 -724 379 -724 337 -746 769 -324 779 -334 745 -340 777 -312 341 -764 771 -296 769 -546 523 -4654 359 -734 779 -320 757 -328 349 -756 347 -720 377 -742 743 -326 777 -334 353 -722 349 -754 743 -360 745 -336 743 -342 343 -736 329 -768 321 -768 757 -322 369 -722 341 -770 349 -734 311 -768 777 -326 311 -778 331 -746 335 -754 767 -324 775 -332 745 -340 777 -312 355 -760 755 -346 741 -88244 133 -132 99 -232 165 -100 97 -730 99 -66 2213 -264 995 -100 631 -132 6925 -4032 +RAW_Data: 133 -66 65 -2118 165 -1032 197 -66 65 -66 197 -66 99 -132 267 -66 297 -434 133 -134 133 -68 65 -66 131 -266 299 -64 67 -362 161 -296 165 -132 229 -66 361 -498 197 -132 657 -132 1031 -98 1595 -100 965 -132 165 -7880 99 -164 99 -564 67 -928 165 -166 231 -100 65 -166 333 -66 165 -266 165 -398 953 -132 1755 -66 1541 -98 4449 -8044 99 -166 303 -368 591 -132 359 -264 227 -164 99 -1550 299 -200 435 -100 67 -66 593 -132 2943 -134 895 -198 3879 -7540 99 -938 99 -860 99 -1392 99 -1474 197 -166 199 -134 99 -264 233 -134 265 -100 397 -134 1497 -2162 99 -1496 67 -1392 99 -230 233 -66 735 -66 567 -364 197 -66 99 -232 2109 -64 429 -98 99 -98 131 -66 359 -198 195 -162 4861 -4980 131 -950 131 -228 359 -1078 297 -398 231 -262 231 -66 65 -726 295 -366 199 -232 229 -328 459 -68 231 -132 367 -132 3483 -100 597 -134 7113 -1274 99 -236 165 -4414 199 -1432 67 -298 267 -166 329 -234 529 -200 197 -296 129 -294 163 -98 65 -362 131 -100 65 -1426 959 -332 265 -66 297 -166 2683 -66 535 -66 199 -4286 99 -164 525 -1224 363 -166 199 -270 131 -1758 165 -200 557 -298 163 -132 329 -68 233 -66 965 -100 99 -166 365 -234 1391 -9070 131 -1526 97 -1546 131 -98 329 -364 363 -132 329 -164 1183 -10266 65 -6530 65 -732 131 -398 197 -230 195 -98 65 -364 63 -458 65 -198 65 -658 65 -196 163 -98 1805 -98 463 -164 99 -66 623 -98 423 -228 325 -66 233 -100 5543 -5982 97 -1486 331 -198 131 -526 133 -232 131 -132 131 -66 231 -98 131 -134 629 -2026 65 -266 163 -334 265 -66 363 -134 2383 -134 131 -68 233 -98 6503 -98 1329 -9556 65 -166 463 -66 133 -166 233 -266 203 -68 67 -168 99 -66 1161 -66 1667 -132 265 -168 197 -100 199 -200 889 -15904 99 -132 133 -300 1093 -198 201 -132 133 -366 1193 -166 101 -66 935 -134 367 -14672 195 -824 131 -788 395 -430 231 -166 99 -68 99 -17390 65 -1062 65 -498 99 -134 99 -368 65 -66 65 -464 65 -332 265 -132 231 -66 597 -266 133 -330 165 -100 2127 -234 1395 -132 10439 -1004 67 -698 97 -2784 65 -66 265 -264 133 -528 331 -100 131 -234 2027 -164 693 -100 65 -134 197 -130 97 -66 457 -100 4649 -4556 65 -3626 67 -464 65 -100 133 -100 131 -532 67 -566 133 -134 231 -564 65 -166 99 -134 165 -102 65 -1206 199 -666 1261 -66 1031 -132 869 -134 199 -66 597 -100 7409 -7344 97 -296 99 -232 99 -232 65 -662 263 -66 131 -266 397 -100 363 -66 2553 -98 531 -166 +RAW_Data: 7313 -3784 133 -168 133 -1022 99 -558 361 -68 65 -66 97 -166 229 -132 265 -198 97 -792 97 -132 97 -558 163 -264 161 -658 197 -294 231 -328 193 -130 295 -166 231 -166 65 -98 489 -66 885 -100 921 -66 461 -66 323 -304 99 -3408 65 -166 99 -66 195 -296 265 -134 133 -364 65 -296 197 -228 97 -294 231 -368 1387 -66 133 -166 1133 -100 333 -68 431 -66 165 -134 4955 -5736 97 -1088 99 -100 99 -166 199 -264 131 -68 165 -398 199 -630 99 -66 233 -68 403 -98 233 -662 133 -1126 65 -228 131 -98 65 -490 199 -132 229 -232 491 -64 429 -66 667 -100 167 -200 531 -100 263 -264 295 -100 429 -14212 97 -956 65 -930 363 -66 299 -200 331 -66 63 -100 131 -230 1215 -66 1425 -132 927 -132 8041 -732 133 -1064 97 -270 269 -298 129 -228 65 -262 65 -198 459 -100 667 -166 129 -688 67 -2106 97 -232 329 -64 1065 -66 99 -334 167 -132 969 -100 1855 -98 1189 -100 5599 -4798 99 -2932 557 -200 163 -492 295 -758 457 -1788 99 -198 131 -402 197 -134 129 -524 231 -266 1295 -68 1135 -102 701 -10576 65 -5130 63 -100 97 -464 395 -298 99 -100 365 -134 201 -100 99 -100 2515 -98 1611 -132 327 -3806 97 -2502 197 -654 131 -196 97 -196 163 -392 263 -1018 97 -826 197 -130 331 -298 367 -98 267 -68 803 -236 367 -132 851 -166 299 -100 6833 -6158 65 -1062 199 -294 163 -326 227 -724 65 -164 1215 -132 855 -198 467 -66 431 -200 393 -100 229 -98 10229 -338 197 -1756 97 -298 263 -166 97 -164 195 -228 131 -198 199 -234 533 -66 529 -134 397 -100 165 -166 199 -168 99 -100 99 -166 301 -202 529 -66 921 -98 6861 -7702 65 -400 65 -1856 201 -134 65 -100 197 -166 199 -300 165 -134 65 -20006 99 -332 561 -164 199 -630 133 -66 99 -134 131 -200 2393 -134 199 -132 1127 -6284 67 -1900 97 -494 131 -490 163 -264 231 -66 197 -130 327 -164 129 -332 133 -132 3021 -13676 97 -1056 63 -232 65 -264 295 -596 731 -66 295 -66 161 -66 589 -68 3121 -66 199 -68 299 -100 629 -68 8427 -262 405 -744 739 -362 743 -338 353 -760 317 -756 313 -768 741 -360 741 -356 339 -756 307 -786 741 -358 743 -334 743 -374 311 -772 295 -774 319 -764 753 -352 341 -756 307 -758 337 -744 339 -772 743 -338 353 -726 353 -760 313 -766 773 -312 753 -330 771 -354 737 -362 317 -754 745 -364 743 -538 539 -4668 325 -742 781 -320 761 -328 349 -756 347 -724 341 -744 775 -326 777 -334 355 -732 353 -722 779 -332 745 -338 769 -352 311 -768 317 -760 325 -776 +RAW_Data: 761 -320 345 -734 351 -732 345 -770 317 -760 753 -322 369 -724 341 -756 335 -756 765 -324 775 -332 747 -338 755 -340 343 -736 781 -346 755 -516 543 -4650 349 -756 755 -352 755 -314 333 -776 321 -740 361 -752 763 -322 773 -332 353 -722 347 -736 781 -332 745 -338 771 -318 343 -736 351 -758 325 -774 761 -322 341 -736 349 -736 349 -756 347 -724 773 -326 347 -756 345 -724 341 -768 747 -338 777 -344 741 -344 739 -348 353 -722 763 -354 757 -510 543 -4654 353 -740 757 -354 771 -296 353 -756 347 -724 341 -758 769 -326 777 -332 349 -736 341 -736 775 -326 775 -320 773 -330 355 -720 349 -736 349 -754 741 -330 351 -756 347 -722 343 -758 337 -744 771 -324 347 -756 345 -736 349 -734 767 -346 765 -296 769 -354 739 -330 353 -758 743 -364 747 -536 535 -4668 325 -740 777 -320 761 -328 349 -758 347 -722 341 -758 769 -324 777 -334 353 -732 353 -722 777 -332 745 -338 769 -354 315 -752 317 -768 319 -766 755 -322 371 -724 375 -724 337 -746 339 -754 767 -326 345 -756 345 -734 351 -732 755 -350 767 -314 765 -346 757 -324 349 -744 767 -326 775 -530 537 -4636 359 -738 777 -318 761 -328 353 -732 389 -696 389 -724 777 -330 747 -336 357 -730 355 -728 779 -310 779 -348 741 -348 321 -758 353 -722 351 -752 769 -314 333 -742 353 -740 361 -718 363 -752 763 -322 345 -734 351 -726 377 -726 771 -324 777 -332 747 -338 769 -320 343 -766 739 -324 783 -522 561 -4654 315 -778 747 -320 767 -328 351 -758 347 -726 341 -758 765 -324 779 -330 357 -724 347 -724 773 -326 779 -334 747 -340 357 -728 355 -728 355 -758 739 -352 355 -722 341 -736 353 -754 321 -744 793 -318 345 -724 379 -724 337 -746 771 -324 777 -332 755 -336 779 -310 343 -732 779 -346 757 -514 543 -4650 351 -756 753 -352 751 -348 329 -752 321 -746 361 -752 761 -322 775 -298 387 -730 355 -724 781 -296 781 -336 755 -336 353 -730 343 -736 349 -756 751 -322 369 -734 351 -732 345 -732 353 -756 751 -322 369 -726 375 -712 375 -734 747 -338 777 -310 771 -352 733 -344 341 -740 757 -322 803 -528 533 -4634 359 -736 779 -318 763 -328 349 -758 347 -724 339 -756 767 -324 777 -334 351 -734 343 -732 773 -326 775 -322 777 -332 355 -730 357 -722 347 -726 773 -326 349 -734 353 -732 387 -698 389 -724 777 -296 387 -722 347 -726 375 -714 773 -324 777 -334 745 -342 779 -310 343 -766 747 -346 757 -514 543 -4654 341 -764 779 -296 767 -320 373 -724 377 -724 335 -746 771 -324 777 -332 +RAW_Data: 353 -734 343 -732 771 -324 777 -322 779 -332 355 -732 355 -724 347 -724 777 -324 349 -756 347 -724 339 -746 375 -734 747 -338 351 -732 343 -734 349 -756 753 -320 801 -328 747 -336 757 -336 357 -724 781 -332 745 -536 539 -4642 359 -738 779 -318 761 -328 351 -736 353 -756 347 -724 771 -324 777 -334 357 -724 349 -724 775 -326 779 -334 745 -340 351 -732 345 -734 351 -756 753 -322 369 -724 377 -702 383 -734 341 -734 773 -324 345 -752 333 -748 335 -748 771 -324 775 -334 745 -338 779 -312 357 -728 777 -350 741 -548 511 -4676 325 -740 781 -320 763 -328 351 -758 347 -724 341 -746 775 -326 775 -334 355 -732 355 -724 779 -330 747 -336 779 -310 357 -728 355 -724 353 -756 767 -322 351 -722 345 -766 319 -762 325 -778 761 -320 345 -724 377 -724 337 -758 767 -322 775 -332 755 -336 745 -342 341 -732 769 -330 769 -546 523 -4664 345 -742 779 -320 759 -326 349 -736 353 -756 347 -726 771 -324 779 -334 351 -734 341 -736 779 -324 773 -320 777 -296 389 -728 357 -722 349 -724 777 -326 347 -726 379 -734 351 -734 351 -722 793 -322 351 -720 343 -762 323 -744 779 -320 763 -328 781 -334 755 -336 353 -734 767 -316 761 -536 541 -4650 349 -756 753 -352 755 -312 333 -746 353 -742 361 -752 765 -322 773 -298 389 -722 349 -724 775 -326 781 -332 747 -338 357 -728 355 -726 355 -724 799 -322 351 -718 347 -740 353 -738 359 -720 793 -320 343 -724 379 -726 337 -748 767 -324 779 -332 747 -338 757 -340 357 -728 755 -342 757 -538 539 -4660 317 -780 751 -320 767 -328 353 -756 347 -740 347 -726 771 -326 777 -334 355 -730 357 -724 781 -330 747 -336 747 -342 353 -732 349 -754 347 -720 777 -316 341 -746 361 -720 363 -754 331 -748 767 -322 347 -732 355 -758 321 -754 769 -320 765 -354 757 -322 757 -352 331 -736 777 -320 757 -556 533 -4634 359 -738 779 -320 761 -326 351 -756 347 -722 373 -726 767 -322 775 -334 355 -724 349 -724 773 -326 779 -334 747 -338 353 -732 343 -734 349 -760 751 -320 371 -740 347 -726 375 -726 335 -748 769 -322 347 -734 351 -732 345 -768 743 -322 785 -324 777 -334 753 -336 357 -728 777 -312 777 -546 509 -4670 323 -744 779 -320 763 -328 353 -732 353 -732 389 -722 777 -330 747 -338 357 -724 349 -756 741 -328 779 -336 745 -340 341 -736 347 -742 351 -740 791 -288 373 -724 379 -712 377 -724 337 -748 769 -322 347 -758 347 -724 339 -746 771 -324 777 -334 747 -340 767 -322 341 -766 739 -348 755 -558 527 -4632 +RAW_Data: 359 -736 781 -318 761 -326 351 -756 347 -726 339 -748 771 -324 783 -332 351 -736 341 -734 771 -324 775 -322 775 -332 351 -736 341 -734 347 -750 753 -322 367 -742 347 -724 339 -746 375 -734 747 -338 357 -728 353 -728 353 -724 775 -350 767 -320 757 -350 739 -352 353 -724 765 -322 761 -556 523 -4648 347 -754 753 -322 767 -328 351 -734 387 -732 355 -722 779 -330 747 -338 355 -730 355 -728 753 -340 777 -312 791 -310 357 -728 355 -728 353 -758 741 -352 355 -722 351 -720 383 -720 345 -758 745 -346 331 -756 323 -742 361 -752 763 -322 773 -332 749 -336 777 -310 343 -734 781 -346 755 -514 543 -4652 349 -752 769 -348 749 -318 347 -746 337 -754 335 -756 767 -320 775 -332 351 -734 343 -736 775 -326 775 -320 773 -332 351 -734 341 -732 349 -754 749 -322 367 -732 353 -732 343 -734 349 -756 753 -322 371 -734 349 -734 343 -734 775 -322 783 -322 777 -332 747 -338 357 -728 777 -312 791 -508 541 -4660 349 -750 751 -320 765 -330 351 -732 353 -732 389 -722 781 -296 785 -334 357 -730 355 -724 779 -330 747 -338 779 -310 357 -728 355 -726 355 -758 737 -352 341 -732 349 -752 323 -744 363 -746 763 -322 347 -756 345 -726 337 -758 767 -322 775 -332 747 -338 779 -310 343 -764 771 -296 767 -548 523 -4660 345 -756 771 -326 771 -318 345 -724 379 -722 337 -758 767 -324 777 -330 351 -734 341 -738 775 -326 773 -320 775 -300 383 -736 309 -764 347 -754 749 -322 367 -722 341 -760 337 -746 339 -746 773 -324 347 -756 345 -724 339 -746 773 -326 777 -332 747 -340 779 -310 357 -726 765 -356 757 -524 545 -4646 351 -740 791 -320 771 -328 357 -722 349 -724 377 -726 767 -322 777 -334 351 -734 341 -734 769 -316 783 -324 777 -332 353 -732 343 -734 349 -752 751 -322 367 -736 349 -732 353 -752 347 -722 781 -312 333 -744 353 -744 361 -754 763 -320 771 -332 753 -336 747 -340 353 -734 787 -318 759 -548 511 -4672 323 -778 749 -320 763 -328 353 -758 347 -740 347 -726 775 -326 777 -332 357 -722 349 -726 775 -326 777 -334 755 -338 351 -732 343 -732 353 -756 755 -320 369 -722 377 -712 375 -702 389 -724 779 -294 353 -758 347 -724 377 -722 769 -322 777 -332 747 -338 779 -310 343 -764 771 -296 767 -548 523 -4666 345 -758 745 -346 759 -324 347 -752 335 -754 333 -748 769 -322 777 -332 353 -732 343 -730 771 -326 777 -322 777 -334 351 -734 353 -720 351 -754 755 -318 335 -766 319 -764 357 -718 363 -754 765 -318 345 -724 379 -732 351 -732 +RAW_Data: 765 -316 791 -316 775 -322 775 -330 357 -730 747 -340 781 -510 543 -4670 325 -740 779 -322 761 -328 351 -764 319 -756 347 -756 741 -328 777 -336 349 -736 313 -766 771 -326 777 -322 773 -332 353 -720 349 -734 349 -764 735 -350 333 -742 351 -740 325 -780 331 -746 767 -324 343 -756 345 -724 339 -754 767 -324 775 -334 745 -338 771 -350 311 -768 741 -356 751 -91544 97 -1916 131 -560 161 -784 65 -64 495 -98 589 -296 2305 -15072 197 -1258 65 -130 97 -164 97 -98 297 -198 201 -234 261 -98 99 -66 1333 -166 759 -98 95 -196 295 -66 491 -64 163 -66 4795 -4508 131 -922 65 -166 129 -164 163 -66 131 -164 65 -164 99 -196 163 -264 229 -164 65 -164 131 -1932 231 -164 261 -130 65 -264 65 -362 727 -130 2635 -66 327 -66 2397 -4778 65 -364 67 -1134 67 -438 99 -864 163 -366 1187 -830 99 -328 165 -100 131 -134 199 -568 99 -100 99 -466 231 -560 131 -100 129 -132 329 -64 263 -296 1049 -132 333 -98 703 -364 231 -13082 99 -2554 133 -832 133 -164 395 -132 295 -164 65 -66 131 -66 131 -132 65 -134 955 -100 99 -66 961 -66 4911 -4040 65 -2524 165 -896 65 -498 65 -66 99 -232 133 -268 197 -300 265 -266 133 -400 395 -166 297 -98 131 -1020 97 -492 199 -100 563 -132 99 -66 133 -100 3051 -66 591 -196 195 -162 1921 -66 9139 -3400 129 -692 301 -1262 131 -100 265 -166 337 -134 363 -66 133 -332 233 -134 919 -64 2019 -132 295 -132 165 -200 6921 -4912 133 -336 165 -98 99 -66 261 -298 63 -100 65 -264 163 -296 297 -132 465 -100 65 -332 195 -196 165 -334 97 -100 131 -132 165 -300 629 -66 65 -66 165 -134 663 -134 233 -66 861 -66 3939 -134 567 -1310 163 -2894 229 -168 99 -234 431 -494 97 -396 133 -66 1563 -100 497 -198 265 -14052 65 -524 99 -398 923 -66 3991 -6098 99 -1626 99 -1394 99 -100 265 -200 163 -168 97 -432 99 -100 133 -200 4699 -4592 63 -1486 65 -1786 131 -66 197 -334 101 -400 99 -200 99 -168 131 -100 99 -430 231 -234 167 -2338 763 -364 263 -66 131 -200 263 -132 333 -66 3823 -198 1091 -1186 65 -756 65 -494 99 -1546 97 -1432 131 -66 131 -132 295 -132 131 -300 231 -562 99 -66 363 -100 663 -166 457 -66 3199 -6668 99 -962 65 -164 133 -132 131 -266 363 -430 363 -364 99 -66 365 -132 67 -2376 299 -166 165 -130 161 -360 97 -132 953 -198 2041 -66 855 -12212 95 -330 97 -164 97 -1388 65 -366 99 -964 165 -398 163 -232 427 -66 363 -98 133 -166 895 -98 1519 -132 101 -100 +RAW_Data: 133 -166 691 -100 8965 -4740 131 -196 99 -162 231 -226 195 -524 263 -98 391 -66 97 -98 489 -98 2167 -66 129 -198 263 -66 397 -9262 65 -164 97 -2798 197 -830 265 -232 463 -228 425 -230 2667 -132 67 -164 197 -98 2023 -14336 99 -922 65 -1262 531 -100 65 -200 97 -200 197 -102 133 -134 99 -168 395 -100 133 -68 199 -100 855 -66 9821 -5296 65 -4678 229 -166 265 -134 131 -100 65 -166 167 -132 1217 -66 1351 -98 393 -164 487 -12590 99 -2428 131 -434 131 -330 65 -98 131 -298 163 -66 229 -232 559 -66 1805 -66 3565 -100 4163 -4266 67 -3536 65 -824 229 -132 399 -166 67 -100 231 -166 497 -1526 99 -560 231 -134 133 -68 665 -230 291 -230 4463 -66 199 -100 1419 -832 65 -200 65 -464 199 -866 265 -264 231 -100 331 -100 65 -100 131 -100 2415 -132 827 -168 1991 -3852 65 -1928 67 -2620 99 -560 65 -362 65 -198 493 -132 525 -360 231 -100 1017 -132 555 -198 825 -100 10151 -296 131 -698 131 -300 99 -502 99 -966 293 -264 97 -66 395 -430 65 -164 131 -96 97 -98 1617 -132 455 -132 1017 -16428 65 -164 97 -458 131 -66 163 -132 429 -98 463 -66 397 -68 97 -100 367 -100 829 -332 231 -134 1655 -4488 165 -102 165 -830 197 -458 163 -164 65 -132 97 -694 297 -2498 99 -302 165 -764 133 -166 131 -100 763 -98 657 -66 819 -132 229 -130 97 -64 361 -66 401 -66 2079 -5522 99 -2848 297 -298 165 -332 99 -562 99 -1280 99 -594 165 -264 491 -132 99 -164 393 -132 461 -100 465 -132 799 -12900 65 -1660 133 -2006 613 -792 669 -430 671 -436 219 -842 289 -810 259 -826 689 -390 699 -396 311 -782 311 -774 739 -346 737 -348 741 -354 327 -774 307 -772 349 -734 769 -314 345 -742 353 -740 327 -748 363 -750 763 -324 343 -756 347 -722 337 -756 767 -324 775 -334 745 -338 777 -310 343 -766 739 -330 767 -548 523 -4662 345 -760 745 -346 757 -324 347 -752 333 -754 333 -746 769 -326 779 -332 319 -768 309 -766 773 -324 777 -322 773 -330 355 -730 353 -730 353 -722 779 -332 349 -736 311 -768 323 -750 353 -742 759 -352 341 -738 347 -756 345 -720 769 -326 775 -334 745 -340 779 -310 355 -728 787 -346 739 -546 511 -4674 323 -746 781 -320 763 -328 351 -756 347 -726 339 -746 771 -324 779 -334 357 -724 349 -724 777 -326 779 -332 747 -338 351 -732 345 -736 347 -758 751 -320 371 -734 351 -732 343 -736 351 -756 751 -322 369 -736 349 -734 343 -736 771 -324 779 -324 775 -334 755 -336 357 -728 777 -312 775 -548 509 -4676 323 -742 +RAW_Data: 783 -320 759 -328 351 -758 345 -726 375 -722 767 -326 777 -332 357 -722 349 -740 781 -296 781 -336 745 -342 351 -732 353 -754 347 -718 769 -344 333 -756 323 -744 361 -718 365 -752 763 -320 345 -758 345 -734 349 -732 767 -346 761 -316 775 -322 773 -332 351 -734 769 -320 757 -548 513 -4668 347 -752 751 -322 765 -328 353 -756 347 -726 375 -714 773 -326 775 -334 355 -730 353 -724 783 -330 745 -338 777 -312 355 -728 353 -726 353 -756 765 -322 351 -722 345 -770 319 -760 325 -750 791 -320 343 -724 379 -726 335 -746 771 -324 775 -334 745 -340 769 -322 341 -768 741 -322 783 -520 563 -4658 325 -738 777 -318 765 -326 351 -758 347 -724 341 -758 769 -324 775 -332 351 -734 341 -734 773 -324 777 -320 775 -332 355 -724 347 -740 349 -740 777 -296 353 -756 347 -724 375 -724 337 -748 767 -324 349 -732 351 -730 345 -770 743 -324 783 -324 779 -334 745 -340 357 -730 775 -312 791 -508 541 -4664 323 -776 747 -320 767 -328 351 -734 353 -732 353 -766 751 -336 747 -340 357 -730 355 -726 777 -348 755 -310 791 -310 357 -728 355 -726 355 -758 755 -348 319 -758 341 -736 323 -780 319 -744 791 -320 341 -724 377 -724 339 -756 765 -324 775 -332 745 -340 779 -310 343 -764 735 -350 771 -516 527 -4664 345 -760 743 -346 759 -324 349 -752 333 -754 335 -746 767 -324 777 -334 351 -734 341 -734 773 -324 777 -322 775 -332 351 -734 341 -734 347 -754 749 -322 367 -734 351 -732 351 -754 347 -720 785 -314 333 -742 351 -740 361 -752 763 -322 773 -332 751 -334 745 -342 341 -764 739 -332 769 -546 521 -4664 347 -756 745 -346 757 -324 347 -752 333 -754 335 -748 767 -322 777 -332 355 -724 347 -758 741 -328 779 -334 753 -338 351 -732 343 -732 349 -756 753 -322 369 -734 351 -732 343 -736 349 -756 751 -322 371 -734 349 -734 343 -736 775 -324 779 -322 779 -332 745 -338 351 -732 767 -344 765 -512 549 -4650 343 -756 771 -326 769 -320 345 -722 379 -724 339 -744 771 -324 779 -334 349 -736 341 -734 771 -324 779 -322 775 -330 351 -734 343 -732 349 -752 751 -320 369 -734 349 -734 349 -756 333 -732 775 -324 347 -752 333 -746 337 -746 771 -324 777 -332 755 -338 747 -340 353 -732 755 -354 765 -512 543 -4646 351 -744 789 -322 773 -296 387 -724 347 -724 375 -724 771 -324 775 -332 351 -734 341 -736 771 -324 777 -322 775 -332 355 -724 347 -724 377 -736 743 -340 351 -732 343 -734 349 -758 325 -746 795 -288 373 -724 377 -732 351 -732 769 -320 +RAW_Data: 765 -354 759 -320 753 -352 335 -736 779 -320 757 -556 533 -4636 359 -734 779 -318 761 -328 349 -756 347 -742 347 -722 773 -326 777 -332 357 -724 349 -756 743 -326 781 -334 747 -338 353 -732 351 -720 383 -718 783 -312 333 -744 353 -740 363 -720 363 -752 763 -322 343 -758 345 -734 351 -732 765 -346 765 -296 801 -320 773 -298 353 -766 745 -338 779 -510 543 -4670 325 -742 777 -320 761 -328 353 -766 355 -722 349 -738 777 -330 747 -338 357 -728 353 -728 777 -348 741 -350 739 -350 355 -722 351 -720 381 -722 781 -314 341 -740 361 -720 363 -754 331 -748 767 -322 347 -732 351 -730 345 -770 743 -324 785 -324 777 -334 747 -338 353 -732 765 -350 769 -498 565 -4652 333 -746 767 -324 777 -334 355 -724 347 -726 377 -724 767 -324 777 -334 351 -734 341 -734 771 -324 779 -322 775 -332 355 -730 355 -732 353 -724 779 -330 351 -734 341 -734 347 -754 323 -742 795 -320 341 -724 379 -724 337 -744 771 -324 777 -334 745 -340 777 -312 357 -728 787 -310 779 -546 511 -4674 325 -738 779 -320 763 -328 353 -732 353 -766 355 -722 779 -328 747 -336 357 -724 349 -758 741 -328 779 -334 747 -340 353 -732 351 -720 383 -716 767 -318 341 -776 333 -748 335 -756 333 -744 769 -324 347 -732 355 -758 355 -722 755 -350 757 -348 741 -350 737 -352 353 -722 765 -354 759 -524 521 -4650 349 -758 751 -322 799 -296 353 -758 349 -724 375 -724 767 -322 775 -334 353 -734 353 -720 765 -344 767 -320 757 -326 351 -734 351 -758 347 -726 773 -326 347 -758 345 -722 339 -758 335 -746 769 -326 347 -734 341 -766 323 -744 781 -320 763 -328 783 -334 749 -338 355 -728 755 -342 779 -512 543 -4670 325 -742 779 -320 761 -328 351 -756 347 -724 377 -726 767 -322 777 -334 355 -732 355 -730 745 -340 757 -338 779 -312 355 -730 353 -726 351 -756 767 -322 351 -724 383 -720 345 -758 325 -740 777 -320 363 -722 341 -758 335 -746 769 -324 777 -334 745 -340 769 -322 341 -766 739 -324 781 -522 563 -4652 317 -778 747 -320 763 -328 353 -732 387 -724 347 -722 775 -326 781 -332 355 -724 347 -724 775 -326 781 -332 747 -340 353 -732 343 -736 353 -754 749 -320 369 -726 375 -724 335 -748 339 -756 767 -322 345 -736 351 -756 345 -724 775 -324 777 -332 753 -336 747 -340 341 -764 739 -330 769 -546 521 -4660 329 -766 777 -320 757 -326 349 -758 347 -724 373 -724 769 -324 777 -332 353 -732 343 -734 777 -326 773 -320 775 -332 355 -722 349 -732 351 -732 765 -346 339 -754 +RAW_Data: 321 -744 363 -718 363 -748 765 -324 345 -734 349 -732 345 -768 745 -322 783 -326 779 -332 747 -340 353 -730 769 -352 753 -524 557 -4630 351 -740 755 -322 803 -296 387 -722 347 -724 377 -724 769 -322 779 -332 357 -722 349 -724 773 -326 779 -334 747 -338 353 -732 351 -754 345 -722 783 -312 333 -744 353 -744 363 -718 365 -754 761 -322 343 -736 351 -732 349 -756 751 -352 755 -346 753 -326 773 -322 345 -756 743 -326 781 -534 537 -4638 359 -738 779 -320 759 -326 351 -756 347 -726 341 -746 771 -326 777 -334 351 -734 341 -734 777 -324 777 -320 773 -332 355 -732 355 -730 355 -728 777 -310 357 -728 353 -758 341 -732 347 -752 751 -322 367 -724 375 -712 375 -724 767 -324 779 -332 753 -336 747 -342 353 -732 765 -344 763 -516 543 -4650 351 -756 753 -352 753 -314 333 -748 351 -744 361 -752 761 -320 773 -332 355 -724 347 -724 777 -326 781 -332 747 -338 351 -732 343 -734 349 -758 751 -322 371 -724 377 -722 335 -746 339 -746 773 -324 349 -734 353 -734 353 -756 743 -328 781 -336 747 -340 757 -340 355 -730 757 -340 769 -516 549 -4642 353 -758 755 -320 767 -330 353 -758 347 -726 339 -748 771 -324 779 -334 353 -732 343 -732 773 -324 777 -322 775 -332 355 -730 355 -724 349 -758 743 -324 351 -758 347 -724 339 -748 373 -736 747 -336 357 -726 357 -726 355 -726 797 -324 755 -320 783 -316 767 -320 367 -724 773 -326 781 -530 535 -4632 359 -738 781 -318 761 -328 351 -734 387 -724 347 -726 773 -326 779 -332 355 -730 355 -732 745 -342 777 -312 777 -314 357 -726 353 -758 353 -718 789 -322 353 -720 343 -734 349 -760 355 -718 791 -320 343 -724 377 -726 339 -748 771 -324 781 -330 747 -338 777 -312 343 -766 745 -348 757 -514 543 -4678 347 -716 769 -346 757 -324 347 -746 337 -760 333 -758 763 -320 775 -330 357 -730 355 -730 747 -342 777 -310 777 -348 319 -758 341 -734 347 -752 749 -320 371 -722 377 -724 337 -756 333 -748 767 -324 347 -734 349 -732 345 -766 775 -320 755 -328 783 -332 747 -338 357 -730 779 -310 779 -512 543 -4642 359 -738 779 -318 763 -328 351 -734 353 -734 353 -764 747 -336 757 -338 355 -728 355 -726 789 -310 769 -350 733 -342 339 -758 323 -744 363 -746 765 -322 345 -756 345 -742 345 -742 345 -742 743 -328 351 -764 319 -764 353 -728 751 -340 777 -346 739 -346 737 -352 351 -722 767 -350 755 -89978 97 -228 99 -392 97 -364 131 -364 261 -98 491 -198 265 -200 595 -166 2189 -134 1781 -98 131 -66 +RAW_Data: 4895 -3912 129 -1214 65 -132 99 -266 131 -232 201 -200 65 -100 199 -166 265 -100 263 -998 165 -198 97 -298 329 -198 563 -870 99 -166 299 -332 231 -98 163 -98 99 -164 591 -66 1607 -98 327 -11988 65 -134 131 -162 193 -1974 97 -1982 65 -300 265 -230 493 -66 99 -17484 65 -458 165 -362 99 -664 131 -1126 99 -100 99 -168 431 -98 133 -498 197 -66 2277 -100 133 -66 533 -8150 97 -328 97 -100 291 -98 1015 -96 3367 -168 133 -100 1163 -66 667 -66 393 -66 425 -66 5567 -7622 659 -366 199 -330 361 -66 129 -494 131 -264 367 -334 165 -1022 165 -66 133 -166 199 -432 595 -66 131 -98 1363 -6728 65 -2332 65 -7664 99 -1682 99 -196 163 -924 65 -330 65 -196 589 -132 229 -228 229 -198 1909 -100 1477 -66 701 -66 5773 -4316 163 -232 131 -194 65 -392 229 -458 165 -1216 461 -562 263 -462 131 -166 97 -528 97 -394 131 -558 367 -100 233 -68 133 -366 167 -166 267 -66 333 -132 2219 -168 431 -100 1461 -66 1433 -100 5641 -4648 65 -802 97 -794 65 -2290 133 -266 167 -100 165 -334 365 -134 263 -168 65 -266 67 -132 365 -100 599 -168 297 -98 567 -66 331 -198 65 -100 599 -100 1065 -100 5343 -4728 99 -1760 165 -1430 165 -198 99 -202 299 -294 197 -198 129 -64 131 -328 229 -100 357 -464 197 -100 565 -134 133 -102 401 -134 601 -164 129 -66 895 -168 397 -198 397 -100 197 -68 9979 -3582 65 -300 99 -400 63 -694 131 -798 133 -898 167 -200 131 -134 229 -264 197 -360 65 -264 97 -100 763 -100 295 -166 867 -68 65 -132 559 -12458 65 -2028 97 -132 163 -166 129 -100 195 -262 97 -296 263 -130 991 -66 1361 -134 661 -66 361 -66 197 -1088 167 -336 65 -366 65 -794 165 -68 133 -100 131 -266 133 -100 65 -198 135 -366 65 -198 729 -68 995 -100 397 -134 97 -132 363 -232 431 -64 1573 -4672 63 -8966 99 -464 197 -828 165 -602 131 -360 295 -164 63 -66 625 -398 197 -100 2475 -66 367 -132 133 -100 6651 -4462 99 -3092 101 -100 99 -234 99 -198 233 -66 165 -300 165 -132 65 -100 99 -264 65 -598 429 -2318 399 -200 67 -198 133 -166 199 -164 65 -132 165 -98 263 -64 2613 -166 697 -66 6631 -6580 131 -890 65 -66 165 -166 165 -300 133 -368 265 -726 65 -98 161 -164 97 -296 131 -98 131 -988 65 -232 201 -132 165 -100 165 -300 229 -100 261 -268 1459 -132 1575 -364 461 -132 297 -332 8997 -9896 229 -134 265 -164 267 -300 299 -300 763 -134 1933 -100 465 -100 431 -98 199 -134 6761 -2074 65 -3566 65 -132 195 -166 +RAW_Data: 133 -462 67 -166 99 -100 265 -100 131 -364 925 -132 763 -700 231 -856 165 -100 299 -164 631 -166 231 -132 429 -134 463 -66 4979 -4996 165 -430 165 -502 99 -132 97 -1160 457 -100 261 -296 131 -134 201 -98 99 -100 363 -200 361 -134 363 -198 131 -1496 67 -264 329 -360 327 -132 163 -264 985 -68 565 -66 429 -66 263 -130 229 -134 8225 -200 101 -136 101 -368 265 -330 65 -598 195 -304 169 -268 101 -696 99 -1484 67 -1952 99 -1386 165 -66 233 -134 101 -164 65 -364 65 -298 2491 -132 367 -100 1295 -66 6535 -5946 65 -1186 97 -298 623 -426 99 -66 99 -66 559 -134 133 -168 331 -200 133 -132 133 -462 459 -1088 65 -264 131 -164 65 -98 493 -98 97 -198 723 -134 1283 -64 819 -66 459 -66 621 -14282 65 -398 97 -396 97 -366 131 -162 99 -602 165 -66 369 -134 363 -100 561 -134 1261 -100 99 -134 831 -132 8053 -3428 65 -2474 65 -1484 265 -196 131 -98 197 -230 225 -196 97 -232 65 -234 795 -232 397 -234 335 -100 1425 -66 329 -68 527 -134 595 -100 165 -68 165 -200 329 -66 233 -68 889 -64 6761 -1518 97 -5252 133 -1660 65 -528 131 -292 97 -66 165 -66 293 -98 329 -164 97 -130 97 -260 627 -68 1533 -132 867 -132 5585 -6044 97 -1858 99 -132 65 -264 229 -198 97 -924 131 -2698 65 -362 527 -66 263 -100 963 -164 231 -132 295 -166 1093 -66 167 -100 635 -100 165 -68 133 -168 495 -100 299 -100 4855 -6142 65 -1458 97 -134 135 -66 267 -598 131 -168 201 -266 165 -66 133 -232 593 -68 131 -200 97 -198 553 -200 597 -66 1261 -132 2119 -66 199 -168 199 -230 1975 -4282 65 -8382 63 -3286 65 -460 65 -164 97 -100 97 -198 293 -198 63 -326 361 -164 297 -198 1985 -166 297 -100 431 -200 233 -66 65 -68 329 -168 8161 -5090 99 -64 97 -398 67 -2510 263 -1116 65 -230 161 -66 689 -130 129 -132 131 -426 3359 -98 3431 -8782 97 -930 67 -920 97 -786 565 -198 163 -66 461 -198 3347 -164 231 -11298 419 -750 715 -378 721 -360 317 -774 333 -774 305 -782 735 -360 745 -336 315 -768 313 -772 747 -360 741 -356 735 -362 317 -752 347 -752 345 -750 739 -328 347 -756 345 -754 345 -718 339 -772 743 -338 349 -734 349 -754 345 -756 749 -334 737 -354 753 -326 775 -336 347 -736 769 -344 733 -554 507 -4680 351 -722 761 -354 757 -352 317 -760 325 -740 351 -742 757 -354 739 -362 319 -756 347 -756 741 -326 779 -334 745 -340 355 -726 353 -758 319 -758 767 -318 353 -758 311 -754 345 -758 325 -740 777 -322 363 -722 +RAW_Data: 337 -756 337 -756 767 -322 775 -332 747 -338 777 -310 355 -760 739 -350 735 -550 547 -4640 353 -750 751 -320 767 -328 353 -758 347 -724 339 -758 767 -322 777 -332 351 -734 341 -734 773 -324 777 -322 773 -332 355 -732 355 -730 355 -728 753 -338 357 -728 355 -724 355 -758 355 -722 765 -320 351 -754 313 -768 319 -766 753 -352 769 -330 747 -336 779 -310 357 -726 779 -332 747 -540 537 -4670 323 -740 779 -320 761 -328 351 -758 347 -724 375 -724 769 -322 775 -332 351 -734 343 -732 771 -326 777 -322 775 -330 357 -722 347 -726 377 -734 745 -338 353 -732 343 -734 349 -756 325 -744 795 -320 341 -726 377 -724 339 -756 765 -322 777 -332 747 -338 777 -310 343 -764 771 -296 769 -548 521 -4660 329 -768 777 -316 759 -326 351 -758 347 -740 347 -726 771 -324 779 -334 355 -722 349 -724 775 -326 777 -334 747 -340 353 -732 343 -736 351 -756 751 -322 367 -736 351 -732 343 -736 353 -754 751 -322 367 -744 347 -724 339 -746 771 -324 777 -334 745 -340 769 -320 353 -752 769 -314 787 -518 545 -4642 351 -722 789 -310 765 -318 355 -754 337 -758 335 -746 769 -324 775 -334 353 -724 349 -724 773 -326 779 -336 755 -336 353 -732 343 -734 353 -752 753 -320 367 -722 343 -758 337 -746 337 -758 765 -322 345 -756 347 -724 339 -756 767 -324 775 -334 745 -338 777 -312 343 -764 769 -296 769 -548 523 -4650 347 -744 779 -320 763 -330 351 -758 347 -724 341 -758 767 -324 777 -330 351 -734 341 -736 777 -324 775 -320 773 -332 355 -730 357 -722 347 -726 773 -328 349 -756 347 -722 339 -746 375 -734 747 -338 357 -728 353 -728 353 -758 765 -322 757 -352 753 -314 785 -316 345 -752 765 -322 775 -530 535 -4634 359 -736 781 -320 759 -326 351 -756 347 -726 339 -758 769 -324 775 -334 351 -734 341 -734 777 -326 775 -320 773 -298 389 -730 355 -724 347 -722 775 -326 349 -758 345 -724 341 -744 375 -712 773 -324 349 -758 347 -724 339 -756 769 -322 775 -332 745 -340 769 -320 351 -752 771 -314 753 -554 513 -4672 343 -732 771 -318 783 -324 349 -756 347 -724 339 -746 771 -326 775 -336 351 -734 341 -734 777 -326 773 -324 775 -330 355 -724 347 -724 377 -722 767 -324 347 -734 353 -760 353 -722 351 -722 791 -322 351 -720 349 -740 351 -742 757 -352 773 -296 781 -334 755 -338 355 -728 777 -312 777 -544 513 -4674 325 -742 779 -320 759 -328 353 -756 347 -724 341 -758 767 -324 777 -332 357 -730 355 -730 747 -340 781 -310 757 -340 353 -732 343 -738 +RAW_Data: 351 -754 753 -320 369 -724 341 -770 351 -734 341 -732 771 -324 345 -752 333 -748 337 -746 769 -324 777 -332 747 -338 755 -340 353 -732 765 -354 761 -524 515 -4676 319 -764 755 -322 767 -330 351 -758 347 -724 341 -746 773 -324 779 -332 353 -734 343 -732 769 -318 783 -324 779 -332 351 -734 341 -734 347 -754 753 -320 365 -744 347 -724 339 -748 337 -746 773 -324 349 -758 347 -724 339 -744 771 -326 777 -332 745 -340 769 -320 343 -766 741 -322 783 -554 529 -4624 349 -744 779 -320 761 -328 353 -758 347 -724 341 -756 769 -324 775 -334 355 -722 349 -756 741 -326 779 -334 747 -338 353 -732 343 -734 353 -756 751 -322 369 -724 341 -758 337 -746 337 -748 769 -324 349 -732 341 -768 325 -742 781 -322 759 -328 783 -334 747 -338 357 -728 777 -346 755 -510 543 -4664 323 -778 747 -320 763 -330 351 -758 347 -724 339 -746 773 -324 779 -336 351 -734 341 -734 771 -324 777 -324 775 -332 355 -724 347 -724 377 -724 769 -324 347 -756 345 -734 351 -732 343 -732 773 -316 353 -754 337 -746 337 -756 767 -324 777 -334 745 -340 755 -338 353 -732 767 -342 767 -512 549 -4654 345 -754 769 -296 803 -320 341 -724 379 -724 337 -746 769 -326 777 -332 353 -734 341 -732 775 -324 779 -322 773 -332 351 -734 341 -736 323 -780 753 -320 367 -722 375 -722 337 -746 339 -768 747 -336 353 -732 343 -732 351 -754 753 -320 801 -330 745 -338 777 -310 341 -764 767 -318 775 -516 525 -4682 315 -780 749 -320 767 -328 351 -732 353 -758 347 -740 777 -330 749 -336 357 -730 355 -726 779 -310 791 -310 777 -312 357 -726 353 -756 353 -720 765 -354 333 -736 351 -738 359 -716 363 -754 765 -322 343 -724 379 -732 351 -732 767 -314 799 -296 767 -322 801 -296 383 -734 767 -316 763 -522 539 -4680 341 -734 775 -326 773 -322 345 -722 377 -726 337 -756 769 -322 775 -332 351 -736 353 -718 767 -344 765 -320 761 -326 349 -758 347 -740 347 -726 771 -326 347 -758 345 -724 339 -746 375 -734 747 -338 353 -732 341 -734 349 -758 751 -322 767 -330 779 -336 779 -308 357 -726 779 -334 747 -538 539 -4662 317 -780 749 -320 765 -328 353 -732 389 -722 347 -724 775 -326 777 -334 355 -730 355 -724 779 -330 747 -338 777 -310 343 -732 349 -746 353 -740 759 -320 373 -736 349 -734 343 -734 349 -758 755 -320 371 -734 349 -732 343 -760 773 -296 769 -322 801 -328 747 -336 357 -724 781 -332 747 -536 539 -4662 323 -744 781 -318 763 -328 353 -758 347 -726 339 -756 767 -324 +RAW_Data: 777 -334 349 -734 343 -734 777 -326 773 -320 773 -330 355 -724 347 -724 379 -722 769 -324 347 -756 345 -734 351 -732 343 -734 777 -324 347 -752 333 -746 337 -746 769 -326 777 -334 755 -336 779 -308 343 -732 783 -346 755 -514 543 -4646 349 -754 751 -350 753 -346 331 -758 323 -744 361 -754 763 -320 775 -296 389 -732 355 -722 777 -330 747 -336 755 -338 353 -732 351 -720 383 -716 771 -346 329 -756 319 -742 363 -718 365 -752 765 -322 343 -756 347 -732 351 -732 769 -310 799 -316 755 -326 777 -334 353 -732 767 -316 761 -552 545 -4640 345 -732 771 -324 781 -324 347 -758 345 -722 341 -756 767 -326 775 -334 351 -734 341 -736 775 -326 773 -322 771 -332 355 -732 355 -724 349 -724 775 -326 349 -756 345 -724 339 -746 375 -736 745 -338 357 -728 353 -726 353 -758 765 -322 755 -352 753 -348 749 -318 347 -752 765 -322 775 -530 537 -4632 359 -738 779 -320 759 -328 353 -756 347 -726 339 -758 767 -322 777 -334 351 -734 341 -734 771 -318 779 -324 777 -332 357 -730 355 -730 357 -724 777 -332 349 -734 341 -734 323 -782 321 -742 793 -290 373 -722 379 -734 355 -730 747 -340 777 -310 777 -350 739 -348 319 -760 769 -322 767 -520 553 -4646 323 -778 749 -320 767 -328 351 -758 347 -726 339 -756 769 -324 775 -332 353 -734 341 -734 773 -326 775 -322 775 -300 353 -764 309 -766 347 -752 749 -322 367 -722 341 -746 375 -736 351 -732 767 -318 341 -742 353 -738 327 -778 761 -322 773 -332 747 -338 777 -310 355 -728 779 -348 739 -550 511 -4674 323 -746 779 -320 763 -330 351 -758 347 -740 347 -742 743 -330 781 -334 357 -730 357 -728 751 -340 755 -340 769 -318 343 -766 317 -760 325 -778 759 -322 343 -734 351 -732 345 -766 317 -760 755 -322 369 -736 351 -732 353 -756 757 -322 755 -352 753 -346 755 -326 343 -750 767 -322 771 -530 537 -4664 325 -740 777 -320 761 -328 351 -758 347 -726 341 -756 767 -324 777 -332 351 -734 341 -736 775 -326 775 -320 773 -330 351 -734 341 -736 323 -780 749 -320 367 -724 375 -722 337 -744 339 -746 771 -326 347 -758 345 -722 373 -726 767 -324 775 -332 753 -338 745 -340 353 -732 765 -352 753 -526 553 -4646 355 -730 753 -340 779 -312 357 -726 353 -726 353 -758 765 -322 765 -356 317 -758 345 -722 781 -346 755 -326 771 -320 345 -724 377 -726 337 -746 769 -326 347 -732 355 -758 355 -722 351 -754 757 -310 343 -760 325 -746 363 -752 763 -322 771 -332 753 -336 747 -338 353 -732 767 -344 763 -514 +RAW_Data: 541 -4674 313 -768 779 -320 755 -324 349 -734 353 -758 347 -722 773 -326 777 -334 351 -734 341 -734 773 -324 777 -320 775 -332 355 -724 347 -724 379 -732 747 -340 353 -732 343 -732 349 -760 323 -746 795 -290 373 -724 377 -724 337 -746 769 -324 777 -332 747 -338 769 -320 341 -766 743 -322 783 -522 561 -4630 359 -736 777 -320 757 -328 351 -758 347 -724 341 -758 767 -324 779 -300 383 -734 341 -734 779 -296 803 -320 773 -298 387 -724 347 -740 347 -726 775 -322 349 -756 345 -742 347 -724 341 -756 769 -324 345 -724 377 -736 351 -732 765 -312 797 -320 753 -326 777 -334 353 -732 765 -316 761 -536 541 -4648 345 -766 775 -290 785 -324 349 -758 347 -726 339 -746 771 -324 779 -332 353 -730 343 -734 777 -324 777 -322 775 -332 355 -730 357 -724 347 -724 773 -328 349 -758 347 -734 351 -732 343 -732 777 -324 347 -754 335 -758 333 -748 765 -322 775 -332 745 -340 757 -340 355 -728 779 -312 777 -548 511 -4672 323 -742 781 -320 761 -328 387 -698 387 -698 389 -722 781 -296 781 -336 357 -726 349 -732 779 -312 767 -356 759 -322 351 -722 359 -736 351 -740 755 -320 373 -726 375 -726 337 -754 333 -748 767 -324 347 -724 379 -724 339 -758 765 -322 779 -332 745 -340 777 -310 357 -728 775 -348 757 -512 545 -4640 359 -738 779 -320 759 -328 353 -756 347 -726 375 -726 765 -324 777 -300 389 -722 347 -726 775 -324 779 -332 747 -338 353 -730 345 -734 351 -754 753 -322 369 -734 351 -732 343 -728 349 -744 781 -320 365 -726 339 -758 335 -748 769 -324 777 -332 745 -340 779 -312 357 -730 777 -310 795 -510 541 -4666 315 -746 783 -320 763 -326 355 -758 347 -726 339 -748 769 -326 777 -334 353 -730 343 -732 773 -324 779 -322 777 -298 389 -724 347 -726 375 -724 767 -324 347 -724 379 -724 339 -746 339 -760 765 -324 345 -724 377 -726 339 -758 765 -322 777 -332 747 -338 779 -310 341 -734 771 -346 757 -546 543 -4620 383 -716 769 -346 757 -324 345 -752 333 -750 335 -758 765 -320 775 -332 353 -724 349 -756 741 -328 777 -334 753 -338 351 -732 343 -732 349 -756 751 -322 369 -724 341 -746 375 -736 349 -734 769 -322 351 -720 345 -734 349 -762 755 -322 767 -328 781 -334 747 -342 357 -728 777 -346 741 -548 511 -4670 323 -744 779 -320 763 -330 351 -758 349 -724 339 -758 767 -324 775 -330 353 -732 341 -736 769 -324 779 -320 777 -330 357 -724 347 -740 347 -724 775 -324 347 -756 345 -724 341 -744 341 -770 743 -338 353 -732 343 -734 +RAW_Data: 349 -758 753 -320 767 -360 747 -336 777 -308 357 -726 789 -312 777 -79086 67 -500 65 -496 63 -458 131 -856 133 -438 131 -202 99 -398 263 -328 195 -198 363 -100 395 -100 961 -66 393 -132 365 -102 199 -66 5167 -4206 99 -640 99 -726 65 -1814 293 -98 163 -98 97 -164 327 -64 259 -132 231 -428 97 -232 197 -134 65 -398 197 -1124 99 -462 465 -68 397 -132 303 -66 665 -66 3199 -66 1825 -5202 65 -8960 231 -460 131 -396 97 -166 99 -132 133 -330 99 -328 425 -166 133 -100 199 -68 131 -168 133 -66 3381 -66 13735 -270 199 -134 99 -166 133 -302 1029 -100 165 -200 201 -198 301 -132 1467 -66 501 -68 367 -168 1925 -66 495 -98 299 -66 455 -262 5365 -6980 65 -66 129 -462 65 -130 97 -98 327 -394 65 -98 359 -232 97 -330 295 -430 365 -2796 263 -134 199 -198 291 -164 3701 -66 9467 -9052 99 -802 329 -200 197 -64 129 -294 131 -300 891 -266 133 -166 329 -102 99 -132 2173 -64 161 -98 6545 -8052 129 -562 429 -100 563 -168 335 -134 133 -98 133 -232 363 -66 299 -66 1129 -164 397 -464 561 -68 795 -100 1687 -13310 133 -1490 101 -170 231 -66 199 -66 197 -134 65 -334 365 -134 297 -66 959 -100 293 -198 795 -362 231 -100 365 -166 365 -100 4957 -7546 231 -268 397 -232 131 -398 231 -730 65 -434 199 -1492 65 -728 65 -528 97 -164 229 -66 131 -64 197 -132 391 -164 2959 -66 65 -12414 65 -1126 65 -534 67 -400 231 -366 99 -134 65 -166 67 -166 167 -166 167 -298 335 -232 299 -66 1697 -66 233 -134 67 -166 529 -100 67 -66 7763 -728 99 -932 99 -1296 197 -100 99 -630 65 -794 165 -634 165 -130 97 -198 199 -132 133 -198 99 -262 2175 -66 97 -132 1645 -164 563 -12852 131 -1032 67 -1730 99 -166 199 -236 99 -300 263 -196 293 -198 357 -66 1263 -100 1363 -98 725 -134 231 -66 627 -66 5743 -4102 263 -230 131 -262 131 -66 67 -198 99 -498 165 -364 131 -1000 263 -100 101 -464 197 -198 399 -98 1029 -166 133 -198 99 -300 131 -100 199 -432 99 -230 1829 -66 429 -134 131 -66 131 -230 133 -394 395 -196 397 -3828 63 -960 65 -458 197 -198 129 -1480 97 -1948 97 -428 195 -66 229 -426 197 -426 1185 -64 1181 -132 633 -166 363 -170 167 -66 329 -232 4851 -4466 67 -930 65 -434 165 -268 65 -166 133 -234 133 -330 261 -132 199 -68 99 -134 99 -68 65 -234 99 -2214 63 -132 361 -164 297 -98 227 -456 163 -130 127 -228 397 -13124 131 -3210 365 -722 163 -360 97 -362 427 -66 395 -66 163 -132 6621 -9772 +RAW_Data: 231 -332 265 -132 665 -66 531 -232 693 -66 363 -66 1253 -132 621 -428 599 -98 7479 -6028 99 -296 97 -654 99 -724 97 -328 97 -98 435 -166 295 -264 129 -132 589 -66 627 -66 397 -98 199 -66 199 -1528 297 -6504 63 -900 65 -1130 133 -166 663 -398 395 -298 131 -100 599 -98 67 -66 695 -166 403 -164 1807 -200 4679 -3774 131 -130 99 -98 457 -2774 231 -396 525 -262 197 -294 97 -68 163 -134 331 -298 365 -166 99 -634 99 -362 165 -1196 163 -166 231 -98 267 -132 197 -300 2521 -100 895 -100 401 -134 503 -12428 163 -362 231 -396 165 -166 199 -66 99 -232 167 -134 197 -100 99 -330 365 -168 1927 -334 231 -198 495 -66 8407 -5784 229 -1188 163 -492 65 -336 99 -602 99 -100 365 -200 431 -334 331 -100 1791 -134 397 -132 65 -166 359 -66 297 -100 465 -68 1097 -4396 67 -564 431 -298 99 -132 429 -198 1053 -66 327 -98 723 -12552 65 -1232 199 -864 131 -1890 99 -132 133 -134 99 -66 233 -100 165 -628 65 -132 2857 -66 295 -166 631 -100 197 -100 4333 -1082 131 -1476 359 -366 97 -166 99 -100 231 -166 861 -100 529 -98 863 -200 99 -102 99 -132 493 -132 325 -100 8365 -2990 65 -302 133 -964 97 -1100 65 -266 867 -166 99 -100 131 -134 565 -166 695 -100 901 -100 497 -66 401 -12558 63 -830 99 -100 131 -694 99 -498 129 -200 99 -402 99 -266 231 -66 199 -134 65 -200 99 -132 133 -68 167 -166 67 -168 599 -202 1633 -66 723 -100 1547 -64 7133 -5950 97 -522 97 -428 97 -554 65 -2048 133 -132 363 -66 297 -234 2847 -164 791 -132 301 -3286 131 -6472 99 -364 99 -1096 199 -590 65 -362 131 -66 133 -134 299 -98 369 -66 2063 -166 99 -132 599 -100 7507 -8234 199 -232 97 -168 201 -530 229 -132 163 -66 427 -68 165 -100 1981 -66 463 -100 65 -166 1017 -132 6219 -6002 131 -64 165 -428 199 -432 131 -530 133 -200 67 -11500 65 -6344 65 -1958 165 -100 97 -664 65 -334 99 -730 331 -236 367 -168 329 -200 395 -66 131 -98 527 -68 99 -132 1493 -66 197 -14856 199 -1364 197 -132 165 -366 163 -234 65 -98 131 -428 65 -98 65 -232 2273 -164 553 -392 6131 -6662 233 -832 231 -432 63 -1328 263 -300 131 -866 197 -926 65 -166 65 -232 227 -98 263 -198 131 -164 65 -166 791 -100 525 -98 361 -198 365 -132 859 -66 329 -228 529 -7030 131 -620 97 -164 163 -132 131 -66 195 -100 163 -394 229 -262 131 -66 131 -198 527 -100 133 -400 133 -166 99 -1232 65 -134 197 -66 131 -232 431 -596 131 -166 2673 -134 295 -166 +RAW_Data: 5357 -11284 99 -1290 65 -134 1501 -200 263 -100 325 -132 399 -166 1997 -15232 131 -1320 99 -168 65 -466 65 -134 65 -100 165 -98 97 -196 425 -134 331 -132 1491 -168 395 -134 299 -100 1519 -12916 99 -998 197 -794 131 -1654 165 -100 97 -362 163 -66 163 -230 231 -434 497 -100 1499 -100 1495 -166 65 -298 229 -5848 99 -134 99 -8920 133 -1126 131 -234 231 -134 265 -66 131 -134 365 -166 829 -100 1793 -134 395 -12288 97 -2094 65 -430 65 -268 65 -400 65 -232 335 -166 199 -132 231 -100 2191 -100 929 -15146 299 -230 129 -788 591 -100 231 -100 165 -66 431 -100 65 -100 65 -166 133 -264 199 -134 595 -100 397 -132 927 -68 435 -166 267 -232 65 -166 99 -68 7469 -3932 99 -360 231 -2184 131 -166 293 -200 229 -262 99 -1020 65 -656 261 -66 229 -132 163 -66 97 -760 1663 -66 233 -166 397 -100 329 -132 955 -166 491 -14812 167 -1052 163 -528 131 -132 227 -66 659 -66 367 -100 2749 -68 1595 -66 10545 -1162 67 -3130 131 -1224 131 -66 99 -230 199 -166 529 -662 299 -18024 131 -298 201 -366 131 -100 65 -166 333 -166 65 -132 297 -164 395 -392 131 -166 9295 -9924 133 -1430 133 -334 397 -134 131 -68 65 -100 331 -100 197 -200 691 -166 329 -13826 131 -1978 131 -66 531 -66 265 -268 165 -136 165 -100 263 -166 467 -66 365 -102 467 -166 631 -136 67 -696 133 -396 97 -758 165 -3180 131 -362 163 -132 63 -164 461 -164 229 -164 197 -296 2399 -194 293 -13158 131 -1494 231 -524 327 -198 97 -394 297 -68 2025 -66 227 -296 365 -13564 65 -1380 131 -954 67 -658 429 -166 195 -66 65 -98 163 -130 823 -100 99 -64 757 -66 131 -98 99 -64 165 -132 11025 -21882 65 -1816 65 -822 229 -326 163 -100 723 -264 427 -66 329 -98 985 -68 1827 -66 133 -168 401 -98 301 -132 399 -100 1725 -4022 65 -1726 67 -732 99 -1070 99 -198 65 -494 197 -298 165 -100 131 -66 823 -134 299 -166 363 -102 363 -66 823 -132 7641 -4542 65 -834 65 -1220 67 -1164 133 -562 65 -698 67 -464 197 -736 263 -134 231 -332 99 -302 131 -264 361 -164 1245 -66 65 -66 395 -130 161 -98 65 -12312 65 -1324 65 -572 67 -166 101 -202 65 -702 395 -198 401 -100 333 -68 331 -66 133 -132 1281 -68 367 -132 433 -132 99 -66 8729 -2158 65 -3984 65 -1562 265 -166 161 -194 165 -132 497 -300 1055 -166 425 -100 599 -134 991 -66 6793 -5222 99 -1602 65 -328 129 -132 291 -330 99 -228 97 -196 97 -98 297 -624 297 -1186 165 -502 165 -498 97 -1086 525 -230 261 -292 199 -298 +RAW_Data: 2443 -100 8837 -7844 99 -300 101 -3474 65 -426 131 -786 131 -66 261 -66 131 -132 623 -198 431 -98 3805 -64 163 -132 4689 -2290 65 -5964 129 -996 197 -2760 165 -230 395 -300 263 -234 301 -166 2423 -68 367 -200 197 -134 429 -66 131 -100 231 -100 1455 -100 7041 -260 63 -2606 163 -262 97 -164 261 -166 161 -130 493 -200 799 -132 525 -132 129 -1222 97 -918 919 -68 65 -264 165 -168 3119 -64 97 -98 265 -66 293 -66 9961 -3892 97 -168 461 -362 165 -438 267 -100 531 -134 1659 -168 167 -66 101 -762 99 -330 231 -8514 65 -4398 99 -1312 99 -130 163 -294 163 -822 197 -270 429 -100 461 -66 329 -130 295 -330 829 -66 1461 -66 629 -66 233 -168 593 -66 13101 -102 133 -232 1405 -198 327 -296 331 -100 197 -200 365 -66 369 -98 1419 -230 527 -66 529 -302 5013 -3942 99 -1150 165 -298 65 -296 197 -822 133 -528 97 -230 163 -762 99 -666 65 -432 265 -332 201 -66 431 -198 267 -132 2459 -132 403 -100 1359 -68 7933 -3998 67 -4454 131 -198 97 -132 131 -198 295 -162 329 -298 1189 -132 327 -366 435 -66 503 -66 983 -132 4845 -5250 131 -132 133 -98 165 -134 101 -300 233 -332 231 -66 99 -132 99 -132 335 -198 165 -366 131 -1060 197 -402 99 -132 197 -168 67 -266 629 -330 65 -134 131 -336 721 -100 1501 -132 731 -66 1127 -132 5451 -4352 131 -854 163 -296 165 -432 99 -396 493 -132 131 -294 163 -1052 131 -14776 65 -5234 65 -164 129 -852 65 -98 131 -66 165 -164 97 -330 429 -66 165 -432 329 -98 491 -100 857 -198 889 -164 329 -66 295 -806 65 -722 99 -3564 199 -864 397 -400 231 -98 367 -100 797 -164 395 -98 393 -166 6901 -1552 65 -530 165 -66 99 -1186 65 -394 131 -198 99 -366 165 -198 99 -404 99 -2092 261 -264 331 -132 231 -360 297 -234 331 -64 2139 -100 399 -13226 99 -2394 65 -502 63 -394 163 -260 65 -66 131 -198 229 -132 99 -132 297 -296 263 -196 987 -132 265 -198 163 -12344 99 -696 65 -1292 65 -198 99 -894 163 -68 431 -102 65 -102 231 -166 199 -64 263 -164 359 -66 2025 -130 327 -98 11033 -788 99 -2174 65 -722 97 -100 163 -66 263 -362 789 -100 2493 -100 299 -200 7351 -4204 65 -1286 67 -1766 67 -566 99 -266 65 -200 67 -930 97 -134 429 -100 99 -132 65 -198 229 -262 163 -460 789 -98 361 -130 259 -66 657 -134 491 -166 197 -164 163 -166 5757 -6452 65 -864 65 -368 395 -230 165 -468 99 -796 133 -166 99 -134 101 -828 131 -600 163 -560 197 -328 263 -200 295 -66 97 -294 97 -198 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/gang_qi.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/gang_qi.sub new file mode 100644 index 00000000000..592f86095bf --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/gang_qi.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: GangQi +Bit: 34 +Key: 00 00 00 00 31 B7 74 C8 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub new file mode 100644 index 00000000000..9ecb1401637 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 215 -646 1237 -482 513 -1208 1205 -476 1231 -490 1177 -488 537 -1168 1205 -522 483 -1204 1217 -482 1183 -502 1207 -516 477 -1232 489 -1180 1213 -514 497 -1176 475 -1244 477 -2198 509 -1184 537 -1184 479 -1208 521 -1176 1219 -482 1189 -488 551 -1170 503 -1198 517 -1190 1201 -484 1225 -486 517 -1176 1181 -538 1195 -490 489 -1198 1209 -480 1219 -506 1185 -522 489 -1174 1253 -482 1173 -490 1239 -474 521 -1192 1201 -490 479 -1212 1205 -488 1237 -484 1183 -502 515 -1182 503 -1214 1209 -456 515 -1214 487 -1186 547 -2138 543 -1200 491 -1220 485 -1174 523 -1208 1173 -484 1257 -450 521 -1208 513 -1172 481 -1232 1197 -484 1223 -472 507 -1216 1211 -450 1261 -486 497 -1180 1203 -490 1205 -490 1213 -480 517 -1216 1197 -488 1209 -480 1207 -488 535 -1158 1195 -538 499 -1176 1227 -478 1183 -502 1229 -480 491 -1208 499 -1206 1203 -490 521 -1154 535 -1196 513 -2180 513 -1208 481 -1182 507 -1218 487 -1200 1209 -470 1221 -498 529 -1172 503 -1188 513 -1174 1243 -486 1201 -456 547 -1162 1219 -516 1177 -474 515 -1232 1171 -484 1227 -486 1193 -526 523 -1142 1253 -486 1201 -458 1241 -482 487 -1228 1203 -488 485 -1198 1199 -484 1257 -450 1225 -510 501 -1178 503 -1206 1181 -488 555 -1174 489 -1228 477 -2174 551 -1174 489 -1220 487 -1176 521 -1212 1175 -486 1257 -450 523 -1220 477 -1176 519 -1194 1209 -480 1217 -486 525 -1212 1169 -482 1235 -478 505 -1180 1237 -478 1195 -516 1203 -490 491 -1216 1207 -486 1223 -472 1213 -508 501 -1178 1233 -464 515 -1174 1241 -482 1201 -492 1221 -448 531 -1188 515 -1172 1251 -448 511 -1206 513 -1176 517 -2188 513 -1204 523 -1150 485 -1230 505 -1176 1217 -490 1203 -502 503 -1196 499 -1208 505 -1154 1245 -488 1195 -500 527 -1176 1233 -460 1205 -490 517 -1204 1185 -498 1225 -490 1211 -478 513 -1178 1207 -480 1209 -514 1203 -460 511 -1208 1203 -488 509 -1212 1181 -506 1211 -488 1229 -468 515 -1172 523 -1210 1175 -484 561 -1154 501 -1220 489 -2202 517 -1160 499 -1208 515 -1170 547 -1176 1197 -524 1173 -486 501 -1232 499 -1178 537 -1154 1205 -524 1205 -474 489 -1232 1193 -462 1237 -490 479 -1240 1197 -484 1203 -522 1173 -474 507 -1216 1205 -474 1231 -486 1201 -520 475 -1210 1209 -482 503 -1184 1217 -490 1207 -522 1183 -484 489 -1230 499 -1176 1231 -478 491 -1208 503 -1182 515 -2198 481 -1222 485 -1214 517 -1182 501 -1212 1173 -520 1205 -482 485 -1216 485 -1210 501 -1172 1231 -506 1161 -528 493 -1206 1229 -476 1183 -504 513 -1178 1211 -512 1203 -486 1209 -482 511 -1178 1243 -478 1177 -548 1169 -490 505 -1216 1183 -486 549 -1174 1185 -536 1191 -488 1209 -482 511 -1178 511 -1206 1185 -536 497 -1176 475 -1242 479 -2198 +RAW_Data: 507 -1184 501 -1210 481 -1206 515 -1178 1211 -514 1197 -490 471 -1238 489 -1176 545 -1174 1205 -516 1171 -486 505 -1230 1171 -486 1251 -464 515 -1206 1193 -488 1243 -486 1185 -484 523 -1186 1199 -526 1165 -508 1215 -490 487 -1208 1199 -520 477 -1212 1199 -478 1219 -488 1195 -492 513 -1202 503 -1210 1171 -522 479 -1214 505 -1184 489 -2200 515 -1192 519 -1180 521 -1184 501 -1208 1207 -480 1203 -510 475 -1212 511 -1194 473 -1230 1209 -482 1199 -518 497 -1178 1199 -496 1209 -522 481 -1200 1219 -478 1187 -522 1211 -480 483 -1246 1181 -484 1217 -480 1185 -504 505 -1218 1183 -488 515 -1204 1213 -482 1187 -522 1211 -480 481 -1212 511 -1198 1187 -532 497 -1178 475 -1242 479 -2200 505 -1182 519 -1204 479 -1240 479 -1174 1245 -486 1195 -486 513 -1176 517 -1216 499 -1176 1231 -462 1209 -488 483 -1222 1179 -542 1195 -462 511 -1238 1169 -486 1233 -480 1199 -478 527 -1186 1193 -524 1181 -520 1213 -480 479 -1214 1205 -480 517 -1198 1211 -480 1233 -484 1197 -488 513 -1178 517 -1214 1195 -486 483 -1230 483 -1186 537 -2184 515 -1168 507 -1220 479 -1188 501 -1212 1209 -488 1209 -480 507 -1182 537 -1196 463 -1246 1177 -488 1209 -512 483 -1182 1237 -484 1185 -536 499 -1178 1217 -488 1177 -520 1205 -482 487 -1248 1189 -464 1233 -488 1205 -488 511 -1202 1183 -532 497 -1178 1201 -492 1205 -474 1217 -516 477 -1238 475 -1210 1205 -482 503 -1182 537 -1166 507 -2204 481 -1202 525 -1184 501 -1210 507 -1182 1211 -488 1203 -498 515 -1180 485 -1216 513 -1176 1209 -512 1173 -514 531 -1158 1189 -524 1185 -520 483 -1228 1177 -478 1223 -486 1193 -526 493 -1206 1197 -506 1179 -486 1247 -478 475 -1242 1181 -482 485 -1230 1209 -482 1201 -516 1195 -520 473 -1210 481 -1218 1175 -486 505 -1230 479 -1186 533 -2188 507 -1206 481 -1234 481 -1184 503 -1214 1183 -502 1211 -490 505 -1212 481 -1204 485 -1236 1179 -478 1217 -486 503 -1236 1179 -486 1209 -512 473 -1200 1209 -510 1165 -548 1173 -486 503 -1220 1183 -520 1215 -476 1171 -518 531 -1158 1229 -512 495 -1176 1197 -508 1183 -506 1195 -508 489 -1238 473 -1182 1247 -484 483 -1196 519 -1182 481 -2232 477 -1216 505 -1202 475 -1214 505 -1170 1235 -484 1183 -540 501 -1180 485 -1210 513 -1178 1205 -514 1175 -546 475 -1182 1227 -480 1185 -520 481 -1230 1179 -478 1221 -488 1191 -524 493 -1208 1217 -486 1171 -512 1201 -508 475 -1244 1175 -480 503 -1234 1183 -484 1217 -514 1157 -554 487 -1178 487 -1228 1191 -474 537 -1184 501 -1218 489 -2210 481 -1214 475 -1218 487 -1184 515 -1206 1195 -486 1205 -498 511 -1206 479 -1210 477 -1220 1201 -480 1221 -488 519 -1212 1175 -486 1235 -480 507 -1180 1219 -490 1197 -520 1181 -504 +RAW_Data: 473 -1248 1175 -488 1209 -512 1171 -546 477 -1188 1213 -492 515 -1170 1237 -484 1171 -544 1179 -478 507 -1216 513 -1160 1215 -496 513 -1208 503 -1198 463 -2238 485 -1230 485 -1190 463 -1244 489 -1184 1205 -520 1173 -516 509 -1176 513 -1190 485 -1216 1215 -490 1199 -530 461 -1208 1197 -508 1183 -484 551 -1174 1183 -538 1159 -500 1235 -488 477 -1202 1203 -516 1171 -554 1177 -484 489 -1232 1191 -462 543 -1180 1205 -518 1177 -486 1227 -506 487 -1172 513 -1206 1203 -484 535 -1194 463 -1246 485 -2200 479 -1188 499 -1216 513 -1176 511 -1214 1173 -514 1203 -492 473 -1244 481 -1206 517 -1174 1179 -542 1199 -462 517 -1204 1203 -480 1231 -484 519 -1182 1213 -478 1237 -476 1203 -484 497 -1212 1183 -504 1213 -490 1231 -478 489 -1178 1249 -484 479 -1210 1209 -482 1207 -516 1173 -488 499 -1214 515 -1172 1211 -516 481 -1208 511 -1172 507 -2206 489 -1208 503 -1184 547 -1178 473 -1246 1175 -488 1209 -510 475 -1212 477 -1224 487 -1214 1191 -520 1211 -480 481 -1214 1207 -482 1183 -508 519 -1184 1199 -532 1191 -486 1207 -484 511 -1174 1239 -478 1199 -518 1177 -486 519 -1216 1173 -486 541 -1198 1181 -520 1183 -486 1213 -514 481 -1184 537 -1198 1153 -560 461 -1210 485 -1212 513 -2198 501 -1176 505 -1212 479 -1206 515 -1176 1245 -486 1161 -520 481 -1230 483 -1180 537 -1194 1165 -540 1195 -486 481 -1230 1177 -514 1193 -486 497 -1246 1181 -486 1205 -512 1167 -514 531 -1194 1157 -526 1189 -520 1213 -480 481 -1216 1205 -482 487 -1250 1157 -520 1215 -480 1173 -516 533 -1192 463 -1248 1179 -476 511 -1226 485 -1180 489 -2202 513 -1192 519 -1182 519 -1184 505 -1198 1201 -488 1235 -464 515 -1176 519 -1212 483 -1220 1173 -486 1249 -496 483 -1176 1209 -516 1171 -520 515 -1194 1189 -508 1181 -504 1211 -482 513 -1210 1181 -480 1247 -484 1199 -486 519 -1178 1181 -544 501 -1180 1199 -496 1207 -486 1211 -514 483 -1186 535 -1190 1203 -480 495 -1212 487 -1208 481 -2242 461 -1210 505 -1182 515 -1210 483 -1212 1207 -480 1195 -506 507 -1212 475 -1218 485 -1196 1219 -488 1195 -488 547 -1174 1165 -530 1185 -520 483 -1230 1175 -480 1221 -488 1195 -540 499 -1180 1203 -494 1209 -488 1209 -482 485 -1216 1215 -490 485 -1214 1203 -486 1233 -484 1179 -490 547 -1178 473 -1250 1175 -474 519 -1208 481 -1214 509 -2190 515 -1174 485 -1248 497 -1174 475 -1242 1171 -520 1205 -480 509 -1214 501 -1176 505 -1204 1183 -506 1199 -508 487 -1210 1205 -486 1173 -552 485 -1200 1185 -510 1185 -504 1211 -482 511 -1198 1197 -490 1241 -484 1175 -512 507 -1204 1181 -516 481 -1214 1201 -506 1169 -516 1193 -520 483 -1210 483 -1206 1207 -516 479 -1174 549 -1176 489 -2208 479 -1212 509 -1200 +RAW_Data: 491 -1234 461 -1208 1203 -506 1181 -506 505 -1184 517 -1204 505 -1164 1221 -522 1181 -486 515 -1210 1181 -514 1175 -518 479 -1218 1185 -506 1213 -490 1197 -518 487 -1208 1183 -516 1171 -518 1209 -482 489 -1248 1157 -520 481 -1224 1169 -514 1189 -510 1183 -538 501 -1180 473 -1242 1173 -514 473 -1216 487 -1228 501 -2174 511 -1202 491 -1230 477 -1184 503 -1210 1207 -472 1215 -516 477 -1236 475 -1202 475 -1216 1209 -484 1217 -480 493 -1244 1187 -498 1213 -486 487 -1200 1189 -510 1183 -520 1185 -514 483 -1218 1175 -520 1189 -510 1183 -520 513 -1172 1215 -514 495 -1178 1203 -494 1205 -474 1213 -516 481 -1238 473 -1180 1241 -484 481 -1188 531 -1200 499 -2202 485 -1234 483 -1186 499 -1214 491 -1182 1205 -518 1175 -514 509 -1174 515 -1226 485 -1182 1215 -490 1183 -516 515 -1176 1205 -516 1171 -520 477 -1218 1183 -538 1191 -462 1235 -490 481 -1204 1215 -484 1203 -484 1229 -478 485 -1248 1161 -520 481 -1226 1169 -514 1225 -480 1169 -540 501 -1178 485 -1240 1173 -486 539 -1194 473 -1232 501 -2204 481 -1194 473 -1232 513 -1158 531 -1184 1207 -522 1173 -512 477 -1216 513 -1194 463 -1246 1179 -476 1239 -478 477 -1242 1181 -484 1213 -518 499 -1178 1219 -488 1177 -554 1177 -484 491 -1218 1185 -520 1179 -514 1177 -546 475 -1180 1231 -478 495 -1210 1197 -504 1183 -536 1183 -482 481 -1248 481 -1200 1219 -476 491 -1244 463 -1212 481 -2198 505 -1216 489 -1182 515 -1208 473 -1198 1219 -488 1191 -524 491 -1208 473 -1238 487 -1174 1239 -486 1171 -554 485 -1198 1191 -506 1183 -488 517 -1202 1181 -536 1191 -494 1197 -504 489 -1206 1205 -490 1173 -552 1175 -480 507 -1216 1177 -520 495 -1214 1175 -540 1167 -504 1219 -492 473 -1214 481 -1220 1175 -554 483 -1180 489 -1210 501 -2204 485 -1192 493 -1240 473 -1192 523 -1188 1193 -522 1187 -486 517 -1224 481 -1168 539 -1198 1181 -518 1181 -504 481 -1226 1169 -516 1225 -480 505 -1198 1207 -482 1203 -516 1193 -484 519 -1176 1201 -514 1199 -488 1233 -478 491 -1210 1199 -490 513 -1170 1217 -516 1207 -474 1207 -482 509 -1212 501 -1180 1197 -528 481 -1206 505 -1198 483 -2196 515 -1192 487 -1214 519 -1184 473 -1248 1177 -506 1217 -486 481 -1208 513 -1172 519 -1212 1165 -520 1207 -482 513 -1178 1209 -514 1177 -514 507 -1182 1227 -500 1175 -488 1211 -514 483 -1182 1231 -480 1201 -514 1197 -492 475 -1242 1175 -486 541 -1192 1165 -538 1193 -474 1229 -512 461 -1206 507 -1198 1193 -520 501 -1172 507 -1204 519 -2198 475 -1206 507 -1206 481 -1226 475 -1198 1207 -512 1169 -516 499 -1214 493 -1182 513 -1210 1205 -488 1173 -506 485 -1238 1173 -512 1189 -506 507 -1214 1195 -484 1209 -514 1171 -486 539 -1196 1155 -528 +RAW_Data: 1189 -500 1235 -484 481 -1206 1213 -482 513 -1210 1173 -508 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/hay21_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/hay21_raw.sub new file mode 100644 index 00000000000..beab064622a --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/hay21_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 99 -820 65 -230 65 -802 361 -852 131 -162 131 -298 133 -306 99 -198 129 -430 99 -732 197 -742 131 -302 197 -238 233 -132 99 -532 99 -168 101 -306 65 -832 133 -304 65 -300 65 -664 131 -198 133 -232 101 -234 99 -134 133 -404 65 -262 163 -654 131 -702 133 -864 131 -194 95 -390 131 -388 99 -1078 65 -260 97 -364 65 -194 161 -258 163 -228 97 -394 131 -336 133 -198 63 -358 97 -392 199 -164 65 -390 97 -426 99 -162 163 -326 193 -326 131 -456 131 -400 99 -700 133 -198 133 -400 131 -302 99 -202 65 -200 99 -1002 133 -236 169 -406 165 -372 99 -202 99 -334 165 -304 131 -332 133 -132 65 -464 133 -400 99 -298 67 -960 163 -400 133 -402 129 -166 101 -268 133 -432 133 -374 101 -366 101 -19558 129 -454 97 -23210 133 -688 129 -196 131 -162 65 -422 65 -132 163 -228 63 -194 65 -228 131 -292 129 -552 65 -986 65 -530 131 -164 99 -294 65 -796 65 -466 133 -200 131 -136 133 -1970 99 -1594 133 -966 65 -100 99 -300 99 -534 65 -664 99 -332 65 -198 97 -1086 131 -304 133 -402 167 -166 67 -996 99 -728 133 -268 131 -1684 163 -394 129 -690 65 -558 65 -132 131 -162 95 -456 97 -362 133 -168 67 -306 133 -202 67 -168 197 -338 167 -438 101 -362 97 -470 101 -402 65 -1058 131 -336 133 -1402 133 -402 165 -236 65 -432 99 -764 133 -470 65 -200 67 -166 131 -436 99 -398 99 -168 135 -902 65 -234 135 -200 199 -166 65 -628 197 -662 165 -694 65 -166 67 -564 65 -1072 99 -334 167 -168 131 -1058 131 -336 131 -370 99 -198 133 -462 131 -302 133 -438 67 -368 133 -1036 97 -634 165 -134 135 -670 99 -370 161 -690 65 -296 131 -1000 99 -436 133 -170 101 -404 99 -170 101 -270 67 -268 131 -302 131 -672 133 -234 65 -502 99 -604 65 -1260 99 -232 99 -964 131 -338 99 -200 65 -232 99 -168 135 -168 67 -204 67 -134 133 -370 99 -428 133 -234 135 -1128 163 -454 97 -362 163 -458 65 -164 99 -596 99 -268 131 -1562 65 -398 99 -402 163 -438 67 -368 65 -988 97 -622 131 -162 97 -390 133 -368 135 -402 133 -164 65 -438 131 -686 165 -334 99 -460 99 -368 167 -22538 65 -170 65 -766 99 -1098 165 -760 99 -364 65 -722 65 -2132 163 -326 163 -402 133 -266 161 -406 97 -168 101 -404 163 -168 67 -266 65 -334 65 -402 97 -494 65 -132 97 -462 99 -336 133 -334 131 -198 133 -672 131 -200 65 -1036 67 -1028 165 -702 99 -402 97 -1234 97 -196 63 -488 131 -658 65 -498 +RAW_Data: 97 -270 131 -566 65 -168 67 -336 67 -996 133 -300 67 -166 101 -702 99 -1202 131 -264 97 -590 163 -1680 99 -228 95 -162 97 -194 65 -886 99 -3586 65 -558 131 -1486 99 -634 65 -100 133 -132 67 -1134 97 -658 65 -1446 65 -564 133 -234 133 -372 65 -166 99 -1362 99 -332 97 -202 133 -1984 97 -198 65 -394 161 -23544 65 -334 99 -298 165 -570 167 -334 99 -198 67 -836 131 -290 65 -724 99 -298 165 -130 97 -264 127 -628 165 -266 131 -200 101 -234 135 -564 165 -234 99 -202 97 -368 131 -466 131 -1770 65 -326 165 -622 131 -296 133 -496 97 -1166 65 -1512 97 -1090 99 -534 165 -498 101 -336 99 -300 167 -302 65 -302 133 -1158 65 -166 99 -666 65 -736 233 -566 99 -502 99 -596 131 -168 135 -370 99 -1758 67 -3408 129 -1212 99 -690 65 -2674 67 -696 97 -200 65 -500 97 -338 65 -298 99 -234 165 -636 97 -724 65 -1424 97 -918 131 -198 65 -366 65 -562 99 -456 163 -1142 99 -394 165 -262 325 -230 97 -424 65 -460 131 -1150 129 -394 163 -356 197 -722 131 -920 97 -424 65 -1114 65 -262 97 -394 97 -888 97 -520 97 -21882 97 -2496 97 -164 97 -848 99 -47158 99 -234 99 -600 67 -1088 65 -918 63 -230 99 -162 127 -288 131 -164 97 -756 131 -392 99 -404 65 -400 67 -132 99 -302 131 -688 65 -982 131 -970 199 -372 101 -966 97 -130 129 -980 133 -1116 99 -162 95 -390 65 -428 163 -324 131 -266 99 -266 135 -1302 131 -470 199 -472 97 -358 97 -164 65 -230 99 -402 99 -398 99 -370 133 -372 99 -398 99 -166 129 -394 99 -266 67 -668 133 -1000 133 -734 131 -898 163 -324 131 -164 97 -424 99 -336 165 -328 163 -162 63 -946 129 -620 131 -130 129 -356 63 -296 131 -194 65 -390 97 -1692 129 -360 195 -390 127 -400 133 -200 65 -1034 133 -630 97 -162 129 -422 133 -1626 97 -368 133 -202 97 -1038 133 -498 133 -630 165 -730 97 -704 65 -134 97 -434 165 -462 99 -268 99 -628 165 -672 131 -1448 165 -604 167 -366 99 -398 131 -230 67 -438 65 -134 133 -432 67 -430 97 -232 65 -404 101 -426 131 -198 97 -756 131 -290 165 -298 99 -200 65 -1330 99 -702 131 -462 229 -294 161 -656 97 -196 97 -390 165 -1510 63 -2134 131 -328 129 -164 97 -726 99 -166 67 -134 97 -66 65 -730 99 -264 133 -266 165 -298 67 -1132 99 -1000 101 -200 67 -766 101 -368 165 -404 133 -832 99 -604 133 -640 197 -234 101 -134 99 -432 99 -100 133 -792 131 -168 101 -500 99 -298 101 -764 +RAW_Data: 133 -334 97 -196 97 -266 131 -202 167 -798 97 -966 99 -802 65 -396 65 -1062 101 -794 97 -770 131 -230 133 -728 99 -398 99 -268 133 -268 101 -1004 65 -964 97 -402 101 -438 131 -1168 97 -1494 65 -1446 99 -202 65 -566 131 -306 99 -198 65 -234 131 -470 63 -1092 165 -660 99 -266 131 -1006 67 -198 99 -3394 65 -696 199 -1100 65 -228 163 -230 131 -360 65 -228 97 -230 97 -164 97 -228 197 -164 135 -332 165 -166 133 -168 131 -1696 97 -1742 99 -556 131 -1180 65 -534 67 -794 65 -360 99 -2958 99 -532 65 -234 101 -166 67 -232 99 -734 99 -528 65 -432 65 -198 133 -66 197 -334 63 -924 131 -754 131 -1064 67 -298 99 -566 65 -330 65 -202 65 -998 65 -2024 163 -834 99 -366 65 -398 167 -5114 755 -4222 691 -310 657 -348 247 -724 257 -714 257 -726 283 -698 669 -302 683 -294 703 -312 285 -694 679 -290 679 -308 691 -318 657 -290 289 -702 677 -316 659 -324 297 -678 677 -316 691 -292 693 -4228 675 -318 667 -304 281 -692 289 -700 285 -694 281 -728 669 -302 683 -294 701 -312 285 -664 683 -324 673 -312 657 -316 691 -290 283 -702 677 -318 659 -322 295 -674 707 -284 697 -274 685 -4252 677 -318 663 -304 317 -688 259 -698 309 -696 283 -684 677 -316 661 -342 653 -294 309 -692 675 -318 659 -324 655 -344 657 -318 287 -698 683 -278 695 -310 285 -694 675 -318 663 -302 683 -4250 675 -320 659 -292 303 -682 291 -700 311 -662 317 -690 677 -318 661 -292 703 -310 269 -696 669 -316 691 -290 677 -310 689 -320 287 -682 685 -314 657 -314 285 -694 677 -316 663 -294 701 -4224 677 -318 661 -322 293 -676 289 -700 297 -696 281 -694 679 -294 701 -312 657 -316 285 -688 681 -314 695 -310 649 -294 701 -302 277 -700 681 -314 681 -290 285 -704 677 -318 659 -292 721 -4218 675 -318 693 -290 295 -680 291 -702 275 -698 313 -686 677 -318 663 -304 681 -294 277 -716 671 -318 659 -324 661 -344 655 -318 285 -698 685 -278 693 -312 285 -686 677 -316 661 -306 683 -4248 679 -318 663 -304 317 -656 289 -700 311 -662 317 -692 677 -318 663 -292 705 -310 271 -696 687 -312 657 -292 701 -312 657 -316 287 -686 677 -316 693 -310 287 -694 677 -318 665 -300 679 -4246 677 -318 665 -300 279 -692 289 -700 309 -662 317 -692 677 -318 667 -300 683 -294 277 -716 677 -320 659 -290 689 -310 689 -320 287 -682 687 -314 657 -314 287 -694 677 -318 663 -304 681 -4254 677 -286 701 -300 277 -684 289 -698 285 -726 277 -704 677 -294 699 -274 +RAW_Data: 693 -320 273 -696 681 -290 681 -308 691 -320 677 -290 295 -680 677 -318 695 -290 295 -678 675 -320 695 -258 721 -4222 677 -320 673 -294 301 -682 291 -696 311 -664 317 -692 673 -320 665 -300 681 -294 275 -718 677 -318 661 -290 687 -308 691 -320 285 -698 683 -280 691 -312 287 -694 677 -318 663 -144512 67 -362 131 -164 97 -456 99 -268 167 -674 133 -404 165 -334 165 -168 67 -404 133 -440 165 -304 165 -568 163 -298 97 -1054 65 -864 165 -302 101 -370 67 -764 97 -362 65 -690 99 -2320 99 -200 65 -1630 131 -564 99 -200 67 -302 65 -762 65 -366 99 -432 131 -134 131 -166 99 -366 133 -168 103 -668 99 -166 133 -304 133 -338 65 -200 99 -768 99 -368 131 -264 101 -402 65 -1062 131 -134 65 -434 133 -234 65 -396 99 -166 133 -366 65 -432 99 -766 167 -762 165 -1320 65 -490 97 -396 131 -464 97 -1346 99 -230 63 -420 97 -324 127 -822 131 -1558 65 -472 99 -500 65 -134 131 -434 65 -664 163 -470 133 -328 131 -1228 97 -164 97 -692 129 -936 133 -1882 99 -1620 63 -1118 97 -488 129 -728 99 -466 101 -468 65 -198 131 -202 65 -266 167 -630 65 -232 99 -1590 131 -666 97 -1294 99 -728 97 -564 67 -436 97 -22018 99 -1560 101 -200 65 -1896 65 -532 133 -202 97 -2158 133 -1600 65 -1016 65 -198 65 -260 67 -1154 65 -2234 97 -1188 133 -232 101 -336 99 -2400 99 -856 133 -884 97 -1312 129 -456 129 -746 65 -988 165 -324 99 -430 129 -164 99 -362 129 -360 131 -428 131 -598 65 -464 99 -468 131 -22500 65 -758 67 -2260 99 -164 99 -658 63 -228 163 -708 65 -730 99 -370 99 -728 97 -502 67 -298 165 -968 99 -198 65 -398 129 -882 131 -358 97 -22984 65 -688 97 -196 97 -718 131 -1210 129 -654 99 -170 135 -168 67 -338 135 -266 65 -500 65 -794 99 -100 99 -406 97 -234 65 -168 99 -406 63 -100 165 -200 99 -1298 131 -772 165 -704 65 -132 65 -1660 163 -360 133 -830 97 -724 99 -732 99 -426 63 -1356 165 -1180 131 -228 129 -720 167 -832 131 -262 163 -590 131 -400 99 -234 133 -166 67 -1598 99 -1428 65 -592 163 -286 131 -816 133 -266 167 -500 131 -698 133 -468 99 -402 99 -434 167 -200 165 -162 99 -304 101 -738 133 -336 99 -1800 165 -732 133 -722 67 -556 97 -326 97 -164 163 -458 99 -434 65 -166 65 -198 161 -1148 165 -914 99 -162 65 -130 165 -992 163 -952 65 -560 99 -826 65 -664 163 -620 197 -350 161 -292 161 -388 65 -494 65 -432 67 -202 101 -234 65 -722 +RAW_Data: 163 -196 63 -460 163 -468 65 -166 99 -334 129 -666 63 -230 63 -66 97 -328 129 -232 127 -494 129 -358 131 -260 197 -322 97 -628 99 -656 163 -358 99 -2128 133 -336 99 -1070 165 -368 99 -1004 65 -332 65 -330 163 -102 99 -2830 65 -1434 65 -800 65 -530 65 -1516 131 -400 97 -554 63 -300 99 -334 99 -1130 65 -896 99 -166 65 -1724 131 -270 99 -1068 131 -1168 97 -52402 99 -2098 99 -196 65 -454 65 -1644 97 -1754 65 -332 97 -794 131 -364 165 -330 99 -2220 129 -468 197 -1090 97 -360 65 -1746 63 -164 127 -784 131 -1284 65 -396 65 -390 97 -422 65 -428 97 -592 97 -1312 65 -694 131 -266 67 -732 97 -460 195 -360 65 -982 97 -2244 133 -472 99 -1096 97 -1762 65 -1664 131 -134 131 -1192 97 -1736 131 -204 99 -668 99 -602 165 -654 163 -324 161 -328 129 -960 65 -466 101 -768 131 -1588 99 -502 67 -988 65 -952 129 -424 65 -228 161 -162 129 -452 131 -954 65 -954 99 -328 65 -1564 133 -1300 131 -164 133 -728 135 -200 165 -298 131 -1572 131 -328 65 -164 133 -336 99 -1260 133 -370 97 -466 67 -830 197 -1260 131 -330 131 -1034 65 -198 97 -1378 133 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm.sub new file mode 100644 index 00000000000..0b29739ee75 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Hollarm +Bit: 42 +Key: 00 00 00 ED 24 3C 22 6F diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm_raw.sub new file mode 100644 index 00000000000..8bc83019e2e --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 211 -978 199 -1602 209 -988 193 -990 217 -1592 209 -1616 205 -958 201 -1618 211 -1574 195 -1628 193 -1590 201 -992 209 -2406 199 -1604 195 -1592 195 -1616 193 -990 185 -1628 211 -1586 201 -986 201 -1608 211 -984 199 -996 233 -1576 195 -998 203 -990 195 -1632 193 -994 189 -998 205 -990 199 -1006 205 -1586 197 -1596 225 -1584 195 -1614 195 -992 211 -1020 195 -960 207 -984 195 -1618 201 -998 247 -952 199 -998 201 -1610 197 -1002 205 -1018 197 -1566 193 -1618 201 -1000 209 -1582 195 -1632 195 -1560 197 -1638 207 -956 199 -2416 199 -1626 177 -1614 201 -1580 201 -1032 213 -1548 197 -1626 193 -994 187 -1628 207 -950 225 -992 203 -1588 207 -1026 203 -968 205 -1622 197 -970 191 -1028 209 -982 199 -1028 205 -1552 201 -1628 201 -1556 207 -1632 197 -974 239 -978 201 -982 205 -1022 199 -1572 201 -1032 177 -984 197 -1024 185 -1594 209 -1016 201 -1000 211 -1594 197 -1572 201 -1034 177 -1582 197 -1626 195 -1622 193 -1556 199 -1030 207 -2384 199 -1594 195 -1618 201 -1562 241 -982 195 -1630 195 -1590 195 -1022 189 -1590 185 -1030 205 -954 227 -1590 191 -996 207 -1030 195 -1584 195 -1026 185 -1000 197 -974 205 -1020 199 -1572 227 -1584 193 -1616 195 -1586 201 -1028 207 -956 203 -1016 203 -986 203 -1610 211 -980 199 -976 235 -992 195 -1620 193 -996 211 -974 201 -1590 211 -1610 201 -980 193 -1620 191 -1592 209 -1618 205 -1586 197 -1000 191 -2416 205 -1586 207 -1564 225 -1586 227 -958 221 -1620 189 -1590 215 -994 207 -1588 229 -968 191 -996 205 -1588 229 -972 189 -1028 211 -1574 227 -1000 193 -962 243 -1002 201 -968 201 -1612 197 -1594 203 -1592 209 -1618 207 -958 203 -992 229 -1006 201 -980 199 -1602 195 -996 189 -1028 213 -976 201 -1592 209 -980 195 -1026 187 -1590 211 -1608 201 -978 205 -1610 211 -1606 199 -1574 201 -1596 201 -994 195 -2424 193 -1588 227 -1554 235 -1592 205 -988 227 -1562 201 -1620 195 -990 211 -1608 199 -978 205 -1014 199 -1574 201 -1032 211 -958 199 -1626 211 -958 199 -1038 211 -974 201 -962 229 -1600 195 -1622 193 -1588 193 -1618 195 -988 185 -1032 205 -960 203 -1014 237 -1546 201 -1028 187 -996 201 -978 223 -1582 225 -994 211 -986 199 -1624 213 -1550 195 -1036 201 -1556 207 -1630 197 -1602 195 -1590 193 -1022 189 -2382 215 -1590 211 -1586 203 -1580 195 -1020 225 -1558 185 -1628 209 -988 225 -1580 195 -1020 191 -996 205 -1620 197 -970 191 -996 207 -1594 197 -1004 239 -980 199 -980 205 -1016 199 -1576 201 -1628 203 -1606 213 -1550 195 -1034 203 -976 199 -976 225 -990 211 -1614 199 -978 205 -992 193 -1032 203 -1574 213 -1002 201 -968 +RAW_Data: 207 -1594 231 -1598 195 -1000 207 -1576 245 -1564 193 -1618 195 -1554 257 -990 207 -2372 207 -1596 193 -1590 225 -1586 225 -958 221 -1590 219 -1592 213 -982 193 -1586 199 -1040 211 -970 201 -1588 209 -986 201 -1006 209 -1596 193 -1024 193 -994 211 -1002 201 -968 207 -1596 229 -1566 201 -1596 201 -1618 211 -982 199 -978 199 -1018 201 -996 199 -1606 197 -998 207 -988 229 -974 203 -1612 211 -974 201 -1014 207 -1554 225 -1584 225 -960 219 -1590 219 -1590 215 -1590 185 -1624 185 -998 199 -2404 195 -1626 195 -1556 235 -1594 191 -996 207 -1584 229 -1600 193 -998 205 -1584 207 -1004 201 -992 203 -1580 201 -1030 211 -960 197 -1630 211 -958 199 -1008 241 -964 201 -996 197 -1602 195 -1628 195 -1560 235 -1592 211 -958 199 -1032 207 -964 203 -996 241 -1568 195 -1032 193 -992 211 -976 201 -1606 209 -960 235 -996 207 -1558 259 -1554 195 -1020 225 -1558 209 -1620 207 -1552 201 -1626 199 -996 233 -2368 195 -1588 225 -1586 225 -1552 227 -992 207 -1584 201 -1612 195 -1000 205 -1584 207 -1004 203 -992 201 -1582 227 -994 205 -982 195 -1624 195 -994 189 -1032 211 -970 201 -994 237 -1546 201 -1624 201 -1570 247 -1550 229 -1008 201 -994 197 -976 203 -1016 199 -1574 201 -1030 185 -998 199 -1010 201 -1566 211 -1022 201 -998 213 -1596 197 -1570 201 -1030 185 -1594 247 -1544 197 -1626 195 -1588 193 -1024 205 -2378 207 -1594 195 -1588 227 -1586 225 -960 219 -1594 207 -1584 201 -1010 193 -1588 205 -1014 201 -980 191 -1620 191 -996 207 -1028 195 -1582 195 -1028 213 -956 199 -976 237 -996 201 -1606 211 -1582 197 -1602 193 -1596 201 -1000 211 -982 201 -1030 205 -954 203 -1612 211 -978 195 -1024 185 -996 201 -1610 195 -1002 205 -984 225 -1560 225 -1588 227 -958 219 -1594 219 -1558 217 -1596 211 -1610 201 -982 205 -2402 211 -1608 199 -1572 203 -1592 225 -960 245 -1598 197 -1600 195 -998 205 -1582 209 -1004 201 -960 197 -1630 195 -1000 243 -946 231 -1596 195 -994 191 -996 205 -994 199 -998 199 -1610 195 -1598 239 -1550 193 -1620 191 -996 207 -1032 201 -964 201 -984 203 -1628 207 -968 199 -1014 201 -994 199 -1604 195 -996 189 -1030 211 -1570 193 -1622 193 -990 189 -1628 207 -1586 207 -1556 227 -1588 225 -958 219 -2388 209 -1618 205 -1592 195 -1598 201 -998 207 -1600 193 -1592 201 -992 211 -1608 199 -978 203 -1016 201 -1578 201 -1030 185 -996 197 -1602 197 -996 191 -1028 211 -972 195 -992 247 -1548 229 -1596 197 -1588 195 -1616 195 -990 185 -1028 207 -960 235 -994 201 -1578 201 -1030 185 -996 199 -1008 195 -1582 193 -1028 211 -980 201 -1604 209 -1582 197 -1008 195 -1588 +RAW_Data: 203 -1610 211 -1606 199 -1574 201 -1000 215 -2388 211 -1580 195 -1626 195 -1560 271 -960 211 -1574 229 -1566 201 -1026 209 -1588 197 -1008 201 -996 197 -1602 193 -996 189 -996 241 -1570 195 -1032 203 -976 199 -976 205 -1024 199 -1570 201 -1622 195 -1622 203 -1554 207 -1000 235 -962 201 -1012 195 -992 211 -1608 201 -982 205 -984 229 -970 237 -1556 243 -974 195 -990 209 -1608 201 -1608 197 -998 207 -1578 245 -1564 193 -1588 227 -1584 225 -994 205 -2380 207 -1556 259 -1556 193 -1616 225 -958 219 -1594 209 -1580 199 -1014 195 -1582 255 -960 211 -982 201 -1602 209 -986 195 -1018 193 -1592 211 -1020 193 -992 189 -1030 211 -970 201 -1608 211 -1554 197 -1630 195 -1622 195 -990 189 -996 205 -988 201 -996 201 -1606 195 -998 189 -1030 211 -976 203 -1588 211 -986 199 -1008 209 -1596 195 -1584 227 -990 187 -1624 187 -1594 243 -1548 201 -1610 195 -998 189 -2414 189 -1620 191 -1590 185 -1622 185 -998 235 -1584 195 -1622 193 -992 189 -1626 207 -950 195 -1022 225 -1556 209 -1020 195 -998 207 -1582 245 -968 203 -1012 205 -956 203 -994 195 -1630 193 -1590 227 -1552 225 -1590 199 -998 201 -1016 199 -990 213 -1006 195 -1586 193 -1026 185 -998 199 -974 225 -1584 203 -998 241 -968 195 -1618 195 -1584 191 -1028 211 -1574 193 -1592 225 -1558 271 -1554 191 -1028 211 -2366 227 -1562 237 -1586 199 -1568 211 -1016 193 -1580 197 -1614 195 -990 211 -1612 199 -982 239 -996 197 -1600 195 -994 191 -996 205 -1586 229 -968 191 -1032 211 -976 201 -996 239 -1548 201 -1624 201 -1590 209 -1582 197 -1028 195 -992 211 -972 223 -990 211 -1552 263 -978 203 -978 199 -1012 201 -1568 211 -1018 201 -1000 213 -1596 197 -1566 227 -992 205 -1620 211 -1566 193 -1592 227 -1554 235 -1000 213 -2398 199 -1570 201 -1598 203 -1610 211 -984 199 -1606 209 -1584 197 -1010 199 -1570 211 -1018 201 -1000 211 -1594 199 -970 193 -1028 211 -1572 195 -1028 195 -992 211 -1006 201 -966 201 -1614 197 -1594 193 -1618 201 -1564 245 -982 195 -1000 205 -984 229 -970 191 -1626 203 -984 195 -1028 193 -992 211 -1604 197 -974 203 -1026 199 -1574 203 -1594 203 -990 197 -1630 193 -1560 271 -1554 189 -1628 205 -988 193 -2382 237 -1588 199 -1592 211 -1596 199 -974 191 -1622 189 -1624 205 -968 235 -1576 197 -1000 191 -996 241 -1570 193 -1028 195 -992 211 -1604 199 -976 203 -990 195 -1028 201 -978 197 -1606 195 -1628 195 -1558 235 -1588 187 -996 201 -1016 199 -1006 205 -952 255 -1584 193 -962 279 -948 199 -1006 205 -1582 229 -968 191 -1028 211 -1574 193 -1594 227 -960 243 -1590 205 -1588 197 -1600 201 -1596 203 -990 +RAW_Data: 195 -2422 193 -1584 227 -1618 191 -1558 235 -994 209 -1558 225 -1588 237 -956 211 -1612 197 -980 205 -1000 245 -1560 193 -1026 193 -994 211 -1598 197 -974 205 -1022 199 -980 203 -1022 199 -1570 201 -1598 201 -1588 207 -1620 199 -972 237 -992 211 -974 201 -1012 207 -1550 227 -992 237 -958 195 -1034 193 -1588 189 -1032 211 -974 201 -1608 211 -1556 195 -1034 199 -1558 243 -1596 197 -1602 195 -1594 195 -1026 205 -2388 185 -1592 211 -1602 199 -1574 227 -992 203 -1614 211 -1570 193 -1030 203 -1554 207 -1032 201 -970 207 -1590 229 -968 191 -1030 211 -1572 195 -1032 203 -958 195 -1004 205 -1022 197 -1568 227 -1590 201 -1600 203 -1586 207 -990 225 -958 217 -1000 239 -950 225 -1588 225 -962 209 -996 225 -990 185 -1624 209 -956 225 -962 211 -1616 199 -1608 195 -1002 205 -1608 211 -1568 195 -1588 227 -1588 237 -956 211 -2406 199 -1604 195 -1594 201 -1596 209 -990 201 -1592 209 -1584 233 -986 201 -1590 211 -984 201 -976 203 -1614 197 -1000 207 -988 229 -1566 237 -990 185 -996 197 -1012 201 -996 197 -1602 195 -1592 193 -1616 201 -1598 203 -982 195 -998 223 -990 211 -984 201 -1590 213 -984 195 -1024 187 -994 201 -1610 195 -1004 203 -1000 209 -1562 225 -1586 227 -956 243 -1582 207 -1596 229 -1566 203 -1598 201 -982 197 -2426 193 -1588 227 -1554 271 -1550 193 -1028 211 -1578 195 -1622 193 -992 187 -1622 189 -996 205 -988 225 -1556 203 -1014 237 -952 203 -1618 211 -976 201 -1010 205 -966 225 -964 245 -1564 231 -1598 195 -1590 193 -1618 193 -990 185 -1030 207 -964 201 -1016 237 -1548 201 -1028 211 -960 199 -1032 207 -1556 235 -990 187 -996 203 -1612 197 -1596 201 -998 209 -1560 227 -1590 201 -1624 201 -1572 211 -1012 201 -2360 243 -1580 207 -1586 229 -1566 203 -1002 209 -1580 227 -1596 195 -958 251 -1592 207 -988 195 -1000 191 -1624 205 -982 193 -994 189 -1626 205 -952 257 -964 235 -960 195 -1036 201 -1556 207 -1630 199 -1600 195 -1594 201 -998 207 -1002 201 -958 231 -1006 193 -1622 203 -976 199 -974 191 -1028 211 -1576 227 -968 227 -960 245 -1596 197 -1602 195 -1000 205 -1584 207 -1598 193 -1586 225 -1584 225 -986 189 -2420 207 -1550 201 -1614 195 -1624 195 -994 189 -1626 207 -1550 203 -1016 201 -1592 211 -1008 201 -966 209 -1628 197 -972 191 -1028 211 -1576 195 -1030 201 -978 199 -1006 193 -992 211 -1610 199 -1576 195 -1620 195 -1614 195 -990 211 -956 235 -996 207 -998 201 -1586 213 -978 195 -1024 187 -998 199 -1606 195 -1004 205 -1000 207 -1562 225 -1588 225 -960 219 -1592 219 -1594 207 -1586 199 -1612 195 -998 207 -2372 209 -1598 231 -1562 195 -1614 +RAW_Data: 195 -986 219 -1592 209 -1618 207 -960 203 -1624 211 -974 193 -1026 211 -1566 207 -996 235 -962 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F.sub new file mode 100644 index 00000000000..7041324cb6d --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F.sub @@ -0,0 +1,8 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Legrand +Bit: 18 +Key: 00 00 00 00 00 02 E3 7F +TE: 358 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F_raw.sub new file mode 100644 index 00000000000..ba703925c32 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F_raw.sub @@ -0,0 +1,22 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 10133 -4946 65 -5114 65 -1750 67 -232 165 -536 165 -166 533 -694 395 -198 263 -66 395 -12664 297 -662 133 -264 99 -102 131 -200 131 -234 263 -66 265 -100 661 -168 197 -134 297 -66 431 -132 45005 -12358 131 -100 129 -66 65 -198 65 -66 197 -1018 131 -266 97 -1052 97 -228 459 -100 1517 -100 4361 -10350 165 -1264 65 -232 131 -200 65 -166 133 -232 299 -132 65 -166 299 -134 231 -198 99 -68 429 -12270 231 -628 163 -594 97 -496 227 -1220 163 -166 129 -66 655 -98 163 -66 393 -66 195 -198 293 -12130 67 -68 331 -134 99 -98 99 -332 99 -562 163 -164 65 -130 131 -920 131 -98 65 -198 133 -98 427 -130 359 -132 627 -66 2207 -16066 163 -1316 331 -832 131 -370 131 -132 661 -166 265 -134 833 -168 34477 -10228 65 -2266 261 -230 131 -198 129 -1282 65 -66 463 -100 365 -232 233 -66 297 -166 2151 -12330 99 -400 97 -436 131 -896 165 -400 363 -298 199 -166 97 -430 165 -168 365 -132 725 -130 3253 -12440 131 -796 297 -332 65 -830 65 -828 429 -198 335 -66 665 -266 29175 -12140 163 -230 131 -992 165 -1230 397 -132 199 -132 299 -66 659 -100 9675 -11036 99 -570 99 -830 165 -662 331 -266 429 -132 391 -396 431 -132 233 -166 231 -100 3435 -11728 99 -332 165 -166 63 -128 161 -326 129 -690 231 -130 265 -98 167 -232 199 -66 201 -264 165 -166 365 -66 727 -100 363 -12688 229 -228 95 -98 391 -198 129 -196 97 -364 97 -100 65 -266 99 -64 293 -98 327 -262 761 -66 7681 -5384 99 -762 195 -134 525 -992 99 -166 67 -98 329 -100 659 -100 293 -100 97 -98 163 -264 1741 -100 57331 -9834 67 -664 67 -2158 99 -862 133 -368 331 -864 65 -330 65 -794 99 -66 431 -100 3017 -66 7061 -6558 99 -6316 99 -266 131 -166 97 -198 65 -294 99 -66 661 -132 2661 -130 19413 -12380 65 -262 133 -66 67 -232 133 -798 197 -264 165 -498 97 -166 199 -134 559 -98 165 -13118 99 -562 65 -1256 231 -232 99 -132 131 -66 199 -66 429 -296 131 -200 201 -266 65 -66 895 -132 829 -66 12455 -11974 199 -334 99 -2160 165 -1232 929 -100 327 -166 295 -134 2191 -100 20415 -11032 65 -1170 131 -2326 163 -398 263 -596 99 -400 165 -68 499 -66 661 -11724 97 -1226 99 -166 233 -400 131 -662 165 -400 165 -166 299 -296 1159 -100 131 -98 427 -68 1643 -13934 101 -1294 65 -394 63 -1458 265 -166 265 -364 133 -434 101 -398 195 -264 1097 -166 265 -166 58013 -11978 131 -100 165 -666 199 -66 163 -166 65 -198 195 -592 1295 -134 597 -136 567 -100 1615 -100 17759 -12402 261 -692 +RAW_Data: 265 -730 327 -398 131 -300 199 -432 7947 -4772 233 -366 365 -166 133 -522 99 -164 65 -366 99 -100 395 -66 4423 -15068 197 -430 163 -398 65 -230 165 -228 97 -494 165 -134 197 -168 131 -168 65 -298 267 -132 1657 -98 99 -66 165 -100 7687 -12010 197 -132 163 -198 527 -130 293 -396 297 -360 163 -264 95 -164 161 -694 427 -262 129 -100 885 -100 131 -66 461 -9862 97 -5002 497 -594 197 -66 229 -596 65 -132 195 -262 99 -132 63 -166 65 -230 431 -100 165 -168 461 -164 13159 -12060 133 -64 129 -1316 131 -758 165 -430 165 -270 133 -564 995 -7536 99 -4746 165 -358 457 -132 165 -166 99 -100 397 -132 299 -66 197 -66 131 -392 129 -196 131 -328 459 -100 565 -66 165 -66 265 -100 1131 -100 9533 -12070 65 -400 163 -366 165 -530 197 -196 133 -68 233 -398 165 -66 99 -100 163 -132 791 -66 17359 -12434 131 -328 229 -558 195 -564 167 -132 133 -234 131 -100 65 -364 65 -496 65 -200 297 -66 1725 -12958 63 -68 65 -164 67 -132 63 -200 131 -166 165 -696 131 -166 67 -200 65 -168 1061 -12848 199 -166 2039 -1660 201 -5822 1017 -1126 299 -414 1015 -388 1061 -380 1055 -1086 327 -1118 339 -1084 351 -360 1051 -376 1083 -1070 343 -346 1105 -350 1069 -354 1087 -346 1063 -362 1075 -372 1067 -334 1097 -5694 1083 -1074 351 -378 1057 -332 1101 -370 1065 -1050 379 -1050 379 -1066 363 -348 1073 -388 1047 -1076 351 -380 1053 -362 1071 -372 1067 -352 1081 -352 1069 -350 1091 -346 1087 -5682 1095 -1044 381 -342 1097 -326 1111 -346 1061 -1064 379 -1066 381 -1032 379 -360 1065 -364 1067 -1066 375 -352 1081 -350 1069 -350 1089 -352 1081 -350 1069 -350 1097 -326 1081 -5698 1097 -1074 353 -354 1083 -326 1111 -344 1083 -1054 387 -1046 349 -1094 345 -350 1081 -354 1069 -1076 385 -350 1051 -354 1077 -386 1057 -334 1099 -370 1051 -354 1083 -356 1087 -5670 1107 -1072 353 -354 1081 -326 1111 -346 1085 -1054 389 -1050 353 -1056 377 -352 1083 -350 1071 -1080 381 -312 1099 -334 1107 -358 1079 -320 1091 -350 1095 -348 1081 -318 1113 -5688 1075 -1076 353 -354 1085 -324 1111 -346 1067 -1056 387 -1048 381 -1070 383 -314 1085 -352 1073 -1078 385 -348 1049 -354 1103 -356 1055 -334 1097 -372 1049 -354 1081 -354 1087 -5680 1109 -1038 383 -356 1085 -326 1107 -344 1065 -1066 361 -1076 371 -1054 389 -330 1069 -376 1069 -1054 389 -332 1073 -374 1069 -354 1079 -320 1097 -350 1093 -348 1083 -322 1111 -5680 1105 -1044 359 -356 1083 -354 1085 -348 1097 -1050 387 -1042 349 -1074 385 -350 1053 -352 1077 -1082 379 -314 1099 -336 1095 -346 1075 -374 1071 -354 1081 -320 1095 -348 1097 -5686 +RAW_Data: 1085 -1062 369 -346 1093 -322 1105 -350 1063 -1076 351 -1070 381 -1068 355 -358 1087 -354 1049 -1070 351 -384 1081 -318 1113 -344 1065 -348 1083 -352 1071 -388 1051 -352 1081 -5706 1065 -1064 361 -348 1087 -356 1079 -348 1091 -1072 381 -1020 375 -1068 361 -356 1081 -354 1085 -1042 381 -352 1079 -352 1101 -320 1093 -346 1087 -322 1117 -354 1057 -334 1099 -5702 1085 -1044 381 -340 1087 -352 1081 -352 1069 -1080 379 -1032 379 -1050 377 -346 1099 -332 1077 -1084 355 -334 1101 -334 1089 -350 1097 -320 1095 -348 1097 -326 1077 -376 1053 -5706 1073 -1088 367 -346 1063 -354 1071 -382 1067 -1076 347 -1068 381 -1064 347 -360 1085 -354 1047 -1072 385 -352 1087 -328 1073 -374 1051 -388 1045 -354 1093 -348 1085 -354 1079 -5668 1085 -1082 349 -348 1079 -374 1051 -382 1063 -1076 355 -1082 349 -1068 353 -364 1065 -362 1075 -1064 373 -346 1067 -362 1073 -382 1063 -352 1067 -380 1065 -326 1081 -376 1065 -5714 1075 -1072 345 -346 1099 -332 1097 -346 1075 -1062 373 -1066 347 -1076 373 -344 1069 -362 1073 -1072 383 -314 1113 -344 1063 -350 1079 -374 1065 -332 1099 -370 1065 -336 1099 -5694 1087 -1046 351 -368 1097 -348 1051 -354 1109 -1046 383 -1060 365 -1072 365 -352 1049 -352 1091 -1074 347 -384 1051 -352 1073 -384 1051 -350 1079 -354 1073 -380 1067 -326 1081 -5722 1065 -1078 355 -352 1081 -356 1085 -344 1083 -1050 385 -1050 353 -1092 345 -384 1051 -352 1069 -1078 381 -350 1051 -354 1069 -386 1057 -364 1073 -368 1071 -352 1049 -354 1093 -5710 1077 -1072 353 -354 1085 -326 1079 -376 1069 -1052 381 -1064 349 -1074 381 -346 1073 -368 1067 -1056 359 -350 1107 -348 1063 -352 1069 -382 1065 -326 1111 -346 1063 -364 1071 -5686 1099 -1072 355 -352 1083 -326 1111 -346 1065 -1086 353 -1050 383 -1068 383 -350 1047 -354 1071 -1076 381 -346 1069 -370 1065 -336 1095 -334 1099 -336 1099 -330 1073 -354 1081 -5710 1077 -1050 385 -348 1085 -322 1109 -356 1055 -1084 355 -1054 377 -1052 375 -346 1103 -350 1065 -1074 351 -342 1093 -346 1091 -322 1107 -356 1055 -364 1071 -372 1053 -354 1085 -5704 1077 -1050 383 -346 1073 -370 1065 -334 1097 -1060 371 -1062 347 -1080 373 -344 1069 -360 1075 -1076 351 -346 1109 -344 1063 -364 1069 -370 1065 -334 1099 -332 1097 -336 1097 -5690 1087 -1044 383 -338 1095 -348 1083 -320 1109 -1048 385 -1056 365 -1072 365 -356 1081 -320 1095 -1078 343 -346 1103 -330 1075 -352 1095 -350 1069 -350 1085 -352 1081 -350 1071 -5712 1075 -1042 385 -354 1085 -326 1079 -374 1051 -1084 351 -1064 383 -1068 347 -346 1099 -334 1103 -1054 347 -354 1099 -346 1083 -354 1081 -354 1053 -362 1071 -374 1065 -346 1067 -5726 1053 -1082 351 -360 1091 -344 1083 -350 +RAW_Data: 1081 -1074 353 -1074 351 -1088 325 -386 1051 -386 1047 -1074 353 -378 1051 -384 1047 -354 1073 -384 1049 -376 1065 -356 1073 -352 1087 -5680 1079 -1074 381 -350 1051 -354 1071 -386 1051 -1086 351 -1080 351 -1070 381 -350 1051 -352 1071 -1080 383 -348 1049 -354 1075 -384 1065 -324 1113 -346 1061 -350 1079 -374 1051 -5706 1077 -1086 333 -384 1047 -354 1093 -346 1065 -1078 353 -1094 345 -1082 351 -360 1089 -346 1063 -1074 353 -366 1065 -360 1075 -372 1067 -334 1101 -368 1051 -352 1085 -356 1051 -5734 1073 -1072 353 -354 1083 -328 1073 -376 1083 -1040 375 -1066 359 -1082 353 -334 1099 -368 1069 -1070 343 -346 1105 -354 1055 -362 1071 -370 1069 -352 1077 -352 1069 -350 1087 -5680 1079 -1086 367 -352 1049 -354 1097 -346 1063 -1078 349 -1092 345 -1098 347 -358 1065 -350 1079 -1064 373 -346 1067 -362 1081 -350 1065 -350 1095 -346 1067 -362 1075 -372 1049 -5706 1071 -1086 367 -352 1083 -320 1095 -348 1087 -1050 387 -1050 353 -1094 345 -346 1101 -332 1073 -1072 383 -346 1083 -346 1087 -352 1051 -354 1093 -346 1085 -346 1061 -354 1103 -5700 1069 -1050 393 -352 1063 -352 1069 -350 1097 -1044 383 -1068 379 -1030 379 -358 1065 -348 1073 -1068 377 -346 1099 -330 1073 -352 1093 -350 1073 -348 1087 -352 1081 -350 1069 -5710 1073 -1076 353 -354 1085 -324 1111 -344 1083 -1040 389 -1044 381 -1070 347 -350 1085 -352 1071 -1078 383 -352 1047 -352 1075 -352 1089 -350 1083 -352 1069 -350 1097 -326 1109 -5664 1113 -1040 383 -354 1085 -328 1075 -374 1051 -1084 351 -1066 351 -1096 379 -314 1099 -334 1097 -1052 379 -356 1069 -354 1079 -320 1097 -348 1093 -346 1083 -354 1077 -354 1055 -5714 1073 -1076 345 -350 1081 -354 1069 -382 1065 -1074 349 -1068 379 -1064 347 -360 1065 -364 1071 -1066 371 -344 1067 -360 1077 -354 1083 -354 1087 -346 1065 -364 1071 -368 1071 -5682 1075 -1084 367 -342 1067 -360 1075 -352 1097 -1040 353 -1074 385 -1058 363 -346 1075 -354 1081 -1076 351 -378 1057 -334 1101 -334 1103 -356 1079 -320 1091 -348 1093 -348 1085 -5678 1095 -1050 379 -356 1065 -334 1097 -370 1049 -1086 353 -1086 325 -1080 375 -352 1081 -350 1067 -1078 383 -350 1051 -352 1071 -386 1053 -334 1103 -336 1085 -354 1087 -324 1111 -5676 1079 -1078 351 -380 1055 -364 1073 -368 1051 -1082 349 -1064 351 -1092 347 -378 1073 -334 1099 -1050 381 -328 1095 -346 1083 -350 1081 -352 1069 -382 1049 -344 1095 -354 1077 -5682 1071 -1078 359 -352 1081 -356 1085 -346 1065 -1082 353 -1080 351 -1070 385 -348 1051 -354 1077 -1076 381 -314 1103 -334 1105 -354 1081 -318 1095 -348 1087 -354 1081 -320 1097 -5712 1077 -1074 319 -380 1067 -356 1087 -346 1065 -1080 349 -1092 345 -1082 351 -360 +RAW_Data: 1053 -378 1083 -1050 381 -346 1053 -376 1067 -364 1069 -370 1047 -386 1047 -356 1093 -344 1083 -5690 1079 -1060 371 -344 1067 -362 1073 -348 1095 -1076 353 -1074 353 -1054 359 -352 1101 -348 1085 -1046 361 -388 1043 -350 1093 -346 1081 -352 1081 -352 1067 -384 1055 -346 1085 -5678 1083 -1084 347 -344 1093 -348 1097 -326 1075 -1070 375 -1062 347 -1080 373 -344 1067 -362 1073 -1074 381 -314 1115 -344 1085 -356 1047 -354 1091 -348 1085 -354 1081 -320 1095 -5708 1075 -1074 353 -354 1083 -326 1109 -346 1065 -1054 387 -1050 351 -1096 381 -316 1083 -352 1073 -1080 381 -312 1101 -336 1105 -350 1063 -352 1067 -384 1065 -324 1111 -346 1065 -5704 1073 -1080 347 -350 1083 -352 1073 -350 1085 -1064 375 -1064 357 -1072 383 -314 1111 -344 1087 -1042 387 -330 1071 -374 1069 -352 1081 -350 1067 -350 1097 -348 1083 -322 1113 -5682 1075 -1076 353 -354 1083 -326 1117 -342 1085 -1054 351 -1062 383 -1070 377 -314 1103 -332 1105 -1042 381 -346 1083 -346 1065 -360 1071 -374 1069 -352 1079 -352 1067 -348 1089 -5682 1077 -1088 367 -354 1047 -354 1095 -346 1083 -1068 345 -1096 351 -1074 351 -346 1077 -372 1065 -1066 349 -386 1069 -346 1085 -356 1077 -354 1057 -364 1071 -370 1071 -352 1079 -5676 1073 -1074 381 -314 1117 -344 1063 -352 1081 -1076 357 -1080 355 -1052 359 -352 1095 -334 1097 -1064 371 -352 1083 -320 1095 -348 1085 -352 1081 -350 1069 -350 1093 -348 1085 -5676 1095 -1052 379 -356 1065 -346 1087 -356 1075 -1048 387 -1058 363 -1074 367 -356 1049 -354 1091 -1072 347 -346 1101 -332 1073 -384 1063 -350 1067 -350 1101 -326 1079 -376 1065 -5680 1107 -1074 343 -346 1067 -362 1083 -352 1085 -1078 349 -1070 345 -1066 379 -360 1065 -348 1079 -1062 375 -344 1069 -362 1075 -352 1081 -356 1085 -344 1063 -384 1047 -354 1073 -5708 1073 -1074 357 -354 1083 -356 1087 -344 1087 -1052 351 -1064 379 -1068 379 -314 1103 -334 1099 -1052 347 -386 1061 -348 1073 -374 1067 -352 1083 -350 1067 -350 1095 -348 1081 -5682 1085 -1054 383 -344 1087 -346 1067 -362 1069 -1064 373 -1062 347 -1078 373 -352 1081 -350 1065 -1078 383 -350 1051 -352 1071 -386 1051 -352 1081 -352 1069 -350 1095 -346 1087 -5678 1089 -1052 387 -330 1073 -374 1083 -354 1045 -1072 353 -1074 385 -1056 361 -350 1081 -352 1083 -1080 349 -376 1059 -346 1087 -356 1075 -354 1055 -362 1075 -370 1067 -352 1081 -5676 1075 -1076 387 -330 1071 -374 1065 -352 1079 -1072 355 -1082 353 -1054 361 -350 1095 -348 1073 -1068 373 -352 1081 -322 1097 -348 1085 -354 1079 -352 1069 -348 1093 -348 1083 -5676 1097 -1056 361 -348 1071 -354 1081 -354 1089 -1074 345 -1062 383 -1050 353 -380 1057 -364 1071 -1066 371 -354 1081 -318 +RAW_Data: 1099 -348 1085 -352 1079 -352 1071 -348 1087 -346 1095 -5678 1095 -1050 383 -328 1091 -348 1061 -386 1047 -1078 357 -1084 351 -1066 351 -366 1087 -348 1061 -1076 357 -354 1081 -354 1089 -346 1065 -352 1079 -354 1069 -386 1055 -334 1099 -5694 1085 -1044 383 -340 1087 -352 1081 -350 1065 -1080 383 -1052 351 -1082 349 -376 1059 -348 1083 -1046 395 -356 1049 -352 1091 -348 1085 -354 1083 -320 1093 -348 1087 -354 1081 -5670 1107 -1070 343 -348 1067 -384 1067 -354 1083 -1068 345 -1064 349 -1080 373 -350 1081 -352 1067 -1076 383 -348 1049 -354 1071 -386 1053 -364 1071 -368 1069 -352 1079 -350 1069 -5708 1075 -1074 351 -354 1083 -326 1111 -344 1067 -1052 385 -1050 381 -1070 347 -346 1101 -332 1073 -1072 383 -344 1085 -346 1067 -362 1069 -370 1053 -352 1085 -356 1085 -346 1067 -5682 1111 -1060 369 -344 1071 -360 1081 -354 1053 -1080 353 -1092 345 -1084 351 -360 1053 -376 1067 -1086 351 -330 1081 -376 1051 -382 1067 -352 1067 -380 1067 -326 1081 -374 1051 -5696 1109 -1058 369 -354 1079 -320 1097 -350 1085 -1054 387 -1048 353 -1060 377 -352 1085 -350 1069 -1078 383 -350 1049 -352 1071 -384 1065 -326 1081 -376 1067 -334 1101 -334 1101 -5692 1063 -1064 375 -346 1067 -362 1073 -380 1065 -1074 355 -1072 349 -1066 349 -366 1085 -350 1081 -1076 355 -350 1085 -326 1077 -376 1083 -352 1049 -354 1095 -346 1065 -380 1051 -5712 1083 -1052 389 -330 1073 -374 1053 -354 1083 -1074 351 -1074 385 -1052 343 -346 1107 -352 1065 -1072 351 -376 1065 -356 1081 -346 1065 -362 1069 -372 1067 -336 1097 -332 1099 -5678 1101 -1068 343 -350 1081 -352 1069 -384 1055 -1082 349 -1056 377 -1082 353 -330 1081 -374 1067 -1082 351 -330 1081 -376 1081 -352 1047 -354 1097 -348 1081 -352 1081 -352 1069 -5712 1077 -1038 383 -354 1083 -326 1079 -374 1055 -1074 383 -1064 347 -1066 381 -316 1099 -370 1051 -1082 353 -336 1097 -368 1053 -352 1081 -354 1089 -346 1063 -350 1081 -352 1071 -5714 1075 -1074 355 -350 1083 -358 1053 -376 1065 -1084 347 -1064 353 -1070 385 -346 1085 -352 1077 -1042 387 -346 1053 -354 1077 -386 1055 -364 1069 -370 1051 -388 1051 -354 1087 -5672 1081 -1074 351 -378 1065 -356 1083 -346 1065 -1078 347 -1092 345 -1066 359 -350 1107 -356 1045 -1068 383 -354 1083 -328 1075 -372 1053 -388 1051 -356 1087 -346 1065 -362 1071 -5702 1083 -1076 349 -376 1055 -346 1083 -356 1073 -1078 353 -1054 361 -1078 369 -352 1083 -352 1065 -1072 347 -346 1103 -332 1101 -346 1081 -354 1045 -386 1051 -362 1073 -370 1049 -5718 1075 -1048 365 -388 1047 -354 1091 -346 1085 -1040 387 -1050 351 -1096 349 -348 1083 -352 1073 -1076 379 -316 1101 -334 1097 -336 1099 -330 1071 -388 1047 -354 +RAW_Data: 1087 -348 1085 -5684 1075 -1084 367 -344 1067 -358 1073 -350 1063 -1074 353 -1108 349 -1068 353 -362 1067 -344 1097 -1050 363 -386 1047 -356 1087 -346 1085 -352 1079 -320 1097 -346 1083 -352 1081 -5676 1103 -1054 387 -330 1071 -372 1053 -354 1085 -1074 351 -1070 385 -1058 347 -362 1069 -350 1087 -1054 381 -346 1085 -346 1065 -364 1069 -370 1071 -354 1081 -320 1097 -348 1083 -5676 1079 -1090 367 -344 1067 -360 1073 -350 1095 -1074 351 -1076 349 -1068 353 -364 1081 -352 1081 -1074 321 -382 1051 -360 1075 -374 1051 -386 1049 -354 1091 -346 1085 -346 1067 -5706 1065 -1084 351 -360 1087 -346 1085 -356 1047 -1074 353 -1072 383 -1064 347 -362 1067 -364 1069 -1068 371 -352 1083 -320 1095 -350 1097 -346 1083 -322 1077 -388 1051 -350 1081 -5706 1051 -1084 387 -328 1073 -372 1049 -386 1049 -1076 353 -1072 383 -1056 363 -348 1071 -354 1085 -1076 351 -376 1057 -344 1087 -356 1073 -352 1081 -350 1053 -376 1051 -384 1049 -5710 1083 -1076 351 -348 1073 -372 1063 -334 1099 -1062 371 -1052 389 -1050 353 -364 1087 -354 1049 -1072 353 -382 1055 -362 1075 -370 1051 -352 1095 -350 1067 -348 1099 -326 1077 -5702 1077 -1076 353 -378 1053 -362 1071 -370 1051 -1084 349 -1066 353 -1096 345 -382 1049 -354 1069 -1080 379 -346 1069 -368 1041 -386 1047 -354 1093 -346 1085 -350 1083 -350 1067 -5708 1075 -1074 353 -352 1083 -326 1109 -344 1083 -1050 387 -1052 355 -1054 377 -352 1085 -350 1069 -1076 377 -314 1103 -332 1101 -336 1097 -330 1073 -354 1085 -354 1089 -346 1083 -5688 1073 -1084 331 -386 1047 -356 1087 -346 1061 -1082 383 -1050 353 -1070 385 -346 1051 -354 1105 -1046 385 -346 1085 -322 1073 -386 1049 -382 1047 -354 1069 -386 1053 -362 1071 -5692 1079 -1076 351 -378 1055 -364 1071 -370 1073 -1040 373 -1070 357 -1084 353 -334 1097 -334 1105 -1056 387 -330 1071 -372 1069 -354 1081 -318 1095 -348 1085 -352 1077 -352 1069 -5708 1075 -1076 353 -352 1087 -326 1081 -372 1067 -1084 351 -1050 353 -1098 345 -344 1101 -332 1101 -1054 365 -348 1079 -354 1087 -326 1081 -374 1049 -382 1063 -352 1067 -384 1055 -5708 1071 -1076 345 -350 1081 -352 1069 -386 1059 -1054 361 -1076 371 -1054 387 -330 1073 -372 1069 -1054 383 -344 1085 -346 1065 -364 1073 -368 1065 -334 1099 -334 1073 -382 1061 -5700 1067 -1064 383 -328 1093 -348 1083 -354 1083 -1040 383 -1046 387 -1056 361 -348 1073 -354 1085 -1074 351 -378 1055 -332 1099 -338 1089 -354 1085 -324 1115 -344 1085 -350 1063 -5704 1069 -1068 349 -360 1091 -346 1067 -362 1075 -1062 373 -1068 333 -1102 365 -354 1049 -356 1087 -1074 345 -384 1047 -352 1069 -386 1053 -364 1071 -370 1051 -352 1085 -354 1085 -5678 1081 -1072 351 -378 +RAW_Data: 1055 -362 1069 -372 1069 -1054 387 -1048 353 -1092 345 -346 1101 -332 1073 -1074 383 -312 1113 -346 1063 -364 1071 -370 1073 -354 1081 -320 1091 -348 1085 -5680 1075 -1088 367 -344 1069 -360 1075 -350 1063 -1074 353 -1076 385 -1054 365 -348 1071 -354 1083 -1074 351 -374 1067 -326 1077 -376 1085 -352 1049 -354 1091 -346 1063 -380 1051 -5714 1085 -1038 387 -328 1081 -376 1053 -382 1063 -1072 355 -1076 349 -1064 349 -368 1097 -326 1073 -1070 377 -344 1099 -330 1085 -354 1087 -326 1079 -374 1069 -350 1081 -352 1071 -5700 1067 -1076 357 -350 1095 -320 1095 -348 1065 -1078 349 -1092 347 -1066 379 -358 1069 -332 1101 -1062 371 -350 1085 -320 1095 -348 1097 -346 1049 -356 1075 -386 1057 -364 1069 -5692 1077 -1070 351 -380 1051 -350 1075 -376 1065 -1052 385 -1048 383 -1068 381 -316 1083 -352 1073 -1080 377 -314 1103 -334 1099 -336 1099 -328 1075 -350 1095 -352 1065 -350 1095 -5674 1079 -1076 379 -346 1071 -368 1067 -336 1065 -1088 369 -1050 387 -1048 353 -366 1063 -382 1045 -1078 361 -386 1047 -354 1089 -346 1063 -384 1045 -354 1071 -386 1057 -332 1101 -5698 1081 -1044 383 -340 1085 -352 1079 -352 1067 -1080 379 -1030 379 -1050 377 -344 1099 -330 1073 -1074 381 -346 1085 -346 1085 -356 1047 -354 1091 -348 1063 -362 1075 -374 1063 -5678 1103 -1042 377 -352 1081 -352 1073 -348 1095 -1056 347 -1080 373 -1054 383 -314 1113 -346 1065 -1082 355 -358 1067 -352 1079 -352 1067 -350 1093 -346 1083 -354 1075 -354 1087 -5678 1079 -1074 345 -348 1099 -332 1101 -336 1067 -1090 365 -1052 387 -1048 355 -362 1067 -364 1073 -1066 371 -350 1081 -352 1065 -348 1069 -362 1075 -372 1067 -334 1099 -332 1099 -848 153 -153886 131 -896 231 -464 231 -428 97 -166 99 -966 233 -200 101 -66 199 -102 265 -266 299 -98 131 -100 65 -232 131 -100 44699 -12320 65 -132 131 -300 231 -100 167 -266 197 -68 297 -330 131 -496 131 -400 131 -166 633 -66 431 -230 589 -166 10885 -11354 329 -792 99 -296 129 -166 97 -98 65 -132 229 -294 297 -98 561 -166 231 -98 825 -166 57693 -12116 131 -98 295 -424 163 -398 131 -232 97 -130 65 -66 97 -66 165 -460 529 -66 197 -132 393 -198 267 -168 43035 -10678 99 -1716 97 -498 65 -298 67 -2020 331 -166 957 -66 199 -100 529 -12206 199 -796 67 -66 131 -132 129 -398 197 -230 131 -66 227 -196 65 -526 197 -132 589 -132 597 -100 327 -66 8489 -11212 133 -630 131 -100 133 -166 99 -994 99 -198 333 -1626 329 -130 6045 -13890 65 -434 463 -264 295 -266 1385 -132 461 -134 163951 -12284 131 -858 233 -532 199 -402 97 -266 133 -496 431 -66 1161 -66 493 -68 21495 -5856 +RAW_Data: 95 -560 65 -2896 199 -762 97 -100 65 -430 131 -896 199 -234 101 -800 231 -332 99 -334 133 -132 265 -268 1425 -66 33043 -12400 99 -666 131 -234 67 -232 65 -498 65 -266 65 -498 165 -102 165 -200 2189 -11534 133 -266 197 -232 97 -166 165 -100 99 -98 99 -500 97 -332 99 -200 12547 -12014 65 -232 99 -600 131 -330 299 -332 625 -66 1243 -134 7929 -12344 97 -762 131 -860 165 -298 295 -298 231 -266 97 -134 397 -132 2891 -68 299 -16210 67 -266 133 -234 101 -268 163 -466 97 -232 65 -198 67 -132 67 -100 263 -98 437 -302 133 -66 165 -168 24439 -10722 131 -1534 229 -1318 99 -98 195 -2100 597 -100 733 -134 28455 -10484 231 -2030 67 -100 101 -132 163 -166 265 -854 361 -166 531 -134 233 -100 495 -164 25733 -12966 65 -1880 65 -132 163 -1086 799 -68 16865 -12956 295 -330 163 -232 233 -166 97 -1860 99 -68 333 -66 1613 -98 55627 -12998 97 -266 263 -1594 131 -894 167 -134 231 -332 131 -66 399 -98 99 -66 697 -4972 65 -3944 65 -132 459 -328 197 -100 1557 -98 23673 -12982 333 -928 133 -232 433 -198 131 -360 99 -64 497 -100 463 -98 397 -132 197 -68 765 -13710 65 -166 99 -1684 131 -632 691 -230 263 -66 359 -132 2073 -64 6059 -12430 97 -462 65 -328 65 -792 229 -824 97 -892 529 -166 163 -168 165 -698 165 -166 431 -130 20385 -12774 97 -98 65 -1384 131 -198 131 -622 131 -598 99 -164 129 -98 193 -98 195 -98 263 -98 459 -132 131 -66 73855 -13048 65 -2554 97 -166 761 -68 761 -366 15305 -12094 165 -764 963 -68 65 -66 163 -66 233 -102 333 -100 965 -66 40087 -10292 165 -1724 65 -1754 165 -266 463 -396 267 -432 795 -132 297 -66 267 -68 261 -134 36583 -10588 65 -2738 97 -1184 259 -298 131 -294 395 -98 819 -132 689 -166 7999 -11970 65 -468 63 -1892 429 -262 263 -200 199 -632 265 -66 229 -66 1149 -68 2355 -15782 233 -198 67 -166 295 -818 229 -164 1059 -68 265 -68 1789 -10374 131 -1904 65 -196 229 -230 197 -360 229 -164 129 -1120 963 -166 231 -200 199 -230 333 -10180 67 -966 133 -1264 65 -798 99 -432 65 -898 65 -134 7681 -12052 131 -928 129 -624 99 -526 65 -432 65 -532 65 -596 199 -100 265 -296 895 -100 229 -98 589 -15506 97 -266 65 -434 65 -1520 199 -98 265 -894 293 -198 427 -198 97 -132 459 -64 2145 -66 9075 -7224 99 -66 65 -1060 65 -200 99 -932 167 -894 65 -528 165 -102 927 -100 597 -232 99 -66 97 -98 461 -196 261 -98 197 -264 2909 -134 11635 -804 99 -240 143 -244 369 -5700 1077 -1074 353 -354 1083 -324 +RAW_Data: 1117 -346 1063 -1086 353 -1050 381 -1070 383 -348 1049 -354 1073 -1082 383 -350 1047 -354 1077 -386 1057 -334 1101 -336 1105 -354 1081 -320 1093 -5710 1073 -1076 351 -354 1085 -324 1111 -344 1065 -1084 351 -1082 349 -1068 385 -348 1053 -354 1075 -1078 385 -348 1051 -354 1075 -382 1065 -354 1085 -346 1065 -364 1069 -370 1069 -5686 1077 -1086 367 -354 1047 -354 1095 -346 1095 -1054 363 -1072 369 -1050 387 -328 1077 -374 1051 -1084 349 -348 1081 -376 1081 -348 1063 -352 1073 -380 1067 -356 1053 -376 1083 -5684 1073 -1086 365 -356 1049 -354 1089 -348 1085 -1066 385 -1046 351 -1074 385 -348 1083 -320 1109 -1048 381 -346 1071 -336 1097 -336 1097 -334 1085 -352 1093 -320 1097 -348 1095 -5680 1089 -1064 371 -352 1081 -352 1067 -348 1067 -1078 349 -1094 347 -1096 349 -358 1067 -350 1081 -1076 355 -352 1081 -356 1055 -378 1065 -350 1079 -352 1069 -384 1053 -348 1079 -5702 1099 -1072 353 -350 1065 -354 1087 -348 1097 -1046 347 -1096 377 -1034 377 -360 1085 -356 1049 -1074 351 -382 1051 -362 1071 -374 1051 -388 1049 -352 1093 -346 1061 -384 1049 -5708 1087 -1068 349 -362 1089 -344 1061 -382 1051 -1076 359 -1080 351 -1088 355 -358 1069 -352 1081 -1078 353 -350 1087 -326 1079 -376 1065 -350 1079 -354 1069 -384 1059 -332 1101 -5700 1087 -1044 353 -368 1095 -348 1085 -320 1111 -1044 381 -1064 347 -1090 345 -344 1101 -332 1073 -1074 383 -344 1087 -344 1067 -352 1083 -352 1071 -384 1051 -352 1083 -352 1071 -5712 1077 -1076 355 -350 1087 -326 1079 -374 1053 -1070 375 -1072 357 -1080 353 -334 1103 -334 1073 -1084 349 -378 1051 -376 1067 -364 1073 -368 1065 -336 1101 -332 1083 -352 1083 -5712 1075 -1044 383 -348 1069 -372 1051 -354 1083 -1076 351 -1074 383 -1052 385 -326 1089 -346 1065 -1066 381 -340 1099 -326 1077 -374 1067 -352 1083 -350 1069 -350 1087 -352 1081 -5676 1085 -1074 387 -330 1071 -372 1069 -352 1079 -1076 355 -1078 351 -1084 347 -360 1067 -348 1081 -1074 357 -352 1081 -356 1085 -344 1065 -384 1049 -354 1071 -384 1059 -346 1085 -5680 1087 -1084 343 -348 1103 -352 1065 -354 1087 -1070 345 -1086 351 -1082 351 -340 1097 -346 1087 -1046 361 -352 1083 -354 1089 -346 1067 -350 1081 -354 1071 -386 1053 -346 1097 -5676 1085 -1084 349 -360 1085 -344 1081 -348 1065 -1076 357 -1080 351 -1086 325 -388 1065 -366 1067 -1064 371 -352 1081 -352 1065 -382 1049 -348 1083 -352 1071 -382 1049 -384 1047 -5708 1065 -1062 377 -350 1083 -354 1085 -326 1077 -1070 377 -1052 381 -1066 351 -378 1057 -332 1103 -1060 373 -344 1069 -362 1073 -350 1095 -350 1065 -348 1095 -350 1085 -344 1065 -5704 1079 -1072 347 -382 1049 -354 1075 -382 1051 -1082 351 -1082 351 -1072 +RAW_Data: 381 -348 1053 -354 1071 -1074 381 -348 1071 -370 1049 -386 1047 -356 1091 -346 1083 -346 1067 -354 1071 -5700 1103 -1046 361 -386 1047 -354 1087 -346 1085 -1050 387 -1050 351 -1098 345 -350 1083 -352 1073 -1078 379 -316 1103 -332 1101 -336 1097 -330 1073 -380 1065 -352 1069 -384 1061 -5684 1089 -1064 369 -346 1093 -320 1109 -352 1067 -1076 349 -1070 381 -1032 379 -360 1065 -362 1071 -1064 373 -342 1099 -330 1073 -350 1093 -352 1067 -350 1087 -350 1081 -352 1071 -5710 1077 -1074 355 -354 1081 -326 1113 -346 1083 -1054 381 -1034 383 -1066 379 -316 1099 -334 1097 -1052 379 -358 1067 -350 1081 -352 1067 -386 1055 -334 1101 -334 1107 -322 1085 -5708 1077 -1050 387 -348 1087 -320 1111 -356 1055 -1086 355 -1050 375 -1054 387 -330 1075 -376 1067 -1068 385 -326 1087 -346 1063 -382 1047 -354 1105 -354 1057 -332 1097 -372 1049 -5716 1071 -1080 365 -356 1047 -354 1095 -348 1085 -1070 353 -1050 383 -1070 379 -314 1101 -334 1099 -1052 377 -356 1071 -354 1081 -320 1097 -348 1087 -346 1095 -322 1105 -352 1063 -5702 1075 -1076 351 -346 1109 -342 1087 -322 1081 -1074 351 -1076 383 -1062 347 -362 1065 -364 1071 -1064 373 -344 1099 -330 1077 -350 1097 -320 1097 -348 1095 -326 1079 -376 1063 -5712 1071 -1074 347 -346 1101 -332 1083 -350 1097 -1040 385 -1044 387 -1054 363 -348 1085 -354 1087 -1046 351 -370 1085 -346 1097 -320 1107 -350 1063 -350 1087 -346 1065 -360 1075 -5704 1077 -1076 351 -378 1055 -362 1071 -370 1049 -1084 351 -1084 355 -1054 375 -350 1083 -352 1067 -1076 379 -346 1075 -332 1101 -336 1065 -362 1073 -382 1065 -352 1069 -384 1049 -5682 1077 -1090 369 -354 1049 -354 1093 -348 1087 -1070 347 -1062 383 -1042 385 -346 1073 -372 1051 -1084 351 -346 1079 -374 1083 -354 1051 -354 1091 -348 1089 -354 1047 -354 1097 -5702 1075 -1076 353 -352 1085 -326 1077 -374 1053 -1082 385 -1050 353 -1092 345 -348 1083 -352 1069 -1076 383 -346 1051 -354 1073 -384 1051 -374 1067 -358 1073 -350 1069 -354 1087 -5706 1075 -1042 385 -352 1085 -326 1077 -378 1067 -1050 387 -1048 383 -1064 381 -350 1049 -354 1069 -1080 383 -350 1049 -354 1073 -388 1055 -334 1101 -336 1107 -354 1047 -354 1093 -5674 1109 -1072 353 -350 1083 -348 1051 -376 1065 -1082 351 -1082 351 -1072 379 -348 1073 -332 1073 -1072 381 -346 1085 -344 1065 -362 1073 -372 1047 -386 1047 -354 1089 -346 1083 -5686 1075 -1092 367 -354 1049 -354 1093 -348 1065 -1066 383 -1070 347 -1062 379 -358 1063 -348 1079 -1066 375 -344 1067 -362 1073 -350 1097 -350 1071 -348 1095 -346 1083 -320 1107 -5668 1107 -1078 329 -388 1047 -354 1093 -344 1065 -1082 343 -1098 353 -1080 349 -346 1077 -370 1067 -1052 347 -390 +RAW_Data: 1067 -364 1069 -366 1051 -386 1051 -356 1053 -378 1085 -346 1067 -5712 1053 -1074 381 -346 1083 -344 1063 -350 1077 -1068 377 -1066 383 -1050 351 -378 1057 -364 1073 -1066 371 -346 1063 -354 1071 -386 1053 -346 1103 -332 1071 -382 1063 -352 1065 -5716 1077 -1074 353 -352 1083 -326 1077 -376 1051 -1084 381 -1066 351 -1066 379 -348 1069 -368 1067 -1066 349 -362 1067 -362 1071 -370 1067 -334 1099 -366 1065 -336 1067 -364 1073 -5714 1075 -1050 361 -388 1045 -350 1091 -348 1085 -1054 381 -1066 349 -1070 381 -346 1071 -368 1065 -1052 379 -358 1067 -334 1097 -334 1085 -352 1085 -354 1087 -346 1083 -354 1051 -5706 1087 -1078 349 -348 1075 -372 1051 -382 1067 -1072 353 -1076 353 -1056 361 -350 1083 -352 1083 -1076 351 -376 1055 -364 1071 -370 1049 -352 1083 -356 1087 -346 1083 -352 1049 -5702 1087 -1052 389 -346 1087 -322 1111 -354 1057 -1082 355 -1054 375 -1064 347 -354 1105 -354 1081 -1040 383 -352 1085 -326 1075 -374 1051 -354 1083 -354 1089 -346 1085 -348 1065 -5710 1087 -1062 345 -352 1071 -382 1061 -352 1069 -1078 383 -1052 351 -1082 349 -380 1055 -334 1099 -1062 371 -354 1083 -318 1097 -348 1083 -352 1081 -352 1065 -350 1087 -352 1077 -5710 1069 -1054 389 -328 1075 -376 1049 -356 1079 -1076 351 -1074 385 -1058 365 -344 1073 -352 1097 -1036 383 -350 1063 -354 1087 -348 1097 -328 1071 -376 1063 -332 1101 -336 1101 -5676 1103 -1038 379 -344 1099 -332 1077 -354 1085 -1076 349 -1070 385 -1052 353 -360 1087 -344 1085 -1040 387 -328 1081 -374 1051 -386 1047 -354 1089 -346 1065 -362 1077 -372 1065 -5710 1075 -1042 377 -350 1083 -352 1069 -350 1095 -1050 373 -1064 357 -1074 353 -364 1073 -372 1053 -1074 351 -346 1081 -376 1069 -332 1099 -334 1087 -352 1085 -354 1085 -346 1085 -5682 1075 -1088 329 -388 1049 -354 1089 -346 1065 -1070 353 -1096 345 -1084 351 -362 1085 -344 1067 -1082 355 -358 1083 -354 1047 -354 1093 -346 1065 -360 1073 -372 1081 -354 1045 -5708 1073 -1086 353 -346 1075 -374 1055 -352 1095 -1074 353 -1074 351 -1062 379 -340 1095 -326 1079 -1070 373 -344 1099 -330 1083 -356 1083 -324 1113 -344 1067 -352 1081 -352 1073 -5706 1073 -1076 355 -354 1085 -326 1081 -374 1067 -1054 389 -1048 353 -1096 345 -350 1081 -352 1071 -1080 383 -348 1047 -354 1073 -386 1057 -334 1099 -334 1077 -384 1063 -350 1067 -5704 1071 -1076 357 -354 1081 -356 1083 -346 1067 -1086 353 -1048 383 -1070 383 -314 1081 -354 1071 -1078 385 -348 1047 -354 1107 -354 1057 -334 1099 -334 1085 -354 1083 -354 1085 -5670 1111 -1038 383 -354 1085 -328 1071 -376 1053 -1088 353 -1086 355 -1048 375 -352 1081 -350 1069 -1078 381 -350 1049 -352 1071 -386 1055 -334 1097 -336 +RAW_Data: 1087 -356 1081 -356 1085 -5672 1077 -1074 353 -382 1053 -364 1073 -372 1073 -1054 389 -1050 355 -1054 377 -344 1099 -330 1073 -1076 387 -330 1069 -372 1067 -344 1099 -330 1073 -354 1081 -354 1087 -348 1063 -5718 1081 -1060 369 -342 1067 -360 1073 -354 1083 -1076 349 -1068 385 -1052 353 -360 1085 -346 1087 -1052 389 -330 1069 -372 1051 -356 1083 -354 1087 -346 1089 -348 1065 -352 1069 -5700 1101 -1046 359 -354 1083 -354 1087 -348 1063 -1082 353 -1054 377 -1062 379 -356 1067 -334 1101 -1060 369 -344 1067 -360 1083 -356 1087 -328 1075 -374 1067 -352 1081 -350 1071 -5706 1075 -1076 351 -354 1085 -324 1111 -344 1085 -1040 389 -1048 353 -1094 345 -350 1081 -352 1071 -1076 379 -316 1097 -336 1097 -336 1097 -334 1095 -346 1073 -372 1051 -354 1079 -5692 1085 -1084 351 -346 1075 -374 1051 -354 1083 -1074 351 -1072 385 -1058 381 -328 1073 -348 1085 -1054 389 -328 1075 -376 1067 -350 1081 -352 1069 -350 1085 -352 1083 -350 1071 -5710 1077 -1042 383 -352 1089 -326 1073 -376 1065 -1064 375 -1072 365 -1038 373 -348 1071 -386 1059 -1050 379 -358 1087 -354 1047 -354 1089 -348 1085 -354 1081 -320 1095 -348 1087 -5686 1079 -1084 365 -356 1049 -354 1093 -346 1085 -1052 387 -1048 355 -1090 347 -350 1083 -352 1071 -1076 379 -314 1099 -334 1097 -336 1097 -332 1099 -336 1095 -332 1075 -354 1083 -5708 1051 -1080 383 -348 1049 -354 1105 -354 1055 -1084 355 -1052 375 -1084 351 -330 1079 -376 1051 -1074 387 -328 1075 -376 1067 -350 1079 -352 1069 -380 1067 -326 1081 -374 1051 -5714 1075 -1050 395 -356 1047 -354 1091 -348 1095 -1052 375 -1064 353 -1076 351 -346 1077 -372 1065 -1050 379 -360 1065 -362 1069 -370 1065 -334 1099 -332 1097 -336 1097 -332 1083 -5682 1101 -1046 395 -356 1047 -354 1089 -346 1097 -1050 385 -1046 351 -1074 385 -348 1051 -354 1105 -1042 385 -350 1051 -354 1073 -384 1067 -326 1113 -344 1063 -364 1069 -370 1065 -5690 1077 -1074 383 -348 1047 -354 1075 -386 1057 -1054 361 -1076 373 -1052 387 -330 1073 -374 1069 -1054 387 -330 1075 -374 1067 -352 1081 -352 1067 -350 1085 -352 1079 -352 1069 -5712 1075 -1076 351 -354 1085 -326 1109 -344 1083 -1054 387 -1052 355 -1054 375 -352 1085 -318 1097 -1076 379 -314 1099 -334 1103 -356 1079 -320 1091 -348 1085 -352 1081 -350 1067 -5708 1075 -1076 355 -350 1085 -326 1079 -374 1053 -1084 351 -1084 353 -1090 343 -350 1079 -354 1069 -1080 379 -346 1073 -332 1073 -382 1065 -352 1067 -380 1067 -326 1081 -374 1069 -5680 1103 -1070 345 -346 1099 -330 1073 -388 1047 -1070 351 -1078 385 -1058 363 -346 1081 -354 1087 -1046 351 -368 1095 -348 1051 -354 1077 -384 1065 -326 1113 -344 1085 -350 1061 -5708 1053 -1084 +RAW_Data: 351 -364 1073 -372 1069 -352 1083 -1040 353 -1110 353 -1056 361 -348 1081 -354 1083 -1078 351 -376 1059 -346 1055 -354 1079 -386 1057 -364 1071 -368 1037 -386 1047 -5706 1073 -1084 355 -334 1101 -336 1083 -354 1083 -1074 351 -1072 383 -1050 351 -360 1087 -346 1087 -1038 383 -344 1087 -346 1063 -362 1077 -370 1051 -354 1085 -356 1087 -344 1065 -5704 1081 -1074 345 -384 1047 -354 1069 -384 1057 -1086 325 -1078 373 -1052 385 -330 1079 -374 1049 -1072 381 -346 1085 -344 1067 -362 1073 -370 1067 -334 1101 -332 1071 -386 1049 -5712 1077 -1044 383 -346 1075 -370 1065 -348 1085 -1048 361 -1072 389 -1048 353 -364 1085 -354 1079 -1042 385 -354 1087 -328 1073 -374 1071 -352 1081 -320 1099 -348 1085 -352 1083 -5668 1087 -1084 353 -364 1069 -368 1053 -380 1067 -1072 353 -1078 349 -1068 355 -362 1067 -348 1083 -1074 357 -350 1085 -356 1081 -344 1083 -354 1047 -354 1093 -348 1083 -352 1079 -5704 1073 -1052 387 -330 1077 -372 1051 -352 1085 -1076 349 -1072 379 -1070 323 -388 1063 -348 1077 -1064 375 -352 1079 -352 1065 -384 1049 -352 1083 -352 1069 -350 1085 -352 1083 -5676 1085 -1080 351 -366 1071 -366 1053 -352 1085 -1076 351 -1070 379 -1064 349 -360 1065 -364 1073 -1064 369 -346 1071 -358 1073 -350 1065 -354 1091 -380 1051 -348 1083 -352 1069 -5712 1077 -1074 353 -352 1085 -326 1075 -374 1065 -1066 361 -1074 371 -1056 387 -330 1071 -372 1051 -1086 353 -336 1095 -370 1069 -354 1079 -320 1095 -348 1097 -350 1051 -354 1077 -5708 1075 -1078 355 -352 1085 -326 1081 -374 1051 -1082 349 -1100 321 -1098 345 -348 1101 -332 1099 -1072 325 -388 1065 -334 1099 -368 1051 -352 1083 -356 1053 -378 1083 -352 1047 -5710 1073 -1072 383 -314 1113 -344 1067 -364 1067 -1068 371 -1054 389 -1050 355 -362 1087 -354 1049 -1074 351 -382 1053 -362 1077 -370 1051 -352 1095 -352 1065 -348 1097 -324 1079 -5690 1101 -1074 355 -350 1081 -350 1085 -346 1081 -1050 387 -1048 355 -1094 345 -350 1083 -352 1069 -1074 379 -346 1073 -366 1067 -346 1085 -354 1073 -352 1055 -360 1075 -374 1051 -5718 1071 -1048 395 -356 1047 -354 1091 -346 1085 -1052 383 -1066 349 -1070 381 -314 1101 -334 1085 -1074 351 -346 1081 -376 1067 -332 1099 -334 1099 -336 1101 -330 1085 -350 1065 -5702 1075 -1072 381 -348 1051 -374 1069 -366 1067 -1064 371 -1070 351 -1080 351 -376 1047 -382 1047 -1078 357 -352 1083 -358 1053 -374 1051 -386 1049 -354 1093 -344 1065 -350 1079 -5720 1067 -1076 355 -352 1085 -326 1077 -376 1053 -1086 353 -1084 355 -1056 375 -344 1093 -322 1105 -1074 351 -348 1073 -372 1065 -334 1099 -332 1101 -346 1083 -352 1079 -354 1057 -5706 1077 -1074 347 -348 1081 -354 1071 -384 1057 -1052 +RAW_Data: 361 -1076 373 -1050 387 -330 1075 -374 1049 -1086 387 -330 1073 -370 1053 -352 1083 -354 1085 -346 1065 -362 1071 -370 1065 -5682 1105 -1036 377 -346 1099 -330 1085 -354 1085 -1046 353 -1096 347 -1086 351 -360 1085 -344 1085 -1052 381 -314 1113 -344 1083 -354 1047 -354 1093 -348 1067 -362 1073 -374 1049 -5716 1071 -1052 363 -388 1047 -354 1091 -346 1065 -1080 347 -1090 345 -1064 379 -358 1069 -334 1097 -1062 369 -352 1083 -320 1099 -348 1065 -362 1075 -374 1067 -334 1099 -332 1073 -5720 1073 -1048 395 -356 1049 -356 1089 -346 1065 -1084 343 -1072 361 -1084 355 -334 1101 -336 1099 -1058 363 -344 1085 -354 1089 -326 1075 -376 1051 -356 1081 -356 1085 -346 1065 -5688 1111 -1058 367 -348 1065 -352 1069 -384 1067 -1042 379 -1070 383 -1052 351 -330 1115 -346 1087 -1056 351 -346 1077 -376 1083 -352 1061 -352 1067 -350 1097 -326 1109 -346 1083 -5686 1075 -1048 397 -356 1047 -354 1091 -346 1085 -1054 389 -1048 353 -1058 377 -352 1085 -352 1069 -1074 381 -350 1051 -352 1069 -386 1055 -366 1069 -368 1051 -354 1083 -356 1083 -5672 1081 -1074 351 -382 1055 -364 1069 -372 1053 -1086 355 -1054 359 -1076 373 -352 1079 -350 1065 -1078 383 -316 1083 -354 1073 -352 1085 -352 1083 -350 1071 -348 1099 -328 1075 -5694 1099 -1072 351 -354 1083 -326 1111 -342 1085 -1054 353 -1062 381 -1064 379 -314 1101 -334 1099 -1058 361 -348 1081 -354 1081 -348 1087 -346 1085 -356 1049 -354 1091 -348 1065 -5710 1073 -1078 347 -346 1101 -332 1073 -350 1093 -1074 355 -1050 385 -1062 347 -366 1099 -326 1077 -1066 373 -352 1083 -320 1097 -350 1097 -326 1075 -376 1065 -332 1097 -370 1065 -5684 1101 -1036 377 -344 1101 -330 1073 -356 1079 -1074 349 -1074 385 -1056 365 -344 1081 -354 1085 -1042 379 -340 1095 -348 1085 -320 1109 -356 1055 -332 1101 -334 1107 -354 1049 -5704 1087 -1048 389 -350 1081 -320 1111 -356 1055 -1052 389 -1048 377 -1056 391 -328 1073 -374 1057 -1084 353 -344 1077 -372 1053 -356 1083 -356 1085 -346 1063 -352 1081 -352 1073 -5712 1073 -1074 353 -356 1079 -318 1117 -346 1065 -1056 389 -1048 381 -1066 383 -314 1081 -352 1073 -1080 385 -316 1085 -352 1071 -352 1097 -326 1109 -344 1071 -354 1081 -320 1099 -5696 1069 -1076 355 -356 1083 -324 1113 -346 1063 -1078 347 -1090 379 -1032 377 -356 1069 -354 1081 -1040 387 -354 1087 -326 1075 -376 1069 -342 1097 -330 1077 -356 1083 -324 1115 -5678 1081 -1076 349 -346 1089 -334 1095 -336 1107 -1058 355 -1054 389 -1046 377 -354 1081 -320 1097 -1078 379 -314 1097 -332 1099 -338 1093 -332 1073 -354 1091 -350 1069 -350 1095 -5674 1111 -1044 381 -314 1099 -336 1097 -336 1095 -1064 369 -1038 389 -1050 381 -338 1093 -350 +RAW_Data: 1081 -1044 395 -322 1081 -354 1087 -348 1085 -356 1083 -320 1093 -348 1089 -356 1049 -5706 1077 -1052 387 -350 1087 -320 1113 -318 1097 -1042 379 -1066 381 -1030 379 -362 1063 -364 1069 -1068 373 -356 1081 -320 1095 -350 1087 -352 1063 -352 1071 -350 1099 -326 1111 -5670 1081 -1076 349 -380 1057 -334 1097 -334 1089 -1054 389 -1056 361 -1072 373 -354 1083 -320 1091 -1074 381 -318 1079 -352 1071 -352 1091 -348 1083 -322 1113 -358 1053 -332 1133 -810 65 -262 181 -142572 65 -98 199 -100 133 -300 99 -166 99 -232 99 -134 333 -166 231 -330 99 -230 493 -100 361 -66 525 -12248 131 -268 133 -268 131 -400 229 -726 97 -494 265 -402 65 -664 363 -134 365 -166 131 -262 395 -98 795 -98 68827 -6766 99 -1626 99 -66 65 -700 97 -864 565 -464 99 -98 133 -230 197 -166 591 -98 5135 -12244 97 -2452 65 -734 165 -198 233 -266 631 -198 12423 -12322 165 -796 67 -100 99 -98 67 -862 133 -728 263 -66 361 -166 129 -100 395 -166 625 -232 131 -66 8113 -12068 229 -132 65 -1394 99 -134 65 -300 165 -134 65 -102 99 -166 133 -766 297 -98 199 -102 1067 -166 859 -98 25307 -13210 65 -1764 97 -264 163 -496 133 -132 65 -66 427 -98 721 -68 531 -134 1591 -100 54955 -11122 65 -726 65 -368 65 -492 99 -428 233 -164 99 -266 131 -498 197 -430 295 -66 2793 -130 11307 -12324 97 -132 193 -1216 65 -1286 131 -594 399 -100 431 -266 495 -100 165 -132 63531 -12252 99 -166 165 -596 99 -496 99 -298 97 -368 65 -134 131 -198 165 -434 99 -266 301 -364 37153 -11928 65 -332 195 -528 131 -230 97 -1126 131 -530 99 -790 361 -100 895 -98 597 -66 699 -100 15803 -10136 99 -2044 65 -400 165 -534 165 -134 99 -434 65 -966 97 -100 133 -134 1125 -66 589 -100 26555 -12218 165 -334 65 -100 99 -2586 65 -732 531 -100 461 -132 3347 -10206 97 -2084 63 -296 99 -164 65 -1052 97 -66 231 -330 65 -232 331 -596 1119 -424 361 -66 28413 -12166 67 -264 161 -228 97 -390 65 -856 131 -66 763 -132 201 -132 9717 -13508 129 -990 65 -100 97 -296 165 -724 65 -368 231 -98 401 -66 527 -66 767 -100 637 -66 109351 -13036 165 -796 65 -200 133 -100 199 -600 133 -134 99 -932 461 -132 399 -264 47323 -12184 97 -566 231 -400 67 -1456 229 -132 97 -394 163 -230 1579 -66 231 -164 10685 -12812 99 -132 67 -464 133 -1162 331 -132 99 -266 167 -200 99 -268 791 -164 823 -132 329 -134 63603 -10646 65 -662 165 -234 163 -630 463 -98 233 -100 195 -262 131 -132 491 -12204 65 -1156 131 -954 295 -132 99 -332 65 -664 789 -328 +RAW_Data: 1351 -8346 67 -4708 133 -400 99 -298 65 -556 65 -396 295 -66 263 -64 163 -100 131 -100 97 -68 131 -166 65 -166 497 -132 999 -132 5609 -4806 131 -4842 131 -298 133 -332 67 -596 131 -1186 263 -268 495 -100 461 -462 165 -66 525 -100 1579 -100 4557 -10356 165 -1614 165 -98 97 -630 65 -164 461 -164 65 -558 231 -130 131 -164 591 -66 557 -9122 65 -166 101 -6060 295 -68 65 -594 163 -368 263 -98 65 -98 99 -294 99 -66 363 -432 329 -66 1987 -100 25465 -9810 197 -100 131 -262 97 -530 99 -168 65 -166 431 -530 99 -232 167 -266 97 -234 1065 -66 131 -198 17549 -9930 899 -100 367 -994 67 -132 167 -794 231 -98 99 -464 299 -134 131 -100 199 -732 97 -296 131 -66 1157 -132 359 -130 47799 -12132 99 -630 197 -132 165 -502 195 -164 261 -98 261 -98 263 -66 195 -296 195 -198 65 -66 393 -66 955 -100 12501 -12452 97 -2942 165 -262 97 -228 65 -98 359 -130 625 -100 723 -66 365 -13612 99 -832 233 -66 99 -298 65 -464 233 -164 65 -164 1053 -362 10409 -11212 197 -794 131 -970 67 -132 99 -366 167 -366 165 -134 167 -664 99 -302 1253 -200 131 -15330 97 -132 259 -100 63 -558 165 -398 65 -860 231 -66 163 -98 263 -364 559 -100 1313 -66 89369 -10410 65 -1788 233 -132 133 -1062 165 -532 65 -632 63 -794 65 -166 97 -132 133 -66 431 -100 467 -132 199 -364 15615 -12276 99 -662 165 -66 133 -564 197 -1460 65 -66 65 -364 231 -396 165 -134 5835 -12662 165 -436 163 -468 65 -100 299 -728 99 -534 265 -166 263 -100 627 -100 197 -66 43301 -12090 163 -96 197 -692 97 -862 129 -368 165 -232 65 -998 197 -66 393 -196 683 -98 6471 -12036 165 -662 133 -302 99 -566 727 -66 2289 -66 7119 -12372 99 -662 97 -300 99 -66 131 -962 165 -362 131 -168 65 -428 133 -134 1797 -66 63965 -10524 263 -1458 265 -298 99 -166 199 -130 789 -68 23871 -12668 65 -990 99 -196 331 -990 755 -100 233 -132 267 -13192 65 -932 233 -134 199 -164 133 -568 99 -898 331 -134 99 -66 961 -66 7013 -10302 65 -664 131 -432 99 -532 199 -466 329 -364 65 -134 429 -198 759 -132 617 -198 38455 -12426 199 -134 99 -1252 99 -396 229 -660 99 -362 197 -164 197 -132 689 -66 161 -98 357 -330 265 -100 15001 -11544 133 -636 131 -132 99 -232 65 -1488 165 -636 131 -266 133 -134 367 -66 197 -100 267 -6574 131 -260 165 -166 65 -132 65 -828 295 -66 589 -100 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub new file mode 100644 index 00000000000..3ea21478e15 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 868350000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Marantec24 +Bit: 24 +Key: 00 00 00 00 00 AC 05 C4 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24_raw.sub new file mode 100644 index 00000000000..4a8c34b212f --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24_raw.sub @@ -0,0 +1,14 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 868350000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1224 -1300 1801 -3200 1615 -2374 821 -3198 1603 -2410 785 -3196 815 -3188 1605 -2398 1605 -2398 1607 -2400 1605 -2398 1605 -2396 1601 -2400 1605 -2398 809 -3184 1603 -2396 815 -3194 811 -3190 811 -3194 1603 -2398 1603 -2398 1601 -2392 811 -3194 1605 -2394 1607 -16170 131 -196 217 -493440 135 -1296 1807 -3210 1591 -2396 811 -3198 1591 -2394 807 -3218 807 -3188 1607 -2400 1605 -2394 1599 -2402 1601 -2392 1609 -2400 1605 -2392 1603 -2392 815 -3190 1609 -2402 809 -3188 813 -3192 813 -3190 1605 -2400 1603 -2396 1605 -2396 813 -3194 1601 -2402 1601 -16170 133 -200 219 -382462 101 -1314 1813 -3194 1581 -2414 801 -3214 1605 -2398 807 -3190 811 -3190 1601 -2394 1603 -2398 1607 -2398 1605 -2396 1605 -2394 1601 -2394 1609 -2396 815 -3194 1603 -2400 809 -3194 811 -3190 811 -3190 1603 -2396 1603 -2396 1607 -2398 811 -3192 1607 -2396 1601 -16176 131 -198 217 -348436 303 -1106 1817 -3194 1609 -2386 803 -3214 1597 -2392 811 -3186 815 -3192 1611 -2396 1601 -2394 1609 -2404 1605 -2396 1605 -2396 1607 -2392 1601 -2396 813 -3192 1603 -2394 813 -3190 815 -3188 811 -3194 1601 -2396 1607 -2394 1601 -2396 815 -3186 1611 -2396 1609 -16168 131 -198 217 -349492 347 -1080 1799 -3192 1617 -2388 801 -3218 1601 -2396 809 -3190 809 -3192 1605 -2394 1599 -2394 1605 -2398 1607 -2398 1599 -2398 1607 -2396 1601 -2396 811 -3192 1605 -2400 811 -3184 813 -3192 811 -3192 1607 -2398 1601 -2398 1607 -2400 811 -3190 1603 -2394 1607 -16176 131 -204 213 -447994 135 -1330 977 -1036 65 -230 181 -514880 135 -66 67 -1140 1815 -3192 1615 -2388 803 -3214 1603 -2396 813 -3190 811 -3190 1609 -2398 1601 -2392 1603 -2396 1607 -2398 1607 -2398 1607 -2398 1605 -2394 813 -3186 1611 -2404 809 -3186 811 -3192 813 -3188 1605 -2394 1607 -2400 1607 -2398 807 -3190 1605 -2398 1603 -16172 131 -200 217 -395118 99 -1304 1841 -3160 1621 -2388 805 -3186 1631 -2392 809 -3182 811 -3188 1605 -2402 1601 -2398 1601 -2402 1607 -2398 1605 -2398 1601 -2392 1605 -2404 809 -3188 1599 -2396 817 -3192 811 -3192 811 -3190 1599 -2392 1603 -2398 1607 -2404 809 -3192 1603 -2402 1605 -16164 133 -198 187 -382202 137 -1302 1803 -3192 1601 -2404 803 -3184 1633 -2392 807 -3190 811 -3188 1601 -2400 1607 -2402 1601 -2392 1601 -2396 1607 -2400 1603 -2398 1605 -2398 811 -3184 1601 -2400 813 -3188 809 -3190 811 -3192 1605 -2400 1605 -2396 1599 -2402 809 -3192 1607 -2400 1607 -16174 99 -232 181 -361858 65 -1368 1785 -3228 1567 -2426 777 -3222 1601 -2402 785 -3198 815 -3186 1609 -2402 1601 -2396 1605 -2402 1603 -2396 1605 -2398 1601 -2400 1603 -2398 813 -3194 1605 -2400 809 -3186 813 -3190 813 -3188 1607 -2396 1605 -2400 1605 -2394 809 -3182 1607 -2400 1607 -16210 65 -236 177 -379100 1819 -3192 1611 -2384 799 -3220 1601 -2396 811 -3186 809 -3188 1605 -2394 1607 -2398 +RAW_Data: 1599 -2394 1603 -2396 1609 -2402 1603 -2396 1607 -2398 809 -3196 1603 -2394 809 -3188 813 -3194 809 -3188 1605 -2394 1599 -2396 1609 -2404 811 -3184 1605 -2400 1601 -16162 133 -234 191 -393094 97 -1316 1021 -1010 67 -246 173 -677840 131 -64 59 -1178 1773 -3210 1593 -2430 773 -3222 1601 -2396 811 -3186 813 -3190 1603 -2398 1603 -2396 1607 -2398 1605 -2400 1601 -2396 1605 -2396 1601 -2396 815 -3190 1607 -2402 811 -3190 811 -3186 811 -3192 1607 -2396 1603 -2396 1601 -2400 813 -3188 1607 -2404 1607 -15160 827 -3204 1577 -2404 813 -3200 1591 -2390 807 -3220 807 -3186 1599 -2400 1605 -2398 1603 -2400 1603 -2396 1605 -2398 1605 -2398 1599 -2394 809 -3190 1611 -2394 809 -3186 815 -3192 809 -3192 1603 -2398 1601 -2396 1599 -2396 815 -3188 1609 -2400 1605 -15178 801 -3222 1575 -2392 805 -3190 1615 -2396 809 -3190 819 -3198 1601 -2402 1577 -2402 1609 -2400 1605 -2398 1605 -2396 1605 -2398 1601 -2400 809 -3184 1605 -2396 809 -3190 811 -3192 813 -3190 1601 -2404 1605 -2394 1599 -2396 811 -3190 1605 -2400 1601 -15174 831 -3166 1615 -2396 783 -3200 1611 -2398 813 -3192 811 -3188 1601 -2396 1603 -2398 1607 -2396 1605 -2396 1603 -2398 1601 -2394 1601 -2398 811 -3192 1601 -2394 813 -3192 809 -3194 807 -3190 1605 -2394 1599 -2394 1601 -2394 813 -3194 1601 -2398 1603 -15178 793 -3228 1577 -2404 809 -3186 1611 -2396 815 -3192 811 -3188 1605 -2400 1577 -2404 1603 -2396 1607 -2400 1601 -2398 1603 -2394 1605 -2396 811 -3192 1605 -2394 811 -3190 811 -3188 807 -3186 1601 -2396 1605 -2398 1601 -2398 813 -3186 1601 -2394 1605 -15178 797 -3204 1581 -2400 813 -3188 1603 -2400 813 -3192 811 -3192 1607 -2398 1605 -2398 1607 -2394 1601 -2400 1605 -2398 1601 -2396 1601 -2394 809 -3190 1605 -2400 811 -3186 813 -3192 811 -3184 1601 -2396 1605 -2396 1605 -2400 809 -3184 1599 -2400 1605 -15146 827 -3188 1613 -2402 785 -3200 1605 -2396 815 -3192 811 -3190 1605 -2396 1605 -2396 1607 -2398 1601 -2398 1601 -2392 1599 -2398 1603 -2398 811 -3186 1605 -2396 811 -3190 811 -3192 809 -3190 1597 -2394 1599 -2398 1605 -2398 813 -3186 1599 -2396 1605 -15176 793 -3226 1577 -2398 817 -3198 1605 -2370 817 -3192 813 -3192 1609 -2396 1601 -2396 1605 -2396 1603 -2394 1605 -2394 1607 -2398 1607 -2394 809 -3188 1605 -2400 811 -3194 809 -3188 811 -3192 1605 -2400 1603 -2388 1605 -2394 811 -3186 1605 -2396 1605 -15180 797 -3202 1605 -2398 781 -3196 1605 -2396 815 -3184 817 -3196 1603 -2398 1605 -2398 1605 -2400 1603 -2394 1601 -2396 1607 -2398 1605 -2396 811 -3188 1605 -2396 809 -3186 807 -3194 811 -3194 1603 -2396 1597 -2396 1605 -2396 811 -3192 1603 -2396 1601 -15146 831 -3190 1603 -2404 777 -3224 1605 -2398 785 -3196 813 -3192 1607 -2396 1601 -2398 1607 -2394 1605 -2398 1603 -2394 1601 -2400 1599 -2396 807 -3192 1603 -2396 809 -3186 +RAW_Data: 813 -3190 809 -3190 1603 -2400 1603 -2398 1599 -2390 813 -3192 1603 -2394 1603 -15146 823 -3204 1603 -2398 787 -3204 1595 -2388 805 -3216 807 -3192 1605 -2400 1601 -2398 1597 -2394 1605 -2396 1603 -2398 1605 -2392 1601 -2396 809 -3192 1605 -2398 807 -3190 809 -3186 811 -3194 1603 -2394 1605 -2394 1599 -2398 813 -3192 1609 -2394 1603 -15174 795 -3206 1605 -2398 783 -3196 1607 -2400 809 -3188 813 -3188 1609 -2402 1601 -2394 1609 -2396 1603 -2396 1603 -2400 1599 -2388 1599 -2400 811 -3192 1607 -2394 811 -3186 811 -3190 809 -3194 1603 -2400 1599 -2394 1601 -2392 813 -3192 1603 -2396 1605 -15162 799 -3218 1581 -2404 807 -3202 1603 -2396 787 -3196 819 -3192 1611 -2394 1603 -2396 1607 -2402 1601 -2392 1599 -2392 1601 -2400 1607 -2398 811 -3192 1603 -2396 811 -3190 813 -3188 813 -3186 1603 -2394 1601 -2392 1605 -2400 809 -3188 1609 -2394 1601 -15156 829 -3188 1601 -2414 797 -3182 1629 -2394 807 -3192 811 -3188 1603 -2398 1599 -2392 1603 -2398 1603 -2396 1603 -2396 1607 -2400 1607 -2392 809 -3186 1603 -2400 813 -3194 811 -3192 809 -3188 1599 -2400 1603 -2404 1609 -2394 809 -3194 1599 -2394 1607 -15176 829 -3158 1623 -2404 773 -3224 1605 -2386 799 -3210 811 -3190 1607 -2392 1605 -2398 1607 -2400 1601 -2388 1605 -2398 1603 -2402 1599 -2392 809 -3188 1605 -2400 811 -3186 813 -3190 809 -3190 1603 -2396 1599 -2404 1603 -2400 809 -3188 1605 -2396 1607 -15146 829 -3216 1561 -2414 817 -3196 1599 -2404 797 -3180 809 -3212 1607 -2400 1601 -2394 1603 -2400 1603 -2396 1599 -2400 1605 -2396 1605 -2394 813 -3186 1607 -2394 811 -3186 809 -3190 813 -3192 1607 -2398 1603 -2398 1601 -2396 813 -3192 1603 -2392 1605 -15144 827 -3188 1613 -2404 809 -3192 1615 -2370 811 -3188 811 -3188 1611 -2398 1603 -2400 1601 -2394 1601 -2402 1605 -2396 1601 -2394 1609 -2398 811 -3186 1603 -2392 813 -3196 811 -3182 809 -3188 1603 -2402 1605 -2400 1599 -2394 809 -3194 1607 -2398 1601 -15148 831 -3186 1587 -2424 811 -3192 1575 -2408 803 -3188 805 -3222 1599 -2392 1601 -2400 1609 -2398 1601 -2392 1597 -2394 1601 -2400 1601 -2400 807 -3190 1601 -2400 813 -3190 809 -3190 809 -3188 1607 -2398 1601 -2396 1605 -2398 809 -3184 1603 -2400 1605 -15176 795 -3200 1613 -2400 783 -3198 1603 -2398 813 -3192 809 -3186 1607 -2398 1605 -2398 1605 -2398 1599 -2394 1605 -2398 1603 -2392 1599 -2396 809 -3194 1609 -2390 811 -3194 813 -3188 811 -3188 1599 -2394 1603 -2398 1601 -2394 815 -3192 1605 -2402 1601 -15150 831 -3186 1605 -2412 799 -3206 1601 -2392 809 -3186 813 -3192 1603 -2402 1601 -2392 1605 -2398 1607 -2396 1601 -2392 1609 -2402 1599 -2396 811 -3186 1601 -2398 815 -3196 809 -3188 809 -3188 1607 -2394 1605 -2394 1603 -2394 811 -3194 1603 -2398 1607 -15174 797 -3218 1563 -2424 785 -3194 1633 -2396 795 -3178 805 -3214 1607 -2394 1603 -2400 +RAW_Data: 1603 -2392 1603 -2398 1605 -2400 1597 -2392 1603 -2396 811 -3198 1603 -2390 809 -3192 811 -3188 813 -3192 1599 -2394 1607 -2398 1607 -2394 811 -3192 1601 -2394 1605 -15152 861 -3154 1603 -2410 799 -3186 1601 -2422 809 -3190 809 -3186 1601 -2392 1603 -2394 1611 -2398 1605 -2400 1601 -2392 1609 -2396 1603 -2398 809 -3186 1605 -2400 811 -3188 811 -3188 807 -3192 1605 -2402 1597 -2392 1603 -2396 813 -3194 1601 -2398 1605 -15174 795 -3200 1597 -2428 785 -3196 1613 -2398 785 -3192 815 -3192 1611 -2400 1603 -2394 1603 -2400 1601 -2398 1607 -2394 1603 -2398 1603 -2396 811 -3190 1605 -2394 811 -3194 811 -3182 811 -3192 1607 -2392 1599 -2394 1601 -2398 811 -3192 1607 -2392 1603 -15156 827 -3190 1607 -2408 797 -3210 1599 -2398 777 -3218 811 -3192 1601 -2400 1599 -2398 1601 -2396 1597 -2396 1601 -2392 1607 -2392 1605 -2400 813 -3190 1601 -2396 811 -3194 809 -3190 813 -3190 1603 -2394 1599 -2390 1603 -2400 811 -3190 1607 -2398 1605 -15150 825 -3192 1603 -2404 793 -3178 1605 -2422 777 -3222 775 -3218 1603 -2398 1605 -2398 1597 -2392 1603 -2398 1605 -2400 1601 -2394 1601 -2392 811 -3192 1609 -2398 813 -3190 809 -3182 809 -3184 1607 -2398 1603 -2396 1607 -2398 813 -3190 1607 -2396 1601 -15172 797 -3230 1563 -2424 805 -3190 1599 -2404 795 -3182 807 -3214 1601 -2402 1603 -2396 1601 -2396 1603 -2398 1605 -2398 1599 -2392 1601 -2402 813 -3192 1601 -2396 809 -3188 811 -3188 809 -3192 1605 -2400 1607 -2398 1599 -2394 809 -3190 1607 -2400 1605 -15180 827 -3190 1577 -2394 819 -3196 1613 -2366 815 -3196 813 -3190 1607 -2396 1607 -2402 1599 -2398 1605 -2400 1603 -2398 1601 -2392 1605 -2400 811 -3186 1603 -2400 813 -3190 809 -3196 807 -3182 1601 -2396 1609 -2398 1601 -2398 813 -3192 1601 -2394 1607 -15174 793 -3202 1599 -2424 787 -3196 1607 -2404 785 -3192 815 -3188 1609 -2404 1603 -2398 1607 -2396 1601 -2400 1603 -2394 1601 -2394 1603 -2400 811 -3190 1605 -2400 811 -3188 809 -3190 813 -3194 1597 -2398 1607 -2394 1603 -2394 809 -3190 1603 -2392 1607 -15180 795 -3230 1581 -2392 807 -3218 1593 -2408 777 -3220 781 -3204 1597 -2424 1605 -2394 1595 -2392 1605 -2394 1599 -2396 1605 -2402 1603 -2394 809 -3188 1601 -2396 813 -3194 811 -3188 813 -3190 1605 -2398 1607 -2392 1601 -2398 811 -3192 1599 -2400 1605 -15178 797 -3218 1595 -2400 803 -3198 1605 -2370 825 -3182 803 -3214 1603 -2396 1601 -2398 1601 -2394 1599 -2398 1603 -2396 1607 -2394 1605 -2394 809 -3190 1607 -2398 809 -3194 811 -3188 809 -3194 1605 -2394 1599 -2396 1605 -2396 809 -3196 1603 -2402 1599 -15160 829 -3192 1579 -2400 817 -3198 1605 -2398 783 -3194 813 -3190 1609 -2400 1607 -2400 1599 -2394 1601 -2394 1609 -2398 1601 -2396 1605 -2394 809 -3186 1609 -2400 811 -3186 809 -3196 811 -3190 1605 -2396 1601 -2398 1607 -2396 809 -3186 1605 -2398 1607 -15170 +RAW_Data: 827 -3192 1595 -2376 813 -3192 1601 -2414 797 -3186 807 -3220 1601 -2398 1603 -2394 1599 -2396 1607 -2400 1605 -2394 1597 -2398 1603 -2398 813 -3192 1603 -2394 809 -3188 809 -3188 811 -3192 1607 -2396 1601 -2398 1605 -2398 811 -3188 1603 -2400 1603 -15174 829 -3162 1627 -2374 803 -3224 1571 -2412 801 -3186 807 -3222 1605 -2392 1605 -2392 1599 -2394 1605 -2404 1601 -2396 1607 -2396 1601 -2394 809 -3188 1601 -2398 811 -3190 815 -3194 811 -3184 1603 -2400 1605 -2400 1605 -2394 809 -3188 1609 -2394 1605 -15154 829 -3188 1603 -2412 801 -3210 1603 -2398 807 -3182 809 -3196 1605 -2400 1605 -2396 1599 -2402 1607 -2390 1599 -2396 1599 -2400 1607 -2396 811 -3192 1605 -2396 813 -3196 809 -3190 811 -3192 1609 -2394 1597 -2396 1607 -2398 809 -3186 1605 -2394 1605 -15178 795 -3216 1577 -2408 819 -3190 1607 -2394 817 -3194 779 -3194 1607 -2404 1605 -2398 1607 -2394 1601 -2398 1605 -2400 1603 -2402 1607 -2394 811 -3192 1601 -2396 809 -3186 813 -3194 811 -3188 1599 -2394 1601 -2402 1601 -2398 811 -3186 1603 -2396 1611 -15176 799 -3224 1567 -2424 785 -3202 1599 -2396 809 -3204 783 -3198 1605 -2398 1607 -2402 1605 -2398 1607 -2400 1599 -2398 1605 -2392 1603 -2400 811 -3186 1601 -2400 811 -3194 809 -3184 811 -3186 1603 -2396 1603 -2398 1607 -2398 811 -3188 1605 -2396 1605 -15174 829 -3166 1605 -2402 809 -3190 1615 -2368 815 -3194 815 -3192 1605 -2396 1603 -2400 1603 -2400 1605 -2392 1601 -2400 1607 -2400 1601 -2402 811 -3194 1599 -2392 809 -3188 813 -3184 813 -3192 1605 -2400 1605 -2400 1607 -2390 809 -3188 1607 -2398 1603 -15174 829 -3158 1617 -2400 787 -3192 1607 -2404 811 -3184 815 -3190 1607 -2402 1601 -2396 1605 -2400 1601 -2396 1603 -2396 1607 -2400 1603 -2394 809 -3188 1609 -2398 809 -3190 811 -3188 809 -3188 1607 -2396 1599 -2396 1607 -2400 809 -3188 1607 -2398 1603 -15172 797 -3228 1575 -2424 771 -3202 1615 -2386 801 -3198 807 -3218 1587 -2390 1603 -2394 1603 -2424 1603 -2396 1603 -2398 1599 -2394 1605 -2396 809 -3192 1605 -2400 807 -3184 809 -3190 813 -3190 1603 -2390 1601 -2394 1601 -2396 813 -3196 1607 -2402 1599 -15152 829 -3194 1605 -2408 793 -3182 1597 -2426 807 -3184 811 -3192 1607 -2392 1603 -2396 1605 -2400 1601 -2394 1603 -2394 1605 -2400 1605 -2394 809 -3190 1605 -2396 811 -3192 809 -3186 811 -3190 1601 -2394 1605 -2400 1607 -2398 809 -3186 1601 -2394 1603 -15174 829 -3160 1635 -2382 811 -3194 1609 -2400 779 -3220 781 -3222 1575 -2406 1603 -2398 1607 -2402 1601 -2394 1603 -2396 1601 -2402 1605 -2398 805 -3190 1605 -2394 813 -3194 809 -3188 811 -3192 1603 -2396 1599 -2394 1607 -2394 811 -3194 1603 -2394 1601 -15174 799 -3216 1599 -2402 785 -3198 1615 -2376 819 -3194 811 -3190 1599 -2394 1623 -2392 1599 -2396 1611 -2382 1599 -2390 1633 -2392 1599 -2396 811 -3194 1599 -2394 811 -3188 +RAW_Data: 811 -3190 809 -3192 1603 -2398 1607 -2392 1599 -2398 811 -3190 1603 -2402 1601 -15172 795 -3194 1603 -2404 807 -3186 1599 -2394 821 -3196 785 -3196 1609 -2396 1609 -2398 1603 -2396 1605 -2400 1599 -2394 1605 -2396 1605 -2398 809 -3190 1601 -2396 811 -3190 809 -3194 809 -3188 1601 -2398 1603 -2398 1607 -2392 807 -3190 1603 -2402 1601 -15178 803 -3198 1579 -2410 807 -3188 1625 -2406 793 -3204 779 -3192 1609 -2408 1597 -2392 1595 -2424 1605 -2394 1601 -2394 1601 -2392 1601 -2396 809 -3194 1607 -2398 811 -3194 811 -3186 809 -3182 1607 -2398 1605 -2392 1605 -2392 809 -3190 1611 -2400 1605 -15154 799 -3228 1567 -2434 795 -3180 1627 -2392 809 -3190 809 -3186 1603 -2396 1599 -2394 1603 -2398 1603 -2398 1603 -2392 1607 -2400 1601 -2390 809 -3186 1601 -2404 811 -3188 811 -3190 813 -3186 1605 -2398 1605 -2392 1599 -2400 813 -3190 1599 -2396 1603 -15184 799 -3194 1607 -2410 795 -3176 1603 -2428 807 -3188 811 -3188 1603 -2394 1607 -2398 1599 -2396 1603 -2400 1605 -2394 1601 -2394 1607 -2400 809 -3186 1607 -2400 809 -3184 811 -3188 809 -3196 1605 -2396 1603 -2394 1607 -2392 809 -3188 1607 -2396 1609 -15176 795 -3226 1567 -2406 819 -3198 1579 -2406 809 -3190 821 -3198 1575 -2400 1603 -2398 1611 -2400 1603 -2398 1607 -2396 1601 -2394 1607 -2402 809 -3190 1603 -2396 811 -3186 809 -3192 811 -3192 1607 -2394 1603 -2398 1601 -2396 809 -3196 1605 -2398 1603 -15148 827 -3196 1597 -2426 775 -3200 1613 -2398 783 -3198 813 -3184 1613 -2400 1607 -2400 1605 -2398 1603 -2400 1601 -2394 1603 -2398 1605 -2398 809 -3192 1603 -2396 811 -3190 811 -3190 809 -3194 1605 -2394 1601 -2396 1601 -2400 811 -3192 1607 -2396 1603 -15162 797 -3244 1573 -2398 817 -3196 1603 -2404 795 -3210 775 -3220 1603 -2396 1603 -2396 1607 -2394 1607 -2368 1633 -2392 1601 -2396 1607 -2396 811 -3190 1605 -2400 807 -3186 811 -3194 809 -3186 1607 -2396 1603 -2392 1599 -2394 811 -3186 1611 -2396 1601 -15178 763 -3288 1501 -2496 741 -3254 1543 -2442 777 -3194 815 -3206 1585 -2390 1603 -2426 1601 -2392 1599 -2400 1605 -2396 1599 -2398 1603 -2398 809 -3190 1601 -2396 811 -3188 811 -3188 811 -3194 1607 -2396 1599 -2396 1605 -2398 813 -3190 1605 -2400 1603 -16206 65 -230 181 -579692 165 -1118 1797 -3196 1591 -2420 773 -3224 1603 -2394 809 -3188 809 -3188 1609 -2402 1603 -2398 1599 -2400 1605 -2400 1605 -2396 1605 -2396 1603 -2394 813 -3194 1607 -2398 809 -3188 809 -3192 809 -3196 1603 -2394 1599 -2396 1605 -2402 811 -3190 1605 -2400 1605 -15178 793 -3222 1577 -2402 809 -3192 1601 -2394 807 -3202 819 -3196 1609 -2396 1603 -2396 1601 -2392 1613 -2400 1579 -2398 1613 -2396 1603 -2396 813 -3192 1607 -2394 813 -3198 809 -3188 809 -3188 1599 -2398 1607 -2400 1607 -2398 807 -3186 1603 -2400 1607 -15178 823 -3168 1615 -2398 809 -3192 1615 -2398 783 -3228 +RAW_Data: 779 -3200 1607 -2394 1605 -2402 1607 -2394 1601 -2396 1603 -2400 1607 -2398 1603 -2396 809 -3182 1607 -2402 813 -3194 811 -3188 811 -3186 1603 -2402 1605 -2398 1607 -2396 809 -3188 1603 -2398 1609 -15162 829 -3204 1575 -2428 783 -3202 1597 -2422 775 -3214 809 -3192 1605 -2400 1603 -2402 1601 -2392 1603 -2394 1605 -2392 1611 -2398 1603 -2398 811 -3182 1609 -2400 813 -3196 811 -3186 811 -3186 1609 -2400 1605 -2394 1601 -2402 807 -3190 1607 -2398 1607 -15178 829 -3182 1595 -2424 773 -3224 1589 -2384 805 -3222 809 -3188 1603 -2398 1605 -2400 1599 -2396 1601 -2392 1601 -2400 1609 -2396 1605 -2398 813 -3190 1603 -2396 813 -3186 811 -3194 811 -3196 1603 -2394 1603 -2400 1603 -2396 809 -3186 1609 -2400 1605 -15160 825 -3198 1605 -2402 785 -3208 1599 -2426 775 -3220 807 -3186 1601 -2396 1609 -2398 1607 -2392 1599 -2402 1605 -2398 1599 -2398 1603 -2402 807 -3190 1603 -2398 813 -3186 813 -3196 809 -3184 1601 -2394 1603 -2428 1571 -2400 815 -3220 1575 -2402 1609 -15178 793 -3234 1575 -2404 819 -3188 1599 -2398 807 -3204 819 -3192 1581 -2400 1607 -2396 1607 -2402 1601 -2392 1605 -2398 1605 -2400 1605 -2398 811 -3190 1609 -2396 811 -3186 811 -3194 811 -3186 1603 -2396 1609 -2396 1601 -2400 811 -3192 1603 -2394 1603 -15188 831 -3184 1609 -2382 803 -3190 1629 -2396 809 -3192 809 -3188 1607 -2396 1607 -2398 1607 -2392 1599 -2396 1607 -2398 1605 -2398 1605 -2394 811 -3188 1607 -2400 813 -3192 811 -3190 813 -3186 1603 -2400 1603 -2402 1599 -2394 811 -3190 1609 -2396 1609 -15164 823 -3196 1599 -2396 789 -3210 1595 -2424 809 -3188 811 -3186 1603 -2398 1605 -2390 1601 -2394 1609 -2400 1605 -2396 1607 -2394 1603 -2398 813 -3194 1599 -2394 815 -3194 809 -3192 809 -3190 1607 -2398 1605 -2396 1603 -2394 809 -3188 1605 -2402 1601 -15162 827 -3196 1579 -2426 805 -3206 1605 -2366 811 -3208 799 -3212 1603 -2400 1603 -2394 1601 -2398 1605 -2398 1599 -2394 1601 -2394 1609 -2394 813 -3192 1607 -2398 813 -3186 807 -3188 813 -3188 1601 -2396 1609 -2396 1603 -2392 811 -3194 1601 -2398 1611 -15174 831 -3186 1595 -2406 785 -3200 1625 -2378 813 -3190 815 -3202 1593 -2424 1603 -2400 1603 -2394 1597 -2400 1603 -2400 1605 -2396 1597 -2400 811 -3192 1601 -2400 811 -3190 811 -3190 811 -3192 1607 -2398 1603 -2392 1607 -2394 811 -3194 1603 -2396 1601 -15154 831 -3190 1605 -2404 797 -3180 1635 -2392 807 -3190 809 -3188 1605 -2400 1603 -2394 1605 -2396 1605 -2398 1601 -2394 1605 -2400 1605 -2396 811 -3192 1603 -2394 809 -3186 815 -3192 805 -3192 1601 -2396 1601 -2366 1629 -2388 807 -3192 1603 -2396 1599 -15118 825 -3198 1605 -2400 783 -3198 1589 -2392 809 -3180 809 -3186 1629 -2400 1573 -2390 1631 -2362 1633 -2360 1631 -2366 1599 -2394 1603 -2392 805 -3214 1601 -2396 809 -3184 811 -3190 807 -3160 1631 -2394 1601 -2364 1601 -2420 +RAW_Data: 807 -3192 1603 -2360 1633 -15120 827 -3200 1575 -2400 809 -3196 1605 -2394 807 -3186 809 -3160 1633 -2392 1599 -2366 1599 -2394 1631 -2358 1635 -2366 1601 -2396 1629 -2390 777 -3190 1629 -2400 775 -3218 775 -3216 809 -3188 1603 -2362 1631 -2390 1601 -2396 811 -3190 1597 -2400 1601 -15128 809 -3220 1577 -2398 809 -3196 1603 -2364 811 -3194 811 -3192 1605 -2400 1605 -2360 1601 -2396 1601 -2392 1603 -2390 1631 -2394 1571 -2394 807 -3218 1603 -2396 775 -3214 807 -3186 807 -3162 1603 -2394 1601 -2390 1603 -2396 805 -3222 1603 -2364 1635 -15142 791 -3228 1571 -2400 811 -3188 1601 -2394 809 -3194 809 -3186 1605 -2398 1601 -2390 1603 -2362 1633 -2362 1601 -2394 1635 -2362 1631 -2390 807 -3190 1605 -2394 773 -3220 775 -3186 807 -3192 1599 -2424 1597 -2366 1603 -2396 807 -3216 1601 -2398 1601 -15140 813 -3196 1571 -2398 813 -3190 1601 -2396 811 -3186 811 -3192 1603 -2402 1601 -2392 1601 -2392 1609 -2394 1603 -2394 1607 -2394 1611 -2396 811 -3190 1605 -2400 811 -3190 811 -3190 813 -3190 1601 -2400 1603 -2394 1607 -2398 809 -3188 1607 -2398 1605 -15176 793 -3226 1579 -2400 811 -3186 1613 -2400 785 -3194 815 -3194 1611 -2396 1607 -2396 1601 -2400 1607 -2396 1605 -2398 1603 -2394 1599 -2392 811 -3190 1605 -2396 815 -3192 815 -3190 813 -3188 1601 -2398 1603 -2398 1603 -2398 811 -3194 1605 -2398 1601 -15156 859 -3148 1639 -2378 803 -3214 1569 -2430 807 -3186 809 -3194 1601 -2396 1605 -2398 1607 -2400 1605 -2396 1605 -2396 1607 -2392 1599 -2394 811 -3184 1609 -2400 815 -3194 809 -3188 809 -3196 1605 -2394 1607 -2394 1599 -2396 813 -3194 1603 -2398 1603 -15170 797 -3212 1595 -2402 819 -3184 1613 -2390 831 -3174 819 -3196 1597 -2402 1589 -2388 1601 -2396 1633 -2398 1601 -2392 1599 -2400 1607 -2396 811 -3186 1609 -2402 809 -3188 813 -3192 809 -3188 1607 -2396 1601 -2398 1601 -2398 811 -3192 1599 -2396 1607 -15174 831 -3186 1579 -2402 801 -3202 1615 -2388 827 -3178 803 -3188 1617 -2392 1601 -2392 1635 -2396 1599 -2392 1603 -2398 1605 -2400 1601 -2392 813 -3194 1601 -2400 813 -3190 811 -3190 809 -3188 1603 -2396 1601 -2398 1605 -2400 809 -3184 1601 -2396 1607 -15178 831 -3166 1611 -2398 815 -3198 1577 -2398 811 -3194 815 -3192 1607 -2400 1605 -2400 1599 -2398 1603 -2396 1601 -2398 1605 -2400 1609 -2392 811 -3192 1605 -2398 811 -3188 811 -3192 813 -3190 1607 -2394 1605 -2398 1603 -2400 809 -3190 1601 -2396 1609 -15174 795 -3230 1567 -2432 781 -3204 1597 -2394 807 -3222 807 -3182 1605 -2398 1603 -2392 1603 -2396 1607 -2396 1603 -2404 1605 -2400 1599 -2396 811 -3186 1611 -2398 813 -3188 811 -3192 811 -3188 1605 -2404 1603 -2400 1605 -2398 807 -3190 1605 -2396 1605 -15164 827 -3198 1605 -2398 783 -3206 1595 -2424 807 -3192 807 -3184 1605 -2396 1605 -2400 1607 -2398 1599 -2394 1607 -2396 1605 -2400 1599 -2394 +RAW_Data: 809 -3184 1609 -2400 809 -3194 813 -3188 807 -3188 1603 -2400 1605 -2400 1599 -2398 809 -3190 1605 -2400 1603 -15170 803 -3208 1595 -2402 809 -3196 1589 -2388 807 -3216 809 -3182 1603 -2394 1607 -2398 1603 -2396 1607 -2396 1603 -2400 1605 -2396 1599 -2394 811 -3188 1605 -2396 817 -3196 811 -3182 811 -3192 1607 -2394 1603 -2394 1607 -2398 811 -3190 1603 -2398 1601 -15186 833 -3156 1605 -2412 799 -3218 1595 -2392 809 -3186 811 -3186 1609 -2404 1607 -2394 1605 -2396 1601 -2400 1607 -2396 1601 -2392 1607 -2400 809 -3192 1603 -2396 815 -3194 809 -3188 809 -3192 1603 -2400 1599 -2394 1605 -2400 811 -3188 1599 -2400 1605 -16142 167 -202 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub new file mode 100644 index 00000000000..ba6e37d010b --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433889000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Revers_RB2 +Bit: 64 +Key: FF FF FF FF 39 F9 0A 00 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2_raw.sub new file mode 100644 index 00000000000..f50ad7442b0 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2_raw.sub @@ -0,0 +1,17 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 215 -498 257 -246 243 -276 215 -280 215 -278 247 -250 507 -258 247 -504 479 -274 253 -254 219 -290 213 -530 485 -482 481 -308 217 -254 253 -252 241 -234 257 -250 249 -278 219 -252 247 -250 279 -544 235 -268 259 -226 255 -250 249 -280 219 -252 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 215 -280 279 -218 251 -250 249 -280 219 -252 251 -248 281 -220 251 -250 249 -248 247 -278 219 -252 249 -250 279 -220 251 -250 247 -280 219 -254 249 -248 217 -280 277 -220 507 -258 247 -504 225 -278 245 -246 469 -292 213 -530 227 -276 215 -274 247 -248 249 -248 247 -248 501 -258 249 -502 479 -272 251 -254 255 -254 249 -476 481 -514 481 -274 253 -254 255 -250 239 -262 225 -254 249 -248 217 -278 247 -250 251 -572 267 -238 263 -224 251 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -248 249 -248 247 -250 251 -250 249 -280 219 -252 251 -248 217 -280 247 -250 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 281 -220 251 -250 247 -280 479 -228 279 -500 255 -216 277 -214 531 -228 279 -500 257 -216 275 -214 275 -216 277 -278 217 -250 505 -260 217 -500 509 -258 243 -246 273 -216 275 -500 479 -546 479 -238 253 -256 253 -250 243 -268 221 -250 247 -250 251 -250 247 -280 219 -574 265 -268 199 -292 219 -250 279 -220 251 -250 249 -248 249 -278 219 -252 249 -250 279 -220 251 -248 249 -280 219 -252 251 -248 217 -280 247 -250 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 503 -260 217 -532 225 -276 215 -278 503 -238 251 -502 249 -244 241 -278 215 -272 215 -272 277 -214 493 -310 215 -530 483 -232 261 -258 223 -254 249 -538 483 -482 509 -274 217 -290 217 -252 241 -236 259 -250 247 -248 247 -280 217 -252 249 -602 203 -272 229 -256 281 -220 251 -250 249 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 247 -280 221 -252 249 -250 215 -280 247 -250 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 507 -258 215 -530 227 -278 215 -276 501 -258 215 -530 227 -278 215 -276 215 -276 247 -250 247 -250 501 -260 249 -502 481 -272 251 -254 219 -290 247 -474 481 -514 481 -274 289 -218 253 -252 241 -230 253 -282 217 -252 249 -248 279 -220 251 -574 267 -238 263 -222 +RAW_Data: 251 -280 219 -252 249 -250 215 -280 279 -220 251 -248 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 277 -222 251 -250 247 -280 219 -252 249 -250 217 -280 247 -250 251 -250 247 -280 219 -252 249 -250 279 -222 251 -250 247 -250 501 -258 249 -502 257 -218 275 -216 497 -272 287 -464 219 -274 275 -216 273 -216 271 -278 213 -274 499 -238 253 -498 479 -262 261 -228 257 -252 249 -506 481 -512 507 -236 291 -218 253 -290 211 -270 223 -250 247 -250 251 -250 247 -248 249 -568 267 -272 201 -292 221 -248 217 -280 247 -250 251 -250 247 -280 221 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -222 251 -248 249 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 219 -252 507 -260 217 -502 269 -252 253 -256 495 -236 265 -482 259 -250 247 -278 217 -252 249 -248 215 -280 503 -258 217 -532 515 -238 253 -254 255 -254 213 -504 513 -514 477 -274 215 -290 217 -256 247 -234 253 -252 249 -250 249 -280 219 -252 249 -602 203 -272 229 -256 281 -220 251 -250 249 -280 219 -252 249 -250 247 -248 249 -250 251 -250 249 -280 219 -250 249 -250 279 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 281 -220 249 -250 249 -280 219 -252 249 -250 215 -280 503 -260 217 -530 227 -280 213 -278 501 -258 217 -496 257 -276 215 -278 215 -278 245 -250 251 -250 501 -260 249 -502 479 -272 251 -256 217 -290 247 -474 483 -514 481 -274 251 -256 253 -252 241 -230 253 -282 217 -252 249 -248 217 -278 247 -576 269 -240 265 -222 251 -248 249 -278 219 -252 249 -250 279 -220 249 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 535 -226 251 -502 225 -246 275 -246 467 -290 245 -504 225 -276 245 -248 247 -246 247 -248 245 -280 475 -228 279 -500 479 -272 251 -256 253 -256 247 -470 483 -514 513 -238 289 -220 253 -288 209 -270 223 -250 215 -280 245 -250 251 -248 249 -570 267 -238 229 -288 221 -254 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -222 251 -250 247 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -280 217 -252 +RAW_Data: 249 -250 279 -220 251 -250 249 -278 221 -252 505 -228 245 -530 257 -214 275 -246 505 -226 247 -532 257 -214 275 -216 275 -246 249 -248 217 -280 503 -258 217 -498 543 -236 251 -254 255 -254 251 -474 513 -516 477 -238 253 -292 217 -254 245 -234 253 -252 251 -248 249 -278 219 -252 251 -602 203 -272 229 -258 279 -222 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -248 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 503 -258 217 -564 195 -278 215 -276 503 -258 215 -500 271 -288 215 -256 253 -250 207 -262 251 -252 505 -256 247 -504 481 -306 215 -254 253 -256 213 -534 487 -480 511 -274 215 -292 253 -218 247 -236 257 -250 247 -278 219 -250 249 -250 279 -544 235 -268 259 -226 253 -250 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 277 -220 251 -250 247 -280 221 -252 249 -250 279 -220 251 -250 471 -290 247 -502 225 -278 245 -246 469 -306 251 -466 251 -242 245 -272 245 -246 241 -246 241 -278 497 -238 253 -500 483 -264 229 -258 283 -220 253 -508 481 -508 477 -308 253 -218 253 -254 243 -264 225 -256 247 -250 279 -220 249 -250 249 -570 269 -236 231 -286 223 -252 251 -248 217 -278 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 279 -220 251 -250 247 -280 221 -252 249 -250 215 -280 247 -250 251 -250 247 -280 219 -254 249 -250 247 -248 277 -220 251 -250 247 -280 479 -228 279 -500 257 -216 275 -214 531 -228 279 -500 257 -216 275 -216 275 -246 249 -250 247 -250 503 -260 215 -500 541 -238 249 -256 253 -256 215 -508 481 -548 479 -238 253 -292 217 -254 245 -232 221 -280 247 -250 251 -250 247 -280 219 -574 263 -268 199 -292 219 -250 279 -220 253 -250 247 -280 221 -252 249 -248 249 -248 277 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 219 -252 249 -250 505 -260 217 -498 257 -276 213 -278 503 -260 215 -498 257 -246 243 -276 215 -280 215 -278 247 -252 505 -256 247 -506 479 -274 253 -254 219 -290 213 -530 485 -482 509 -274 +RAW_Data: 215 -292 217 -252 243 -236 259 -250 249 -280 219 -250 249 -250 215 -632 205 -272 261 -226 255 -250 249 -248 247 -280 217 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -218 507 -258 247 -504 225 -278 215 -274 499 -258 215 -530 225 -280 213 -278 245 -250 249 -248 247 -248 501 -260 247 -502 479 -272 251 -256 253 -254 249 -476 481 -514 483 -274 253 -254 255 -252 239 -260 225 -254 249 -248 215 -280 247 -250 251 -572 267 -238 263 -224 249 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -280 277 -220 251 -248 249 -280 219 -252 251 -248 247 -248 279 -220 251 -250 247 -282 219 -250 249 -250 279 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 479 -228 277 -500 257 -214 275 -216 529 -228 279 -500 257 -216 275 -216 275 -216 277 -278 217 -250 507 -258 219 -500 511 -274 253 -254 255 -218 245 -500 483 -544 479 -226 273 -244 243 -276 213 -278 213 -278 245 -250 251 -248 247 -280 219 -572 265 -268 199 -292 219 -250 279 -222 251 -250 247 -248 249 -278 221 -250 249 -250 279 -220 251 -250 249 -280 219 -252 251 -248 247 -248 279 -220 251 -248 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 247 -250 247 -280 219 -250 505 -260 217 -500 257 -276 215 -278 503 -236 249 -504 247 -246 241 -278 213 -274 243 -244 275 -214 493 -310 215 -516 477 -272 235 -262 227 -256 249 -504 509 -482 511 -274 215 -292 217 -252 279 -202 259 -250 249 -248 247 -278 219 -250 249 -604 205 -272 229 -254 281 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -222 249 -250 249 -280 219 -252 249 -250 247 -248 277 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 221 -252 249 -248 279 -220 507 -256 215 -532 225 -280 213 -276 501 -258 217 -530 227 -280 213 -276 215 -276 247 -248 249 -250 535 -226 249 -502 479 -258 243 -276 213 -276 245 -502 481 -514 483 -272 253 -254 255 -250 239 -230 253 -280 219 -250 249 -248 279 -220 253 -572 267 -238 263 -224 249 -282 219 -250 249 -250 217 -280 277 -220 251 -250 247 -280 221 -252 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 +RAW_Data: 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 277 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 501 -260 249 -502 257 -216 275 -216 497 -272 287 -464 243 -290 253 -212 271 -226 251 -280 219 -250 505 -226 247 -530 477 -274 251 -256 253 -218 283 -472 483 -514 515 -236 291 -218 253 -288 209 -268 223 -250 247 -250 251 -250 247 -248 247 -570 267 -270 201 -294 219 -250 247 -248 279 -220 249 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 249 -280 219 -252 249 -250 277 -222 251 -250 247 -250 247 -278 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 249 -250 247 -280 221 -252 505 -260 219 -500 271 -252 253 -256 487 -234 267 -488 257 -250 247 -248 245 -278 219 -252 249 -248 505 -258 217 -532 515 -238 253 -254 255 -254 213 -506 511 -514 477 -274 215 -290 219 -290 211 -234 285 -220 251 -250 247 -280 219 -252 249 -602 239 -238 229 -256 281 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 251 -250 247 -280 219 -252 249 -250 247 -248 247 -252 251 -248 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -248 249 -280 219 -252 251 -248 249 -248 503 -258 217 -532 227 -278 215 -276 501 -260 215 -498 257 -276 213 -278 215 -278 245 -252 249 -250 535 -226 249 -504 479 -272 251 -254 217 -292 247 -474 483 -514 481 -274 253 -256 253 -252 239 -230 253 -280 219 -252 247 -250 215 -280 277 -544 269 -240 265 -224 251 -248 247 -278 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 277 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 277 -222 251 -250 535 -228 249 -502 225 -246 275 -246 469 -306 251 -464 243 -290 253 -212 273 -226 251 -248 247 -280 475 -228 279 -500 477 -274 251 -254 255 -254 247 -472 481 -514 515 -226 273 -214 271 -246 241 -276 215 -278 215 -278 245 -252 249 -250 249 -570 267 -236 231 -288 221 -254 249 -250 277 -222 251 -248 249 -248 247 -280 219 -252 249 -248 281 -220 251 -250 249 -280 219 -252 249 -250 215 -280 247 -250 251 -250 247 -280 221 -252 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 477 -228 279 -500 255 -216 275 -246 505 -228 247 -530 255 -216 275 -216 275 -246 +RAW_Data: 247 -250 249 -248 503 -260 217 -498 541 -238 249 -256 253 -256 251 -474 513 -518 477 -238 253 -292 217 -254 243 -234 283 -222 249 -250 249 -248 247 -278 219 -606 239 -238 231 -256 249 -248 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -250 249 -250 249 -248 247 -250 251 -250 247 -280 219 -252 251 -248 281 -220 251 -250 249 -248 247 -280 219 -252 249 -248 505 -258 217 -498 257 -276 215 -278 501 -258 217 -498 257 -276 215 -278 215 -278 215 -278 247 -250 505 -260 245 -504 481 -288 215 -274 215 -276 213 -530 515 -478 511 -274 215 -256 289 -220 243 -234 255 -250 245 -280 217 -252 249 -248 279 -544 237 -268 259 -224 255 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -248 249 -278 219 -252 249 -248 279 -222 251 -250 247 -280 219 -254 249 -248 247 -248 279 -220 251 -250 249 -278 221 -252 249 -248 279 -222 251 -250 469 -292 245 -504 235 -288 253 -218 489 -266 269 -500 195 -280 215 -276 247 -248 249 -250 247 -280 479 -228 277 -502 477 -272 253 -254 253 -256 247 -474 481 -516 481 -276 253 -256 253 -214 273 -260 223 -254 249 -248 279 -220 251 -250 249 -570 267 -236 231 -288 221 -254 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -280 219 -252 249 -250 217 -280 247 -250 251 -250 249 -278 479 -228 279 -500 257 -214 275 -216 531 -228 279 -500 257 -214 275 -216 275 -248 247 -250 249 -248 503 -258 217 -500 545 -238 251 -256 253 -218 247 -502 481 -546 481 -238 289 -256 217 -290 213 -234 223 -280 247 -250 251 -250 247 -280 219 -574 263 -268 199 -292 219 -250 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 249 -280 219 -252 249 -248 281 -220 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -280 219 -252 249 -250 503 -260 217 -498 257 -276 215 -278 503 -258 217 -500 269 -254 253 -254 255 -250 205 -264 281 -220 507 -256 247 -504 481 -272 253 -256 217 -290 213 -532 487 -480 511 -274 215 -292 217 -252 243 -236 257 -250 247 -280 219 -250 249 -250 215 -632 205 -272 261 -226 255 -250 249 -248 249 -278 219 -252 +RAW_Data: 249 -248 279 -222 251 -250 247 -280 219 -252 249 -250 247 -248 279 -220 249 -252 247 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -278 221 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 505 -258 245 -504 227 -278 213 -274 501 -258 215 -530 227 -280 213 -276 247 -248 249 -248 247 -248 501 -258 249 -502 479 -272 253 -254 253 -256 249 -474 483 -514 483 -274 255 -254 255 -214 273 -260 223 -254 249 -248 215 -280 247 -252 249 -574 267 -238 263 -224 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 253 -250 247 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -280 477 -228 279 -500 257 -216 275 -214 531 -226 279 -500 225 -244 277 -214 277 -216 277 -278 219 -250 505 -260 217 -500 513 -274 251 -256 253 -218 247 -500 481 -546 479 -238 289 -218 255 -286 211 -270 223 -250 247 -250 249 -250 249 -280 219 -572 265 -268 199 -292 221 -248 281 -220 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 247 -280 219 -252 505 -260 217 -532 225 -276 215 -278 503 -236 251 -504 247 -254 251 -280 201 -260 251 -248 247 -252 505 -258 215 -530 513 -238 253 -254 255 -254 213 -504 513 -514 477 -274 215 -290 219 -252 281 -204 259 -252 247 -248 247 -278 219 -250 249 -604 203 -272 229 -256 281 -220 251 -250 247 -280 219 -252 251 -248 281 -220 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 277 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 507 -258 215 -530 227 -278 215 -276 499 -260 215 -530 225 -280 213 -276 215 -278 247 -248 249 -248 503 -260 249 -502 479 -258 243 -274 215 -274 247 -504 481 -512 477 -274 251 -256 253 -252 241 -230 253 -280 219 -252 249 -248 279 -220 251 -574 267 -238 263 -224 249 -282 219 -250 249 -250 217 -280 245 -252 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -248 217 -280 277 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 +RAW_Data: 249 -250 535 -228 249 -502 257 -218 275 -216 497 -272 285 -466 243 -290 253 -212 271 -226 251 -280 219 -250 505 -228 245 -530 479 -272 253 -254 253 -220 283 -470 481 -516 515 -236 255 -254 253 -288 209 -268 223 -248 217 -278 247 -250 251 -250 247 -570 267 -238 231 -286 221 -254 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 251 -248 249 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -278 219 -252 249 -248 281 -220 251 -248 249 -280 219 -252 249 -250 249 -248 247 -252 249 -250 249 -280 219 -252 505 -228 247 -530 227 -246 273 -246 505 -228 245 -530 255 -216 275 -214 275 -248 247 -250 247 -250 503 -258 217 -564 483 -238 251 -256 253 -254 215 -504 515 -514 475 -258 213 -274 243 -276 213 -276 245 -248 247 -248 247 -280 219 -250 249 -604 203 -272 229 -256 281 -220 251 -250 247 -280 221 -252 249 -250 215 -280 277 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -218 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 253 -250 247 -280 219 -252 249 -250 217 -280 503 -258 217 -532 225 -280 213 -278 501 -258 217 -496 257 -276 215 -278 215 -278 247 -250 249 -250 469 -292 245 -504 481 -272 251 -254 217 -292 247 -474 485 -512 481 -274 253 -254 255 -252 239 -230 255 -280 219 -250 249 -248 217 -278 279 -544 269 -238 265 -224 251 -248 249 -278 219 -252 249 -250 279 -220 251 -250 247 -280 219 -252 249 -250 217 -280 247 -252 249 -250 249 -280 219 -252 249 -250 247 -248 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 535 -228 249 -504 237 -250 291 -218 491 -264 265 -498 193 -280 247 -248 249 -248 249 -248 247 -278 477 -230 277 -500 479 -272 215 -292 253 -256 247 -472 481 -514 515 -236 291 -218 255 -252 239 -262 225 -252 249 -250 279 -220 249 -250 249 -570 267 -238 231 -286 221 -254 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 253 -250 247 -280 219 -252 249 -250 247 -248 279 -220 251 -248 249 -280 221 -252 249 -248 247 -248 279 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 477 -228 277 -500 257 -216 275 -246 505 -226 247 -530 257 -214 275 -216 275 -246 249 -250 247 -250 503 -258 217 -498 541 -228 245 -244 243 -278 247 -500 511 -516 479 -238 253 -292 217 -252 209 -266 281 -222 +RAW_Data: 249 -250 249 -248 247 -278 219 -606 239 -238 231 -258 249 -248 247 -250 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 249 -278 221 -250 249 -250 279 -222 251 -250 247 -248 249 -278 219 -252 249 -250 503 -260 217 -498 257 -276 215 -278 501 -258 217 -498 257 -276 215 -278 215 -278 215 -278 247 -250 505 -258 245 -506 479 -308 215 -254 219 -290 213 -534 487 -482 479 -288 213 -274 243 -246 275 -214 275 -216 277 -278 217 -250 247 -248 279 -546 235 -268 259 -226 253 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 249 -280 219 -252 249 -248 281 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -218 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 471 -292 245 -502 227 -276 245 -248 467 -308 215 -504 243 -290 217 -244 265 -228 253 -250 247 -280 477 -228 279 -500 479 -272 251 -256 253 -254 249 -472 483 -514 479 -256 275 -244 243 -246 243 -276 215 -278 215 -276 247 -250 249 -250 249 -570 267 -236 231 -286 221 -254 249 -250 217 -278 279 -220 251 -250 247 -280 221 -252 249 -248 247 -248 279 -220 251 -250 247 -280 219 -254 249 -248 279 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 249 -250 249 -280 477 -228 277 -502 255 -216 275 -216 531 -228 279 -500 257 -216 275 -214 277 -246 249 -250 247 -250 503 -260 215 -500 541 -226 245 -246 243 -246 275 -500 477 -548 477 -236 255 -290 217 -254 245 -234 221 -282 247 -250 249 -250 249 -280 219 -572 265 -266 199 -292 221 -248 281 -220 251 -250 249 -278 221 -252 249 -250 247 -248 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 279 -220 249 -250 249 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 503 -260 217 -498 257 -276 215 -278 503 -258 217 -498 257 -244 243 -278 215 -278 217 -278 245 -252 505 -258 247 -506 479 -272 255 -254 217 -292 211 -532 485 -480 509 -274 217 -290 219 -252 243 -236 259 -250 247 -280 219 -250 249 -250 217 -630 205 -272 261 -226 255 -252 247 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 247 -280 219 -252 249 -250 279 -220 251 -250 +RAW_Data: 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 507 -258 247 -504 225 -278 213 -274 501 -258 215 -530 225 -280 213 -276 247 -248 249 -248 249 -246 501 -260 249 -502 479 -272 251 -254 255 -254 249 -476 481 -514 483 -274 253 -256 253 -250 239 -230 251 -280 219 -252 247 -250 279 -220 251 -572 269 -236 265 -222 251 -280 219 -252 249 -250 277 -222 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 251 -250 247 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -252 247 -248 503 -258 249 -502 257 -216 277 -214 531 -228 279 -502 237 -254 253 -256 253 -216 271 -260 223 -254 505 -260 217 -500 513 -274 251 -256 253 -218 247 -498 483 -546 479 -238 289 -220 253 -288 209 -268 223 -250 247 -252 249 -250 249 -278 219 -574 265 -268 199 -292 219 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -278 221 -252 249 -250 215 -280 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 505 -258 219 -498 257 -276 215 -278 503 -238 249 -504 245 -254 253 -280 203 -260 219 -280 215 -278 503 -260 215 -532 515 -238 253 -254 255 -254 213 -506 511 -516 477 -272 215 -292 217 -254 279 -204 261 -250 249 -246 247 -278 219 -252 249 -602 205 -272 229 -256 281 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 281 -220 249 -250 249 -248 247 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -250 249 -250 217 -280 247 -252 249 -250 249 -280 219 -252 249 -248 281 -220 507 -258 215 -530 227 -280 213 -276 499 -258 215 -532 225 -280 213 -276 215 -276 247 -250 249 -248 503 -258 251 -502 479 -272 251 -254 219 -290 247 -474 515 -482 481 -274 253 -256 253 -252 239 -230 253 -280 219 -252 247 -250 279 -220 251 -572 269 -236 263 -224 251 -280 219 -252 249 -250 215 -280 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 253 -250 247 -280 219 -252 249 -250 217 -280 247 -250 251 -250 535 -226 251 -502 257 -216 277 -216 497 -272 287 -464 245 -288 253 -212 271 -224 251 -280 219 -250 507 -228 247 -528 +RAW_Data: 477 -274 251 -254 255 -218 283 -472 481 -516 515 -236 255 -254 255 -250 245 -266 223 -250 217 -278 245 -252 249 -250 249 -570 267 -238 229 -288 221 -254 249 -250 279 -220 251 -250 247 -280 221 -252 249 -248 217 -278 279 -220 251 -250 247 -282 219 -252 249 -250 277 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 219 -252 507 -228 247 -530 255 -216 275 -246 503 -228 245 -530 257 -214 275 -216 275 -246 249 -248 249 -248 503 -260 217 -532 515 -238 253 -254 253 -256 213 -506 511 -516 477 -272 215 -292 217 -254 245 -234 255 -252 249 -250 249 -278 219 -252 249 -602 205 -272 229 -256 281 -220 251 -250 249 -248 249 -278 219 -252 249 -250 279 -220 249 -250 249 -280 219 -254 249 -248 217 -280 277 -220 251 -250 247 -280 221 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 247 -280 221 -252 249 -248 249 -248 503 -258 217 -532 227 -280 213 -278 499 -258 215 -500 271 -288 217 -254 255 -248 241 -234 259 -250 469 -306 249 -464 501 -280 215 -284 207 -262 251 -508 515 -480 481 -274 253 -254 253 -254 241 -230 253 -282 219 -250 249 -248 217 -278 247 -576 269 -240 265 -222 251 -248 249 -278 219 -252 249 -248 279 -220 251 -250 249 -248 249 -278 219 -252 249 -248 281 -220 249 -250 249 -280 219 -252 249 -250 217 -280 247 -250 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 535 -228 249 -502 225 -246 275 -248 465 -290 245 -504 225 -276 245 -246 247 -248 247 -246 247 -278 477 -228 279 -500 477 -274 251 -254 255 -254 247 -474 483 -514 515 -238 253 -256 253 -250 239 -262 223 -254 249 -250 279 -220 249 -250 249 -570 267 -238 229 -288 221 -254 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 249 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -248 249 -280 221 -252 249 -250 279 -220 251 -250 249 -248 247 -280 477 -228 277 -500 257 -216 275 -246 505 -228 245 -530 257 -214 275 -216 275 -246 249 -250 247 -250 503 -258 217 -498 543 -226 243 -246 243 -278 247 -500 479 -546 477 -238 255 -290 217 -252 245 -232 283 -222 249 -250 249 -248 247 -280 217 -608 239 -238 229 -256 219 -280 247 -250 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 +RAW_Data: 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 247 -280 219 -252 249 -250 505 -258 217 -500 255 -278 215 -278 501 -260 215 -498 257 -276 215 -278 215 -278 215 -278 247 -252 505 -258 245 -504 481 -272 251 -254 217 -292 213 -532 485 -480 511 -274 215 -292 217 -252 243 -236 259 -250 249 -278 219 -252 249 -248 279 -546 235 -268 259 -226 255 -250 249 -278 221 -250 249 -250 215 -280 279 -220 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 471 -288 247 -502 227 -276 245 -248 469 -292 213 -530 225 -278 213 -276 245 -250 247 -248 249 -278 477 -228 279 -500 477 -256 245 -242 277 -246 247 -502 479 -512 475 -274 291 -218 255 -250 241 -262 223 -254 249 -250 247 -252 249 -250 249 -570 267 -238 231 -286 221 -254 251 -248 217 -278 247 -252 251 -250 247 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 221 -252 249 -248 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 247 -280 221 -252 249 -248 217 -280 247 -250 251 -250 249 -280 477 -228 279 -500 257 -214 275 -216 529 -228 279 -500 257 -216 275 -216 275 -216 277 -278 219 -250 505 -258 217 -500 547 -238 251 -254 255 -218 245 -502 481 -544 479 -236 291 -254 217 -292 213 -268 221 -250 247 -252 249 -250 249 -280 219 -572 265 -268 199 -292 219 -250 279 -222 251 -250 247 -282 219 -252 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/roger.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/roger.sub new file mode 100644 index 00000000000..2304b43d2ab --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/roger.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Roger +Bit: 28 +Key: 00 00 00 00 05 AB A1 01 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/roger_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/roger_raw.sub new file mode 100644 index 00000000000..0827fb0d2a7 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/roger_raw.sub @@ -0,0 +1,23 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 22710 -100 52363 -100 323 -66 1865 -66 32843 -66 753 -100 461 -100 19881 -66 16113 -66 20557 -66 6287 -64 25981 -100 587 -66 24707 -66 2367 -66 4681 -66 291 -98 4567 -100 1001 -100 33935 -66 20561 -100 5745 -66 2563 -66 4245 -66 22121 -66 1517 -100 2895 -66 15919 -66 20885 -100 12513 -890 839 -458 415 -914 843 -452 837 -482 387 -928 849 -446 415 -900 843 -474 415 -902 843 -470 841 -470 843 -468 383 -914 845 -460 415 -914 409 -884 423 -902 411 -902 835 -482 411 -880 423 -902 411 -908 397 -898 405 -920 411 -880 441 -896 835 -8268 411 -888 877 -430 415 -908 841 -460 869 -434 413 -920 845 -458 415 -912 845 -454 409 -884 879 -452 869 -428 873 -434 413 -904 871 -434 413 -918 415 -874 441 -882 425 -900 835 -448 443 -880 423 -904 409 -902 409 -904 409 -910 399 -896 417 -894 851 -8248 421 -912 853 -446 427 -872 863 -444 867 -446 441 -876 867 -456 415 -882 879 -452 419 -880 853 -448 881 -450 835 -460 415 -918 845 -454 409 -884 419 -906 411 -910 397 -898 865 -446 453 -860 421 -884 453 -876 415 -876 447 -878 441 -880 437 -882 861 -8216 457 -882 853 -456 405 -884 889 -420 879 -448 413 -890 873 -432 443 -892 841 -456 409 -922 843 -458 841 -460 873 -432 413 -918 843 -456 409 -918 387 -906 409 -912 427 -870 863 -446 439 -874 437 -888 409 -880 439 -898 419 -888 421 -880 453 -876 843 -8232 449 -874 891 -418 451 -878 865 -454 849 -448 413 -902 843 -474 411 -888 877 -432 413 -920 843 -454 869 -432 875 -432 413 -920 845 -458 415 -884 421 -910 395 -900 439 -888 839 -454 451 -880 419 -878 449 -876 415 -876 445 -878 439 -880 435 -870 867 -8246 423 -888 849 -454 445 -880 863 -418 879 -446 413 -896 875 -444 411 -902 873 -442 411 -904 839 -472 837 -472 837 -474 413 -874 871 -438 443 -892 415 -874 441 -878 439 -878 867 -454 417 -882 425 -908 399 -896 419 -896 419 -882 453 -876 413 -878 871 -8228 451 -876 853 -442 437 -904 841 -450 855 -450 449 -886 839 -474 411 -890 843 -460 415 -886 879 -456 843 -458 875 -428 409 -906 869 -436 413 -920 417 -884 423 -874 435 -892 857 -456 417 -880 453 -876 413 -910 413 -878 439 -870 439 -872 439 -870 871 -8248 421 -892 851 -454 445 -880 861 -452 843 -448 413 -896 877 -444 413 -898 853 -450 417 -898 877 -446 841 -474 839 -472 411 -892 843 -460 409 -918 417 -882 423 -872 435 -896 869 -418 453 -888 421 -878 451 -876 415 -876 443 -878 441 -876 437 -882 861 -8236 423 -878 883 -454 401 -884 +RAW_Data: 857 -450 881 -446 413 -888 873 -434 415 -906 875 -428 411 -904 869 -434 873 -438 875 -436 413 -906 869 -434 413 -906 411 -904 411 -906 415 -908 835 -460 411 -906 409 -904 411 -908 417 -874 411 -910 415 -914 421 -884 849 -8232 453 -870 853 -440 439 -902 841 -450 885 -452 413 -870 861 -452 447 -862 877 -446 411 -900 877 -444 839 -474 839 -472 411 -902 841 -470 409 -890 415 -882 421 -910 425 -872 863 -446 451 -866 417 -906 417 -906 419 -868 451 -870 415 -900 413 -904 841 -8244 439 -886 855 -456 415 -908 853 -444 861 -452 421 -886 851 -452 447 -860 877 -448 413 -898 875 -444 873 -442 837 -474 409 -904 839 -472 409 -870 441 -898 421 -886 413 -890 873 -434 443 -890 417 -882 423 -876 433 -896 417 -894 421 -880 453 -876 843 -8254 435 -870 865 -448 409 -904 869 -454 843 -458 415 -912 843 -456 409 -914 835 -458 409 -920 841 -456 867 -432 873 -434 443 -888 845 -460 415 -910 417 -882 425 -872 435 -892 867 -448 407 -898 409 -902 417 -898 419 -880 453 -874 415 -908 413 -878 871 -8236 417 -904 845 -454 451 -880 863 -420 881 -448 413 -902 841 -476 411 -892 873 -430 415 -918 843 -456 875 -426 869 -434 443 -890 841 -458 409 -920 415 -882 425 -870 439 -904 835 -450 421 -912 427 -872 437 -888 419 -888 421 -882 453 -876 413 -880 871 -8234 457 -848 881 -444 435 -880 867 -450 847 -448 415 -920 841 -470 411 -888 845 -460 415 -916 847 -454 835 -460 871 -466 381 -920 843 -458 409 -916 417 -878 411 -912 425 -870 887 -418 445 -878 419 -914 419 -876 415 -908 413 -876 443 -880 441 -880 863 -8232 423 -880 881 -454 401 -904 865 -450 847 -446 415 -898 875 -444 411 -902 839 -476 411 -902 839 -474 837 -472 839 -472 411 -888 875 -430 415 -908 415 -908 409 -882 421 -904 837 -450 421 -910 425 -872 451 -868 419 -882 451 -874 413 -906 413 -902 843 -8256 419 -892 851 -472 405 -906 837 -480 821 -482 417 -904 823 -482 387 -918 843 -472 413 -884 845 -462 875 -432 875 -468 381 -916 843 -460 415 -914 387 -908 395 -938 399 -892 863 -444 409 -902 405 -918 409 -898 407 -920 411 -878 417 -918 417 -880 839 -8254 439 -898 837 -448 411 -906 869 -454 845 -460 415 -882 881 -450 409 -914 845 -452 409 -914 843 -456 843 -458 843 -462 415 -914 843 -456 413 -912 387 -910 423 -908 415 -870 873 -460 413 -910 381 -906 411 -906 409 -906 411 -904 411 -904 411 -904 839 -8254 409 -882 865 -446 439 -874 889 -418 873 -458 417 -878 885 -454 +RAW_Data: 403 -884 857 -482 385 -918 843 -474 843 -468 839 -470 411 -906 837 -468 411 -904 379 -904 413 -900 415 -918 841 -474 381 -918 417 -912 385 -912 395 -900 451 -866 419 -918 417 -878 843 -8274 397 -896 865 -446 411 -904 871 -452 845 -458 417 -874 869 -458 415 -882 879 -454 417 -882 881 -448 837 -458 869 -432 413 -906 869 -434 413 -906 411 -904 411 -904 411 -904 869 -432 415 -916 387 -910 425 -908 415 -868 415 -908 415 -906 415 -876 879 -8236 409 -912 837 -454 451 -882 845 -452 875 -452 417 -890 849 -446 415 -896 877 -446 411 -900 841 -474 841 -470 839 -472 411 -904 839 -472 413 -886 415 -916 387 -904 411 -908 853 -448 409 -912 395 -900 435 -892 409 -916 407 -896 411 -912 409 -894 835 -8258 411 -890 871 -436 445 -888 841 -462 873 -430 413 -920 843 -456 409 -906 869 -430 415 -920 843 -454 869 -432 873 -434 413 -906 865 -470 411 -888 409 -884 449 -882 419 -890 845 -486 411 -870 437 -874 439 -870 439 -902 409 -902 409 -902 409 -902 839 -8252 405 -896 865 -446 441 -876 869 -454 845 -458 415 -882 879 -454 417 -882 879 -418 441 -882 881 -450 845 -456 867 -432 413 -906 869 -432 411 -906 409 -920 415 -884 425 -872 893 -412 439 -912 399 -892 409 -902 417 -900 421 -880 451 -878 413 -876 877 -8222 457 -886 845 -440 441 -880 869 -450 849 -450 415 -922 839 -472 411 -890 841 -462 413 -884 879 -452 869 -432 873 -434 413 -920 843 -458 409 -886 419 -912 417 -880 453 -882 847 -454 443 -880 399 -882 433 -884 427 -916 399 -886 429 -884 429 -886 853 -8258 423 -878 879 -454 403 -884 859 -452 877 -446 413 -888 873 -434 445 -890 843 -460 413 -884 879 -456 845 -458 867 -430 415 -920 843 -454 409 -920 385 -912 427 -872 435 -890 855 -456 419 -878 453 -876 415 -878 445 -878 439 -878 439 -880 401 -914 861 -8224 419 -906 845 -470 407 -902 841 -450 887 -418 451 -884 841 -474 413 -888 875 -432 413 -908 843 -460 867 -434 873 -436 443 -874 869 -436 443 -874 411 -920 415 -884 425 -874 893 -412 435 -894 441 -870 451 -862 419 -880 453 -876 417 -910 413 -878 869 -8234 457 -848 879 -456 403 -902 865 -452 847 -448 413 -896 877 -444 411 -900 873 -444 411 -902 841 -474 841 -472 839 -472 411 -890 845 -462 413 -884 421 -912 425 -872 437 -888 871 -418 445 -878 419 -914 419 -878 415 -910 413 -876 443 -880 439 -880 863 -8226 419 -904 841 -472 417 -872 879 -442 861 -450 423 -884 857 -450 451 -858 879 -448 411 -898 875 -444 +RAW_Data: 841 -474 837 -474 411 -902 839 -472 411 -902 411 -904 409 -872 443 -898 845 -448 415 -900 413 -898 425 -886 425 -888 425 -886 425 -886 423 -898 863 -8226 451 -872 877 -434 409 -904 873 -416 891 -420 453 -886 841 -474 411 -888 873 -430 413 -908 843 -460 869 -432 873 -436 445 -874 869 -436 443 -890 415 -884 423 -902 409 -904 867 -418 419 -912 425 -872 435 -894 409 -914 407 -898 411 -880 447 -880 851 -8230 457 -868 879 -452 417 -868 869 -452 849 -450 449 -858 877 -448 411 -896 877 -444 413 -900 875 -446 841 -438 875 -438 445 -890 845 -460 415 -882 421 -912 395 -898 439 -870 867 -450 425 -910 399 -894 405 -920 413 -878 419 -914 419 -878 415 -910 843 -8232 457 -886 845 -442 439 -876 869 -454 855 -448 415 -886 875 -438 443 -876 875 -434 413 -904 871 -432 873 -434 873 -436 445 -874 869 -436 413 -920 417 -880 423 -902 411 -904 867 -418 421 -912 427 -868 437 -890 409 -916 413 -876 419 -914 417 -876 879 -8234 423 -888 843 -456 449 -880 863 -420 881 -448 413 -902 843 -476 413 -888 877 -430 413 -886 877 -454 867 -432 873 -434 413 -918 845 -460 415 -882 423 -908 397 -898 437 -890 855 -426 447 -874 453 -876 415 -878 447 -878 441 -878 437 -880 435 -880 859 -8212 457 -884 847 -454 445 -880 863 -420 881 -448 411 -902 875 -442 411 -902 839 -474 411 -888 875 -430 875 -432 875 -432 413 -922 843 -458 417 -884 421 -910 397 -898 453 -864 879 -454 415 -878 439 -878 435 -880 435 -882 395 -902 437 -868 437 -870 871 -8244 421 -894 845 -470 409 -908 843 -456 857 -448 415 -890 871 -436 445 -890 843 -460 415 -882 881 -452 869 -428 867 -436 443 -888 841 -460 409 -918 417 -882 453 -844 447 -876 853 -454 449 -880 435 -878 403 -916 397 -914 397 -884 431 -884 429 -884 889 -8228 425 -878 879 -422 435 -886 855 -452 877 -448 413 -888 877 -432 413 -886 877 -454 409 -886 891 -446 855 -444 867 -456 415 -882 851 -448 439 -884 425 -902 409 -874 435 -892 867 -444 409 -910 427 -872 437 -888 411 -880 439 -892 419 -890 421 -878 879 -8234 421 -894 881 -434 409 -902 841 -456 859 -450 415 -900 885 -420 451 -886 839 -472 411 -900 847 -448 877 -446 841 -474 411 -890 845 -460 415 -884 421 -906 409 -912 397 -898 889 -420 447 -876 421 -880 455 -880 411 -878 443 -878 439 -880 435 -882 861 -8210 437 -896 865 -442 407 -908 867 -452 845 -458 415 -912 843 -454 409 -884 879 -452 407 -908 867 -432 873 -432 873 -432 415 -904 869 -434 +RAW_Data: 415 -904 411 -906 409 -906 409 -906 869 -430 415 -908 415 -880 439 -876 411 -906 411 -912 395 -898 437 -890 851 -8232 443 -890 845 -460 415 -884 879 -454 843 -458 415 -884 879 -454 409 -884 879 -448 409 -884 879 -454 841 -458 869 -432 413 -904 869 -434 413 -906 411 -904 409 -908 417 -882 881 -450 409 -880 441 -876 411 -910 425 -109718 133 -700 197 -334 133 -132 133 -166 131 -134 167 -200 427 -234 1129 -132 923 -100 22805 -66 22225 -66 655 -64 24395 -98 5203 -98 15817 -66 5793 -98 819 -98 4477 -66 12519 -68 64793 -66 425 -100 3651 -66 10365 -66 2361 -100 697 -66 13695 -100 15599 -66 1829 -100 21103 -66 40353 -64 1751 -98 14265 -132 54383 -66 2653 -98 13411 -66 15223 -66 8943 -892 857 -432 443 -876 843 -480 857 -452 421 -882 843 -474 413 -886 879 -432 415 -916 845 -454 837 -464 875 -432 415 -914 845 -458 411 -914 389 -908 427 -874 433 -894 867 -450 409 -898 409 -916 409 -896 417 -888 417 -880 449 -876 413 -908 839 -8254 415 -896 853 -470 407 -880 875 -450 853 -450 415 -920 843 -470 411 -872 869 -470 413 -888 843 -462 875 -430 875 -432 415 -918 847 -458 417 -880 425 -908 415 -904 407 -896 835 -456 443 -878 419 -882 449 -878 413 -908 413 -876 441 -876 439 -878 867 -8218 457 -886 845 -452 445 -876 865 -450 847 -450 417 -900 877 -444 413 -870 871 -440 441 -870 873 -438 873 -440 873 -438 443 -870 881 -446 417 -902 413 -902 417 -870 429 -886 891 -416 387 -978 355 -964 353 -930 387 -938 353 -942 385 -940 383 -912 845 -8258 421 -876 879 -422 469 -848 893 -420 843 -506 353 -944 813 -502 383 -912 849 -460 419 -904 837 -460 871 -466 843 -466 381 -900 875 -446 419 -912 383 -934 383 -914 415 -886 843 -462 411 -904 417 -916 417 -882 383 -964 343 -986 307 -982 345 -980 767 -8306 375 -934 839 -484 377 -932 837 -458 839 -466 407 -910 841 -478 395 -916 861 -446 421 -886 851 -448 877 -446 809 -536 353 -962 779 -502 385 -930 383 -936 387 -926 385 -926 815 -474 417 -914 381 -914 417 -912 419 -882 397 -900 405 -918 409 -898 861 -8248 437 -878 861 -450 419 -886 851 -448 877 -444 413 -884 873 -472 411 -886 845 -460 411 -916 847 -454 871 -430 877 -434 415 -916 845 -460 417 -880 423 -904 411 -908 399 -898 853 -454 415 -914 415 -882 415 -908 411 -910 409 -880 439 -878 435 -872 867 -8234 451 -864 875 -428 443 -876 875 -454 865 -482 355 -926 819 -504 355 -940 813 -504 385 -944 815 -488 819 -486 807 -492 387 -934 841 -458 +RAW_Data: 413 -914 389 -904 393 -932 411 -906 825 -480 381 -930 413 -908 413 -866 413 -914 415 -884 449 -876 411 -912 803 -8306 381 -934 827 -480 381 -932 709 -24288 131 -15484 407 -916 799 -514 373 -914 829 -500 793 -510 393 -910 855 -448 387 -912 881 -444 383 -948 789 -524 791 -524 825 -490 375 -936 811 -456 407 -920 411 -918 373 -946 373 -920 831 -478 399 -918 395 -916 395 -914 395 -914 427 -882 431 -880 397 -918 893 -8186 479 -826 881 -438 265 -5122 99 -604 291 -990 785 -540 321 -958 815 -504 813 -472 849 -440 411 -916 845 -450 437 -900 411 -888 415 -916 413 -884 841 -478 393 -916 431 -882 431 -878 431 -878 431 -872 437 -876 437 -876 863 -8226 451 -890 849 -488 369 -920 825 -478 819 -510 385 -912 845 -470 383 -908 845 -476 415 -884 845 -464 877 -432 875 -436 417 -914 843 -460 417 -906 411 -880 425 -908 397 -900 849 -454 417 -914 417 -878 415 -910 411 -912 407 -878 439 -878 439 -876 865 -8228 437 -894 853 -428 449 -878 881 -442 857 -454 423 -888 883 -418 415 -890 875 -438 445 -888 845 -456 869 -432 875 -436 445 -868 869 -438 445 -878 447 -870 409 -886 451 -874 865 -420 441 -886 421 -912 429 -870 441 -854 455 -852 455 -878 451 -840 907 -8212 437 -876 857 -456 415 -918 845 -454 867 -450 417 -886 853 -446 413 -920 843 -440 441 -872 871 -438 871 -472 839 -472 411 -888 843 -464 415 -904 409 -910 417 -876 409 -912 853 -446 411 -906 411 -910 427 -870 453 -866 415 -910 419 -878 449 -876 843 -8242 453 -868 873 -450 415 -880 867 -446 849 -484 383 -918 843 -474 409 -906 841 -470 411 -886 843 -464 875 -432 875 -434 415 -914 845 -458 417 -884 423 -902 411 -906 397 -898 867 -446 409 -906 407 -918 407 -898 409 -900 409 -918 407 -898 417 -888 845 -8236 453 -872 849 -486 411 -872 871 -446 853 -482 417 -890 847 -446 413 -896 875 -446 413 -900 851 -448 875 -444 875 -442 413 -898 841 -474 411 -902 411 -902 411 -904 413 -886 843 -462 417 -906 417 -882 423 -906 397 -900 407 -922 417 -890 419 -880 875 -8242 407 -904 867 -420 421 -906 869 -456 835 -462 409 -918 843 -460 409 -884 879 -452 411 -906 835 -462 869 -434 873 -438 445 -870 871 -438 413 -920 417 -878 423 -902 409 -906 857 -448 429 -872 437 -892 419 -892 419 -880 451 -874 413 -878 441 -868 873 -8250 421 -890 853 -438 439 -878 873 -452 855 -450 415 -888 873 -438 445 -888 843 -462 415 -882 883 -452 835 -462 869 -434 415 -918 843 -458 409 -908 417 -874 +RAW_Data: 439 -874 441 -876 869 -454 409 -908 415 -880 443 -880 427 -872 437 -894 409 -882 449 -878 877 -8236 415 -878 881 -452 411 -880 883 -450 837 -460 411 -916 847 -456 409 -914 845 -456 419 -880 851 -452 881 -452 837 -460 413 -914 843 -458 411 -916 387 -910 425 -906 415 -868 875 -460 415 -878 415 -908 413 -910 409 -878 439 -878 437 -880 437 -880 863 -8226 449 -878 853 -452 443 -878 861 -450 847 -450 415 -920 841 -438 445 -888 843 -462 415 -882 879 -454 867 -432 875 -432 415 -916 845 -460 417 -880 423 -904 409 -912 397 -900 867 -448 419 -890 419 -882 451 -876 415 -912 409 -880 439 -880 435 -872 867 -8242 409 -914 835 -442 451 -870 875 -460 845 -440 437 -902 839 -446 425 -904 863 -452 423 -888 851 -448 879 -444 845 -474 413 -886 843 -462 417 -916 387 -912 427 -872 451 -870 877 -432 441 -872 445 -872 411 -904 411 -904 409 -906 409 -904 411 -902 839 -8242 453 -866 877 -450 413 -874 871 -448 851 -484 383 -920 843 -472 413 -888 845 -462 415 -882 881 -452 837 -460 871 -436 413 -920 845 -460 415 -882 423 -902 411 -910 395 -902 861 -444 441 -874 437 -894 413 -882 419 -912 419 -880 415 -908 413 -880 869 -8228 457 -884 845 -442 435 -878 871 -452 853 -450 415 -896 881 -444 413 -904 841 -474 411 -884 879 -430 875 -432 875 -434 415 -904 869 -432 445 -888 417 -876 411 -906 411 -904 867 -452 411 -906 409 -882 421 -910 397 -900 451 -864 419 -882 449 -878 873 -8238 421 -890 843 -452 447 -878 865 -450 847 -450 415 -894 881 -444 413 -902 841 -474 413 -890 841 -462 869 -436 873 -436 415 -918 845 -462 409 -904 409 -916 387 -912 427 -872 863 -446 441 -872 451 -866 419 -912 419 -880 413 -908 413 -876 443 -880 867 -8224 447 -880 879 -430 445 -876 877 -422 859 -452 449 -860 875 -448 415 -898 851 -450 417 -894 875 -448 877 -446 841 -440 443 -890 877 -428 409 -904 411 -884 453 -880 425 -872 861 -446 441 -874 453 -866 415 -908 419 -880 451 -876 415 -876 443 -878 869 -8224 455 -884 843 -468 407 -906 841 -448 887 -448 417 -892 849 -448 415 -918 839 -472 413 -886 875 -432 845 -462 873 -432 411 -906 873 -434 415 -920 417 -880 425 -904 399 -898 865 -450 407 -902 415 -894 419 -912 417 -878 413 -908 413 -910 409 -878 869 -8234 449 -874 877 -450 413 -872 869 -448 883 -448 413 -872 889 -450 417 -890 847 -448 415 -920 841 -438 877 -436 875 -436 441 -874 873 -434 441 -872 441 -868 451 -884 413 -900 839 -476 413 -902 +RAW_Data: 411 -886 417 -884 421 -910 397 -900 451 -864 415 -910 843 -8248 445 -858 879 -458 417 -882 881 -418 879 -454 409 -882 881 -452 411 -882 883 -418 443 -874 867 -458 871 -434 875 -434 415 -918 845 -460 417 -878 421 -908 427 -872 451 -864 879 -450 417 -880 439 -880 437 -878 435 -880 401 -914 429 -870 435 -870 867 -8252 411 -886 877 -430 447 -876 879 -414 887 -452 419 -886 851 -448 447 -860 877 -446 413 -896 877 -444 873 -444 871 -442 409 -902 839 -474 409 -900 411 -902 409 -900 411 -900 875 -442 411 -902 409 -902 409 -904 409 -900 421 -888 423 -888 423 -890 849 -8264 421 -878 877 -454 401 -884 857 -452 879 -446 411 -900 875 -444 411 -900 839 -474 411 -900 839 -474 839 -474 839 -472 409 -906 839 -472 411 -872 445 -888 417 -874 441 -882 851 -450 423 -912 427 -868 439 -888 411 -882 453 -884 419 -876 449 -874 841 -8238 453 -888 843 -470 407 -904 839 -446 887 -450 415 -904 825 -482 417 -890 849 -448 415 -898 877 -446 845 -474 843 -470 381 -918 845 -460 417 -882 421 -908 427 -872 451 -866 873 -444 413 -908 417 -878 449 -876 413 -908 411 -876 441 -876 439 -878 865 -8234 417 -906 851 -440 437 -904 839 -448 885 -448 419 -890 847 -446 415 -900 857 -450 417 -918 843 -474 841 -472 843 -468 383 -916 869 -430 411 -904 411 -904 411 -902 411 -904 869 -430 443 -870 411 -904 411 -904 411 -902 411 -904 411 -906 409 -906 837 -8266 413 -904 873 -414 453 -870 867 -450 883 -414 447 -860 875 -448 411 -888 873 -440 441 -874 875 -436 873 -436 871 -436 443 -874 875 -436 443 -890 415 -876 423 -910 395 -902 863 -448 441 -872 439 -888 421 -888 419 -880 451 -874 413 -910 411 -874 869 -8234 447 -876 875 -432 445 -874 877 -454 829 -450 449 -890 847 -446 413 -898 877 -444 411 -904 843 -472 841 -474 843 -470 413 -868 875 -436 445 -888 417 -880 423 -910 415 -874 877 -428 447 -876 449 -874 413 -910 411 -876 441 -878 439 -880 437 -878 863 -8232 417 -910 845 -470 405 -904 839 -478 855 -448 421 -882 845 -476 415 -884 875 -432 415 -916 845 -456 839 -464 875 -434 417 -914 845 -458 409 -916 387 -912 425 -906 399 -894 853 -456 413 -916 415 -880 413 -910 411 -912 409 -880 435 -874 437 -872 865 -8248 453 -866 879 -402 475 -842 907 -422 859 -450 415 -886 873 -438 443 -866 879 -446 415 -896 877 -446 873 -444 841 -474 411 -890 843 -462 415 -882 421 -912 427 -872 437 -892 857 -428 447 -880 449 -878 411 -904 409 -872 441 -872 +RAW_Data: 441 -872 441 -872 871 -8252 413 -880 865 -446 439 -872 899 -416 867 -456 409 -904 869 -432 415 -886 877 -460 407 -904 867 -432 877 -434 875 -434 415 -916 845 -460 417 -882 423 -902 411 -902 411 -910 857 -444 411 -904 409 -904 411 -904 409 -902 411 -908 399 -894 407 -922 837 -8230 443 -902 873 -444 411 -898 871 -442 839 -442 443 -890 875 -432 415 -914 845 -456 409 -912 837 -462 845 -462 871 -432 415 -914 843 -462 409 -918 419 -878 409 -904 411 -902 869 -450 411 -880 423 -904 411 -904 409 -910 397 -896 407 -922 417 -890 851 -8226 463 -868 867 -448 415 -882 891 -420 879 -450 419 -886 851 -450 417 -920 839 -474 411 -890 877 -430 875 -432 877 -430 415 -904 869 -434 413 -906 409 -916 407 -906 409 -882 879 -418 443 -882 421 -912 397 -900 453 -862 421 -878 453 -874 449 -878 841 -8230 449 -876 879 -426 449 -876 881 -416 889 -418 447 -890 847 -450 449 -858 877 -446 413 -900 883 -418 879 -446 845 -474 409 -902 839 -474 409 -902 409 -900 411 -900 411 -888 873 -436 413 -920 417 -882 425 -870 453 -868 417 -906 415 -906 417 -874 875 -8238 425 -876 893 -418 445 -880 875 -440 877 -408 447 -874 877 -442 433 -870 871 -450 423 -882 889 -420 879 -446 877 -444 413 -900 839 -476 411 -888 415 -882 421 -912 429 -870 865 -446 453 -864 419 -882 449 -870 417 -910 411 -906 411 -904 407 -904 837 -8248 457 -864 875 -408 449 -874 881 -440 863 -454 427 -888 881 -416 417 -896 875 -446 413 -900 877 -444 841 -440 873 -440 445 -890 843 -460 415 -884 453 -880 429 -868 451 -866 875 -442 415 -874 449 -872 449 -872 447 -870 413 -902 413 -904 409 -904 873 -8206 449 -880 879 -452 415 -880 865 -450 845 -448 415 -894 875 -446 413 -902 853 -448 449 -858 877 -446 877 -444 875 -444 411 -888 877 -426 441 -874 409 -920 417 -880 425 -904 835 -448 441 -882 423 -904 407 -876 433 -900 409 -884 439 -896 411 -882 889 -8232 413 -886 867 -460 415 -884 881 -420 867 -462 415 -916 845 -454 409 -908 843 -460 409 -918 845 -454 869 -432 877 -432 413 -918 845 -460 417 -880 441 -880 451 -848 453 -888 851 -442 433 -880 439 -878 437 -880 435 -882 397 -902 435 -872 437 -874 869 -8244 441 -854 909 -420 415 -906 847 -440 877 -442 433 -870 871 -448 423 -882 891 -450 419 -886 851 -450 879 -446 843 -472 413 -872 875 -470 381 -918 417 -880 425 -906 399 -900 867 -448 409 -920 413 -880 417 -914 417 -878 415 -908 413 -880 439 -878 869 -8228 457 -852 +RAW_Data: 883 -456 405 -882 889 -420 883 -448 415 -888 875 -434 445 -872 869 -436 443 -892 843 -458 869 -432 873 -434 445 -870 871 -436 445 -874 441 -886 415 -876 441 -882 885 -418 425 -902 409 -912 397 -898 419 -894 421 -882 451 -880 413 -876 875 -8222 447 -884 855 -452 449 -878 865 -454 849 -450 413 -902 875 -444 413 -888 875 -432 415 -908 843 -462 875 -430 867 -436 445 -890 843 -458 407 -888 451 -874 411 -906 409 -912 855 -448 429 -874 437 -892 413 -880 455 -880 419 -876 449 -878 413 -876 871 -8238 449 -876 879 -420 449 -878 863 -420 875 -448 413 -894 877 -446 413 -898 875 -444 411 -898 875 -444 839 -474 839 -474 409 -888 877 -432 415 -918 417 -880 411 -884 447 -880 877 -452 417 -876 439 -878 437 -878 437 -878 435 -878 435 -880 433 -848 893 -8224 457 -848 885 -456 437 -870 865 -420 879 -450 445 -862 877 -448 413 -890 873 -432 441 -876 869 -436 869 -438 867 -440 441 -900 847 -450 415 -900 413 -890 445 -890 417 -882 851 -450 421 -910 397 -900 439 -888 409 -886 453 -880 419 -880 449 -876 841 -8234 447 -878 891 -432 443 -876 843 -456 891 -418 415 -898 885 -420 451 -854 879 -450 413 -890 873 -438 875 -436 873 -436 443 -892 843 -458 409 -886 451 -874 439 -884 427 -872 891 -420 451 -852 453 -878 449 -842 445 -878 441 -880 439 -880 431 -870 869 -8242 435 -874 857 -458 413 -910 845 -440 865 -454 431 -884 887 -418 449 -886 841 -472 413 -888 877 -430 869 -434 875 -438 413 -918 843 -460 415 -906 409 -910 387 -912 425 -870 867 -450 425 -904 409 -904 411 -904 409 -908 415 -874 419 -914 417 -880 875 -8236 437 -884 855 -444 441 -880 853 -446 869 -446 429 -872 887 -418 447 -878 877 -430 445 -876 875 -420 895 -420 879 -448 413 -902 875 -444 411 -892 415 -884 421 -912 399 -900 867 -448 455 -860 423 -876 453 -872 449 -844 443 -870 443 -870 443 -870 873 -8232 451 -874 889 -402 441 -876 877 -456 853 -452 413 -896 877 -448 413 -890 875 -434 413 -884 879 -460 875 -426 869 -434 445 -892 845 -458 415 -886 423 -908 417 -872 455 -882 845 -440 433 -904 411 -878 443 -880 437 -882 435 -882 431 -870 433 -874 867 -8242 455 -862 879 -452 415 -880 867 -452 853 -448 415 -900 873 -446 411 -900 849 -450 415 -896 875 -446 873 -444 875 -410 443 -876 873 -436 443 -892 415 -884 451 -848 449 -878 879 -434 441 -870 447 -870 413 -902 411 -902 413 -870 445 -870 443 -900 839 -8242 453 -872 881 -452 413 -872 869 -448 849 -450 +RAW_Data: 445 -870 889 -418 449 -892 847 -446 413 -896 879 -446 875 -442 843 -474 411 -888 845 -462 415 -884 423 -910 427 -870 451 -862 875 -428 443 -876 445 -872 413 -906 413 -904 411 -904 411 -904 409 -904 839 -8264 409 -884 887 -430 445 -876 843 -448 887 -450 417 -888 849 -448 449 -890 847 -446 413 -898 877 -444 871 -444 839 -474 411 -902 839 -474 409 -902 411 -900 409 -888 415 -884 881 -456 417 -882 423 -910 399 -898 419 -896 419 -880 453 -878 413 -878 875 -8236 449 -876 879 -434 441 -870 875 -414 889 -454 419 -890 845 -450 417 -886 871 -440 443 -868 879 -448 879 -444 843 -474 413 -888 845 -462 415 -882 421 -912 427 -872 437 -894 837 -454 449 -884 419 -880 415 -910 413 -878 443 -878 439 -880 437 -878 863 -8230 457 -848 879 -452 437 -872 865 -450 849 -450 415 -902 851 -450 417 -900 887 -418 451 -884 843 -474 839 -476 839 -472 411 -866 877 -448 415 -886 445 -888 417 -880 423 -910 853 -446 409 -912 395 -904 451 -866 415 -910 415 -874 449 -872 445 -874 873 -8212 455 -868 877 -428 445 -874 877 -446 863 -450 425 -882 843 -476 413 -904 839 -472 413 -888 875 -430 875 -432 875 -434 413 -904 873 -434 413 -904 411 -904 411 -916 417 -880 867 -456 409 -908 417 -876 409 -914 425 -872 451 -866 421 -882 415 -944 805 -8276 413 -900 839 -484 389 -908 855 -452 853 -450 425 -906 855 -450 395 -938 827 -448 435 -896 851 -456 841 -476 841 -468 407 -914 839 -452 429 -886 427 -884 427 -884 393 -982 757 -540 325 -992 357 -942 359 -942 355 -976 353 -944 353 -974 355 -942 813 -8292 405 -906 835 -450 431 -884 853 -480 847 -446 413 -886 875 -468 381 -920 845 -460 415 -916 845 -458 843 -458 869 -434 413 -920 843 -460 417 -878 411 -910 411 -908 427 -872 861 -446 441 -874 451 -866 419 -916 417 -878 415 -910 411 -880 443 -878 867 -8226 457 -882 851 -440 433 -904 837 -474 835 -446 427 -916 857 -450 419 -888 849 -448 415 -918 843 -472 845 -470 843 -470 383 -900 871 -468 381 -916 415 -884 423 -908 397 -902 863 -450 439 -874 437 -890 413 -882 419 -882 453 -876 449 -844 445 -876 871 -8232 451 -876 853 -450 445 -880 863 -452 853 -448 415 -886 871 -438 441 -886 871 -432 439 -890 845 -458 843 -460 871 -468 379 -898 879 -444 415 -918 381 -918 417 -880 423 -906 853 -450 427 -902 409 -908 399 -894 417 -894 419 -912 419 -876 415 -910 843 -8250 407 -902 851 -454 445 -878 841 -484 843 -452 427 -886 851 -482 385 -916 843 -472 +RAW_Data: 413 -886 843 -464 843 -466 845 -466 415 -916 847 -458 417 -880 425 -906 413 -100576 129 -4900 97 -1286 555 -132 65 -198 361 -132 98215 -96 21029 -64 5709 -66 22509 -98 23929 -66 4017 -66 687 -98 1353 -66 3641 -66 1391 -64 565 -66 40435 -102 51423 -66 10357 -66 10493 -98 5979 -66 22915 -100 1281 -100 62401 -66 26927 -66 20563 -100 4151 -100 12369 -66 45939 -858 863 -446 437 -894 853 -458 845 -452 449 -878 863 -454 421 -888 849 -448 415 -886 875 -470 841 -470 839 -472 411 -888 843 -464 415 -910 419 -880 425 -872 437 -894 871 -416 449 -882 419 -880 453 -876 415 -906 413 -876 443 -876 441 -878 865 -8230 457 -850 879 -440 449 -872 875 -438 873 -422 433 -882 887 -422 451 -854 875 -440 443 -892 845 -460 875 -428 871 -436 413 -906 869 -434 443 -868 449 -890 419 -884 413 -888 875 -434 415 -916 415 -876 411 -908 411 -910 427 -870 437 -894 409 -882 871 -8250 409 -900 875 -444 411 -888 875 -434 873 -434 445 -864 877 -446 415 -900 873 -446 411 -888 873 -434 871 -436 873 -436 445 -892 841 -458 409 -886 451 -882 453 -844 451 -874 845 -486 415 -878 439 -880 435 -880 401 -914 399 -914 399 -914 397 -904 863 -8224 457 -882 845 -452 441 -872 865 -450 847 -450 417 -918 841 -472 413 -888 841 -464 413 -910 845 -460 875 -432 877 -432 413 -908 843 -460 409 -918 417 -884 425 -874 435 -894 853 -456 417 -880 451 -876 413 -912 411 -904 411 -880 435 -872 439 -872 871 -8244 409 -916 835 -446 439 -904 837 -448 869 -456 411 -906 869 -430 415 -918 845 -458 415 -876 867 -460 875 -430 875 -432 415 -904 869 -434 413 -904 411 -904 409 -906 409 -906 867 -432 413 -906 409 -918 417 -882 425 -870 439 -872 439 -872 439 -904 865 -8220 439 -868 871 -450 423 -884 857 -450 881 -446 413 -902 843 -474 411 -888 877 -430 415 -908 843 -460 869 -434 871 -436 445 -874 869 -436 443 -876 409 -906 409 -906 409 -906 871 -432 415 -916 417 -882 425 -908 399 -896 409 -916 409 -896 411 -880 887 -8232 449 -844 867 -446 439 -872 893 -412 895 -446 429 -868 855 -456 451 -884 845 -442 435 -878 869 -454 853 -448 881 -444 413 -890 875 -432 413 -918 409 -874 441 -876 441 -878 867 -456 415 -882 423 -910 397 -900 437 -888 413 -880 455 -880 419 -876 877 -8238 421 -890 843 -488 413 -880 863 -450 847 -446 415 -892 879 -448 411 -898 875 -444 413 -900 841 -476 843 -472 841 -470 413 -888 843 -464 415 -906 409 -884 421 -908 397 -900 885 -420 445 -880 417 -914 419 -876 +RAW_Data: 415 -910 411 -880 441 -880 435 -872 867 -8254 421 -890 843 -444 445 -874 875 -442 865 -452 427 -890 849 -448 415 -918 841 -472 411 -886 841 -462 871 -434 873 -470 379 -920 843 -458 409 -900 413 -918 413 -886 415 -884 879 -452 409 -906 409 -884 421 -912 395 -900 437 -888 411 -880 441 -896 873 -8228 411 -902 843 -476 411 -888 877 -428 869 -434 415 -916 843 -460 415 -882 869 -458 409 -904 873 -432 875 -436 873 -436 413 -908 875 -430 413 -906 409 -886 419 -914 427 -872 889 -420 451 -882 419 -878 451 -876 415 -876 443 -878 439 -876 437 -878 869 -8228 421 -918 845 -452 403 -904 865 -444 853 -446 417 -924 847 -446 415 -920 839 -468 411 -904 841 -468 839 -468 839 -472 411 -902 841 -470 411 -904 411 -872 413 -902 413 -902 877 -434 411 -900 413 -906 411 -900 415 -916 379 -936 381 -916 415 -908 835 -8254 419 -910 841 -450 423 -884 855 -452 879 -448 417 -900 849 -448 415 -920 841 -472 411 -874 869 -438 871 -472 839 -470 411 -872 869 -440 445 -874 441 -866 449 -884 413 -888 875 -432 413 -906 409 -906 409 -906 409 -886 421 -908 427 -872 451 -866 875 -8236 415 -882 871 -460 417 -880 881 -454 845 -456 417 -880 879 -452 409 -884 881 -452 409 -880 881 -450 837 -462 871 -434 415 -914 845 -458 413 -916 387 -910 427 -904 401 -894 867 -450 411 -884 413 -908 419 -912 417 -876 415 -908 413 -910 409 -878 865 -8234 455 -882 843 -452 445 -880 859 -450 847 -446 415 -894 877 -444 415 -896 879 -444 413 -902 841 -472 841 -472 841 -472 411 -890 845 -462 415 -908 417 -876 411 -908 409 -912 851 -450 425 -908 399 -894 407 -904 437 -888 411 -880 447 -876 419 -880 881 -8238 439 -888 837 -456 451 -880 851 -452 871 -420 449 -892 845 -448 413 -894 879 -446 411 -900 875 -444 839 -474 837 -474 409 -904 839 -472 409 -902 411 -902 409 -904 409 -904 839 -472 409 -904 409 -872 443 -872 443 -890 417 -882 423 -910 417 -874 875 -8220 441 -904 841 -468 411 -904 841 -470 841 -470 413 -886 843 -462 417 -906 843 -458 411 -918 843 -456 869 -432 875 -434 415 -916 845 -456 411 -916 417 -876 411 -912 425 -870 889 -418 445 -882 421 -880 449 -878 415 -910 413 -878 441 -878 439 -880 865 -8230 417 -906 843 -468 407 -906 839 -478 857 -450 423 -884 843 -474 413 -886 877 -432 415 -916 845 -458 845 -460 871 -432 415 -916 845 -458 417 -916 387 -908 427 -870 437 -892 851 -458 415 -882 451 -876 413 -912 413 -878 439 -878 441 -880 435 -878 +RAW_Data: 863 -8240 423 -888 841 -486 415 -878 869 -452 849 -448 415 -920 841 -470 381 -920 845 -460 415 -910 843 -454 869 -432 873 -434 415 -904 869 -436 413 -920 417 -876 441 -880 425 -908 857 -444 409 -910 399 -898 417 -894 419 -882 451 -874 415 -908 413 -878 873 -8254 405 -898 853 -458 417 -914 847 -452 865 -452 421 -884 845 -474 413 -886 873 -430 411 -904 873 -432 871 -470 837 -470 413 -886 843 -460 413 -918 417 -874 413 -906 411 -910 851 -446 411 -914 425 -872 451 -866 417 -916 419 -878 415 -910 413 -878 871 -8228 455 -884 845 -452 445 -880 863 -450 851 -446 413 -920 841 -470 409 -874 873 -468 409 -872 873 -470 843 -470 839 -470 381 -918 843 -462 415 -912 411 -880 423 -906 397 -900 865 -446 419 -894 419 -912 419 -878 413 -910 411 -910 409 -880 441 -878 865 -8254 413 -878 877 -430 445 -880 841 -458 863 -452 415 -920 841 -438 415 -908 871 -434 413 -914 845 -458 871 -466 841 -470 413 -884 843 -460 409 -920 417 -880 425 -872 435 -894 867 -448 407 -902 409 -916 407 -896 407 -902 409 -886 439 -898 411 -880 875 -8248 411 -900 843 -476 413 -886 873 -432 875 -434 413 -918 843 -460 411 -916 845 -454 411 -918 845 -456 845 -460 841 -462 411 -916 843 -456 411 -916 417 -880 425 -908 399 -896 851 -456 415 -916 417 -880 415 -908 413 -880 439 -870 439 -904 407 -874 871 -8238 439 -868 869 -448 411 -906 869 -454 837 -460 411 -916 843 -458 411 -916 843 -456 409 -906 871 -432 873 -434 875 -434 413 -918 845 -458 411 -916 387 -910 425 -908 415 -870 875 -428 447 -880 415 -908 413 -880 439 -872 439 -872 441 -872 439 -872 871 -8246 419 -896 847 -486 413 -882 865 -448 849 -446 415 -928 845 -446 415 -886 875 -468 381 -916 843 -460 843 -464 877 -432 413 -916 843 -458 411 -916 385 -906 411 -910 425 -906 823 -478 411 -902 411 -904 411 -906 397 -898 407 -918 411 -880 417 -916 847 -8236 435 -892 867 -448 397 -898 869 -448 869 -456 417 -906 837 -460 415 -914 847 -456 387 -908 849 -482 837 -458 871 -430 415 -914 847 -458 411 -916 385 -902 411 -910 423 -904 839 -450 423 -910 395 -900 405 -922 417 -888 417 -912 417 -876 415 -910 841 -8264 421 -890 843 -452 445 -880 863 -448 849 -448 417 -918 841 -470 413 -886 871 -430 411 -904 873 -466 837 -470 841 -468 411 -904 839 -470 411 -902 411 -902 381 -918 417 -906 839 -460 415 -914 389 -908 427 -870 437 -892 409 -916 407 -896 409 -916 853 -8234 425 -906 825 -480 401 -894 +RAW_Data: 865 -450 851 -456 415 -918 845 -454 405 -902 865 -448 421 -902 829 -482 847 -446 875 -444 413 -898 845 -474 413 -902 411 -904 413 -904 383 -914 843 -462 411 -914 417 -880 423 -906 397 -900 405 -922 417 -890 417 -882 879 -8232 409 -904 871 -434 411 -904 871 -466 839 -470 381 -932 845 -446 415 -918 839 -470 381 -916 843 -460 873 -466 841 -468 381 -916 841 -460 413 -916 387 -910 423 -908 397 -896 869 -448 427 -906 399 -894 415 -894 417 -912 417 -880 415 -908 411 -882 869 -8228 455 -888 845 -452 409 -916 861 -450 847 -446 415 -896 877 -444 413 -902 853 -448 415 -894 879 -444 841 -476 843 -472 415 -902 839 -472 381 -914 417 -914 387 -910 395 -938 825 -446 437 -894 417 -892 417 -914 415 -876 413 -910 411 -910 409 -910 835 -8232 447 -878 853 -452 451 -880 863 -450 847 -448 413 -920 839 -472 411 -888 877 -430 415 -916 843 -456 843 -460 867 -436 443 -874 869 -436 443 -890 415 -884 421 -904 407 -912 855 -444 409 -906 409 -912 397 -898 439 -890 411 -880 453 -880 421 -872 879 -8246 417 -876 849 -482 411 -880 883 -450 837 -458 411 -916 847 -456 411 -916 847 -454 409 -916 845 -452 835 -462 875 -432 413 -916 843 -460 411 -912 409 -906 411 -878 421 -910 855 -446 411 -910 425 -872 435 -892 409 -918 413 -880 419 -880 451 -880 843 -8264 421 -890 843 -486 411 -872 867 -448 851 -448 417 -926 847 -444 415 -896 875 -442 415 -900 851 -448 877 -444 843 -476 415 -888 843 -462 415 -916 387 -910 425 -908 399 -894 867 -444 411 -908 395 -902 435 -894 417 -892 417 -882 451 -878 413 -878 871 -8250 405 -900 867 -448 409 -910 853 -446 869 -454 411 -914 845 -456 417 -880 881 -448 411 -880 881 -452 837 -460 873 -434 413 -916 845 -460 415 -882 421 -910 395 -902 437 -888 853 -458 415 -882 449 -878 413 -912 411 -880 439 -880 437 -878 435 -880 865 -8224 455 -884 843 -442 437 -878 869 -452 855 -448 415 -920 839 -472 413 -886 845 -462 417 -914 847 -454 869 -426 873 -434 415 -916 843 -460 409 -918 415 -882 425 -906 399 -896 865 -448 407 -902 439 -890 411 -880 417 -916 417 -878 417 -908 413 -880 873 -8230 457 -886 849 -452 407 -906 863 -450 849 -446 415 -894 877 -446 413 -898 877 -442 413 -904 839 -474 843 -472 843 -470 381 -918 843 -462 417 -914 387 -910 427 -872 435 -892 869 -450 407 -896 409 -900 407 -918 407 -896 409 -900 407 -918 407 -898 855 -8234 443 -892 845 -460 415 -916 845 -454 835 -462 417 -912 837 -460 +RAW_Data: 411 -916 843 -458 417 -914 845 -454 835 -462 871 -468 381 -914 871 -430 415 -918 387 -910 425 -906 399 -896 849 -474 407 -896 409 -902 407 -918 407 -898 409 -916 409 -894 409 -884 875 -8230 443 -874 873 -434 413 -920 841 -460 871 -432 413 -918 847 -456 411 -904 871 -430 415 -916 845 -458 845 -460 875 -432 415 -916 843 -456 411 -916 387 -910 425 -908 415 -870 851 -486 411 -872 439 -870 441 -872 439 -904 409 -878 439 -878 437 -878 865 -8230 455 -882 845 -442 437 -878 869 -452 855 -448 415 -920 843 -470 381 -918 845 -460 415 -912 845 -454 869 -432 873 -434 415 -916 845 -458 411 -914 387 -910 425 -902 411 -902 835 -450 441 -880 425 -902 411 -908 397 -894 409 -902 435 -890 419 -892 843 -8266 395 -900 865 -446 439 -890 835 -474 867 -442 409 -910 853 -446 411 -912 851 -450 425 -902 837 -448 869 -458 841 -462 411 -916 843 -456 411 -916 387 -910 425 -908 399 -896 855 -458 415 -914 419 -876 415 -912 411 -880 439 -878 437 -882 401 -912 865 -8226 419 -910 843 -452 447 -880 863 -452 849 -446 413 -898 875 -444 413 -900 875 -442 411 -904 841 -472 841 -472 839 -472 411 -890 843 -460 409 -906 409 -920 417 -880 425 -874 889 -418 445 -880 421 -880 453 -880 413 -910 413 -880 439 -878 437 -878 863 -8238 417 -904 843 -470 405 -902 841 -478 859 -448 421 -890 849 -448 415 -918 841 -472 413 -886 843 -462 869 -468 841 -470 381 -916 845 -460 411 -918 387 -910 425 -906 399 -894 851 -456 415 -916 417 -880 415 -910 411 -912 405 -904 409 -904 407 -904 839 -8246 441 -886 855 -430 449 -878 879 -416 889 -450 415 -900 861 -420 449 -868 889 -418 453 -886 841 -474 839 -472 843 -470 411 -898 845 -450 415 -898 413 -886 445 -874 441 -890 841 -458 409 -898 413 -920 411 -872 441 -890 415 -884 421 -910 397 -902 853 -8254 415 -898 879 -444 413 -904 841 -472 841 -472 413 -886 841 -462 411 -916 843 -458 409 -916 845 -458 841 -462 869 -436 413 -904 869 -470 379 -920 417 -876 421 -908 425 -872 889 -418 451 -884 419 -880 449 -874 415 -908 411 -878 443 -880 435 -872 865 -8226 455 -886 845 -450 445 -880 863 -452 853 -444 415 -918 841 -470 381 -916 845 -462 415 -914 845 -456 837 -460 871 -470 381 -916 843 -460 411 -914 417 -880 423 -902 409 -904 837 -484 389 -910 427 -904 399 -896 407 -916 409 -892 409 -918 409 -896 835 -8254 413 -896 879 -444 413 -900 843 -474 841 -472 411 -902 841 -472 409 -904 839 -472 411 -902 843 -468 +RAW_Data: 839 -472 843 -472 381 -916 843 -462 415 -918 387 -910 427 -870 435 -894 851 -456 415 -914 419 -880 413 -912 411 -880 441 -878 439 -880 401 -914 865 -8224 417 -908 843 -468 407 -904 839 -480 857 -448 421 -886 853 -448 417 -918 841 -472 413 -886 845 -462 867 -466 841 -470 381 -918 847 -460 415 -914 409 -878 413 -908 427 -906 825 -446 441 -902 409 -902 411 -908 397 -894 409 -900 417 -898 419 -914 843 -8246 425 -872 861 -480 399 -898 865 -448 867 -452 411 -880 881 -452 409 -908 845 -456 409 -914 835 -462 873 -432 877 -432 415 -904 869 -434 413 -916 417 -874 441 -880 411 -910 853 -448 411 -912 425 -872 451 -868 419 -914 419 -878 415 -908 411 -910 841 -8226 455 -886 843 -452 449 -878 863 -452 855 -446 415 -886 877 -434 415 -916 843 -462 415 -882 881 -454 845 -460 845 -460 411 -916 845 -456 411 -916 387 -910 425 -872 449 -870 875 -430 445 -880 413 -910 413 -878 441 -868 441 -872 441 -872 441 -902 841 -8246 421 -892 853 -452 443 -872 867 -448 849 -450 415 -926 847 -446 413 -898 877 -444 413 -900 845 -472 839 -470 839 -474 409 -902 843 -470 411 -872 445 -874 411 -904 411 -906 875 -432 413 -908 417 -884 423 -910 399 -898 407 -922 411 -880 445 -878 851 -8250 423 -904 857 -448 397 -902 853 -454 881 -430 443 -878 843 -478 431 -880 867 -450 423 -888 849 -448 843 -476 845 -474 413 -906 843 -470 381 -904 415 -914 417 -880 423 -902 837 -484 411 -878 425 -906 399 -896 405 -922 411 -916 381 -910 415 -910 841 -8232 453 -870 875 -430 447 -878 875 -442 841 -478 397 -912 861 -450 423 -886 845 -474 413 -906 841 -470 843 -470 839 -470 381 -916 843 -462 411 -918 387 -910 425 -902 411 -908 851 -450 411 -882 419 -914 417 -880 415 -908 415 -910 411 -878 439 -878 865 -8232 455 -882 845 -452 443 -880 861 -452 849 -448 417 -902 843 -474 413 -888 873 -430 411 -904 871 -434 869 -470 839 -472 409 -904 839 -470 413 -888 417 -906 411 -874 441 -876 869 -456 409 -886 419 -912 425 -870 451 -866 417 -908 415 -906 415 -872 877 -8248 407 -906 853 -446 411 -906 869 -452 847 -458 417 -880 883 -452 387 -912 851 -450 423 -906 853 -448 223 -124912 1217 -330 99 -132 163 -66 2031 -64 59635 -66 2765 -98 26085 -98 4367 -100 563 -66 24625 -66 1849 -66 10545 -68 21363 -66 15231 -100 42927 -100 3021 -66 55509 -100 4287 -66 2435 -98 1017 -132 3371 -66 11541 -100 1265 -100 799 -66 1859 -68 3385 -66 965 -100 2221 -100 2355 -68 6165 -66 1025 -100 +RAW_Data: 899 -66 173525 -166 2373 -68 397 -66 40101 -66 1891 -66 10969 -132 2617 -66 20187 -66 10559 -100 10491 -98 35135 -66 2287 -68 2649 -66 3393 -98 12375 -100 1265 -100 5605 -66 9997 -68 435 -132 16583 -100 3003 -66 10083 -64 13329 -66 64855 -100 13269 -132 10773 -100 4673 -17250 97 -1358 297 -164 165 -132 199 -66 199 -66 165 -664 65 -98 265 -66 201 -132 531 -132 235 -66 3355 -68 2757 -98 16517 -66 12659 -66 3773 -66 26419 -66 12433 -66 531 -100 20227 -66 1851 -66 11499 -64 10717 diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index ac14bce6a37..ab37ee91aeb 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -672,6 +672,62 @@ MU_TEST(subghz_decoder_dickert_test) { "Test decoder " SUBGHZ_PROTOCOL_DICKERT_MAHS_NAME " error\r\n"); } +MU_TEST(subghz_decoder_legrand_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/legrand_2E37F_raw.sub"), SUBGHZ_PROTOCOL_LEGRAND_NAME), + "Test decoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_marantec24_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/marantec24_raw.sub"), SUBGHZ_PROTOCOL_MARANTEC24_NAME), + "Test decoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_roger_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/roger_raw.sub"), SUBGHZ_PROTOCOL_ROGER_NAME), + "Test decoder " SUBGHZ_PROTOCOL_ROGER_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_feron_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/feron_raw.sub"), SUBGHZ_PROTOCOL_FERON_NAME), + "Test decoder " SUBGHZ_PROTOCOL_FERON_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_gangqi_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/gangqi_raw.sub"), SUBGHZ_PROTOCOL_GANGQI_NAME), + "Test decoder " SUBGHZ_PROTOCOL_GANGQI_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_hollarm_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/hollarm_raw.sub"), SUBGHZ_PROTOCOL_HOLLARM_NAME), + "Test decoder " SUBGHZ_PROTOCOL_HOLLARM_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_reversrb2_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/revers_rb2_raw.sub"), SUBGHZ_PROTOCOL_REVERSRB2_NAME), + "Test decoder " SUBGHZ_PROTOCOL_REVERSRB2_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_hay21_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/hay21_raw.sub"), SUBGHZ_PROTOCOL_HAY21_NAME), + "Test decoder " SUBGHZ_PROTOCOL_HAY21_NAME " error\r\n"); +} + //test encoders MU_TEST(subghz_encoder_princeton_test) { mu_assert( @@ -835,6 +891,48 @@ MU_TEST(subghz_encoder_dickert_test) { "Test encoder " SUBGHZ_PROTOCOL_DICKERT_MAHS_NAME " error\r\n"); } +MU_TEST(subghz_encoder_legrand_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/legrand_2E37F.sub")), + "Test encoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_feron_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/feron.sub")), + "Test encoder " SUBGHZ_PROTOCOL_FERON_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_gangqi_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/gang_qi.sub")), + "Test encoder " SUBGHZ_PROTOCOL_GANGQI_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_hollarm_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/hollarm.sub")), + "Test encoder " SUBGHZ_PROTOCOL_HOLLARM_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_reversrb2_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/revers_rb2.sub")), + "Test encoder " SUBGHZ_PROTOCOL_REVERSRB2_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_roger_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/roger.sub")), + "Test encoder " SUBGHZ_PROTOCOL_ROGER_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_marantec24_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/marantec24.sub")), + "Test encoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); +} + MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } @@ -887,6 +985,14 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_kinggates_stylo4k_test); MU_RUN_TEST(subghz_decoder_mastercode_test); MU_RUN_TEST(subghz_decoder_dickert_test); + MU_RUN_TEST(subghz_decoder_roger_test); + MU_RUN_TEST(subghz_decoder_hollarm_test); + MU_RUN_TEST(subghz_decoder_reversrb2_test); + MU_RUN_TEST(subghz_decoder_gangqi_test); + MU_RUN_TEST(subghz_decoder_hay21_test); + MU_RUN_TEST(subghz_decoder_feron_test); + MU_RUN_TEST(subghz_decoder_legrand_test); + MU_RUN_TEST(subghz_decoder_marantec24_test); MU_RUN_TEST(subghz_encoder_princeton_test); MU_RUN_TEST(subghz_encoder_came_test); @@ -915,6 +1021,13 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_dooya_test); MU_RUN_TEST(subghz_encoder_mastercode_test); MU_RUN_TEST(subghz_encoder_dickert_test); + MU_RUN_TEST(subghz_encoder_feron_test); + MU_RUN_TEST(subghz_encoder_roger_test); + MU_RUN_TEST(subghz_encoder_gangqi_test); + MU_RUN_TEST(subghz_encoder_marantec24_test); + MU_RUN_TEST(subghz_encoder_hollarm_test); + MU_RUN_TEST(subghz_encoder_reversrb2_test); + MU_RUN_TEST(subghz_encoder_legrand_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); From d7ddc1c30de830df79be8b4e76c277e3242a3dd8 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 11 Aug 2025 21:02:21 +0300 Subject: [PATCH 07/19] Add honeywell unittest --- .../resources/unit_tests/subghz/honeywell_sec.sub | 7 +++++++ .../unit_tests/subghz/honeywell_sec_raw.sub | 8 ++++++++ .../debug/unit_tests/tests/subghz/subghz_test.c | 15 +++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub create mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub new file mode 100644 index 00000000000..900a536acbc --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Honeywell Sec +Bit: 62 +Key: 3F FE 80 AC AB 22 F2 8A diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub new file mode 100644 index 00000000000..6281d9650d5 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub @@ -0,0 +1,8 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 265 -107730 281 -110 181 -110 143 -110 181 -110 143 -108 177 -102 169 -100 165 -98 167 -136 135 -140 139 -106 173 -102 171 -102 313 -240 299 -132 127 -132 139 -140 143 -144 139 -104 169 -102 165 -278 273 -268 267 -272 133 -132 279 -130 139 -282 273 -276 275 -246 305 -250 155 -126 309 -106 135 -254 299 -138 139 -132 119 -272 275 -278 153 -122 149 -122 151 -120 289 -132 133 -280 281 -276 269 -136 131 -134 139 -288 279 -268 265 -107754 501 -72 181 -110 181 -108 145 -110 181 -108 145 -104 173 -100 167 -98 167 -134 135 -140 139 -104 173 -102 171 -102 315 -242 297 -132 127 -128 155 -124 121 -150 151 -122 151 -124 123 -284 275 -278 283 -262 133 -132 317 -106 133 -284 279 -272 265 -270 271 -274 135 -134 315 -108 133 -282 279 -134 125 -130 137 -284 277 -270 133 -130 133 -140 143 -144 289 -110 125 -300 267 -270 271 -134 133 -130 151 -244 311 -252 289 -112890 271 -66 167 -142 143 -106 177 -108 181 -110 145 -108 181 -110 145 -108 181 -110 145 -108 171 -104 165 -100 163 -100 307 -292 253 -146 145 -104 175 -108 145 -146 145 -108 145 -146 145 -254 281 -270 269 -270 133 -132 279 -130 139 -286 287 -248 279 -276 271 -274 135 -130 281 -130 173 -246 273 -124 153 -130 127 -280 275 -276 123 -154 121 -130 155 -122 301 -122 121 -280 275 -276 277 -124 177 -106 165 -240 303 -266 267 -107722 265 -90 181 -122 149 -122 151 -124 157 -124 151 -120 151 -120 153 -126 155 -94 183 -90 181 -92 179 -92 193 -96 303 -244 307 -126 125 -126 155 -122 151 -120 151 -122 151 -128 157 -248 275 -278 285 -264 135 -132 317 -108 133 -284 279 -270 267 -270 271 -272 137 -132 317 -106 135 -282 279 -134 127 -130 135 -284 279 -270 131 -130 133 -140 141 -144 289 -110 127 -298 269 -270 271 -134 133 -130 151 -244 311 -252 291 -112912 255 -144 135 -136 133 -134 135 -136 135 -138 137 -138 137 -138 137 -136 137 -136 135 -138 135 -138 135 -138 137 -136 275 -290 253 -146 145 -138 103 -144 143 -146 145 -144 109 -146 145 -254 279 -272 269 -270 133 -134 281 -142 133 -280 277 -270 267 -272 269 -274 135 -134 281 -142 133 -282 277 -134 129 -132 137 -284 279 -270 131 -130 131 -140 141 -142 289 -142 95 -302 269 -270 269 -134 133 -162 121 -274 277 -252 275 -107764 227 -90 121 -168 101 -200 65 -204 67 -206 67 -208 69 -206 69 -206 69 -204 67 -206 67 -206 67 -204 67 -206 69 -204 209 -344 201 -198 99 -168 105 -174 105 -176 105 -138 +RAW_Data: 103 -170 101 -312 237 -302 267 -304 101 -166 219 -194 103 -324 209 -314 243 -314 241 -274 135 -134 281 -164 103 -288 285 -138 103 -174 109 -290 277 -268 133 -128 131 -176 103 -144 287 -110 161 -272 271 -268 267 -136 131 -132 151 -244 311 -248 271 -107752 281 -110 181 -108 143 -108 171 -102 167 -100 165 -100 171 -136 139 -104 173 -104 171 -102 169 -104 167 -102 171 -102 311 -254 291 -146 143 -108 139 -146 143 -110 145 -146 143 -110 181 -254 279 -268 265 -270 133 -132 279 -130 171 -248 273 -276 277 -246 275 -280 157 -124 277 -132 175 -246 275 -122 153 -128 125 -284 273 -278 123 -152 125 -134 161 -122 271 -138 141 -248 303 -248 307 -122 121 -152 119 -292 271 -276 273 -112892 531 -74 181 -108 145 -110 173 -106 167 -100 165 -100 167 -136 139 -138 139 -104 171 -104 169 -102 169 -102 171 -102 309 -256 289 -146 145 -106 139 -144 145 -110 145 -144 145 -110 181 -254 277 -270 265 -270 133 -132 279 -130 137 -282 275 -276 277 -246 275 -280 157 -124 279 -130 139 -282 273 -124 153 -128 125 -282 275 -278 123 -152 123 -136 161 -120 273 -136 143 -248 303 -248 307 -122 121 -152 119 -292 269 -274 275 -107766 243 -72 133 -122 149 -122 151 -120 155 -126 157 -124 149 -122 151 -120 153 -126 157 -94 183 -90 181 -90 181 -90 193 -100 325 -254 291 -108 145 -136 135 -142 141 -108 143 -146 143 -110 145 -290 285 -244 277 -274 135 -132 279 -130 137 -286 287 -246 279 -278 273 -274 133 -132 281 -130 173 -246 275 -124 153 -126 127 -284 273 -278 123 -152 123 -134 161 -122 271 -138 143 -248 301 -250 307 -122 121 -150 121 -290 273 -274 273 -112946 231 -66 171 -146 109 -146 143 -140 137 -136 135 -134 135 -136 135 -136 137 -138 137 -138 135 -138 135 -138 137 -136 137 -136 279 -274 267 -132 131 -132 141 -142 141 -142 139 -138 135 -134 133 -278 273 -268 267 -270 135 -132 281 -142 135 -280 277 -270 269 -270 271 -274 135 -132 281 -142 135 -280 279 -134 127 -132 137 -286 277 -270 131 -130 133 -174 105 -144 287 -140 97 -302 271 -270 269 -134 133 -160 123 -274 279 -248 273 -198912 65 -1282 289 -130 1013 -98 97 -132 1027 -524 127 -1802 163 -132 63 -2054 63 -2504 65 -6158 131 -134 65 -7374 67 -562 99 -8756 99 -6182 133 -436 67 -304 67 -1030 97 -9514 65 -13272 129 -2676 427 -100 361 -296 825 -9058 131 -5872 99 -18954 65 -5058 65 -8702 101 -3996 99 -11900 67 -8368 99 -1700 293 -232 1029 -68 1161 -134 133 -17572 265 -336 97 -3744 +RAW_Data: 63 -6934 99 -1870 67 -264 65 -360 97 -1420 65 -540 65 -330 99 -2646 131 -350 65 -1192 67 -5532 99 -1526 165 -504 199 -1690 67 -134 65 -562 129 -330 65 -6116 65 -8386 65 -1538 65 -658 65 -920 63 -488 129 -524 67 -2038 839 -136 99 -2028 65 -3056 65 -5392 199 -1234 101 -432 99 -2898 67 -7150 167 -2724 63 -134 99 -426 101 -3226 163 -958 101 -468 67 -1468 131 -2006 129 -964 97 -302 99 -3972 99 -4584 197 -2592 95 -1184 97 -390 65 -1514 65 -2600 65 -5218 97 -2748 529 -130 227 -520 163 -66 557 -166 63 -824 165 -3824 133 -14452 269 -7042 67 -168 101 -704 99 -6194 63 -9950 97 -1614 99 -12232 133 -3736 167 -266 129 -1532 65 -1378 129 -8180 101 -18264 465 -100 503 -100 591 -130 127 -98 715 -168 163 -190 127 -7396 63 -652 63 -8308 65 -1048 129 -5408 65 -9848 67 -18404 65 -2542 65 -6094 65 -934 65 -7330 95 -9092 97 -428 97 -1062 67 -3802 881 -66 419 -268 729 -66 133 -268 503 -68 99 -6518 131 -330 97 -194 161 -196 65 -6016 99 -5998 133 -3128 65 -1300 99 -834 65 -1038 97 -230 129 -170 67 -102 131 -562 65 -466 739 -66 737 -100 1169 -266 295 -230 499 -1390 165 -290 65 -452 65 -6048 63 -17618 99 -9778 131 -1240 99 -10614 67 -1052 63 -19206 99 -12288 131 -132 399 -234 133 -132 199 -170 531 -98 393 -64 97 -98 165 -2680 diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index ab37ee91aeb..e78a5d40b3d 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -728,6 +728,13 @@ MU_TEST(subghz_decoder_hay21_test) { "Test decoder " SUBGHZ_PROTOCOL_HAY21_NAME " error\r\n"); } +MU_TEST(subghz_decoder_honeywellsec_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/honeywell_sec_raw.sub"), SUBGHZ_PROTOCOL_HONEYWELL_NAME), + "Test decoder " SUBGHZ_PROTOCOL_HONEYWELL_NAME " error\r\n"); +} + //test encoders MU_TEST(subghz_encoder_princeton_test) { mu_assert( @@ -933,6 +940,12 @@ MU_TEST(subghz_encoder_marantec24_test) { "Test encoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); } +MU_TEST(subghz_encoder_honeywellsec_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/honeywell_sec.sub")), + "Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_NAME " error\r\n"); +} + MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } @@ -993,6 +1006,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_feron_test); MU_RUN_TEST(subghz_decoder_legrand_test); MU_RUN_TEST(subghz_decoder_marantec24_test); + MU_RUN_TEST(subghz_decoder_honeywellsec_test); MU_RUN_TEST(subghz_encoder_princeton_test); MU_RUN_TEST(subghz_encoder_came_test); @@ -1028,6 +1042,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_hollarm_test); MU_RUN_TEST(subghz_encoder_reversrb2_test); MU_RUN_TEST(subghz_encoder_legrand_test); + MU_RUN_TEST(subghz_encoder_honeywellsec_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); From e8c0cf724d9736afe8ca40aebd2cf95f13055553 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 24 Sep 2025 03:44:02 +0300 Subject: [PATCH 08/19] Comment until better solution is found Adding GAPs to be sent first to make signal better suitable for decoder (decoding from only one signal sample) does nothing, needs something else TODO: Fix encoders? --- .../unit_tests/subghz/marantec24.sub | 2 +- .../unit_tests/subghz/revers_rb2.sub | 2 +- .../unit_tests/tests/subghz/subghz_test.c | 26 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub index 3ea21478e15..b15d1cdb37b 100644 --- a/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub @@ -1,6 +1,6 @@ Filetype: Flipper SubGhz Key File Version: 1 -Frequency: 868350000 +Frequency: 433920000 Preset: FuriHalSubGhzPresetOok650Async Protocol: Marantec24 Bit: 24 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub index ba6e37d010b..9a046fd7bee 100644 --- a/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub @@ -1,6 +1,6 @@ Filetype: Flipper SubGhz Key File Version: 1 -Frequency: 433889000 +Frequency: 433920000 Preset: FuriHalSubGhzPresetOok650Async Protocol: Revers_RB2 Bit: 64 diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index e78a5d40b3d..4ed2e3d1567 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -898,11 +898,11 @@ MU_TEST(subghz_encoder_dickert_test) { "Test encoder " SUBGHZ_PROTOCOL_DICKERT_MAHS_NAME " error\r\n"); } -MU_TEST(subghz_encoder_legrand_test) { +/*MU_TEST(subghz_encoder_legrand_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/legrand_2E37F.sub")), "Test encoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); -} +}*/ MU_TEST(subghz_encoder_feron_test) { mu_assert( @@ -910,11 +910,11 @@ MU_TEST(subghz_encoder_feron_test) { "Test encoder " SUBGHZ_PROTOCOL_FERON_NAME " error\r\n"); } -MU_TEST(subghz_encoder_gangqi_test) { +/*MU_TEST(subghz_encoder_gangqi_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/gang_qi.sub")), "Test encoder " SUBGHZ_PROTOCOL_GANGQI_NAME " error\r\n"); -} +}*/ MU_TEST(subghz_encoder_hollarm_test) { mu_assert( @@ -922,11 +922,11 @@ MU_TEST(subghz_encoder_hollarm_test) { "Test encoder " SUBGHZ_PROTOCOL_HOLLARM_NAME " error\r\n"); } -MU_TEST(subghz_encoder_reversrb2_test) { +/*MU_TEST(subghz_encoder_reversrb2_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/revers_rb2.sub")), "Test encoder " SUBGHZ_PROTOCOL_REVERSRB2_NAME " error\r\n"); -} +}*/ MU_TEST(subghz_encoder_roger_test) { mu_assert( @@ -934,7 +934,7 @@ MU_TEST(subghz_encoder_roger_test) { "Test encoder " SUBGHZ_PROTOCOL_ROGER_NAME " error\r\n"); } -MU_TEST(subghz_encoder_marantec24_test) { +/*MU_TEST(subghz_encoder_marantec24_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/marantec24.sub")), "Test encoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); @@ -944,7 +944,7 @@ MU_TEST(subghz_encoder_honeywellsec_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/honeywell_sec.sub")), "Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_NAME " error\r\n"); -} +}*/ MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); @@ -1037,12 +1037,12 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_dickert_test); MU_RUN_TEST(subghz_encoder_feron_test); MU_RUN_TEST(subghz_encoder_roger_test); - MU_RUN_TEST(subghz_encoder_gangqi_test); - MU_RUN_TEST(subghz_encoder_marantec24_test); + //MU_RUN_TEST(subghz_encoder_gangqi_test); + //MU_RUN_TEST(subghz_encoder_marantec24_test); MU_RUN_TEST(subghz_encoder_hollarm_test); - MU_RUN_TEST(subghz_encoder_reversrb2_test); - MU_RUN_TEST(subghz_encoder_legrand_test); - MU_RUN_TEST(subghz_encoder_honeywellsec_test); + //MU_RUN_TEST(subghz_encoder_reversrb2_test); + //MU_RUN_TEST(subghz_encoder_legrand_test); + //MU_RUN_TEST(subghz_encoder_honeywellsec_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); From 9554e162ae8c60298f686d18ceae97e2e5da68a8 Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 24 Sep 2025 12:11:23 +0100 Subject: [PATCH 09/19] suppressed missing issue warning --- lib/subghz/protocols/honeywell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/subghz/protocols/honeywell.c b/lib/subghz/protocols/honeywell.c index e76bb2822be..cec827ea1f6 100644 --- a/lib/subghz/protocols/honeywell.c +++ b/lib/subghz/protocols/honeywell.c @@ -91,7 +91,7 @@ void subghz_protocol_decoder_honeywell_addbit(void* context, bool data) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder - .decode_count_bit; //maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it + .decode_count_bit; //maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it (-nofl) if(instance->base.callback) instance->base.callback(&instance->base, instance->base.context); instance->decoder.decode_data = 0; From 58b2c98b63c542fc8a2877afba91ce87578aab03 Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 24 Sep 2025 15:22:20 +0100 Subject: [PATCH 10/19] subghz: re-enabled failing encoder tests --- .../unit_tests/tests/subghz/subghz_test.c | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index a6141c72c28..c01e0e68272 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -898,11 +898,11 @@ MU_TEST(subghz_encoder_dickert_test) { "Test encoder " SUBGHZ_PROTOCOL_DICKERT_MAHS_NAME " error\r\n"); } -/*MU_TEST(subghz_encoder_legrand_test) { +MU_TEST(subghz_encoder_legrand_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/legrand_2E37F.sub")), "Test encoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); -}*/ +} MU_TEST(subghz_encoder_feron_test) { mu_assert( @@ -910,11 +910,11 @@ MU_TEST(subghz_encoder_feron_test) { "Test encoder " SUBGHZ_PROTOCOL_FERON_NAME " error\r\n"); } -/*MU_TEST(subghz_encoder_gangqi_test) { +MU_TEST(subghz_encoder_gangqi_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/gang_qi.sub")), "Test encoder " SUBGHZ_PROTOCOL_GANGQI_NAME " error\r\n"); -}*/ +} MU_TEST(subghz_encoder_hollarm_test) { mu_assert( @@ -922,11 +922,11 @@ MU_TEST(subghz_encoder_hollarm_test) { "Test encoder " SUBGHZ_PROTOCOL_HOLLARM_NAME " error\r\n"); } -/*MU_TEST(subghz_encoder_reversrb2_test) { +MU_TEST(subghz_encoder_reversrb2_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/revers_rb2.sub")), "Test encoder " SUBGHZ_PROTOCOL_REVERSRB2_NAME " error\r\n"); -}*/ +} MU_TEST(subghz_encoder_roger_test) { mu_assert( @@ -934,7 +934,7 @@ MU_TEST(subghz_encoder_roger_test) { "Test encoder " SUBGHZ_PROTOCOL_ROGER_NAME " error\r\n"); } -/*MU_TEST(subghz_encoder_marantec24_test) { +MU_TEST(subghz_encoder_marantec24_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/marantec24.sub")), "Test encoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); @@ -944,7 +944,7 @@ MU_TEST(subghz_encoder_honeywellsec_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/honeywell_sec.sub")), "Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_NAME " error\r\n"); -}*/ +} MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); @@ -1037,12 +1037,12 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_dickert_test); MU_RUN_TEST(subghz_encoder_feron_test); MU_RUN_TEST(subghz_encoder_roger_test); - //MU_RUN_TEST(subghz_encoder_gangqi_test); - //MU_RUN_TEST(subghz_encoder_marantec24_test); + MU_RUN_TEST(subghz_encoder_gangqi_test); + MU_RUN_TEST(subghz_encoder_marantec24_test); MU_RUN_TEST(subghz_encoder_hollarm_test); - //MU_RUN_TEST(subghz_encoder_reversrb2_test); - //MU_RUN_TEST(subghz_encoder_legrand_test); - //MU_RUN_TEST(subghz_encoder_honeywellsec_test); + MU_RUN_TEST(subghz_encoder_reversrb2_test); + MU_RUN_TEST(subghz_encoder_legrand_test); + MU_RUN_TEST(subghz_encoder_honeywellsec_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); From af7bd1c41d3c1c9d2663a74ceb1e49ea922445dd Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 24 Sep 2025 22:20:41 +0300 Subject: [PATCH 11/19] Fix two? 3 left --- lib/subghz/protocols/gangqi.c | 16 ++++++++-------- lib/subghz/protocols/marantec24.c | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c index aca22cfd781..73e5e471df1 100644 --- a/lib/subghz/protocols/gangqi.c +++ b/lib/subghz/protocols/gangqi.c @@ -106,6 +106,10 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ size_t index = 0; + // Add initial GAP + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long * 2); + // Send key and GAP between parcels for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { if(bit_read(instance->generic.data, i - 1)) { @@ -113,11 +117,9 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_long); if(i == 1) { - //Send gap if bit was last + // Send final gap after last bit instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + - subghz_protocol_gangqi_const.te_delta); + false, (uint32_t)subghz_protocol_gangqi_const.te_short * 4); } else { instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_short); @@ -127,11 +129,9 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_short); if(i == 1) { - //Send gap if bit was last + // Send final gap after last bit instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + - subghz_protocol_gangqi_const.te_delta); + false, (uint32_t)subghz_protocol_gangqi_const.te_short * 4); } else { instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long); diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c index ac602fc965c..cf23818af68 100644 --- a/lib/subghz/protocols/marantec24.c +++ b/lib/subghz/protocols/marantec24.c @@ -96,6 +96,10 @@ static void furi_assert(instance); size_t index = 0; + // Send initial GAP to trigger decoder + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_marantec24_const.te_long * 9); + // Send key and GAP for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { if(bit_read(instance->generic.data, i - 1)) { @@ -105,9 +109,7 @@ static void if(i == 1) { //Send gap if bit was last instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + - subghz_protocol_marantec24_const.te_short); + false, (uint32_t)subghz_protocol_marantec24_const.te_long * 9); } else { instance->encoder.upload[index++] = level_duration_make( false, (uint32_t)subghz_protocol_marantec24_const.te_long * 2); @@ -119,9 +121,7 @@ static void if(i == 1) { //Send gap if bit was last instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + - subghz_protocol_marantec24_const.te_short); + false, (uint32_t)subghz_protocol_marantec24_const.te_long * 9); } else { instance->encoder.upload[index++] = level_duration_make( false, (uint32_t)subghz_protocol_marantec24_const.te_short * 3); From 441462a8c64c8b6c158b7c008be84286c1af1919 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 25 Sep 2025 20:16:41 +0300 Subject: [PATCH 12/19] properly do gangqi and marantec for unit test and real use --- lib/subghz/protocols/gangqi.c | 10 +++++----- lib/subghz/protocols/marantec24.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c index 73e5e471df1..8c353f0e7ea 100644 --- a/lib/subghz/protocols/gangqi.c +++ b/lib/subghz/protocols/gangqi.c @@ -108,7 +108,7 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ // Add initial GAP instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long * 2); + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_short * 4); // Send key and GAP between parcels for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { @@ -118,8 +118,8 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_long); if(i == 1) { // Send final gap after last bit - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_gangqi_const.te_short * 4); + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_delta); } else { instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_short); @@ -130,8 +130,8 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_short); if(i == 1) { // Send final gap after last bit - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_gangqi_const.te_short * 4); + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_delta); } else { instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long); diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c index cf23818af68..e8efbd55561 100644 --- a/lib/subghz/protocols/marantec24.c +++ b/lib/subghz/protocols/marantec24.c @@ -109,7 +109,7 @@ static void if(i == 1) { //Send gap if bit was last instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_marantec24_const.te_long * 9); + false, (uint32_t)subghz_protocol_marantec24_const.te_short); } else { instance->encoder.upload[index++] = level_duration_make( false, (uint32_t)subghz_protocol_marantec24_const.te_long * 2); @@ -121,7 +121,7 @@ static void if(i == 1) { //Send gap if bit was last instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_marantec24_const.te_long * 9); + false, (uint32_t)subghz_protocol_marantec24_const.te_short); } else { instance->encoder.upload[index++] = level_duration_make( false, (uint32_t)subghz_protocol_marantec24_const.te_short * 3); From 3c7602f523923bf3c439cd7f5010c818faf89ca9 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sun, 28 Sep 2025 01:47:35 +0300 Subject: [PATCH 13/19] fix unit tests now --- .../subghz/{gang_qi.sub => gangqi.sub} | 0 .../unit_tests/subghz/honeywell_sec.sub | 7 - .../unit_tests/subghz/honeywell_sec_raw.sub | 8 - .../unit_tests/tests/subghz/subghz_test.c | 17 +- lib/subghz/protocols/gangqi.c | 67 ++-- lib/subghz/protocols/honeywell.c | 371 ------------------ lib/subghz/protocols/honeywell.h | 61 --- lib/subghz/protocols/legrand.c | 63 +-- lib/subghz/protocols/marantec24.c | 60 +-- lib/subghz/protocols/protocol_items.c | 1 - lib/subghz/protocols/protocol_items.h | 1 - lib/subghz/protocols/revers_rb2.c | 39 +- 12 files changed, 129 insertions(+), 566 deletions(-) rename applications/debug/unit_tests/resources/unit_tests/subghz/{gang_qi.sub => gangqi.sub} (100%) delete mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub delete mode 100644 applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub delete mode 100644 lib/subghz/protocols/honeywell.c delete mode 100644 lib/subghz/protocols/honeywell.h diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/gang_qi.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub similarity index 100% rename from applications/debug/unit_tests/resources/unit_tests/subghz/gang_qi.sub rename to applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub deleted file mode 100644 index 900a536acbc..00000000000 --- a/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec.sub +++ /dev/null @@ -1,7 +0,0 @@ -Filetype: Flipper SubGhz Key File -Version: 1 -Frequency: 433920000 -Preset: FuriHalSubGhzPresetOok650Async -Protocol: Honeywell Sec -Bit: 62 -Key: 3F FE 80 AC AB 22 F2 8A diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub deleted file mode 100644 index 6281d9650d5..00000000000 --- a/applications/debug/unit_tests/resources/unit_tests/subghz/honeywell_sec_raw.sub +++ /dev/null @@ -1,8 +0,0 @@ -Filetype: Flipper SubGhz RAW File -Version: 1 -Frequency: 433920000 -Preset: FuriHalSubGhzPresetOok650Async -Protocol: RAW -RAW_Data: 265 -107730 281 -110 181 -110 143 -110 181 -110 143 -108 177 -102 169 -100 165 -98 167 -136 135 -140 139 -106 173 -102 171 -102 313 -240 299 -132 127 -132 139 -140 143 -144 139 -104 169 -102 165 -278 273 -268 267 -272 133 -132 279 -130 139 -282 273 -276 275 -246 305 -250 155 -126 309 -106 135 -254 299 -138 139 -132 119 -272 275 -278 153 -122 149 -122 151 -120 289 -132 133 -280 281 -276 269 -136 131 -134 139 -288 279 -268 265 -107754 501 -72 181 -110 181 -108 145 -110 181 -108 145 -104 173 -100 167 -98 167 -134 135 -140 139 -104 173 -102 171 -102 315 -242 297 -132 127 -128 155 -124 121 -150 151 -122 151 -124 123 -284 275 -278 283 -262 133 -132 317 -106 133 -284 279 -272 265 -270 271 -274 135 -134 315 -108 133 -282 279 -134 125 -130 137 -284 277 -270 133 -130 133 -140 143 -144 289 -110 125 -300 267 -270 271 -134 133 -130 151 -244 311 -252 289 -112890 271 -66 167 -142 143 -106 177 -108 181 -110 145 -108 181 -110 145 -108 181 -110 145 -108 171 -104 165 -100 163 -100 307 -292 253 -146 145 -104 175 -108 145 -146 145 -108 145 -146 145 -254 281 -270 269 -270 133 -132 279 -130 139 -286 287 -248 279 -276 271 -274 135 -130 281 -130 173 -246 273 -124 153 -130 127 -280 275 -276 123 -154 121 -130 155 -122 301 -122 121 -280 275 -276 277 -124 177 -106 165 -240 303 -266 267 -107722 265 -90 181 -122 149 -122 151 -124 157 -124 151 -120 151 -120 153 -126 155 -94 183 -90 181 -92 179 -92 193 -96 303 -244 307 -126 125 -126 155 -122 151 -120 151 -122 151 -128 157 -248 275 -278 285 -264 135 -132 317 -108 133 -284 279 -270 267 -270 271 -272 137 -132 317 -106 135 -282 279 -134 127 -130 135 -284 279 -270 131 -130 133 -140 141 -144 289 -110 127 -298 269 -270 271 -134 133 -130 151 -244 311 -252 291 -112912 255 -144 135 -136 133 -134 135 -136 135 -138 137 -138 137 -138 137 -136 137 -136 135 -138 135 -138 135 -138 137 -136 275 -290 253 -146 145 -138 103 -144 143 -146 145 -144 109 -146 145 -254 279 -272 269 -270 133 -134 281 -142 133 -280 277 -270 267 -272 269 -274 135 -134 281 -142 133 -282 277 -134 129 -132 137 -284 279 -270 131 -130 131 -140 141 -142 289 -142 95 -302 269 -270 269 -134 133 -162 121 -274 277 -252 275 -107764 227 -90 121 -168 101 -200 65 -204 67 -206 67 -208 69 -206 69 -206 69 -204 67 -206 67 -206 67 -204 67 -206 69 -204 209 -344 201 -198 99 -168 105 -174 105 -176 105 -138 -RAW_Data: 103 -170 101 -312 237 -302 267 -304 101 -166 219 -194 103 -324 209 -314 243 -314 241 -274 135 -134 281 -164 103 -288 285 -138 103 -174 109 -290 277 -268 133 -128 131 -176 103 -144 287 -110 161 -272 271 -268 267 -136 131 -132 151 -244 311 -248 271 -107752 281 -110 181 -108 143 -108 171 -102 167 -100 165 -100 171 -136 139 -104 173 -104 171 -102 169 -104 167 -102 171 -102 311 -254 291 -146 143 -108 139 -146 143 -110 145 -146 143 -110 181 -254 279 -268 265 -270 133 -132 279 -130 171 -248 273 -276 277 -246 275 -280 157 -124 277 -132 175 -246 275 -122 153 -128 125 -284 273 -278 123 -152 125 -134 161 -122 271 -138 141 -248 303 -248 307 -122 121 -152 119 -292 271 -276 273 -112892 531 -74 181 -108 145 -110 173 -106 167 -100 165 -100 167 -136 139 -138 139 -104 171 -104 169 -102 169 -102 171 -102 309 -256 289 -146 145 -106 139 -144 145 -110 145 -144 145 -110 181 -254 277 -270 265 -270 133 -132 279 -130 137 -282 275 -276 277 -246 275 -280 157 -124 279 -130 139 -282 273 -124 153 -128 125 -282 275 -278 123 -152 123 -136 161 -120 273 -136 143 -248 303 -248 307 -122 121 -152 119 -292 269 -274 275 -107766 243 -72 133 -122 149 -122 151 -120 155 -126 157 -124 149 -122 151 -120 153 -126 157 -94 183 -90 181 -90 181 -90 193 -100 325 -254 291 -108 145 -136 135 -142 141 -108 143 -146 143 -110 145 -290 285 -244 277 -274 135 -132 279 -130 137 -286 287 -246 279 -278 273 -274 133 -132 281 -130 173 -246 275 -124 153 -126 127 -284 273 -278 123 -152 123 -134 161 -122 271 -138 143 -248 301 -250 307 -122 121 -150 121 -290 273 -274 273 -112946 231 -66 171 -146 109 -146 143 -140 137 -136 135 -134 135 -136 135 -136 137 -138 137 -138 135 -138 135 -138 137 -136 137 -136 279 -274 267 -132 131 -132 141 -142 141 -142 139 -138 135 -134 133 -278 273 -268 267 -270 135 -132 281 -142 135 -280 277 -270 269 -270 271 -274 135 -132 281 -142 135 -280 279 -134 127 -132 137 -286 277 -270 131 -130 133 -174 105 -144 287 -140 97 -302 271 -270 269 -134 133 -160 123 -274 279 -248 273 -198912 65 -1282 289 -130 1013 -98 97 -132 1027 -524 127 -1802 163 -132 63 -2054 63 -2504 65 -6158 131 -134 65 -7374 67 -562 99 -8756 99 -6182 133 -436 67 -304 67 -1030 97 -9514 65 -13272 129 -2676 427 -100 361 -296 825 -9058 131 -5872 99 -18954 65 -5058 65 -8702 101 -3996 99 -11900 67 -8368 99 -1700 293 -232 1029 -68 1161 -134 133 -17572 265 -336 97 -3744 -RAW_Data: 63 -6934 99 -1870 67 -264 65 -360 97 -1420 65 -540 65 -330 99 -2646 131 -350 65 -1192 67 -5532 99 -1526 165 -504 199 -1690 67 -134 65 -562 129 -330 65 -6116 65 -8386 65 -1538 65 -658 65 -920 63 -488 129 -524 67 -2038 839 -136 99 -2028 65 -3056 65 -5392 199 -1234 101 -432 99 -2898 67 -7150 167 -2724 63 -134 99 -426 101 -3226 163 -958 101 -468 67 -1468 131 -2006 129 -964 97 -302 99 -3972 99 -4584 197 -2592 95 -1184 97 -390 65 -1514 65 -2600 65 -5218 97 -2748 529 -130 227 -520 163 -66 557 -166 63 -824 165 -3824 133 -14452 269 -7042 67 -168 101 -704 99 -6194 63 -9950 97 -1614 99 -12232 133 -3736 167 -266 129 -1532 65 -1378 129 -8180 101 -18264 465 -100 503 -100 591 -130 127 -98 715 -168 163 -190 127 -7396 63 -652 63 -8308 65 -1048 129 -5408 65 -9848 67 -18404 65 -2542 65 -6094 65 -934 65 -7330 95 -9092 97 -428 97 -1062 67 -3802 881 -66 419 -268 729 -66 133 -268 503 -68 99 -6518 131 -330 97 -194 161 -196 65 -6016 99 -5998 133 -3128 65 -1300 99 -834 65 -1038 97 -230 129 -170 67 -102 131 -562 65 -466 739 -66 737 -100 1169 -266 295 -230 499 -1390 165 -290 65 -452 65 -6048 63 -17618 99 -9778 131 -1240 99 -10614 67 -1052 63 -19206 99 -12288 131 -132 399 -234 133 -132 199 -170 531 -98 393 -64 97 -98 165 -2680 diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index c01e0e68272..dfe749b2a82 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -728,13 +728,6 @@ MU_TEST(subghz_decoder_hay21_test) { "Test decoder " SUBGHZ_PROTOCOL_HAY21_NAME " error\r\n"); } -MU_TEST(subghz_decoder_honeywellsec_test) { - mu_assert( - subghz_decoder_test( - EXT_PATH("unit_tests/subghz/honeywell_sec_raw.sub"), SUBGHZ_PROTOCOL_HONEYWELL_NAME), - "Test decoder " SUBGHZ_PROTOCOL_HONEYWELL_NAME " error\r\n"); -} - //test encoders MU_TEST(subghz_encoder_princeton_test) { mu_assert( @@ -912,7 +905,7 @@ MU_TEST(subghz_encoder_feron_test) { MU_TEST(subghz_encoder_gangqi_test) { mu_assert( - subghz_encoder_test(EXT_PATH("unit_tests/subghz/gang_qi.sub")), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/gangqi.sub")), "Test encoder " SUBGHZ_PROTOCOL_GANGQI_NAME " error\r\n"); } @@ -940,12 +933,6 @@ MU_TEST(subghz_encoder_marantec24_test) { "Test encoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); } -MU_TEST(subghz_encoder_honeywellsec_test) { - mu_assert( - subghz_encoder_test(EXT_PATH("unit_tests/subghz/honeywell_sec.sub")), - "Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_NAME " error\r\n"); -} - MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } @@ -1006,7 +993,6 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_feron_test); MU_RUN_TEST(subghz_decoder_legrand_test); MU_RUN_TEST(subghz_decoder_marantec24_test); - MU_RUN_TEST(subghz_decoder_honeywellsec_test); MU_RUN_TEST(subghz_encoder_princeton_test); MU_RUN_TEST(subghz_encoder_came_test); @@ -1042,7 +1028,6 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_hollarm_test); MU_RUN_TEST(subghz_encoder_reversrb2_test); MU_RUN_TEST(subghz_encoder_legrand_test); - MU_RUN_TEST(subghz_encoder_honeywellsec_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c index 8c353f0e7ea..ea26fd92798 100644 --- a/lib/subghz/protocols/gangqi.c +++ b/lib/subghz/protocols/gangqi.c @@ -74,7 +74,7 @@ void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; + instance->encoder.size_upload = 512; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; return instance; @@ -106,35 +106,40 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ size_t index = 0; - // Add initial GAP instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_short * 4); - - // Send key and GAP between parcels - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - // Send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_long); - if(i == 1) { - // Send final gap after last bit - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_delta); - } else { - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_short); - } - } else { - // Send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_short); - if(i == 1) { - // Send final gap after last bit + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long * 2); + + for(size_t r = 0; r < 5; r++) { + // Send key and GAP between parcels + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // Send bit 1 instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_delta); + level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + + subghz_protocol_gangqi_const.te_delta); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_gangqi_const.te_short); + } } else { + // Send bit 0 instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long); + level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + + subghz_protocol_gangqi_const.te_delta); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long); + } } } } @@ -249,7 +254,7 @@ void subghz_protocol_decoder_gangqi_feed(void* context, bool level, volatile uin switch(instance->decoder.parser_step) { case GangQiDecoderStepReset: if((!level) && (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_long * 2) < - subghz_protocol_gangqi_const.te_delta * 3)) { + subghz_protocol_gangqi_const.te_delta * 5)) { //Found GAP instance->decoder.decode_data = 0; instance->decoder.decode_count_bit = 0; @@ -283,19 +288,15 @@ void subghz_protocol_decoder_gangqi_feed(void* context, bool level, volatile uin instance->decoder.parser_step = GangQiDecoderStepSaveDuration; } else if( // End of the key - DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short * 4) < - subghz_protocol_gangqi_const.te_delta) { + DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_long * 2) < + subghz_protocol_gangqi_const.te_delta * 5) { //Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes) if((DURATION_DIFF( instance->decoder.te_last, subghz_protocol_gangqi_const.te_short) < - subghz_protocol_gangqi_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short * 4) < subghz_protocol_gangqi_const.te_delta)) { subghz_protocol_blocks_add_bit(&instance->decoder, 0); } if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gangqi_const.te_long) < - subghz_protocol_gangqi_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short * 4) < subghz_protocol_gangqi_const.te_delta)) { subghz_protocol_blocks_add_bit(&instance->decoder, 1); } diff --git a/lib/subghz/protocols/honeywell.c b/lib/subghz/protocols/honeywell.c deleted file mode 100644 index cec827ea1f6..00000000000 --- a/lib/subghz/protocols/honeywell.c +++ /dev/null @@ -1,371 +0,0 @@ -#include "honeywell.h" -#include - -//Created by HTotoo 2023-10-30 -//Got a lot of help from LiQuiDz. -//Protocol decoding help from: https://github.com/merbanan/rtl_433/blob/master/src/devices/honeywell.c - -/* -64 bit packets, repeated multiple times per open/close event. - -Protocol whitepaper: "DEFCON 22: Home Insecurity" by Logan Lamb. - -Data layout: - - PP PP C IIIII EE SS SS - -- P: 16bit Preamble and sync bit (always ff fe) -- C: 4bit Channel -- I: 20bit Device serial number / or counter value -- E: 8bit Event, where 0x80 = Open/Close, 0x04 = Heartbeat / or id -- S: 16bit CRC -*/ - -#define TAG "SubGhzProtocolHoneywell" - -uint16_t subghz_protocol_honeywell_crc16( - uint8_t const message[], - unsigned nBytes, - uint16_t polynomial, - uint16_t init) { - uint16_t remainder = init; - unsigned byte, bit; - - for(byte = 0; byte < nBytes; ++byte) { - remainder ^= message[byte] << 8; - for(bit = 0; bit < 8; ++bit) { - if(remainder & 0x8000) { - remainder = (remainder << 1) ^ polynomial; - } else { - remainder = (remainder << 1); - } - } - } - return remainder; -} - -void subghz_protocol_decoder_honeywell_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell* instance = context; - free(instance); -} - -void subghz_protocol_decoder_honeywell_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell* instance = context; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; -} - -void subghz_protocol_decoder_honeywell_addbit(void* context, bool data) { - SubGhzProtocolDecoderHoneywell* instance = context; - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; - instance->decoder.decode_count_bit++; - - if(instance->decoder.decode_count_bit < 62) return; - - uint16_t preamble = (instance->decoder.decode_data >> 48) & 0xFFFF; - //can be multiple, since flipper can't read it well.. - if(preamble == 0b0011111111111110 || preamble == 0b0111111111111110 || - preamble == 0b1111111111111110) { - uint8_t datatocrc[4]; - datatocrc[0] = (instance->decoder.decode_data >> 40) & 0xFFFF; - datatocrc[1] = (instance->decoder.decode_data >> 32) & 0xFFFF; - datatocrc[2] = (instance->decoder.decode_data >> 24) & 0xFFFF; - datatocrc[3] = (instance->decoder.decode_data >> 16) & 0xFFFF; - uint8_t channel = (instance->decoder.decode_data >> 44) & 0xF; - uint16_t crc_calc = 0; - if(channel == 0x2 || channel == 0x4 || channel == 0xA) { - // 2GIG brand - crc_calc = subghz_protocol_honeywell_crc16(datatocrc, 4, 0x8050, 0); - } else if(channel == 0x8) { - crc_calc = subghz_protocol_honeywell_crc16(datatocrc, 4, 0x8005, 0); - } else { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - return; - } - uint16_t crc = instance->decoder.decode_data & 0xFFFF; - if(crc == crc_calc) { - //the data is good. process it. - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = - instance->decoder - .decode_count_bit; //maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it (-nofl) - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - return; - } - } else if(instance->decoder.decode_count_bit >= 64) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - return; - } -} - -void subghz_protocol_decoder_honeywell_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell* instance = context; - - ManchesterEvent event = ManchesterEventReset; - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_short) < - subghz_protocol_honeywell_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_long) < - subghz_protocol_honeywell_const.te_delta * 2) { - event = ManchesterEventLongLow; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_short) < - subghz_protocol_honeywell_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_honeywell_const.te_long) < - subghz_protocol_honeywell_const.te_delta * 2) { - event = ManchesterEventLongHigh; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - if(data_ok) { - subghz_protocol_decoder_honeywell_addbit(instance, data); - } - } else { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } -} - -uint8_t subghz_protocol_decoder_honeywell_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus subghz_protocol_decoder_honeywell_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - subghz_protocol_decoder_honeywell_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell* instance = context; - return subghz_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - subghz_protocol_honeywell_const.min_count_bit_for_found); -} - -void subghz_protocol_decoder_honeywell_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell* instance = context; - - // Parse here and not in decode to avoid visual glitches when loading from file - instance->generic.serial = (instance->generic.data >> 24) & 0xFFFFF; - instance->generic.btn = (instance->generic.data >> 16) & - 0xFF; //not exactly button, but can contain btn data too. - - uint8_t channel = (instance->generic.data >> 44) & 0xF; - uint8_t contact = (instance->generic.btn & 0x80) >> 7; - uint8_t tamper = (instance->generic.btn & 0x40) >> 6; - uint8_t reed = (instance->generic.btn & 0x20) >> 5; - uint8_t alarm = (instance->generic.btn & 0x10) >> 4; - uint8_t battery_low = (instance->generic.btn & 0x08) >> 3; - uint8_t heartbeat = (instance->generic.btn & 0x04) >> 2; - - furi_string_cat_printf( - output, - "%s\r\n%dbit " - "Sn:%07lu\r\nCh:%u Bat:%d Hb: %d\r\n" - "L1: %u, L2: %u, L3: %u, L4: %u\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - instance->generic.serial, - channel, - battery_low, - heartbeat, - contact, - reed, - alarm, - tamper); -} - -void* subghz_protocol_decoder_honeywell_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderHoneywell* instance = malloc(sizeof(SubGhzProtocolDecoderHoneywell)); - instance->base.protocol = &subghz_protocol_honeywell; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void* subghz_protocol_encoder_honeywell_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderHoneywell* instance = malloc(sizeof(SubGhzProtocolEncoderHoneywell)); - - instance->base.protocol = &subghz_protocol_honeywell; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 3; - instance->encoder.size_upload = 64 * 2 + 10; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_honeywell_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderHoneywell* instance = context; - free(instance->encoder.upload); - free(instance); -} -static LevelDuration - subghz_protocol_encoder_honeywell_add_duration_to_upload(ManchesterEncoderResult result) { - LevelDuration data = {.duration = 0, .level = 0}; - switch(result) { - case ManchesterEncoderResultShortLow: - data.duration = subghz_protocol_honeywell_const.te_short; - data.level = false; - break; - case ManchesterEncoderResultLongLow: - data.duration = subghz_protocol_honeywell_const.te_long; - data.level = false; - break; - case ManchesterEncoderResultLongHigh: - data.duration = subghz_protocol_honeywell_const.te_long; - data.level = true; - break; - case ManchesterEncoderResultShortHigh: - data.duration = subghz_protocol_honeywell_const.te_short; - data.level = true; - break; - - default: - furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); - break; - } - return level_duration_make(data.level, data.duration); -} - -static void - subghz_protocol_encoder_honeywell_get_upload(SubGhzProtocolEncoderHoneywell* instance) { - furi_assert(instance); - size_t index = 0; - - ManchesterEncoderState enc_state; - manchester_encoder_reset(&enc_state); - ManchesterEncoderResult result; - - for(uint8_t i = 63; i > 0; i--) { - if(!manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_honeywell_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result); - } - instance->encoder.upload[index++] = - subghz_protocol_encoder_honeywell_add_duration_to_upload(result); - } - instance->encoder.upload[index] = subghz_protocol_encoder_honeywell_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; - } - instance->encoder.size_upload = index; -} - -SubGhzProtocolStatus - subghz_protocol_encoder_honeywell_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderHoneywell* instance = context; - SubGhzProtocolStatus res = SubGhzProtocolStatusError; - do { - if(SubGhzProtocolStatusOk != - subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_encoder_honeywell_get_upload(instance); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - instance->encoder.is_running = true; - - res = SubGhzProtocolStatusOk; - } while(false); - - return res; -} - -void subghz_protocol_encoder_honeywell_stop(void* context) { - SubGhzProtocolEncoderHoneywell* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_honeywell_yield(void* context) { - SubGhzProtocolEncoderHoneywell* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - return ret; -} - -const SubGhzProtocolDecoder subghz_protocol_honeywell_decoder = { - .alloc = subghz_protocol_decoder_honeywell_alloc, - .free = subghz_protocol_decoder_honeywell_free, - .feed = subghz_protocol_decoder_honeywell_feed, - .reset = subghz_protocol_decoder_honeywell_reset, - .get_hash_data = subghz_protocol_decoder_honeywell_get_hash_data, - .serialize = subghz_protocol_decoder_honeywell_serialize, - .deserialize = subghz_protocol_decoder_honeywell_deserialize, - .get_string = subghz_protocol_decoder_honeywell_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_honeywell_encoder = { - .alloc = subghz_protocol_encoder_honeywell_alloc, - .free = subghz_protocol_encoder_honeywell_free, - .deserialize = subghz_protocol_encoder_honeywell_deserialize, - .stop = subghz_protocol_encoder_honeywell_stop, - .yield = subghz_protocol_encoder_honeywell_yield, -}; - -const SubGhzProtocol subghz_protocol_honeywell = { - .name = SUBGHZ_PROTOCOL_HONEYWELL_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | - SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - .encoder = &subghz_protocol_honeywell_encoder, - .decoder = &subghz_protocol_honeywell_decoder, - -}; diff --git a/lib/subghz/protocols/honeywell.h b/lib/subghz/protocols/honeywell.h deleted file mode 100644 index 8aa35ce6cc4..00000000000 --- a/lib/subghz/protocols/honeywell.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "base.h" -#include "../blocks/generic.h" -#include -#include -#include - -#define SUBGHZ_PROTOCOL_HONEYWELL_NAME "Honeywell Sec" - -typedef struct SubGhzProtocolDecoderHoneywell SubGhzProtocolDecoderHoneywell; -typedef struct SubGhzProtocolEncoderHoneywell SubGhzProtocolEncoderHoneywell; - -extern const SubGhzProtocolDecoder subghz_protocol_honeywell_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_honeywell_encoder; -extern const SubGhzProtocol subghz_protocol_honeywell; - -void* subghz_protocol_decoder_honeywell_alloc(SubGhzEnvironment* environment); - -void subghz_protocol_decoder_honeywell_free(void* context); - -void subghz_protocol_decoder_honeywell_reset(void* context); - -void subghz_protocol_decoder_honeywell_feed(void* context, bool level, uint32_t duration); - -uint8_t subghz_protocol_decoder_honeywell_get_hash_data(void* context); - -SubGhzProtocolStatus subghz_protocol_decoder_honeywell_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -SubGhzProtocolStatus - subghz_protocol_decoder_honeywell_deserialize(void* context, FlipperFormat* flipper_format); - -void subghz_protocol_decoder_honeywell_get_string(void* context, FuriString* output); - -static const SubGhzBlockConst subghz_protocol_honeywell_const = { - .te_long = 280, - .te_short = 143, - .te_delta = 51, - .min_count_bit_for_found = 62, -}; - -struct SubGhzProtocolDecoderHoneywell { - SubGhzProtocolDecoderBase base; - SubGhzBlockGeneric generic; - SubGhzBlockDecoder decoder; - ManchesterState manchester_saved_state; -}; - -struct SubGhzProtocolEncoderHoneywell { - SubGhzProtocolEncoderBase base; - SubGhzBlockGeneric generic; - SubGhzProtocolBlockEncoder encoder; -}; diff --git a/lib/subghz/protocols/legrand.c b/lib/subghz/protocols/legrand.c index 9459fa2e71a..00f53fcafad 100644 --- a/lib/subghz/protocols/legrand.c +++ b/lib/subghz/protocols/legrand.c @@ -81,7 +81,7 @@ void* subghz_protocol_encoder_legrand_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->encoder.repeat = 10; - instance->encoder.size_upload = subghz_protocol_legrand_const.min_count_bit_for_found * 2 + 1; + instance->encoder.size_upload = subghz_protocol_legrand_const.min_count_bit_for_found * 5 + 2; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; return instance; @@ -102,31 +102,50 @@ void subghz_protocol_encoder_legrand_free(void* context) { static bool subghz_protocol_encoder_legrand_get_upload(SubGhzProtocolEncoderLegrand* instance) { furi_assert(instance); - size_t size_upload = (instance->generic.data_count_bit * 2) + 1; - if(size_upload != instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Invalid data bit count"); - return false; - } + //size_t size_upload = (instance->generic.data_count_bit * 2) + 1; + //if(size_upload != instance->encoder.size_upload) { + // FURI_LOG_E(TAG, "Invalid data bit count"); + // return false; + //} size_t index = 0; - // Send sync - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te * 16); - - // Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - // send bit 1 - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)instance->te * 3); - } else { - // send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)instance->te * 3); - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); + for(size_t r = 0; r < 5; r++) { + // Send sync + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)instance->te * 16); // 5728 + // Send key data + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // send bit 1 + if(i == instance->generic.data_count_bit) { + //Send first bit + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te * 3); + } else { + // send bit 1 regular + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)instance->te); + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te * 3); + } + } else { + // send bit 0 + if(i == instance->generic.data_count_bit) { + //Send first bit + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te); + } else { + // send bit 0 regular + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)instance->te * 3); + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te); + } + } } } + instance->encoder.size_upload = index; return true; } @@ -219,7 +238,7 @@ void subghz_protocol_decoder_legrand_feed(void* context, bool level, uint32_t du switch(instance->decoder.parser_step) { case LegrandDecoderStepReset: if(!level && DURATION_DIFF(duration, subghz_protocol_legrand_const.te_short * 16) < - subghz_protocol_legrand_const.te_delta * 8) { + subghz_protocol_legrand_const.te_delta * 8) { // 6000 +- 1200 instance->decoder.parser_step = LegrandDecoderStepFirstBit; instance->decoder.decode_data = 0; instance->decoder.decode_count_bit = 0; diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c index e8efbd55561..a8451d3867b 100644 --- a/lib/subghz/protocols/marantec24.c +++ b/lib/subghz/protocols/marantec24.c @@ -95,36 +95,40 @@ static void subghz_protocol_encoder_marantec24_get_upload(SubGhzProtocolEncoderMarantec24* instance) { furi_assert(instance); size_t index = 0; - // Send initial GAP to trigger decoder instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)subghz_protocol_marantec24_const.te_long * 9); - - // Send key and GAP - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - // Send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_marantec24_const.te_short); - if(i == 1) { - //Send gap if bit was last - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_marantec24_const.te_short); - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_marantec24_const.te_long * 2); - } - } else { - // Send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_marantec24_const.te_long); - if(i == 1) { - //Send gap if bit was last - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_marantec24_const.te_short); + for(size_t r = 0; r < 4; r++) { + // Send key and GAP + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(bit_read(instance->generic.data, i - 1)) { + // Send bit 1 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_marantec24_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + + subghz_protocol_marantec24_const.te_short); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_marantec24_const.te_long * 2); + } } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_marantec24_const.te_short * 3); + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_marantec24_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + + subghz_protocol_marantec24_const.te_short); // 15200 + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_marantec24_const.te_short * 3); + } } } } @@ -231,7 +235,7 @@ void subghz_protocol_decoder_marantec24_feed(void* context, bool level, volatile switch(instance->decoder.parser_step) { case Marantec24DecoderStepReset: if((!level) && (DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 9) < - subghz_protocol_marantec24_const.te_delta * 4)) { + subghz_protocol_marantec24_const.te_delta * 6)) { //Found GAP instance->decoder.decode_data = 0; instance->decoder.decode_count_bit = 0; @@ -267,7 +271,7 @@ void subghz_protocol_decoder_marantec24_feed(void* context, bool level, volatile } else if( // End of the key DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 9) < - subghz_protocol_marantec24_const.te_delta * 4) { + subghz_protocol_marantec24_const.te_delta * 6) { //Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes) if((DURATION_DIFF( instance->decoder.te_last, subghz_protocol_marantec24_const.te_long) < diff --git a/lib/subghz/protocols/protocol_items.c b/lib/subghz/protocols/protocol_items.c index 465585d776a..91ceaec3202 100644 --- a/lib/subghz/protocols/protocol_items.c +++ b/lib/subghz/protocols/protocol_items.c @@ -44,7 +44,6 @@ const SubGhzProtocol* const subghz_protocol_registry_items[] = { &subghz_protocol_kinggates_stylo_4k, &subghz_protocol_bin_raw, &subghz_protocol_mastercode, - &subghz_protocol_honeywell, &subghz_protocol_legrand, &subghz_protocol_dickert_mahs, &subghz_protocol_gangqi, diff --git a/lib/subghz/protocols/protocol_items.h b/lib/subghz/protocols/protocol_items.h index 4f63b030eeb..1cde46ef500 100644 --- a/lib/subghz/protocols/protocol_items.h +++ b/lib/subghz/protocols/protocol_items.h @@ -45,7 +45,6 @@ #include "kinggates_stylo_4k.h" #include "bin_raw.h" #include "mastercode.h" -#include "honeywell.h" #include "legrand.h" #include "dickert_mahs.h" #include "gangqi.h" diff --git a/lib/subghz/protocols/revers_rb2.c b/lib/subghz/protocols/revers_rb2.c index 510e2698a98..8909e639331 100644 --- a/lib/subghz/protocols/revers_rb2.c +++ b/lib/subghz/protocols/revers_rb2.c @@ -78,7 +78,7 @@ void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; + instance->encoder.size_upload = 564; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; return instance; @@ -128,27 +128,30 @@ static void furi_assert(instance); size_t index = 0; - ManchesterEncoderState enc_state; - manchester_encoder_reset(&enc_state); - ManchesterEncoderResult result; - - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(!manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result)) { + for(size_t r = 0; r < 6; r++) { + ManchesterEncoderState enc_state; + manchester_encoder_reset(&enc_state); + ManchesterEncoderResult result; + + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(!manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result)) { + instance->encoder.upload[index++] = + subghz_protocol_encoder_revers_rb2_add_duration_to_upload(result); + manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result); + } instance->encoder.upload[index++] = subghz_protocol_encoder_revers_rb2_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result); } - instance->encoder.upload[index++] = - subghz_protocol_encoder_revers_rb2_add_duration_to_upload(result); - } - instance->encoder.upload[index] = subghz_protocol_encoder_revers_rb2_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; + instance->encoder.upload[index] = + subghz_protocol_encoder_revers_rb2_add_duration_to_upload( + manchester_encoder_finish(&enc_state)); + if(level_duration_get_level(instance->encoder.upload[index])) { + index++; + } + instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)320); } - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)320); instance->encoder.size_upload = index; } From 501605d4e202707e63551491243ba55053d7989d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:52:08 +0300 Subject: [PATCH 14/19] fix possible memory leak --- lib/subghz/protocols/gangqi.c | 2 +- lib/subghz/protocols/legrand.c | 3 ++- lib/subghz/protocols/marantec24.c | 2 +- lib/subghz/protocols/revers_rb2.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c index ea26fd92798..c96d0e48bdc 100644 --- a/lib/subghz/protocols/gangqi.c +++ b/lib/subghz/protocols/gangqi.c @@ -74,7 +74,7 @@ void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->encoder.repeat = 10; - instance->encoder.size_upload = 512; + instance->encoder.size_upload = 1024; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; return instance; diff --git a/lib/subghz/protocols/legrand.c b/lib/subghz/protocols/legrand.c index 00f53fcafad..0df0d255ced 100644 --- a/lib/subghz/protocols/legrand.c +++ b/lib/subghz/protocols/legrand.c @@ -81,7 +81,8 @@ void* subghz_protocol_encoder_legrand_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->encoder.repeat = 10; - instance->encoder.size_upload = subghz_protocol_legrand_const.min_count_bit_for_found * 5 + 2; + instance->encoder.size_upload = + (subghz_protocol_legrand_const.min_count_bit_for_found * 6) * 2 + 2; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; return instance; diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c index a8451d3867b..4365464fbe6 100644 --- a/lib/subghz/protocols/marantec24.c +++ b/lib/subghz/protocols/marantec24.c @@ -74,7 +74,7 @@ void* subghz_protocol_encoder_marantec24_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; + instance->encoder.size_upload = 512; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; return instance; diff --git a/lib/subghz/protocols/revers_rb2.c b/lib/subghz/protocols/revers_rb2.c index 8909e639331..6ea8ebb7535 100644 --- a/lib/subghz/protocols/revers_rb2.c +++ b/lib/subghz/protocols/revers_rb2.c @@ -78,7 +78,7 @@ void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->encoder.repeat = 10; - instance->encoder.size_upload = 564; + instance->encoder.size_upload = 1768; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; return instance; From 5f7689ccf8e33b8dc50d1bb4a14fe4158ab04216 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 30 Sep 2025 19:02:52 +0300 Subject: [PATCH 15/19] reset decoder step too --- lib/subghz/protocols/marantec.c | 1 + lib/subghz/protocols/revers_rb2.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index edb17663596..8ca1f8b38b0 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -265,6 +265,7 @@ void subghz_protocol_decoder_marantec_free(void* context) { void subghz_protocol_decoder_marantec_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderMarantec* instance = context; + instance->decoder.parser_step = MarantecDecoderStepReset; manchester_advance( instance->manchester_saved_state, ManchesterEventReset, diff --git a/lib/subghz/protocols/revers_rb2.c b/lib/subghz/protocols/revers_rb2.c index 6ea8ebb7535..4696b2d29a9 100644 --- a/lib/subghz/protocols/revers_rb2.c +++ b/lib/subghz/protocols/revers_rb2.c @@ -230,6 +230,8 @@ void subghz_protocol_decoder_revers_rb2_free(void* context) { void subghz_protocol_decoder_revers_rb2_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderRevers_RB2* instance = context; + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + instance->header_count = 0; manchester_advance( instance->manchester_saved_state, ManchesterEventReset, From ef20fa5d09c8d382d9dddff4c629613d999bdb98 Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 30 Sep 2025 18:10:26 +0100 Subject: [PATCH 16/19] subghz: extra encoder safety; report random signal test results on failure --- applications/debug/unit_tests/tests/subghz/subghz_test.c | 2 +- lib/subghz/protocols/feron.c | 2 ++ lib/subghz/protocols/gangqi.c | 2 ++ lib/subghz/protocols/hollarm.c | 2 ++ lib/subghz/protocols/marantec.c | 2 ++ lib/subghz/protocols/revers_rb2.c | 2 ++ lib/subghz/protocols/roger.c | 2 ++ 7 files changed, 13 insertions(+), 1 deletion(-) diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index dfe749b2a82..7d1c99364fa 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -17,7 +17,7 @@ #define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s") #define ALUTECH_AT_4N_DIR_NAME EXT_PATH("subghz/assets/alutech_at_4n") #define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub") -#define TEST_RANDOM_COUNT_PARSE 331 +#define TEST_RANDOM_COUNT_PARSE 328 #define TEST_TIMEOUT 10000 static SubGhzEnvironment* environment_handler; diff --git a/lib/subghz/protocols/feron.c b/lib/subghz/protocols/feron.c index 1096f07a77a..855856f51b6 100644 --- a/lib/subghz/protocols/feron.c +++ b/lib/subghz/protocols/feron.c @@ -165,6 +165,7 @@ SubGhzProtocolStatus subghz_protocol_feron_check_remote_controller(&instance->generic); subghz_protocol_encoder_feron_get_upload(instance); + instance->encoder.front = 0; instance->encoder.is_running = true; } while(false); @@ -174,6 +175,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_feron_stop(void* context) { SubGhzProtocolEncoderFeron* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; } LevelDuration subghz_protocol_encoder_feron_yield(void* context) { diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c index c96d0e48bdc..c8a2413370c 100644 --- a/lib/subghz/protocols/gangqi.c +++ b/lib/subghz/protocols/gangqi.c @@ -184,6 +184,7 @@ SubGhzProtocolStatus subghz_protocol_gangqi_remote_controller(&instance->generic); subghz_protocol_encoder_gangqi_get_upload(instance); + instance->encoder.front = 0; if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); @@ -207,6 +208,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_gangqi_stop(void* context) { SubGhzProtocolEncoderGangQi* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; } LevelDuration subghz_protocol_encoder_gangqi_yield(void* context) { diff --git a/lib/subghz/protocols/hollarm.c b/lib/subghz/protocols/hollarm.c index cbc1bd5d922..70ba6c58659 100644 --- a/lib/subghz/protocols/hollarm.c +++ b/lib/subghz/protocols/hollarm.c @@ -181,6 +181,7 @@ SubGhzProtocolStatus subghz_protocol_hollarm_remote_controller(&instance->generic); subghz_protocol_encoder_hollarm_get_upload(instance); + instance->encoder.front = 0; if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); @@ -204,6 +205,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_hollarm_stop(void* context) { SubGhzProtocolEncoderHollarm* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; } LevelDuration subghz_protocol_encoder_hollarm_yield(void* context) { diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index 8ca1f8b38b0..658aac61052 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -219,6 +219,7 @@ SubGhzProtocolStatus subghz_protocol_marantec_remote_controller(&instance->generic); subghz_protocol_encoder_marantec_get_upload(instance); + instance->encoder.front = 0; instance->encoder.is_running = true; } while(false); @@ -228,6 +229,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_marantec_stop(void* context) { SubGhzProtocolEncoderMarantec* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; } LevelDuration subghz_protocol_encoder_marantec_yield(void* context) { diff --git a/lib/subghz/protocols/revers_rb2.c b/lib/subghz/protocols/revers_rb2.c index 4696b2d29a9..156a506be0f 100644 --- a/lib/subghz/protocols/revers_rb2.c +++ b/lib/subghz/protocols/revers_rb2.c @@ -184,6 +184,7 @@ SubGhzProtocolStatus subghz_protocol_revers_rb2_remote_controller(&instance->generic); subghz_protocol_encoder_revers_rb2_get_upload(instance); + instance->encoder.front = 0; instance->encoder.is_running = true; } while(false); @@ -193,6 +194,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_revers_rb2_stop(void* context) { SubGhzProtocolEncoderRevers_RB2* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; } LevelDuration subghz_protocol_encoder_revers_rb2_yield(void* context) { diff --git a/lib/subghz/protocols/roger.c b/lib/subghz/protocols/roger.c index 8d98d98937b..f93b3366efd 100644 --- a/lib/subghz/protocols/roger.c +++ b/lib/subghz/protocols/roger.c @@ -170,6 +170,7 @@ SubGhzProtocolStatus subghz_protocol_roger_check_remote_controller(&instance->generic); subghz_protocol_encoder_roger_get_upload(instance); + instance->encoder.front = 0; instance->encoder.is_running = true; } while(false); @@ -180,6 +181,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_roger_stop(void* context) { SubGhzProtocolEncoderRoger* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; } LevelDuration subghz_protocol_encoder_roger_yield(void* context) { From e0ab90cd1a0689531e7b0daa7626eaf55b884d12 Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 30 Sep 2025 18:11:54 +0100 Subject: [PATCH 17/19] unit_tests: subghz: renamed test file for consistency --- .../unit_tests/subghz/{legrand_2E37F.sub => legrand.sub} | 0 .../subghz/{legrand_2E37F_raw.sub => legrand_raw.sub} | 0 applications/debug/unit_tests/tests/subghz/subghz_test.c | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename applications/debug/unit_tests/resources/unit_tests/subghz/{legrand_2E37F.sub => legrand.sub} (100%) rename applications/debug/unit_tests/resources/unit_tests/subghz/{legrand_2E37F_raw.sub => legrand_raw.sub} (100%) diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand.sub similarity index 100% rename from applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F.sub rename to applications/debug/unit_tests/resources/unit_tests/subghz/legrand.sub diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_raw.sub similarity index 100% rename from applications/debug/unit_tests/resources/unit_tests/subghz/legrand_2E37F_raw.sub rename to applications/debug/unit_tests/resources/unit_tests/subghz/legrand_raw.sub diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index 7d1c99364fa..ae83ed562ec 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -675,7 +675,7 @@ MU_TEST(subghz_decoder_dickert_test) { MU_TEST(subghz_decoder_legrand_test) { mu_assert( subghz_decoder_test( - EXT_PATH("unit_tests/subghz/legrand_2E37F_raw.sub"), SUBGHZ_PROTOCOL_LEGRAND_NAME), + EXT_PATH("unit_tests/subghz/legrand_raw.sub"), SUBGHZ_PROTOCOL_LEGRAND_NAME), "Test decoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); } @@ -893,7 +893,7 @@ MU_TEST(subghz_encoder_dickert_test) { MU_TEST(subghz_encoder_legrand_test) { mu_assert( - subghz_encoder_test(EXT_PATH("unit_tests/subghz/legrand_2E37F.sub")), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/legrand.sub")), "Test encoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); } From 6884103a914ccc93a16a81710585d755434f68de Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 30 Sep 2025 19:10:34 +0100 Subject: [PATCH 18/19] subghz: more explicit buffer position resets --- lib/subghz/protocols/came_twee.c | 2 ++ lib/subghz/protocols/hormann.c | 2 ++ lib/subghz/protocols/intertechno_v3.c | 1 + lib/subghz/protocols/keeloq.c | 3 ++- lib/subghz/protocols/magellan.c | 2 ++ lib/subghz/protocols/marantec24.c | 2 ++ lib/subghz/protocols/power_smart.c | 2 ++ lib/subghz/protocols/secplus_v2.c | 2 ++ 8 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 1d79d2201e2..2369e854d03 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -260,6 +260,7 @@ SubGhzProtocolStatus subghz_protocol_came_twee_remote_controller(&instance->generic); subghz_protocol_encoder_came_twee_get_upload(instance); + instance->encoder.front = 0; // reset position before start instance->encoder.is_running = true; } while(false); @@ -269,6 +270,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_came_twee_stop(void* context) { SubGhzProtocolEncoderCameTwee* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_came_twee_yield(void* context) { diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index 70954bb39d4..43a490ff900 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -158,6 +158,7 @@ SubGhzProtocolStatus flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); if(!subghz_protocol_encoder_hormann_get_upload(instance)) { + instance->encoder.front = 0; // reset position before start ret = SubGhzProtocolStatusErrorEncoderGetUpload; break; } @@ -170,6 +171,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_hormann_stop(void* context) { SubGhzProtocolEncoderHormann* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_hormann_yield(void* context) { diff --git a/lib/subghz/protocols/intertechno_v3.c b/lib/subghz/protocols/intertechno_v3.c index b9af72a579b..da25e1e75c9 100644 --- a/lib/subghz/protocols/intertechno_v3.c +++ b/lib/subghz/protocols/intertechno_v3.c @@ -193,6 +193,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_intertechno_v3_deserialize( void subghz_protocol_encoder_intertechno_v3_stop(void* context) { SubGhzProtocolEncoderIntertechno_V3* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_intertechno_v3_yield(void* context) { diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index b38abb75b50..11b9e1587ac 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -299,7 +299,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorParserKey; break; } - + instance->encoder.front = 0; // reset before start instance->encoder.is_running = true; } while(false); @@ -309,6 +309,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_keeloq_stop(void* context) { SubGhzProtocolEncoderKeeloq* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_keeloq_yield(void* context) { diff --git a/lib/subghz/protocols/magellan.c b/lib/subghz/protocols/magellan.c index 2402f1464ee..0706eec5969 100644 --- a/lib/subghz/protocols/magellan.c +++ b/lib/subghz/protocols/magellan.c @@ -168,6 +168,7 @@ SubGhzProtocolStatus flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); if(!subghz_protocol_encoder_magellan_get_upload(instance)) { + instance->encoder.front = 0; // reset before start ret = SubGhzProtocolStatusErrorEncoderGetUpload; break; } @@ -180,6 +181,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_magellan_stop(void* context) { SubGhzProtocolEncoderMagellan* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_magellan_yield(void* context) { diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c index 4365464fbe6..e2ff9218b27 100644 --- a/lib/subghz/protocols/marantec24.c +++ b/lib/subghz/protocols/marantec24.c @@ -165,6 +165,7 @@ SubGhzProtocolStatus subghz_protocol_marantec24_check_remote_controller(&instance->generic); subghz_protocol_encoder_marantec24_get_upload(instance); + instance->encoder.front = 0; // reset before start instance->encoder.is_running = true; } while(false); @@ -174,6 +175,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_marantec24_stop(void* context) { SubGhzProtocolEncoderMarantec24* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_marantec24_yield(void* context) { diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c index 828c4a76eaa..1359f416d7f 100644 --- a/lib/subghz/protocols/power_smart.c +++ b/lib/subghz/protocols/power_smart.c @@ -212,6 +212,7 @@ SubGhzProtocolStatus subghz_protocol_power_smart_remote_controller(&instance->generic); subghz_protocol_encoder_power_smart_get_upload(instance); + instance->encoder.front = 0; // reset before start instance->encoder.is_running = true; } while(false); @@ -221,6 +222,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_power_smart_stop(void* context) { SubGhzProtocolEncoderPowerSmart* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_power_smart_yield(void* context) { diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 4f11e22b6bd..3a7a465133b 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -554,6 +554,7 @@ SubGhzProtocolStatus break; } + instance->encoder.front = 0; // reset before start instance->encoder.is_running = true; } while(false); @@ -563,6 +564,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_secplus_v2_stop(void* context) { SubGhzProtocolEncoderSecPlus_v2* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_secplus_v2_yield(void* context) { From 920ca45fafad751e6bd4b1105cbf71304733711d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 1 Oct 2025 02:40:56 +0300 Subject: [PATCH 19/19] Fix gangqi samples --- .../resources/unit_tests/subghz/gangqi.sub | 2 +- .../resources/unit_tests/subghz/gangqi_raw.sub | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub index 592f86095bf..33f1ff79f41 100644 --- a/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub @@ -4,4 +4,4 @@ Frequency: 433920000 Preset: FuriHalSubGhzPresetOok650Async Protocol: GangQi Bit: 34 -Key: 00 00 00 00 31 B7 74 C8 +Key: 00 00 00 02 9D DB 77 38 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub index 9ecb1401637..fd76548dd03 100644 --- a/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub @@ -3,8 +3,10 @@ Version: 1 Frequency: 433920000 Preset: FuriHalSubGhzPresetOok650Async Protocol: RAW -RAW_Data: 215 -646 1237 -482 513 -1208 1205 -476 1231 -490 1177 -488 537 -1168 1205 -522 483 -1204 1217 -482 1183 -502 1207 -516 477 -1232 489 -1180 1213 -514 497 -1176 475 -1244 477 -2198 509 -1184 537 -1184 479 -1208 521 -1176 1219 -482 1189 -488 551 -1170 503 -1198 517 -1190 1201 -484 1225 -486 517 -1176 1181 -538 1195 -490 489 -1198 1209 -480 1219 -506 1185 -522 489 -1174 1253 -482 1173 -490 1239 -474 521 -1192 1201 -490 479 -1212 1205 -488 1237 -484 1183 -502 515 -1182 503 -1214 1209 -456 515 -1214 487 -1186 547 -2138 543 -1200 491 -1220 485 -1174 523 -1208 1173 -484 1257 -450 521 -1208 513 -1172 481 -1232 1197 -484 1223 -472 507 -1216 1211 -450 1261 -486 497 -1180 1203 -490 1205 -490 1213 -480 517 -1216 1197 -488 1209 -480 1207 -488 535 -1158 1195 -538 499 -1176 1227 -478 1183 -502 1229 -480 491 -1208 499 -1206 1203 -490 521 -1154 535 -1196 513 -2180 513 -1208 481 -1182 507 -1218 487 -1200 1209 -470 1221 -498 529 -1172 503 -1188 513 -1174 1243 -486 1201 -456 547 -1162 1219 -516 1177 -474 515 -1232 1171 -484 1227 -486 1193 -526 523 -1142 1253 -486 1201 -458 1241 -482 487 -1228 1203 -488 485 -1198 1199 -484 1257 -450 1225 -510 501 -1178 503 -1206 1181 -488 555 -1174 489 -1228 477 -2174 551 -1174 489 -1220 487 -1176 521 -1212 1175 -486 1257 -450 523 -1220 477 -1176 519 -1194 1209 -480 1217 -486 525 -1212 1169 -482 1235 -478 505 -1180 1237 -478 1195 -516 1203 -490 491 -1216 1207 -486 1223 -472 1213 -508 501 -1178 1233 -464 515 -1174 1241 -482 1201 -492 1221 -448 531 -1188 515 -1172 1251 -448 511 -1206 513 -1176 517 -2188 513 -1204 523 -1150 485 -1230 505 -1176 1217 -490 1203 -502 503 -1196 499 -1208 505 -1154 1245 -488 1195 -500 527 -1176 1233 -460 1205 -490 517 -1204 1185 -498 1225 -490 1211 -478 513 -1178 1207 -480 1209 -514 1203 -460 511 -1208 1203 -488 509 -1212 1181 -506 1211 -488 1229 -468 515 -1172 523 -1210 1175 -484 561 -1154 501 -1220 489 -2202 517 -1160 499 -1208 515 -1170 547 -1176 1197 -524 1173 -486 501 -1232 499 -1178 537 -1154 1205 -524 1205 -474 489 -1232 1193 -462 1237 -490 479 -1240 1197 -484 1203 -522 1173 -474 507 -1216 1205 -474 1231 -486 1201 -520 475 -1210 1209 -482 503 -1184 1217 -490 1207 -522 1183 -484 489 -1230 499 -1176 1231 -478 491 -1208 503 -1182 515 -2198 481 -1222 485 -1214 517 -1182 501 -1212 1173 -520 1205 -482 485 -1216 485 -1210 501 -1172 1231 -506 1161 -528 493 -1206 1229 -476 1183 -504 513 -1178 1211 -512 1203 -486 1209 -482 511 -1178 1243 -478 1177 -548 1169 -490 505 -1216 1183 -486 549 -1174 1185 -536 1191 -488 1209 -482 511 -1178 511 -1206 1185 -536 497 -1176 475 -1242 479 -2198 -RAW_Data: 507 -1184 501 -1210 481 -1206 515 -1178 1211 -514 1197 -490 471 -1238 489 -1176 545 -1174 1205 -516 1171 -486 505 -1230 1171 -486 1251 -464 515 -1206 1193 -488 1243 -486 1185 -484 523 -1186 1199 -526 1165 -508 1215 -490 487 -1208 1199 -520 477 -1212 1199 -478 1219 -488 1195 -492 513 -1202 503 -1210 1171 -522 479 -1214 505 -1184 489 -2200 515 -1192 519 -1180 521 -1184 501 -1208 1207 -480 1203 -510 475 -1212 511 -1194 473 -1230 1209 -482 1199 -518 497 -1178 1199 -496 1209 -522 481 -1200 1219 -478 1187 -522 1211 -480 483 -1246 1181 -484 1217 -480 1185 -504 505 -1218 1183 -488 515 -1204 1213 -482 1187 -522 1211 -480 481 -1212 511 -1198 1187 -532 497 -1178 475 -1242 479 -2200 505 -1182 519 -1204 479 -1240 479 -1174 1245 -486 1195 -486 513 -1176 517 -1216 499 -1176 1231 -462 1209 -488 483 -1222 1179 -542 1195 -462 511 -1238 1169 -486 1233 -480 1199 -478 527 -1186 1193 -524 1181 -520 1213 -480 479 -1214 1205 -480 517 -1198 1211 -480 1233 -484 1197 -488 513 -1178 517 -1214 1195 -486 483 -1230 483 -1186 537 -2184 515 -1168 507 -1220 479 -1188 501 -1212 1209 -488 1209 -480 507 -1182 537 -1196 463 -1246 1177 -488 1209 -512 483 -1182 1237 -484 1185 -536 499 -1178 1217 -488 1177 -520 1205 -482 487 -1248 1189 -464 1233 -488 1205 -488 511 -1202 1183 -532 497 -1178 1201 -492 1205 -474 1217 -516 477 -1238 475 -1210 1205 -482 503 -1182 537 -1166 507 -2204 481 -1202 525 -1184 501 -1210 507 -1182 1211 -488 1203 -498 515 -1180 485 -1216 513 -1176 1209 -512 1173 -514 531 -1158 1189 -524 1185 -520 483 -1228 1177 -478 1223 -486 1193 -526 493 -1206 1197 -506 1179 -486 1247 -478 475 -1242 1181 -482 485 -1230 1209 -482 1201 -516 1195 -520 473 -1210 481 -1218 1175 -486 505 -1230 479 -1186 533 -2188 507 -1206 481 -1234 481 -1184 503 -1214 1183 -502 1211 -490 505 -1212 481 -1204 485 -1236 1179 -478 1217 -486 503 -1236 1179 -486 1209 -512 473 -1200 1209 -510 1165 -548 1173 -486 503 -1220 1183 -520 1215 -476 1171 -518 531 -1158 1229 -512 495 -1176 1197 -508 1183 -506 1195 -508 489 -1238 473 -1182 1247 -484 483 -1196 519 -1182 481 -2232 477 -1216 505 -1202 475 -1214 505 -1170 1235 -484 1183 -540 501 -1180 485 -1210 513 -1178 1205 -514 1175 -546 475 -1182 1227 -480 1185 -520 481 -1230 1179 -478 1221 -488 1191 -524 493 -1208 1217 -486 1171 -512 1201 -508 475 -1244 1175 -480 503 -1234 1183 -484 1217 -514 1157 -554 487 -1178 487 -1228 1191 -474 537 -1184 501 -1218 489 -2210 481 -1214 475 -1218 487 -1184 515 -1206 1195 -486 1205 -498 511 -1206 479 -1210 477 -1220 1201 -480 1221 -488 519 -1212 1175 -486 1235 -480 507 -1180 1219 -490 1197 -520 1181 -504 -RAW_Data: 473 -1248 1175 -488 1209 -512 1171 -546 477 -1188 1213 -492 515 -1170 1237 -484 1171 -544 1179 -478 507 -1216 513 -1160 1215 -496 513 -1208 503 -1198 463 -2238 485 -1230 485 -1190 463 -1244 489 -1184 1205 -520 1173 -516 509 -1176 513 -1190 485 -1216 1215 -490 1199 -530 461 -1208 1197 -508 1183 -484 551 -1174 1183 -538 1159 -500 1235 -488 477 -1202 1203 -516 1171 -554 1177 -484 489 -1232 1191 -462 543 -1180 1205 -518 1177 -486 1227 -506 487 -1172 513 -1206 1203 -484 535 -1194 463 -1246 485 -2200 479 -1188 499 -1216 513 -1176 511 -1214 1173 -514 1203 -492 473 -1244 481 -1206 517 -1174 1179 -542 1199 -462 517 -1204 1203 -480 1231 -484 519 -1182 1213 -478 1237 -476 1203 -484 497 -1212 1183 -504 1213 -490 1231 -478 489 -1178 1249 -484 479 -1210 1209 -482 1207 -516 1173 -488 499 -1214 515 -1172 1211 -516 481 -1208 511 -1172 507 -2206 489 -1208 503 -1184 547 -1178 473 -1246 1175 -488 1209 -510 475 -1212 477 -1224 487 -1214 1191 -520 1211 -480 481 -1214 1207 -482 1183 -508 519 -1184 1199 -532 1191 -486 1207 -484 511 -1174 1239 -478 1199 -518 1177 -486 519 -1216 1173 -486 541 -1198 1181 -520 1183 -486 1213 -514 481 -1184 537 -1198 1153 -560 461 -1210 485 -1212 513 -2198 501 -1176 505 -1212 479 -1206 515 -1176 1245 -486 1161 -520 481 -1230 483 -1180 537 -1194 1165 -540 1195 -486 481 -1230 1177 -514 1193 -486 497 -1246 1181 -486 1205 -512 1167 -514 531 -1194 1157 -526 1189 -520 1213 -480 481 -1216 1205 -482 487 -1250 1157 -520 1215 -480 1173 -516 533 -1192 463 -1248 1179 -476 511 -1226 485 -1180 489 -2202 513 -1192 519 -1182 519 -1184 505 -1198 1201 -488 1235 -464 515 -1176 519 -1212 483 -1220 1173 -486 1249 -496 483 -1176 1209 -516 1171 -520 515 -1194 1189 -508 1181 -504 1211 -482 513 -1210 1181 -480 1247 -484 1199 -486 519 -1178 1181 -544 501 -1180 1199 -496 1207 -486 1211 -514 483 -1186 535 -1190 1203 -480 495 -1212 487 -1208 481 -2242 461 -1210 505 -1182 515 -1210 483 -1212 1207 -480 1195 -506 507 -1212 475 -1218 485 -1196 1219 -488 1195 -488 547 -1174 1165 -530 1185 -520 483 -1230 1175 -480 1221 -488 1195 -540 499 -1180 1203 -494 1209 -488 1209 -482 485 -1216 1215 -490 485 -1214 1203 -486 1233 -484 1179 -490 547 -1178 473 -1250 1175 -474 519 -1208 481 -1214 509 -2190 515 -1174 485 -1248 497 -1174 475 -1242 1171 -520 1205 -480 509 -1214 501 -1176 505 -1204 1183 -506 1199 -508 487 -1210 1205 -486 1173 -552 485 -1200 1185 -510 1185 -504 1211 -482 511 -1198 1197 -490 1241 -484 1175 -512 507 -1204 1181 -516 481 -1214 1201 -506 1169 -516 1193 -520 483 -1210 483 -1206 1207 -516 479 -1174 549 -1176 489 -2208 479 -1212 509 -1200 -RAW_Data: 491 -1234 461 -1208 1203 -506 1181 -506 505 -1184 517 -1204 505 -1164 1221 -522 1181 -486 515 -1210 1181 -514 1175 -518 479 -1218 1185 -506 1213 -490 1197 -518 487 -1208 1183 -516 1171 -518 1209 -482 489 -1248 1157 -520 481 -1224 1169 -514 1189 -510 1183 -538 501 -1180 473 -1242 1173 -514 473 -1216 487 -1228 501 -2174 511 -1202 491 -1230 477 -1184 503 -1210 1207 -472 1215 -516 477 -1236 475 -1202 475 -1216 1209 -484 1217 -480 493 -1244 1187 -498 1213 -486 487 -1200 1189 -510 1183 -520 1185 -514 483 -1218 1175 -520 1189 -510 1183 -520 513 -1172 1215 -514 495 -1178 1203 -494 1205 -474 1213 -516 481 -1238 473 -1180 1241 -484 481 -1188 531 -1200 499 -2202 485 -1234 483 -1186 499 -1214 491 -1182 1205 -518 1175 -514 509 -1174 515 -1226 485 -1182 1215 -490 1183 -516 515 -1176 1205 -516 1171 -520 477 -1218 1183 -538 1191 -462 1235 -490 481 -1204 1215 -484 1203 -484 1229 -478 485 -1248 1161 -520 481 -1226 1169 -514 1225 -480 1169 -540 501 -1178 485 -1240 1173 -486 539 -1194 473 -1232 501 -2204 481 -1194 473 -1232 513 -1158 531 -1184 1207 -522 1173 -512 477 -1216 513 -1194 463 -1246 1179 -476 1239 -478 477 -1242 1181 -484 1213 -518 499 -1178 1219 -488 1177 -554 1177 -484 491 -1218 1185 -520 1179 -514 1177 -546 475 -1180 1231 -478 495 -1210 1197 -504 1183 -536 1183 -482 481 -1248 481 -1200 1219 -476 491 -1244 463 -1212 481 -2198 505 -1216 489 -1182 515 -1208 473 -1198 1219 -488 1191 -524 491 -1208 473 -1238 487 -1174 1239 -486 1171 -554 485 -1198 1191 -506 1183 -488 517 -1202 1181 -536 1191 -494 1197 -504 489 -1206 1205 -490 1173 -552 1175 -480 507 -1216 1177 -520 495 -1214 1175 -540 1167 -504 1219 -492 473 -1214 481 -1220 1175 -554 483 -1180 489 -1210 501 -2204 485 -1192 493 -1240 473 -1192 523 -1188 1193 -522 1187 -486 517 -1224 481 -1168 539 -1198 1181 -518 1181 -504 481 -1226 1169 -516 1225 -480 505 -1198 1207 -482 1203 -516 1193 -484 519 -1176 1201 -514 1199 -488 1233 -478 491 -1210 1199 -490 513 -1170 1217 -516 1207 -474 1207 -482 509 -1212 501 -1180 1197 -528 481 -1206 505 -1198 483 -2196 515 -1192 487 -1214 519 -1184 473 -1248 1177 -506 1217 -486 481 -1208 513 -1172 519 -1212 1165 -520 1207 -482 513 -1178 1209 -514 1177 -514 507 -1182 1227 -500 1175 -488 1211 -514 483 -1182 1231 -480 1201 -514 1197 -492 475 -1242 1175 -486 541 -1192 1165 -538 1193 -474 1229 -512 461 -1206 507 -1198 1193 -520 501 -1172 507 -1204 519 -2198 475 -1206 507 -1206 481 -1226 475 -1198 1207 -512 1169 -516 499 -1214 493 -1182 513 -1210 1205 -488 1173 -506 485 -1238 1173 -512 1189 -506 507 -1214 1195 -484 1209 -514 1171 -486 539 -1196 1155 -528 -RAW_Data: 1189 -500 1235 -484 481 -1206 1213 -482 513 -1210 1173 -508 +RAW_Data: 1223 -572304 1675 -132 1183 -536 465 -1214 1203 -502 489 -1210 509 -1202 1171 -518 1175 -522 1189 -508 489 -1176 1229 -504 1177 -520 1205 -482 479 -1232 1203 -478 1233 -486 481 -1216 1197 -480 1221 -486 505 -1182 1241 -486 1175 -482 1245 -484 505 -1218 1185 -498 1211 -490 1185 -482 545 -1174 511 -1206 1177 -516 1189 -516 1165 -508 521 -1184 503 -1232 477 -2210 1171 -510 473 -1232 1183 -514 517 -1174 513 -1194 1209 -478 1219 -486 1191 -492 513 -1204 1199 -532 1159 -500 1237 -486 481 -1206 1209 -480 1203 -480 535 -1198 1189 -496 1187 -520 483 -1230 1175 -478 1219 -506 1199 -510 505 -1180 1231 -496 1179 -486 1211 -482 517 -1214 501 -1182 1199 -508 1179 -502 1205 -516 477 -1240 473 -1206 477 -2200 1231 -478 485 -1222 1189 -520 463 -1202 515 -1208 1199 -494 1207 -486 1209 -516 483 -1182 1217 -488 1197 -534 1159 -520 481 -1234 1179 -478 1219 -486 505 -1216 1183 -506 1201 -510 491 -1174 1229 -506 1177 -542 1185 -496 483 -1208 1195 -502 1213 -490 1169 -528 493 -1208 475 -1242 1171 -482 1235 -484 1181 -542 499 -1180 473 -1242 479 -2204 1201 -490 475 -1248 1177 -488 515 -1206 489 -1236 1153 -520 1215 -480 1175 -514 531 -1192 1167 -538 1195 -484 1215 -482 515 -1176 1207 -512 1165 -548 477 -1184 1233 -478 1187 -520 519 -1174 1185 -536 1191 -474 1231 -478 493 -1212 1203 -492 1177 -544 1179 -480 487 -1250 497 -1176 1197 -496 1211 -486 1211 -480 517 -1214 501 -1178 507 -2208 1209 -486 507 -1182 1197 -526 483 -1204 507 -1198 1187 -508 1183 -506 1217 -490 475 -1244 1175 -486 1237 -484 1181 -492 547 -1176 1167 -528 1185 -520 485 -1232 1175 -478 1223 -486 519 -1216 1169 -520 1203 -482 1197 -480 493 -1242 1167 -504 1217 -490 1201 -518 489 -1176 519 -1210 1175 -514 1191 -486 1213 -518 489 -1176 505 -1214 515 -2198 1167 -506 541 -1174 1175 -520 505 -1184 505 -1216 1183 -504 1211 -490 1199 -530 495 -1178 1199 -494 1205 -484 1207 -514 479 -1200 1203 -516 1175 -512 507 -1184 1227 -498 1181 -486 515 -1204 1185 -532 1159 -504 1231 -478 493 -1210 1215 -486 1171 -544 1173 -512 475 -1216 513 -1194 1185 -510 1181 -520 1185 -514 483 -1216 513 -1158 531 -2174 1243 -486 499 -1176 1217 -490 479 -1236 505 -1184 1203 -522 1181 -484 1213 -502 485 -1206 1197 -500 1213 -490 1197 -498 515 -1180 1197 -532 1161 -502 511 -1202 1201 -482 1225 -476 485 -1248 1191 -486 1211 -482 1207 -484 537 -1196 1179 -516 1179 -506 1199 -508 489 -1172 545 -1178 1201 -520 1179 -488 1215 -494 515 -1170 513 -1204 481 -2238 1157 -520 519 -1176 1183 -540 499 -1178 473 -1236 1179 -520 1209 -480 1175 -552 475 -1188 1225 -502 1177 -488 1207 -510 473 -1232 1207 -480 1203 -520 479 -1184 +RAW_Data: 1227 -480 1189 -554 487 -1174 1217 -502 1181 -486 1211 -514 481 -1216 1207 -484 1221 -478 1185 -520 487 -1196 483 -1218 1215 -490 1229 -478 1183 -520 483 -1228 483 -1188 531 -2150 1239 -480 481 -1246 1181 -482 489 -1218 495 -1206 1197 -506 1183 -520 1205 -480 479 -1232 1181 -514 1209 -486 1199 -526 491 -1184 1207 -520 1183 -484 485 -1208 1209 -506 1181 -518 479 -1242 1169 -482 1235 -474 1201 -480 541 -1174 1205 -512 1207 -474 1215 -516 479 -1174 547 -1176 1185 -536 1193 -462 1249 -486 481 -1206 513 -1176 485 -2240 1173 -518 517 -1158 1223 -506 487 -1174 545 -1172 1207 -514 1175 -484 1223 -510 489 -1178 1219 -516 1173 -486 1235 -484 489 -1218 1185 -520 1217 -480 481 -1214 1205 -484 1183 -540 499 -1182 1201 -494 1207 -476 1241 -478 475 -1244 1171 -512 1203 -520 1173 -490 521 -1184 479 -1246 1179 -482 1243 -486 1195 -484 515 -1210 485 -1214 499 -2204 1175 -482 519 -1224 1171 -490 503 -1210 481 -1210 1213 -482 1205 -518 1175 -486 501 -1246 1179 -486 1211 -480 1213 -512 503 -1182 1231 -498 1179 -486 513 -1202 1183 -534 1159 -498 511 -1204 1199 -482 1227 -480 1199 -514 505 -1182 1229 -478 1185 -520 1209 -482 509 -1202 513 -1174 1215 -516 1153 -520 1211 -480 511 -1204 485 -1208 489 -2210 1175 -548 475 -1186 1217 -492 515 -1174 513 -1210 1177 -510 1201 -490 1233 -496 483 -1174 1215 -516 1173 -514 1209 -484 491 -1232 1159 -520 1209 -480 513 -1210 1183 -482 1245 -486 501 -1178 1231 -496 1177 -508 1205 -482 481 -1244 1171 -510 1211 -486 1199 -494 509 -1210 479 -1212 1181 -514 1207 -486 1201 -492 507 -1216 479 -1210 519 -2198 1165 -494 513 -1210 1193 -488 511 -1208 473 -1246 1175 -474 1239 -478 1203 -486 539 -1194 1155 -528 1187 -520 1211 -480 481 -1210 1203 -512 1169 -548 477 -1186 1215 -492 1205 -486 481 -1220 1177 -510 1219 -488 1199 -522 487 -1206 1197 -504 1181 -486 1241 -478 475 -1244 485 -1202 1219 -478 1187 -486 1241 -478 475 -1244 485 -1202 461 -2214 1245 -482 499 -1178 1231 -478 491 -1240 471 -1184 1243 -486 1175 -480 1241 -482 503 -1182 1233 -478 1215 -506 1165 -510 489 -1208 1195 -506 1211 -506 473 -1214 1185 -522 1207 -478 509 -1174 1243 -480 1199 -514 1169 -506 507 -1214 1197 -486 1209 -482 1201 -520 481 -1192 519 -1208 1175 -514 1199 -510 1175 -514 507 -1186 503 -1210 479 -2234 1171 -490 503 -1208 1177 -520 511 -1198 489 -1232 1169 -490 1215 -492 1205 -488 513 -1202 1185 -534 1161 -518 1209 -482 513 -1178 1205 -516 1175 -512 507 -1184 1233 -498 1175 -474 551 -1182 1177 -546 1165 -510 1189 -510 487 -1208 1215 -486 1175 -546 1173 -480 509 -1216 479 -1190 1223 -506 1179 -520 1183 -516 479 -1234 481 -1198 491 -2210 +RAW_Data: 1211 -482 501 -1184 1227 -500 483 -1208 505 -1200 1205 -474 1213 -484 1205 -520 481 -1232 1177 -478 1219 -486 1197 -504 519 -1184 1193 -522 1181 -520 481 -1230 1177 -478 1217 -508 473 -1248 1155 -504 1231 -500 1179 -486 481 -1224 1179 -510 1217 -490 1229 -480 493 -1210 477 -1238 1169 -486 1235 -484 1181 -524 491 -1206 477 -1240 477 -2206 1199 -492 511 -1180 1205 -518 481 -1190 499 -1212 1207 -486 1213 -480 1213 -512 503 -1182 1213 -490 1205 -486 1209 -512 475 -1216 1209 -484 1211 -504 487 -1174 1237 -488 1173 -518 511 -1200 1189 -530 1155 -500 1237 -486 477 -1200 1205 -516 1169 -552 1179 -482 493 -1232 477 -1182 1233 -478 1189 -554 1169 -480 509 -1210 485 -1206 527 -2182 1203 -484 517 -1194 1179 -510 489 -1210 519 -1184 1209 -484 1203 -494 1197 -508 489 -1210 1193 -490 1243 -486 1177 -482 519 -1212 1173 -522 1181 -510 491 -1206 1197 -506 1215 -492 473 -1246 1177 -506 1217 -486 1171 -514 507 -1202 1187 -534 1155 -498 1235 -488 483 -1206 513 -1208 1173 -512 1203 -490 1201 -494 515 -1174 519 -1214 481 -2198 1187 -504 513 -1208 1175 -512 505 -1182 503 -1200 1201 -490 1229 -498 1173 -520 487 -1208 1221 -478 1185 -520 1181 -512 475 -1246 1175 -478 1235 -486 505 -1182 1229 -498 1179 -520 479 -1202 1211 -504 1179 -506 1203 -490 481 -1240 1179 -516 1209 -486 1177 -488 553 -1182 479 -1242 1183 -480 1211 -520 1173 -490 473 -1244 479 -1210 513 -2166 1239 -486 479 -1244 1167 -490 481 -1242 473 -1210 1209 -484 1205 -520 1195 -486 477 -1238 1167 -514 1207 -520 1177 -518 481 -1182 1235 -484 1181 -492 547 -1178 1197 -530 1153 -520 487 -1232 1177 -478 1217 -508 1165 -542 501 -1178 1227 -498 1177 -486 1211 -510 475 -1216 507 -1200 1183 -530 1191 -486 1211 -482 513 -1176 511 -1202 489 -2210 1173 -550 479 -1188 1225 -502 485 -1172 543 -1180 1171 -548 1171 -486 1223 -506 487 -1208 1217 -484 1171 -554 1179 -484 489 -1232 1159 -520 1211 -482 513 -1176 1209 -512 1207 -520 475 -1180 1231 -478 1183 -520 1209 -480 507 -1200 1205 -480 1237 -486 1171 -486 539 -1182 507 -1218 1179 -490 1209 -518 1177 -480 541 -1172 515 -1228 481 -2192 1187 -520 483 -1228 1169 -480 495 -1246 461 -1248 1183 -476 1237 -482 1175 -516 497 -1214 1187 -500 1215 -492 1173 -548 483 -1176 1207 -518 1171 -518 509 -1200 1157 -528 1189 -520 483 -1228 1177 -480 1219 -488 1195 -524 489 -1208 1195 -506 1181 -506 1199 -508 487 -1210 499 -1210 1203 -484 1181 -486 1229 -516 463 -1246 493 -1180 481 -2234 1173 -524 489 -1198 1211 -490 505 -1180 515 -1208 1177 -516 1175 -516 1225 -482 473 -1198 1235 -484 1183 -524 1181 -506 473 -1250 1181 -476 1241 -480 481 -1246 1177 -484 1215 -514 +RAW_Data: 495 -1180 1197 -494 1211 -506 1199 -502 485 -1210 1195 -488 1211 -520 1183 -514 477 -1214 477 -1220 1181 -506 1215 -490 1197 -498 515 -1182 503 -1218 489 -2198 1205 -482 475 -1246 1161 -520 515 -1174 485 -1246 1195 -484 1209 -482 1207 -484 537 -1196 1181 -520 1179 -504 1209 -482 513 -1174 1237 -478 1199 -518 479 -1190 1225 -504 1181 -488 481 -1224 1177 -542 1197 -492 1199 -494 515 -1172 1215 -516 1173 -486 1233 -484 489 -1216 493 -1212 1205 -488 1175 -522 1205 -482 519 -1216 485 -1176 511 -2198 1229 -498 483 -1174 1239 -486 479 -1240 477 -1202 1201 -486 1205 -490 1217 -490 481 -1238 1165 -530 1213 -462 1215 -480 475 -1244 1181 -482 1215 -516 501 -1216 1187 -498 1211 -494 473 -1202 1203 -520 1179 -516 1175 -516 499 -1214 1189 -498 1213 -492 1185 -512 481 -1208 479 -1232 1175 -514 1193 -520 1179 -522 487 -1206 473 -1214 515 -2198 1173 -486 505 -1218 1189 -554 487 -1174 489 -1232 1159 -520 1209 -482 1209 -482 533 -1196 1181 -518 1181 -488 1211 -514 483 -1182 1233 -484 1181 -538 501 -1180 1213 -488 1205 -474 545 -1180 1173 -544 1173 -490 1227 -502 485 -1176 1213 -516 1171 -552 1177 -482 473 -1250 463 -1212 1197 -508 1185 -520 1183 -514 485 -1214 479 -1192 553 -2178 1215 -496 483 -1176 1215 -516 479 -1210 509 -1172 1215 -516 1155 -520 1217 -482 479 -1244 1175 -514 1209 -486 1199 -494 519 -1176 1203 -518 1177 -486 501 -1214 1211 -476 1205 -512 475 -1246 1173 -482 1243 -482 1197 -494 505 -1216 1177 -518 1171 -510 1199 -518 479 -1184 501 -1212 1209 -520 1183 -484 1213 -516 465 -1212 477 -1240 479 -2198 1199 -492 539 -1180 1183 -520 481 -1202 489 -1216 1183 -520 1211 -480 1173 -550 479 -1186 1231 -478 1189 -520 1209 -482 479 -1246 1177 -482 1217 -516 497 -1178 1213 -490 1173 -540 503 -1164 1223 -488 1195 -506 1215 -490 505 -1180 1205 -518 1173 -522 1197 -478 493 -1238 473 -1182 1243 -492 1185 -514 1175 -520 481 -1220 489 -1182 547 -2172 1201 -508 475 -1246 1183 -484 483 -1218 515 -1172 1207 -516 1177 -518 1209 -484 493 -1216 1181 -486 1215 -514 1175 -514 495 -1192 1227 -504 1181 -486 483 -1222 1209 -476 1217 -488 505 -1232 1173 -490 1233 -476 1189 -520 517 -1168 1203 -510 1197 -474 1231 -480 495 -1210 507 -1206 1175 -518 1179 -520 1219 -478 491 -1206 503 -1184 515 -2196 1175 -554 485 -1178 1215 -506 473 -1216 483 -1208 1181 -514 1205 -486 1211 -516 483 -1182 1231 -482 1199 -478 1223 -486 519 -1212 1175 -518 1207 -482 489 -1184 1239 -474 1193 -524 491 -1210 1215 -486 1169 -520 1207 -482 485 -1248 1161 -500 1235 -486 1177 -520 509 -1196 473 -1228 1191 -474 1225 -506 1181 -486 549 -1172 489 -1216 491 -2172 1233 -484 485 -1248 +RAW_Data: 1157 -498 511 -1202 509 -1174 1237 -476 1201 -514 1205 -484 493 -1200 1187 -520 1213 -482 1173 -548 477 -1190 1215 -492 1211 -476 543 -1174 1183 -538 1163 -498 509 -1204 1205 -484 1231 -482 1169 -542 501 -1184 1215 -490 1173 -518 1207 -480 503 -1236 485 -1198 1213 -500 1175 -476 1233 -488 481 -1206 513 -1210 485 -2212 1181 -538 477 -1174 1213 -518 499 -1182 519 -1180 1205 -516 1169 -508 1215 -504 487 -1176 1241 -484 1173 -552 1181 -484 489 -1216 1183 -518 1213 -480 507 -1208 1169 -510 1203 -520 477 -1188 1215 -494 1205 -474 1215 -516 477 -1240 1165 -492 1237 -474 1195 -502 517 -1182 505 -1232 1153 -518 1215 -482 1175 -514 531 -1194 485 -1214 479 -2234 1175 -488 487 -1246 1175 -484 535 -1192 485 -1206 1205 -476 1239 -480 1175 -516 463 -1246 1187 -532 1157 -500 1237 -484 479 -1208 1211 -480 1203 -484 539 -1188 1165 -538 1191 -474 507 -1214 1187 -502 1213 -482 1207 -518 481 -1190 1217 -494 1177 -520 1209 -482 485 -1250 499 -1180 1199 -494 1205 -476 1209 -514 483 -1244 483 -1196 485 -2208 1221 -478 489 -1210 1213 -486 479 -1202 513 -1212 1177 -512 1199 -490 1201 -510 489 -1208 1199 -502 1181 -520 1203 -478 477 -1246 1181 -482 1211 -518 499 -1210 1167 -510 1217 -490 483 -1216 1209 -484 1203 -494 1199 -504 487 -1210 1189 -494 1239 -492 1165 -526 493 -1208 473 -1244 1177 -476 1235 -480 1201 -518 479 -1190 499 -1244 481 -2194 1207 -482 473 -1250 1155 -520 519 -1176 485 -1248 1161 -518 1209 -482 1203 -480 537 -1192 1167 -536 1197 -462 1229 -506 487 -1206 1201 -502 1181 -520 479 -1204 1219 -480 1187 -520 515 -1172 1181 -542 1199 -486 1205 -516 479 -1176 1243 -480 1173 -550 1173 -486 503 -1238 481 -1172 1217 -518 1171 -484 1235 -480 509 -1212 503 -1182 473 -2238 1213 -496 483 -1174 1239 -486 479 -1242 487 -1176 1215 -514 1159 -520 1213 -480 481 -1246 1177 -482 1243 -484 1165 -518 515 -1208 1179 -512 1199 -486 481 -1230 1201 -482 1227 -482 473 -1216 1211 -490 1231 -478 1185 -518 483 -1228 1175 -478 1217 -508 1183 -536 497 -1176 473 -1232 1199 -494 1197 -508 1181 -554 477 -1174 485 -1248 461 -2236 1175 -482 521 -1212 1171 -518 505 -1198 477 -1222 1181 -490 1237 -474 1199 -536 497 -1178 1219 -486 1177 -520 1205 -482 487 -1184 1239 -474 1191 -526 493 -1208 1195 -508 1181 -504 505 -1198 1201 -520 1197 -482 1203 -522 485 -1164 1249 -462 1207 -506 1197 -504 485 -1210 499 -1182 1241 -480 1205 -518 1173 -482 493 -1240 471 -1184 549 -2170 1203 -508 507 -1178 1207 -480 517 -1216 479 -1186 1229 -482 1187 -520 1213 -478 509 -1208 1185 -480 1229 -520 1173 -492 519 -1184 1207 -518 1175 -486 501 -1218 1209 -488 1205 -482 519 -1216 1193 -488 +RAW_Data: 1215 -480 1207 -484 535 -1156 1217 -516 1177 -486 1247 -476 509 -1176 511 -1204 1183 -534 1195 -486 1211 -478 509 -1172 515 -1192 517 -2210 1171 -488 541 -1196 1157 -528 493 -1208 475 -1240 1169 -488 1237 -482 1183 -538 499 -1178 1229 -480 1183 -486 1245 -480 479 -1232 1177 -480 1245 -484 501 -1184 1233 -464 1211 -520 483 -1200 1219 -478 1183 -522 1211 -480 477 -1232 1185 -480 1243 -482 1193 -474 497 -1252 483 -1174 1217 -516 1171 -514 1209 -484 485 -1220 515 -1170 513 -2204 1205 -490 511 -1202 1199 -498 481 -1210 503 -1198 1209 -490 1197 -528 1191 -486 483 -1226 1175 -482 1223 -486 1197 -538 501 -1180 1219 -488 1173 -520 479 -1218 1179 -506 1215 -490 485 -1244 1171 -486 1235 -480 1199 -478 525 -1186 1199 -534 1193 -486 1215 -480 515 -1176 511 -1204 1185 -532 1191 -486 1213 -480 513 -1180 513 -1204 489 -2212 1175 -512 507 -1182 1233 -478 493 -1176 521 -1210 1171 -548 1175 -488 1217 -492 515 -1172 1241 -484 1175 -482 1235 -482 485 -1252 1159 -522 1213 -480 479 -1214 1207 -480 1209 -512 505 -1180 1229 -478 1189 -486 1243 -478 479 -1234 1177 -514 1211 -486 1201 -490 505 -1192 493 -1242 1181 -486 1207 -520 1181 -482 525 -1184 503 -1212 503 -2156 1241 -486 483 -1232 1177 -480 495 -1240 471 -1198 1235 -484 1185 -534 1161 -500 511 -1202 1201 -486 1231 -484 1179 -524 491 -1208 1201 -490 1209 -480 545 -1170 1169 -540 1199 -486 487 -1236 1173 -480 1221 -486 1193 -524 493 -1206 1197 -508 1181 -486 1217 -514 481 -1218 515 -1160 1223 -506 1183 -474 1241 -480 513 -1210 485 -1204 485 -2196 1197 -510 507 -1184 1227 -500 483 -1178 521 -1212 1179 -512 1203 -460 1251 -486 479 -1208 1209 -482 1207 -518 1173 -486 499 -1238 1181 -488 1213 -514 483 -1220 1173 -484 1235 -514 495 -1178 1217 -488 1171 -538 1195 -500 483 -1208 1197 -502 1209 -474 1197 -506 521 -1180 505 -1218 1179 -506 1197 -506 1181 -504 505 -1184 517 -1204 505 -2212 1171 -516 495 -1214 1187 -464 549 -1180 487 -1216 1203 -486 1229 -484 1183 -502 519 -1182 1197 -532 1193 -486 1215 -480 481 -1208 1207 -478 1203 -548 477 -1182 1229 -480 1185 -504 503 -1216 1177 -486 1245 -476 1199 -516 479 -1190 1229 -502 1179 -474 1245 -480 479 -1246 481 -1198 1217 -478 1183 -522 1209 -478 507 -1210 485 -1208 489 -2210 1207 -486 509 -1182 1229 -478 491 -1208 521 -1184 1209 -482 1203 -490 1219 -490 513 -1172 1209 -482 1205 -520 1209 -480 471 -1234 1209 -486 1215 -500 485 -1208 1181 -514 1203 -506 471 -1216 1203 -506 1161 -528 1185 -522 487 -1196 1209 -478 1221 -488 1185 -548 483 -1172 505 -1204 1207 -488 1211 -514 1173 -514 509 -1180 505 -1216 487 -2204 1179 -484 529 -1216 1183 -488 515 -1202 +RAW_Data: 489 -1232 1171 -490 1233 -478 1187 -486 553 -1168 1201 -512 1197 -492 1199 -496 515 -1174 1209 -516 1167 -520 517 -1192 1187 -508 1185 -486 553 -1172 1187 -534 1187 -474 1231 -476 493 -1206 1197 -508 1181 -520 1205 -478 509 -1206 515 -1170 1217 -504 1177 -506 1205 -482 511 -1208 487 -1206 491 -2212 1209 -482 503 -1184 1227 -500 485 -1206 521 -1174 1203 -514 1167 -506 1231 -484 497 -1210 1199 -478 1221 -488 1197 -498 519 -1184 1201 -516 1177 -504 473 -1216 1207 -474 1249 -484 477 -1238 1169 -516 1201 -506 1161 -496 513 -1202 1199 -502 1211 -488 1229 -480 491 -1208 477 -1236 1167 -482 1237 -482 1183 -542 501 -1180 485 -1214 509 -2194 1197 -490 537 -1166 1197 -506 505 -1180 507 -1218 1183 -504 1211 -488 1185 -516 515 -1170 1237 -486 1201 -488 1207 -482 517 -1196 1215 -480 1229 -484 499 -1178 1235 -478 1181 -486 553 -1174 1183 -534 1191 -462 1247 -486 479 -1204 1207 -482 1205 -520 1209 -486 493 -1218 487 -1176 1217 -514 1175 -520 1213 -450 519 -1210 513 -1172 513 -2174 1249 -482 477 -1236 1197 -464 513 -1206 503 -1200 1205 -474 1195 -506 1213 -490 503 -1198 1201 -472 1229 -516 1193 -486 515 -1174 1209 -512 1201 -492 477 -1242 1173 -486 1237 -482 485 -1240 1175 -486 1241 -480 1175 -514 531 -1156 1189 -524 1185 -520 1209 -480 509 -1168 549 -1176 1183 -536 1195 -488 1211 -480 513 -1174 547 -1174 489 -2194 1201 -482 535 -1196 1187 -498 529 -1178 475 -1242 1173 -482 1235 -482 1183 -526 493 -1208 1195 -506 1179 -486 1243 -480 479 -1232 1181 -480 1229 -522 477 -1180 1231 -478 1185 -556 477 -1174 1243 -486 1195 -488 1217 -482 479 -1248 1181 -484 1215 -506 1183 -476 515 -1196 517 -1218 1169 -486 1229 -482 1191 -500 511 -1204 477 -1200 547 -2164 1209 -482 511 -1206 1185 -514 483 -1216 513 -1160 1249 -462 1209 -522 1175 -482 517 -1218 1199 -484 1211 -482 1207 -518 481 -1188 1215 -494 1207 -472 545 -1182 1175 -550 1173 -490 507 -1208 1175 -488