From f4a205142d9d8a3ba94169d898525b305ee22bc8 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 5 May 2022 02:34:44 +0400 Subject: [PATCH 01/24] SubGhz: bug fixes (#1192) * Subghz: fix simultaneous detection of Princeton and GateTx * SubGhz: fix phantom frequencies in the Frequency Analyzer --- .../subghz_frequency_analyzer_worker.c | 1 + lib/subghz/protocols/firefly.c | 6 ----- lib/subghz/protocols/keeloq.c | 2 +- lib/subghz/protocols/nero_sketch.c | 6 ----- lib/subghz/protocols/nice_flo.c | 6 ----- lib/subghz/protocols/nice_flor_s.c | 1 + lib/subghz/protocols/princeton.c | 24 +++++++++++-------- lib/subghz/protocols/princeton_for_testing.c | 1 + 8 files changed, 18 insertions(+), 29 deletions(-) diff --git a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c index b6b3a1edc20..8d8ad0b653d 100644 --- a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -71,6 +71,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); furi_hal_subghz_set_frequency(433920000); furi_hal_subghz_flush_rx(); + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); furi_hal_subghz_rx(); while(instance->worker_running) { diff --git a/lib/subghz/protocols/firefly.c b/lib/subghz/protocols/firefly.c index e872d5580eb..3a339e0a9a7 100644 --- a/lib/subghz/protocols/firefly.c +++ b/lib/subghz/protocols/firefly.c @@ -6,12 +6,6 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -/* - * Help - * https://phreakerclub.com/447 - * - */ - #define TAG "SubGhzProtocolFirefly" #define DIP_PATTERN "%c%c%c%c%c%c%c%c%c%c" diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 975cd29c8e1..9c6673e82a3 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -11,7 +11,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocolkeeloq" +#define TAG "SubGhzProtocolKeeloq" static const SubGhzBlockConst subghz_protocol_keeloq_const = { .te_short = 400, diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c index 12a1a547615..474b742ad5a 100644 --- a/lib/subghz/protocols/nero_sketch.c +++ b/lib/subghz/protocols/nero_sketch.c @@ -6,12 +6,6 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -/* - * Help - * https://phreakerclub.com/447 - * - */ - #define TAG "SubGhzProtocolNeroSketch" static const SubGhzBlockConst subghz_protocol_nero_sketch_const = { diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index 01371b7350e..6f94e8fdfc5 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -5,12 +5,6 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -/* - * Help - * https://phreakerclub.com/447 - * - */ - #define TAG "SubGhzProtocolNiceFLO" static const SubGhzBlockConst subghz_protocol_nice_flo_const = { diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 8a3e26a8a1f..1fe5876da87 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -5,6 +5,7 @@ #include "../blocks/encoder.h" #include "../blocks/generic.h" #include "../blocks/math.h" + /* * https://phreakerclub.com/1615 * https://phreakerclub.com/forum/showthread.php?t=2360 diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index 4fa2b481088..49d9a9cd3bc 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -12,7 +12,7 @@ * */ -#define TAG "SubGhzProtocolCAME" +#define TAG "SubGhzProtocolPrinceton" static const SubGhzBlockConst subghz_protocol_princeton_const = { .te_short = 400, @@ -28,6 +28,7 @@ struct SubGhzProtocolDecoderPrinceton { SubGhzBlockGeneric generic; uint32_t te; + uint32_t last_data; }; struct SubGhzProtocolEncoderPrinceton { @@ -241,15 +242,18 @@ void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t instance->decoder.parser_step = PrincetonDecoderStepSaveDuration; if(instance->decoder.decode_count_bit == subghz_protocol_princeton_const.min_count_bit_for_found) { - instance->te /= (instance->decoder.decode_count_bit * 4 + 1); - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - instance->generic.serial = instance->decoder.decode_data >> 4; - instance->generic.btn = (uint8_t)instance->decoder.decode_data & 0x00000F; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); + if(instance->last_data == instance->decoder.decode_data) { + instance->te /= (instance->decoder.decode_count_bit * 4 + 1); + + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + instance->generic.serial = instance->decoder.decode_data >> 4; + instance->generic.btn = (uint8_t)instance->decoder.decode_data & 0x00000F; + + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->last_data = instance->decoder.decode_data; } instance->decoder.decode_data = 0; instance->decoder.decode_count_bit = 0; diff --git a/lib/subghz/protocols/princeton_for_testing.c b/lib/subghz/protocols/princeton_for_testing.c index 1c4552f46d0..bdf5f4292d8 100644 --- a/lib/subghz/protocols/princeton_for_testing.c +++ b/lib/subghz/protocols/princeton_for_testing.c @@ -2,6 +2,7 @@ #include "furi_hal.h" #include "../blocks/math.h" + /* * Help * https://phreakerclub.com/447 From c5c0d2e8bcd83641fc7ce8b48f0d0812d483b2b2 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 5 May 2022 02:44:15 +0400 Subject: [PATCH 02/24] SubGhz: Add protocol Security+ 2.0 (#1193) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/subghz/blocks/generic.h | 2 +- lib/subghz/protocols/registry.c | 2 +- lib/subghz/protocols/registry.h | 1 + lib/subghz/protocols/secplus_v2.c | 475 ++++++++++++++++++++++++++++++ lib/subghz/protocols/secplus_v2.h | 74 +++++ 5 files changed, 552 insertions(+), 2 deletions(-) create mode 100644 lib/subghz/protocols/secplus_v2.c create mode 100644 lib/subghz/protocols/secplus_v2.h diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index 0d8fe0a2d33..1a7bca83b42 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -16,7 +16,7 @@ struct SubGhzBlockGeneric { uint32_t serial; uint8_t data_count_bit; uint8_t btn; - uint16_t cnt; + uint32_t cnt; }; /** diff --git a/lib/subghz/protocols/registry.c b/lib/subghz/protocols/registry.c index c384eda1182..2c6ad7e7d15 100644 --- a/lib/subghz/protocols/registry.c +++ b/lib/subghz/protocols/registry.c @@ -7,7 +7,7 @@ const SubGhzProtocol* subghz_protocol_registry[] = { &subghz_protocol_nero_sketch, &subghz_protocol_ido, &subghz_protocol_kia, &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis, &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_gate_tx, - &subghz_protocol_raw, &subghz_protocol_firefly, + &subghz_protocol_raw, &subghz_protocol_firefly, &subghz_protocol_secplus_v2, }; diff --git a/lib/subghz/protocols/registry.h b/lib/subghz/protocols/registry.h index 531caee2ac7..33f676141fa 100644 --- a/lib/subghz/protocols/registry.h +++ b/lib/subghz/protocols/registry.h @@ -22,6 +22,7 @@ #include "gate_tx.h" #include "raw.h" #include "firefly.h" +#include "secplus_v2.h" /** * Registration by name SubGhzProtocol. diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c new file mode 100644 index 00000000000..4ad1ea9ef61 --- /dev/null +++ b/lib/subghz/protocols/secplus_v2.c @@ -0,0 +1,475 @@ +#include "secplus_v2.h" +#include +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +/* +* Help +* https://github.com/argilo/secplus +* https://github.com/merbanan/rtl_433/blob/master/src/devices/secplus_v2.c +*/ + +#define TAG "SubGhzProtocoSecPlus_v2" + +#define SECPLUS_V2_HEADER 0x3C0000000000 +#define SECPLUS_V2_HEADER_MASK 0xFFFF3C0000000000 +#define SECPLUS_V2_PACKET_1 0x000000000000 +#define SECPLUS_V2_PACKET_2 0x010000000000 +#define SECPLUS_V2_PACKET_MASK 0x30000000000 + +static const SubGhzBlockConst subghz_protocol_secplus_v2_const = { + .te_short = 250, + .te_long = 500, + .te_delta = 110, + .min_count_bit_for_found = 62, +}; + +struct SubGhzProtocolDecoderSecPlus_v2 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + + ManchesterState manchester_saved_state; + uint64_t secplus_packet_1; +}; + +struct SubGhzProtocolEncoderSecPlus_v2 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + SecPlus_v2DecoderStepReset = 0, + SecPlus_v2DecoderStepDecoderData, +} SecPlus_v2DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_secplus_v2_decoder = { + .alloc = subghz_protocol_decoder_secplus_v2_alloc, + .free = subghz_protocol_decoder_secplus_v2_free, + + .feed = subghz_protocol_decoder_secplus_v2_feed, + .reset = subghz_protocol_decoder_secplus_v2_reset, + + .get_hash_data = subghz_protocol_decoder_secplus_v2_get_hash_data, + .serialize = subghz_protocol_decoder_secplus_v2_serialize, + .deserialize = subghz_protocol_decoder_secplus_v2_deserialize, + .get_string = subghz_protocol_decoder_secplus_v2_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_secplus_v2_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol subghz_protocol_secplus_v2 = { + .name = SUBGHZ_PROTOCOL_SECPLUS_V2_NAME, + .type = SubGhzProtocolTypeDynamic, + .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &subghz_protocol_secplus_v2_decoder, + .encoder = &subghz_protocol_secplus_v2_encoder, +}; + +void* subghz_protocol_decoder_secplus_v2_alloc(SubGhzEnvironment* environment) { + SubGhzProtocolDecoderSecPlus_v2* instance = malloc(sizeof(SubGhzProtocolDecoderSecPlus_v2)); + instance->base.protocol = &subghz_protocol_secplus_v2; + instance->generic.protocol_name = instance->base.protocol->name; + + return instance; +} + +void subghz_protocol_decoder_secplus_v2_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v2* instance = context; + free(instance); +} + +void subghz_protocol_decoder_secplus_v2_reset(void* context) { + furi_assert(context); + // SubGhzProtocolDecoderSecPlus_v2* instance = context; + // does not reset the decoder because you need to get 2 parts of the package +} + +static bool subghz_protocol_secplus_v2_check_packet(SubGhzProtocolDecoderSecPlus_v2* instance) { + if((instance->decoder.decode_data & SECPLUS_V2_HEADER_MASK) == SECPLUS_V2_HEADER) { + if((instance->decoder.decode_data & SECPLUS_V2_PACKET_MASK) == SECPLUS_V2_PACKET_1) { + instance->secplus_packet_1 = instance->decoder.decode_data; + } else if( + ((instance->decoder.decode_data & SECPLUS_V2_PACKET_MASK) == SECPLUS_V2_PACKET_2) && + (instance->secplus_packet_1)) { + return true; + } + } + return false; +} + +void subghz_protocol_decoder_secplus_v2_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v2* instance = context; + + ManchesterEvent event = ManchesterEventReset; + switch(instance->decoder.parser_step) { + case SecPlus_v2DecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_long * 130) < + subghz_protocol_secplus_v2_const.te_delta * 100)) { + //Found header Security+ 2.0 + instance->decoder.parser_step = SecPlus_v2DecoderStepDecoderData; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->secplus_packet_1 = 0; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); + manchester_advance( + instance->manchester_saved_state, + ManchesterEventLongHigh, + &instance->manchester_saved_state, + NULL); + manchester_advance( + instance->manchester_saved_state, + ManchesterEventShortLow, + &instance->manchester_saved_state, + NULL); + } + break; + case SecPlus_v2DecoderStepDecoderData: + if(!level) { + if(DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_short) < + subghz_protocol_secplus_v2_const.te_delta) { + event = ManchesterEventShortLow; + } else if( + DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_long) < + subghz_protocol_secplus_v2_const.te_delta) { + event = ManchesterEventLongLow; + } else if( + duration >= (subghz_protocol_secplus_v2_const.te_long * 2 + + subghz_protocol_secplus_v2_const.te_delta)) { + if(instance->decoder.decode_count_bit >= + subghz_protocol_secplus_v2_const.min_count_bit_for_found) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + if(subghz_protocol_secplus_v2_check_packet(instance)) { + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + instance->decoder.parser_step = SecPlus_v2DecoderStepReset; + } + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); + manchester_advance( + instance->manchester_saved_state, + ManchesterEventLongHigh, + &instance->manchester_saved_state, + NULL); + manchester_advance( + instance->manchester_saved_state, + ManchesterEventShortLow, + &instance->manchester_saved_state, + NULL); + } else { + instance->decoder.parser_step = SecPlus_v2DecoderStepReset; + } + } else { + if(DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_short) < + subghz_protocol_secplus_v2_const.te_delta) { + event = ManchesterEventShortHigh; + } else if( + DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_long) < + subghz_protocol_secplus_v2_const.te_delta) { + event = ManchesterEventLongHigh; + } else { + instance->decoder.parser_step = SecPlus_v2DecoderStepReset; + } + } + if(event != ManchesterEventReset) { + bool data; + bool data_ok = manchester_advance( + instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); + + if(data_ok) { + instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; + instance->decoder.decode_count_bit++; + } + } + break; + } +} + +/** + * Security+ 2.0 half-message decoding + * @param data data + * @param roll_array[] return roll_array part + * @param fixed[] return fixed part + * @return true On success + */ + +static bool + subghz_protocol_secplus_v2_decode_half(uint64_t data, uint8_t roll_array[], uint32_t* fixed) { + uint8_t order = (data >> 34) & 0x0f; + uint8_t invert = (data >> 30) & 0x0f; + uint16_t p[3] = {0}; + + for(int i = 29; i >= 0; i -= 3) { + p[0] = p[0] << 1 | bit_read(data, i); + p[1] = p[1] << 1 | bit_read(data, i - 1); + p[2] = p[2] << 1 | bit_read(data, i - 2); + } + + // selectively invert buffers + switch(invert) { + case 0x00: // 0b0000 (True, True, False), + p[0] = ~p[0] & 0x03FF; + p[1] = ~p[1] & 0x03FF; + break; + case 0x01: // 0b0001 (False, True, False), + p[1] = ~p[1] & 0x03FF; + break; + case 0x02: // 0b0010 (False, False, True), + p[2] = ~p[2] & 0x03FF; + break; + case 0x04: // 0b0100 (True, True, True), + p[0] = ~p[0] & 0x03FF; + p[1] = ~p[1] & 0x03FF; + p[2] = ~p[2] & 0x03FF; + break; + case 0x05: // 0b0101 (True, False, True), + case 0x0a: // 0b1010 (True, False, True), + p[0] = ~p[0] & 0x03FF; + p[2] = ~p[2] & 0x03FF; + break; + case 0x06: // 0b0110 (False, True, True), + p[1] = ~p[1] & 0x03FF; + p[2] = ~p[2] & 0x03FF; + break; + case 0x08: // 0b1000 (True, False, False), + p[0] = ~p[0] & 0x03FF; + break; + case 0x09: // 0b1001 (False, False, False), + break; + default: + FURI_LOG_E(TAG, "Invert FAIL"); + return false; + } + + uint16_t a = p[0], b = p[1], c = p[2]; + + // selectively reorder buffers + switch(order) { + case 0x06: // 0b0110 2, 1, 0], + case 0x09: // 0b1001 2, 1, 0], + p[2] = a; + p[1] = b; + p[0] = c; + break; + case 0x08: // 0b1000 1, 2, 0], + case 0x04: // 0b0100 1, 2, 0], + p[1] = a; + p[2] = b; + p[0] = c; + break; + case 0x01: // 0b0001 2, 0, 1], + p[2] = a; + p[0] = b; + p[1] = c; + break; + case 0x00: // 0b0000 0, 2, 1], + p[0] = a; + p[2] = b; + p[1] = c; + break; + case 0x05: // 0b0101 1, 0, 2], + p[1] = a; + p[0] = b; + p[2] = c; + break; + case 0x02: // 0b0010 0, 1, 2], + case 0x0A: // 0b1010 0, 1, 2], + p[0] = a; + p[1] = b; + p[2] = c; + break; + default: + FURI_LOG_E(TAG, "Order FAIL"); + return false; + } + + data = order << 4 | invert; + int k = 0; + for(int i = 6; i >= 0; i -= 2) { + roll_array[k++] = (data >> i) & 0x03; + if(roll_array[k] == 3) { + FURI_LOG_E(TAG, "Roll_Array FAIL"); + return false; + } + } + + for(int i = 8; i >= 0; i -= 2) { + roll_array[k++] = (p[2] >> i) & 0x03; + if(roll_array[k] == 3) { + FURI_LOG_E(TAG, "Roll_Array FAIL"); + return false; + } + } + + fixed[0] = p[0] << 10 | p[1]; + return true; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + * @param packet_1 first part of the message + */ +static void + subghz_protocol_secplus_v2_remote_controller(SubGhzBlockGeneric* instance, uint64_t packet_1) { + uint32_t fixed_1[1]; + uint8_t roll_1[9] = {0}; + uint32_t fixed_2[1]; + uint8_t roll_2[9] = {0}; + uint8_t rolling_digits[18] = {0}; + + if(subghz_protocol_secplus_v2_decode_half(packet_1, roll_1, fixed_1) && + subghz_protocol_secplus_v2_decode_half(instance->data, roll_2, fixed_2)) { + rolling_digits[0] = roll_2[8]; + rolling_digits[1] = roll_1[8]; + + rolling_digits[2] = roll_2[4]; + rolling_digits[3] = roll_2[5]; + rolling_digits[4] = roll_2[6]; + rolling_digits[5] = roll_2[7]; + + rolling_digits[6] = roll_1[4]; + rolling_digits[7] = roll_1[5]; + rolling_digits[8] = roll_1[6]; + rolling_digits[9] = roll_1[7]; + + rolling_digits[10] = roll_2[0]; + rolling_digits[11] = roll_2[1]; + rolling_digits[12] = roll_2[2]; + rolling_digits[13] = roll_2[3]; + + rolling_digits[14] = roll_1[0]; + rolling_digits[15] = roll_1[1]; + rolling_digits[16] = roll_1[2]; + rolling_digits[17] = roll_1[3]; + + uint32_t rolling = 0; + for(int i = 0; i < 18; i++) { + rolling = (rolling * 3) + rolling_digits[i]; + } + // Max value = 2^28 (268435456) + if(rolling >= 0x10000000) { + FURI_LOG_E(TAG, "Rolling FAIL"); + instance->cnt = 0; + instance->btn = 0; + instance->serial = 0; + } else { + instance->cnt = subghz_protocol_blocks_reverse_key(rolling, 28); + instance->btn = fixed_1[0] >> 12; + instance->serial = fixed_1[0] << 20 | fixed_2[0]; + } + } else { + instance->cnt = 0; + instance->btn = 0; + instance->serial = 0; + } +} + +uint8_t subghz_protocol_decoder_secplus_v2_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v2* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +bool subghz_protocol_decoder_secplus_v2_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v2* instance = context; + bool res = + subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + + 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->secplus_packet_1 >> i * 8) & 0xFF; + } + + if(res && + !flipper_format_write_hex(flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Unable to add Secplus_packet_1"); + res = false; + } + return res; +} + +bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v2* instance = context; + bool res = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + FURI_LOG_E(TAG, "Deserialize error"); + break; + } + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + uint8_t key_data[sizeof(uint64_t)] = {0}; + if(!flipper_format_read_hex( + flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Missing Secplus_packet_1"); + break; + } + for(uint8_t i = 0; i < sizeof(uint64_t); i++) { + instance->secplus_packet_1 = instance->secplus_packet_1 << 8 | key_data[i]; + } + res = true; + } while(false); + + return res; +} + +void subghz_protocol_decoder_secplus_v2_get_string(void* context, string_t output) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v2* instance = context; + subghz_protocol_secplus_v2_remote_controller(&instance->generic, instance->secplus_packet_1); + + string_cat_printf( + output, + "%s %db\r\n" + "Pk1:0x%lX%08lX\r\n" + "Pk2:0x%lX%08lX\r\n" + "Sn:0x%08lX Btn:0x%01X\r\n" + "Cnt:0x%03X\r\n", + + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->secplus_packet_1 >> 32), + (uint32_t)instance->secplus_packet_1, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)instance->generic.data, + instance->generic.serial, + instance->generic.btn, + instance->generic.cnt); +} diff --git a/lib/subghz/protocols/secplus_v2.h b/lib/subghz/protocols/secplus_v2.h new file mode 100644 index 00000000000..dbb1e1bd212 --- /dev/null +++ b/lib/subghz/protocols/secplus_v2.h @@ -0,0 +1,74 @@ +#pragma once +#include "base.h" + +#define SUBGHZ_PROTOCOL_SECPLUS_V2_NAME "Security+ 2.0" + +typedef struct SubGhzProtocolDecoderSecPlus_v2 SubGhzProtocolDecoderSecPlus_v2; +typedef struct SubGhzProtocolEncoderSecPlus_v2 SubGhzProtocolEncoderSecPlus_v2; + +extern const SubGhzProtocolDecoder subghz_protocol_secplus_v2_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_secplus_v2_encoder; +extern const SubGhzProtocol subghz_protocol_secplus_v2; + +/** + * Allocate SubGhzProtocolDecoderSecPlus_v2. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderSecPlus_v2* pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + */ +void* subghz_protocol_decoder_secplus_v2_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderSecPlus_v2. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + */ +void subghz_protocol_decoder_secplus_v2_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderSecPlus_v2. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + */ +void subghz_protocol_decoder_secplus_v2_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_secplus_v2_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_secplus_v2_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderSecPlus_v2. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param frequency The frequency at which the signal was received, Hz + * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @return true On success + */ +bool subghz_protocol_decoder_secplus_v2_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset); + +/** + * Deserialize data SubGhzProtocolDecoderSecPlus_v2. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_secplus_v2_get_string(void* context, string_t output); From 0c85b8887335112483ff64a82a2a028e2c7bde6c Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 5 May 2022 01:51:45 +0300 Subject: [PATCH 03/24] [FL-2512] Archive favourites fixes (#1195) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Archive favourites fixes * Archive: navigation history fix Co-authored-by: あく --- applications/archive/helpers/archive_browser.c | 4 ++-- applications/archive/scenes/archive_scene_browser.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c index b1e1e3efbbd..cbe57c06e2a 100644 --- a/applications/archive/helpers/archive_browser.c +++ b/applications/archive/helpers/archive_browser.c @@ -80,6 +80,7 @@ void archive_set_item_count(ArchiveBrowserView* browser, uint32_t count) { model->item_idx = CLAMP(model->item_idx, model->item_cnt - 1, 0); return false; }); + archive_update_offset(browser); } void archive_file_array_rm_selected(ArchiveBrowserView* browser) { @@ -396,8 +397,6 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) { return; } - archive_dir_count_items(browser, string_get_cstr(name)); - if(string_cmp(browser->path, name) != 0) { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { @@ -410,6 +409,7 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) { string_set(browser->path, name); } + archive_dir_count_items(browser, string_get_cstr(name)); archive_switch_dir(browser, string_get_cstr(browser->path)); } diff --git a/applications/archive/scenes/archive_scene_browser.c b/applications/archive/scenes/archive_scene_browser.c index bcfd63ba530..0091bc9938c 100644 --- a/applications/archive/scenes/archive_scene_browser.c +++ b/applications/archive/scenes/archive_scene_browser.c @@ -95,6 +95,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { if(known_app) { archive_run_in_app(browser, selected); } + archive_show_file_menu(browser, false); consumed = true; break; case ArchiveBrowserEventFileMenuPin: From f5175e13881398cf0461be6081745a93dfc09e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 5 May 2022 12:49:59 +0300 Subject: [PATCH 04/24] Music player rework (#1189) * Music player: cli tool and new worker * Music player cli: flush message * Music player: fix note calculation * MusicPlayer: fix # parsing and add magic * FuriHal: improve speaker volume handling. MusicPlayer: minor sustain improvements * MusicPlayer: fix buffer overseek * FuriHal: drop unused variables * MusicPlayer: LFO 4 magic * MusicPlayer: add RTTTL parser * MusicPlayer: refactoring and add file open dialog on start * MusicPlayer: fix memcpy issue and more * FuriHal: force disconnect USB on early init and then leave usb line alone for some time. * FuriHal: switch speaker to old volume. MusicPlayer: fix incorrect note history, and drop lfo from worker. Co-authored-by: DrZlo13 --- applications/applications.c | 7 +- applications/music_player/music_player.c | 548 +++++++----------- applications/music_player/music_player_cli.c | 46 ++ .../music_player/music_player_worker.c | 496 ++++++++++++++++ .../music_player/music_player_worker.h | 36 ++ assets/resources/Manifest | 4 +- .../resources/music_player/Marble_Machine.fmf | 6 + .../targets/f7/furi_hal/furi_hal_resources.c | 10 + .../targets/f7/furi_hal/furi_hal_speaker.c | 54 +- .../furi_hal_include/furi_hal_speaker.h | 2 + 10 files changed, 866 insertions(+), 343 deletions(-) create mode 100644 applications/music_player/music_player_cli.c create mode 100644 applications/music_player/music_player_worker.c create mode 100644 applications/music_player/music_player_worker.h create mode 100644 assets/resources/music_player/Marble_Machine.fmf diff --git a/applications/applications.c b/applications/applications.c index b9e8bbd4776..4deae885b40 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -55,6 +55,7 @@ extern void crypto_on_system_start(); extern void ibutton_on_system_start(); extern void infrared_on_system_start(); extern void lfrfid_on_system_start(); +extern void music_player_on_system_start(); extern void nfc_on_system_start(); extern void storage_on_system_start(); extern void subghz_on_system_start(); @@ -280,6 +281,10 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { infrared_on_system_start, #endif +#ifdef APP_MUSIC_PLAYER + music_player_on_system_start, +#endif + #ifdef APP_NFC nfc_on_system_start, #endif @@ -332,7 +337,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = { #ifdef APP_MUSIC_PLAYER {.app = music_player_app, .name = "Music Player", - .stack_size = 1024, + .stack_size = 2048, .icon = &A_Plugins_14, .flags = FlipperApplicationFlagDefault}, #endif diff --git a/applications/music_player/music_player.c b/applications/music_player/music_player.c index 4f8813d6868..73f4bd2c829 100644 --- a/applications/music_player/music_player.c +++ b/applications/music_player/music_player.c @@ -2,132 +2,93 @@ #include #include -#include - -// TODO float note freq -typedef enum { - // Delay - N = 0, - // Octave 4 - B4 = 494, - // Octave 5 - C5 = 523, - D5 = 587, - E5 = 659, - F_5 = 740, - G5 = 784, - A5 = 880, - B5 = 988, - // Octave 6 - C6 = 1046, - D6 = 1175, - E6 = 1319, -} MelodyEventNote; - -typedef enum { - L1 = 1, - L2 = 2, - L4 = 4, - L8 = 8, - L16 = 16, - L32 = 32, - L64 = 64, - L128 = 128, -} MelodyEventLength; +#include +#include "music_player_worker.h" -typedef struct { - MelodyEventNote note; - MelodyEventLength length; -} MelodyEventRecord; +#define TAG "MusicPlayer" -typedef struct { - const MelodyEventRecord* record; - int8_t loop_count; -} SongPattern; - -const MelodyEventRecord melody_start[] = { - {E6, L8}, {N, L8}, {E5, L8}, {B5, L8}, {N, L4}, {E5, L8}, {A5, L8}, {G5, L8}, {A5, L8}, - {E5, L8}, {B5, L8}, {N, L8}, {G5, L8}, {A5, L8}, {D6, L8}, {N, L4}, {D5, L8}, {B5, L8}, - {N, L4}, {D5, L8}, {A5, L8}, {G5, L8}, {A5, L8}, {D5, L8}, {F_5, L8}, {N, L8}, {G5, L8}, - {A5, L8}, {D6, L8}, {N, L4}, {F_5, L8}, {B5, L8}, {N, L4}, {F_5, L8}, {D6, L8}, {C6, L8}, - {B5, L8}, {F_5, L8}, {A5, L8}, {N, L8}, {G5, L8}, {F_5, L8}, {E5, L8}, {N, L8}, {C5, L8}, - {E5, L8}, {B5, L8}, {B4, L8}, {C5, L8}, {D5, L8}, {D6, L8}, {C6, L8}, {B5, L8}, {F_5, L8}, - {A5, L8}, {N, L8}, {G5, L8}, {A5, L8}, {E6, L8}}; - -const MelodyEventRecord melody_loop[] = { - {N, L4}, {E5, L8}, {B5, L8}, {N, L4}, {E5, L8}, {A5, L8}, {G5, L8}, {A5, L8}, {E5, L8}, - {B5, L8}, {N, L8}, {G5, L8}, {A5, L8}, {D6, L8}, {N, L4}, {D5, L8}, {B5, L8}, {N, L4}, - {D5, L8}, {A5, L8}, {G5, L8}, {A5, L8}, {D5, L8}, {F_5, L8}, {N, L8}, {G5, L8}, {A5, L8}, - {D6, L8}, {N, L4}, {F_5, L8}, {B5, L8}, {N, L4}, {F_5, L8}, {D6, L8}, {C6, L8}, {B5, L8}, - {F_5, L8}, {A5, L8}, {N, L8}, {G5, L8}, {F_5, L8}, {E5, L8}, {N, L8}, {C5, L8}, {E5, L8}, - {B5, L8}, {B4, L8}, {C5, L8}, {D5, L8}, {D6, L8}, {C6, L8}, {B5, L8}, {F_5, L8}, {A5, L8}, - {N, L8}, {G5, L8}, {A5, L8}, {E6, L8}}; - -const MelodyEventRecord melody_chords_1bar[] = { - {E6, L8}, {N, L8}, {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, - {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, - {B4, L128}, {E5, L128}, {B5, L8}, {N, L4}, {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, - {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, - {B4, L128}, {E5, L128}, {B4, L128}, {E5, L128}, {A5, L8}}; - -const SongPattern song[] = {{melody_start, 1}, {melody_loop, -1}}; - -typedef enum { - EventTypeTick, - EventTypeKey, - EventTypeNote, - // add your events type -} MusicDemoEventType; +#define MUSIC_PLAYER_APP_PATH_FOLDER "/any/music_player" +#define MUSIC_PLAYER_APP_EXTENSION "*" -typedef struct { - union { - InputEvent input; - const MelodyEventRecord* note_record; - } value; - MusicDemoEventType type; -} MusicDemoEvent; +#define MUSIC_PLAYER_SEMITONE_HISTORY_SIZE 4 typedef struct { - ValueMutex* state_mutex; - osMessageQueueId_t event_queue; + uint8_t semitone_history[MUSIC_PLAYER_SEMITONE_HISTORY_SIZE]; + uint8_t duration_history[MUSIC_PLAYER_SEMITONE_HISTORY_SIZE]; -} MusicDemoContext; + uint8_t volume; + uint8_t semitone; + uint8_t dots; + uint8_t duration; + float position; +} MusicPlayerModel; -#define note_stack_size 4 typedef struct { - // describe state here - const MelodyEventRecord* note_record; - const MelodyEventRecord* note_stack[note_stack_size]; - uint8_t volume_id; - uint8_t volume_id_max; -} State; - -const float volumes[] = {0, .25, .5, .75, 1}; - -bool is_white_note(const MelodyEventRecord* note_record, uint8_t id) { - if(note_record == NULL) return false; + MusicPlayerModel* model; + osMutexId_t* model_mutex; + + osMessageQueueId_t input_queue; + + ViewPort* view_port; + Gui* gui; + + MusicPlayerWorker* worker; +} MusicPlayer; + +static const float MUSIC_PLAYER_VOLUMES[] = {0, .25, .5, .75, 1}; + +static const char* semitone_to_note(int8_t semitone) { + switch(semitone) { + case 0: + return "C"; + case 1: + return "C#"; + case 2: + return "D"; + case 3: + return "D#"; + case 4: + return "E"; + case 5: + return "F"; + case 6: + return "F#"; + case 7: + return "G"; + case 8: + return "G#"; + case 9: + return "A"; + case 10: + return "A#"; + case 11: + return "B"; + default: + return "--"; + } +} - switch(note_record->note) { - case C5: - case C6: +static bool is_white_note(uint8_t semitone, uint8_t id) { + switch(semitone) { + case 0: if(id == 0) return true; break; - case D5: - case D6: + case 2: if(id == 1) return true; break; - case E5: - case E6: + case 4: if(id == 2) return true; break; - case G5: + case 5: + if(id == 3) return true; + break; + case 7: if(id == 4) return true; break; - case A5: + case 9: if(id == 5) return true; break; - case B4: - case B5: + case 11: if(id == 6) return true; break; default: @@ -137,101 +98,33 @@ bool is_white_note(const MelodyEventRecord* note_record, uint8_t id) { return false; } -bool is_black_note(const MelodyEventRecord* note_record, uint8_t id) { - if(note_record == NULL) return false; - - switch(note_record->note) { - case F_5: - if(id == 3) return true; - break; - default: - break; - } - - return false; -} - -const char* get_note_name(const MelodyEventRecord* note_record) { - if(note_record == NULL) return ""; - - switch(note_record->note) { - case N: - return "---"; - break; - case B4: - return "B4-"; - break; - case C5: - return "C5-"; - break; - case D5: - return "D5-"; - break; - case E5: - return "E5-"; - break; - case F_5: - return "F#5"; - break; - case G5: - return "G5-"; - break; - case A5: - return "A5-"; +static bool is_black_note(uint8_t semitone, uint8_t id) { + switch(semitone) { + case 1: + if(id == 0) return true; break; - case B5: - return "B5-"; + case 3: + if(id == 1) return true; break; - case C6: - return "C6-"; + case 6: + if(id == 3) return true; break; - case D6: - return "D6-"; + case 8: + if(id == 4) return true; break; - case E6: - return "E6-"; + case 10: + if(id == 5) return true; break; default: - return "UNK"; break; } -} -const char* get_note_len_name(const MelodyEventRecord* note_record) { - if(note_record == NULL) return ""; - switch(note_record->length) { - case L1: - return "1-"; - break; - case L2: - return "2-"; - break; - case L4: - return "4-"; - break; - case L8: - return "8-"; - break; - case L16: - return "16"; - break; - case L32: - return "32"; - break; - case L64: - return "64"; - break; - case L128: - return "1+"; - break; - default: - return "--"; - break; - } + return false; } static void render_callback(Canvas* canvas, void* ctx) { - State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); + MusicPlayer* music_player = ctx; + furi_check(osMutexAcquire(music_player->model_mutex, osWaitForever) == osOK); canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); @@ -250,7 +143,7 @@ static void render_callback(Canvas* canvas, void* ctx) { // white keys for(size_t i = 0; i < 7; i++) { - if(is_white_note(state->note_record, i)) { + if(is_white_note(music_player->model->semitone, i)) { canvas_draw_box(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); } else { canvas_draw_frame(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); @@ -264,7 +157,7 @@ static void render_callback(Canvas* canvas, void* ctx) { canvas_draw_box( canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); canvas_set_color(canvas, ColorBlack); - if(is_black_note(state->note_record, i)) { + if(is_black_note(music_player->model->semitone, i)) { canvas_draw_box( canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); } else { @@ -277,7 +170,8 @@ static void render_callback(Canvas* canvas, void* ctx) { // volume view_port x_pos = 124; y_pos = 0; - const uint8_t volume_h = (64 / (state->volume_id_max - 1)) * state->volume_id; + const uint8_t volume_h = + (64 / (COUNT_OF(MUSIC_PLAYER_VOLUMES) - 1)) * music_player->model->volume; canvas_draw_frame(canvas, x_pos, y_pos, 4, 64); canvas_draw_box(canvas, x_pos, y_pos + (64 - volume_h), 4, volume_h); @@ -289,171 +183,175 @@ static void render_callback(Canvas* canvas, void* ctx) { canvas_draw_frame(canvas, x_pos, y_pos, 49, 64); canvas_draw_line(canvas, x_pos + 28, 0, x_pos + 28, 64); - for(uint8_t i = 0; i < note_stack_size; i++) { + char duration_text[16]; + for(uint8_t i = 0; i < MUSIC_PLAYER_SEMITONE_HISTORY_SIZE; i++) { + if(music_player->model->duration_history[i] == 0xFF) { + snprintf(duration_text, 15, "--"); + } else { + snprintf(duration_text, 15, "%d", music_player->model->duration_history[i]); + } + if(i == 0) { canvas_draw_box(canvas, x_pos, y_pos + 48, 49, 16); canvas_set_color(canvas, ColorWhite); } else { canvas_set_color(canvas, ColorBlack); } - canvas_draw_str(canvas, x_pos + 4, 64 - 16 * i - 3, get_note_name(state->note_stack[i])); canvas_draw_str( - canvas, x_pos + 31, 64 - 16 * i - 3, get_note_len_name(state->note_stack[i])); + canvas, + x_pos + 4, + 64 - 16 * i - 3, + semitone_to_note(music_player->model->semitone_history[i])); + canvas_draw_str(canvas, x_pos + 31, 64 - 16 * i - 3, duration_text); canvas_draw_line(canvas, x_pos, 64 - 16 * i, x_pos + 48, 64 - 16 * i); } - release_mutex((ValueMutex*)ctx, state); + osMutexRelease(music_player->model_mutex); } static void input_callback(InputEvent* input_event, void* ctx) { - osMessageQueueId_t event_queue = ctx; - - MusicDemoEvent event; - event.type = EventTypeKey; - event.value.input = *input_event; - osMessageQueuePut(event_queue, &event, 0, 0); + MusicPlayer* music_player = ctx; + if(input_event->type == InputTypeShort) { + osMessageQueuePut(music_player->input_queue, input_event, 0, 0); + } } -void process_note( - const MelodyEventRecord* note_record, - float bar_length_ms, - MusicDemoContext* context) { - MusicDemoEvent event; - // send note event - event.type = EventTypeNote; - event.value.note_record = note_record; - osMessageQueuePut(context->event_queue, &event, 0, 0); - - // read volume - State* state = (State*)acquire_mutex(context->state_mutex, 25); - float volume = volumes[state->volume_id]; - release_mutex(context->state_mutex, state); - - // play note - float note_delay = bar_length_ms / (float)note_record->length; - if(note_record->note != N) { - furi_hal_speaker_start(note_record->note, volume); +static void music_player_worker_callback( + uint8_t semitone, + uint8_t dots, + uint8_t duration, + float position, + void* context) { + MusicPlayer* music_player = context; + furi_check(osMutexAcquire(music_player->model_mutex, osWaitForever) == osOK); + + for(size_t i = 0; i < MUSIC_PLAYER_SEMITONE_HISTORY_SIZE - 1; i++) { + size_t r = MUSIC_PLAYER_SEMITONE_HISTORY_SIZE - 1 - i; + music_player->model->duration_history[r] = music_player->model->duration_history[r - 1]; + music_player->model->semitone_history[r] = music_player->model->semitone_history[r - 1]; } - furi_hal_delay_ms(note_delay); - furi_hal_speaker_stop(); + + semitone = (semitone == 0xFF) ? 0xFF : semitone % 12; + + music_player->model->semitone = semitone; + music_player->model->dots = dots; + music_player->model->duration = duration; + music_player->model->position = position; + + music_player->model->semitone_history[0] = semitone; + music_player->model->duration_history[0] = duration; + + osMutexRelease(music_player->model_mutex); + view_port_update(music_player->view_port); } -void music_player_thread(void* p) { - MusicDemoContext* context = (MusicDemoContext*)p; +MusicPlayer* music_player_alloc() { + MusicPlayer* instance = malloc(sizeof(MusicPlayer)); - const float bpm = 130.0f; - // 4/4 - const float bar_length_ms = (60.0f * 1000.0f / bpm) * 4; - const uint16_t melody_start_events_count = sizeof(melody_start) / sizeof(melody_start[0]); - const uint16_t melody_loop_events_count = sizeof(melody_loop) / sizeof(melody_loop[0]); + instance->model = malloc(sizeof(MusicPlayerModel)); + memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); + memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); + instance->model->volume = 3; - for(size_t i = 0; i < melody_start_events_count; i++) { - process_note(&melody_start[i], bar_length_ms, context); - } + instance->model_mutex = osMutexNew(NULL); - while(1) { - for(size_t i = 0; i < melody_loop_events_count; i++) { - process_note(&melody_loop[i], bar_length_ms, context); - } - } + instance->input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); + + instance->worker = music_player_worker_alloc(); + music_player_worker_set_volume( + instance->worker, MUSIC_PLAYER_VOLUMES[instance->model->volume]); + music_player_worker_set_callback(instance->worker, music_player_worker_callback, instance); + + instance->view_port = view_port_alloc(); + view_port_draw_callback_set(instance->view_port, render_callback, instance); + view_port_input_callback_set(instance->view_port, input_callback, instance); + + // Open GUI and register view_port + instance->gui = furi_record_open("gui"); + gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); + + return instance; +} + +void music_player_free(MusicPlayer* instance) { + gui_remove_view_port(instance->gui, instance->view_port); + furi_record_close("gui"); + view_port_free(instance->view_port); + + music_player_worker_free(instance->worker); + + osMessageQueueDelete(instance->input_queue); + + osMutexDelete(instance->model_mutex); + + free(instance->model); + free(instance); } int32_t music_player_app(void* p) { - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(MusicDemoEvent), NULL); + MusicPlayer* music_player = music_player_alloc(); - State _state; - _state.note_record = NULL; - for(size_t i = 0; i < note_stack_size; i++) { - _state.note_stack[i] = NULL; - } - _state.volume_id = 1; - _state.volume_id_max = sizeof(volumes) / sizeof(volumes[0]); + string_t file_path; + string_init(file_path); - ValueMutex state_mutex; - if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("cannot create mutex\r\n"); - return 255; - } + do { + if(p) { + string_cat_str(file_path, p); + } else { + char* file_name = malloc(256); + DialogsApp* dialogs = furi_record_open("dialogs"); + bool res = dialog_file_select_show( + dialogs, + MUSIC_PLAYER_APP_PATH_FOLDER, + MUSIC_PLAYER_APP_EXTENSION, + file_name, + 255, + NULL); + furi_record_close("dialogs"); + if(!res) { + FURI_LOG_E(TAG, "No file selected"); + break; + } + string_cat_str(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); + string_cat_str(file_path, "/"); + string_cat_str(file_path, file_name); + free(file_name); + } - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, &state_mutex); - view_port_input_callback_set(view_port, input_callback, event_queue); + if(!music_player_worker_load(music_player->worker, string_get_cstr(file_path))) { + FURI_LOG_E(TAG, "Unable to load file"); + break; + } - // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - // start player thread - // TODO change to fuirac_start - osThreadAttr_t player_attr = {.name = "music_player_thread", .stack_size = 512}; - MusicDemoContext context = {.state_mutex = &state_mutex, .event_queue = event_queue}; - osThreadId_t player = osThreadNew(music_player_thread, &context, &player_attr); - - if(player == NULL) { - printf("cannot create player thread\r\n"); - return 255; - } + music_player_worker_start(music_player->worker); - MusicDemoEvent event; - while(1) { - osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100); - - State* state = (State*)acquire_mutex_block(&state_mutex); - - if(event_status == osOK) { - if(event.type == EventTypeKey) { - // press events - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyBack) { - release_mutex(&state_mutex, state); - break; - } - - if(event.value.input.type == InputTypePress && - event.value.input.key == InputKeyUp) { - if(state->volume_id < state->volume_id_max - 1) state->volume_id++; - } - - if(event.value.input.type == InputTypePress && - event.value.input.key == InputKeyDown) { - if(state->volume_id > 0) state->volume_id--; - } - - if(event.value.input.type == InputTypePress && - event.value.input.key == InputKeyLeft) { - } - - if(event.value.input.type == InputTypePress && - event.value.input.key == InputKeyRight) { - } - - if(event.value.input.key == InputKeyOk) { - } - - } else if(event.type == EventTypeNote) { - state->note_record = event.value.note_record; - - for(size_t i = note_stack_size - 1; i > 0; i--) { - state->note_stack[i] = state->note_stack[i - 1]; - } - state->note_stack[0] = state->note_record; + InputEvent input; + while(osMessageQueueGet(music_player->input_queue, &input, NULL, osWaitForever) == osOK) { + furi_check(osMutexAcquire(music_player->model_mutex, osWaitForever) == osOK); + + if(input.key == InputKeyBack) { + osMutexRelease(music_player->model_mutex); + break; + } else if(input.key == InputKeyUp) { + if(music_player->model->volume < COUNT_OF(MUSIC_PLAYER_VOLUMES) - 1) + music_player->model->volume++; + music_player_worker_set_volume( + music_player->worker, MUSIC_PLAYER_VOLUMES[music_player->model->volume]); + } else if(input.key == InputKeyDown) { + if(music_player->model->volume > 0) music_player->model->volume--; + music_player_worker_set_volume( + music_player->worker, MUSIC_PLAYER_VOLUMES[music_player->model->volume]); } - } else { - // event timeout + + osMutexRelease(music_player->model_mutex); + view_port_update(music_player->view_port); } - view_port_update(view_port); - release_mutex(&state_mutex, state); - } + music_player_worker_stop(music_player->worker); + } while(0); - osThreadTerminate(player); - furi_hal_speaker_stop(); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close("gui"); - view_port_free(view_port); - osMessageQueueDelete(event_queue); - delete_mutex(&state_mutex); + string_clear(file_path); + music_player_free(music_player); return 0; } diff --git a/applications/music_player/music_player_cli.c b/applications/music_player/music_player_cli.c new file mode 100644 index 00000000000..3c76cb84057 --- /dev/null +++ b/applications/music_player/music_player_cli.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include "music_player_worker.h" + +static void music_player_cli(Cli* cli, string_t args, void* context) { + MusicPlayerWorker* music_player_worker = music_player_worker_alloc(); + Storage* storage = furi_record_open("storage"); + + do { + if(storage_common_stat(storage, string_get_cstr(args), NULL) == FSE_OK) { + if(!music_player_worker_load(music_player_worker, string_get_cstr(args))) { + printf("Failed to open file %s\r\n", string_get_cstr(args)); + break; + } + } else { + if(!music_player_worker_load_rtttl_from_string( + music_player_worker, string_get_cstr(args))) { + printf("Argument is not a file or RTTTL\r\n"); + break; + } + } + + printf("Press CTRL+C to stop\r\n"); + music_player_worker_start(music_player_worker); + while(!cli_cmd_interrupt_received(cli)) { + osDelay(50); + } + music_player_worker_stop(music_player_worker); + } while(0); + + furi_record_close("storage"); + music_player_worker_free(music_player_worker); +} + +void music_player_on_system_start() { +#ifdef SRV_CLI + Cli* cli = furi_record_open("cli"); + + cli_add_command(cli, "music_player", CliCommandFlagDefault, music_player_cli, NULL); + + furi_record_close("cli"); +#else + UNUSED(music_player_cli); +#endif +} diff --git a/applications/music_player/music_player_worker.c b/applications/music_player/music_player_worker.c new file mode 100644 index 00000000000..2c80e6f5e8f --- /dev/null +++ b/applications/music_player/music_player_worker.c @@ -0,0 +1,496 @@ +#include "music_player_worker.h" + +#include +#include + +#include +#include + +#include + +#define TAG "MusicPlayerWorker" + +#define MUSIC_PLAYER_FILETYPE "Flipper Music Format" +#define MUSIC_PLAYER_VERSION 0 + +#define SEMITONE_PAUSE 0xFF + +#define NOTE_C4 261.63f +#define NOTE_C4_SEMITONE (4.0f * 12.0f) +#define TWO_POW_TWELTH_ROOT 1.059463094359f + +typedef struct { + uint8_t semitone; + uint8_t duration; + uint8_t dots; +} NoteBlock; + +ARRAY_DEF(NoteBlockArray, NoteBlock, M_POD_OPLIST); + +struct MusicPlayerWorker { + FuriThread* thread; + bool should_work; + + MusicPlayerWorkerCallback callback; + void* callback_context; + + float volume; + uint32_t bpm; + uint32_t duration; + uint32_t octave; + NoteBlockArray_t notes; +}; + +static int32_t music_player_worker_thread_callback(void* context) { + furi_assert(context); + MusicPlayerWorker* instance = context; + + NoteBlockArray_it_t it; + NoteBlockArray_it(it, instance->notes); + + while(instance->should_work) { + if(NoteBlockArray_end_p(it)) { + NoteBlockArray_it(it, instance->notes); + osDelay(10); + } else { + NoteBlock* note_block = NoteBlockArray_ref(it); + + float note_from_a4 = (float)note_block->semitone - NOTE_C4_SEMITONE; + float frequency = NOTE_C4 * powf(TWO_POW_TWELTH_ROOT, note_from_a4); + float duration = + 60.0 * osKernelGetTickFreq() * 4 / instance->bpm / note_block->duration; + while(note_block->dots > 0) { + duration += duration / 2; + note_block->dots--; + } + uint32_t next_tick = furi_hal_get_tick() + duration; + float volume = instance->volume; + + if(instance->callback) { + instance->callback( + note_block->semitone, + note_block->dots, + note_block->duration, + 0.0, + instance->callback_context); + } + + furi_hal_speaker_stop(); + furi_hal_speaker_start(frequency, volume); + while(instance->should_work && furi_hal_get_tick() < next_tick) { + volume *= 0.9945679; + furi_hal_speaker_set_volume(volume); + furi_hal_delay_ms(2); + } + NoteBlockArray_next(it); + } + } + + furi_hal_speaker_stop(); + + return 0; +} + +MusicPlayerWorker* music_player_worker_alloc() { + MusicPlayerWorker* instance = malloc(sizeof(MusicPlayerWorker)); + + NoteBlockArray_init(instance->notes); + + instance->thread = furi_thread_alloc(); + furi_thread_set_name(instance->thread, "MusicPlayerWorker"); + furi_thread_set_stack_size(instance->thread, 1024); + furi_thread_set_context(instance->thread, instance); + furi_thread_set_callback(instance->thread, music_player_worker_thread_callback); + + return instance; +} + +void music_player_worker_free(MusicPlayerWorker* instance) { + furi_assert(instance); + furi_thread_free(instance->thread); + NoteBlockArray_clear(instance->notes); + free(instance); +} + +static bool is_digit(const char c) { + return isdigit(c) != 0; +} + +static bool is_letter(const char c) { + return islower(c) != 0 || isupper(c) != 0; +} + +static bool is_space(const char c) { + return c == ' ' || c == '\t'; +} + +static size_t extract_number(const char* string, uint32_t* number) { + size_t ret = 0; + while(is_digit(*string)) { + *number *= 10; + *number += (*string - '0'); + string++; + ret++; + } + return ret; +} + +static size_t extract_dots(const char* string, uint32_t* number) { + size_t ret = 0; + while(*string == '.') { + *number += 1; + string++; + ret++; + } + return ret; +} + +static size_t extract_char(const char* string, char* symbol) { + if(is_letter(*string)) { + *symbol = *string; + return 1; + } else { + return 0; + } +} + +static size_t extract_sharp(const char* string, char* symbol) { + if(*string == '#' || *string == '_') { + *symbol = '#'; + return 1; + } else { + return 0; + } +} + +static size_t skip_till(const char* string, const char symbol) { + size_t ret = 0; + while(*string != '\0' && *string != symbol) { + string++; + ret++; + } + if(*string != symbol) { + ret = 0; + } + return ret; +} + +static bool music_player_worker_add_note( + MusicPlayerWorker* instance, + uint8_t semitone, + uint8_t duration, + uint8_t dots) { + NoteBlock note_block; + + note_block.semitone = semitone; + note_block.duration = duration; + note_block.dots = dots; + + NoteBlockArray_push_back(instance->notes, note_block); + + return true; +} + +static int8_t note_to_semitone(const char note) { + switch(note) { + case 'C': + return 0; + // C# + case 'D': + return 2; + // D# + case 'E': + return 4; + case 'F': + return 5; + // F# + case 'G': + return 7; + // G# + case 'A': + return 9; + // A# + case 'B': + return 11; + default: + return 0; + } +} + +static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const char* string) { + const char* cursor = string; + bool result = true; + + while(*cursor != '\0') { + if(!is_space(*cursor)) { + uint32_t duration = 0; + char note_char = '\0'; + char sharp_char = '\0'; + uint32_t octave = 0; + uint32_t dots = 0; + + // Parsing + cursor += extract_number(cursor, &duration); + cursor += extract_char(cursor, ¬e_char); + cursor += extract_sharp(cursor, &sharp_char); + cursor += extract_number(cursor, &octave); + cursor += extract_dots(cursor, &dots); + + // Post processing + note_char = toupper(note_char); + if(!duration) { + duration = instance->duration; + } + if(!octave) { + octave = instance->octave; + } + + // Validation + bool is_valid = true; + is_valid &= (duration >= 1 && duration <= 128); + is_valid &= ((note_char >= 'A' && note_char <= 'G') || note_char == 'P'); + is_valid &= (sharp_char == '#' || sharp_char == '\0'); + is_valid &= (octave >= 0 && octave <= 16); + is_valid &= (dots >= 0 && dots <= 16); + if(!is_valid) { + FURI_LOG_E( + TAG, + "Invalid note: %u%c%c%u.%u", + duration, + note_char == '\0' ? '_' : note_char, + sharp_char == '\0' ? '_' : sharp_char, + octave, + dots); + result = false; + break; + } + + // Note to semitones + uint8_t semitone = 0; + if(note_char == 'P') { + semitone = SEMITONE_PAUSE; + } else { + semitone += octave * 12; + semitone += note_to_semitone(note_char); + semitone += sharp_char == '#' ? 1 : 0; + } + + if(music_player_worker_add_note(instance, semitone, duration, dots)) { + FURI_LOG_D( + TAG, + "Added note: %c%c%u.%u = %u %u", + note_char == '\0' ? '_' : note_char, + sharp_char == '\0' ? '_' : sharp_char, + octave, + dots, + semitone, + duration); + } else { + FURI_LOG_E( + TAG, + "Invalid note: %c%c%u.%u = %u %u", + note_char == '\0' ? '_' : note_char, + sharp_char == '\0' ? '_' : sharp_char, + octave, + dots, + semitone, + duration); + } + cursor += skip_till(cursor, ','); + } + + if(*cursor != '\0') cursor++; + } + + return result; +} + +bool music_player_worker_load(MusicPlayerWorker* instance, const char* file_path) { + furi_assert(instance); + furi_assert(file_path); + + bool ret = false; + if(strcasestr(file_path, ".fmf")) { + ret = music_player_worker_load_fmf_from_file(instance, file_path); + } else { + ret = music_player_worker_load_rtttl_from_file(instance, file_path); + } + return ret; +} + +bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const char* file_path) { + furi_assert(instance); + furi_assert(file_path); + + bool result = false; + string_t temp_str; + string_init(temp_str); + + Storage* storage = furi_record_open("storage"); + FlipperFormat* file = flipper_format_file_alloc(storage); + + do { + if(!flipper_format_file_open_existing(file, file_path)) break; + + uint32_t version = 0; + if(!flipper_format_read_header(file, temp_str, &version)) break; + if(string_cmp_str(temp_str, MUSIC_PLAYER_FILETYPE) || (version != MUSIC_PLAYER_VERSION)) { + FURI_LOG_E(TAG, "Incorrect file format or version"); + break; + } + + if(!flipper_format_read_uint32(file, "BPM", &instance->bpm, 1)) { + FURI_LOG_E(TAG, "BPM is missing"); + break; + } + if(!flipper_format_read_uint32(file, "Duration", &instance->duration, 1)) { + FURI_LOG_E(TAG, "Duration is missing"); + break; + } + if(!flipper_format_read_uint32(file, "Octave", &instance->octave, 1)) { + FURI_LOG_E(TAG, "Octave is missing"); + break; + } + + if(!flipper_format_read_string(file, "Notes", temp_str)) { + FURI_LOG_E(TAG, "Notes is missing"); + break; + } + + if(!music_player_worker_parse_notes(instance, string_get_cstr(temp_str))) { + break; + } + + result = true; + } while(false); + + furi_record_close("storage"); + flipper_format_free(file); + string_clear(temp_str); + + return result; +} + +bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const char* file_path) { + furi_assert(instance); + furi_assert(file_path); + + bool result = false; + string_t content; + string_init(content); + Storage* storage = furi_record_open("storage"); + File* file = storage_file_alloc(storage); + + do { + if(!storage_file_open(file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E(TAG, "Unable to open file"); + break; + }; + + uint16_t ret = 0; + do { + uint8_t buffer[65] = {0}; + ret = storage_file_read(file, buffer, sizeof(buffer) - 1); + for(size_t i = 0; i < ret; i++) { + string_push_back(content, buffer[i]); + } + } while(ret > 0); + + string_strim(content); + if(!string_size(content)) { + FURI_LOG_E(TAG, "Empty file"); + break; + } + + if(!music_player_worker_load_rtttl_from_string(instance, string_get_cstr(content))) { + FURI_LOG_E(TAG, "Invalid file content"); + break; + } + + result = true; + } while(0); + + storage_file_free(file); + furi_record_close("storage"); + string_clear(content); + + return result; +} + +bool music_player_worker_load_rtttl_from_string(MusicPlayerWorker* instance, const char* string) { + furi_assert(instance); + + const char* cursor = string; + + // Skip name + cursor += skip_till(cursor, ':'); + if(*cursor != ':') { + return false; + } + + // Duration + cursor += skip_till(cursor, '='); + if(*cursor != '=') { + return false; + } + cursor++; + cursor += extract_number(cursor, &instance->duration); + + // Octave + cursor += skip_till(cursor, '='); + if(*cursor != '=') { + return false; + } + cursor++; + cursor += extract_number(cursor, &instance->octave); + + // BPM + cursor += skip_till(cursor, '='); + if(*cursor != '=') { + return false; + } + cursor++; + cursor += extract_number(cursor, &instance->bpm); + + // Notes + cursor += skip_till(cursor, ':'); + if(*cursor != ':') { + return false; + } + cursor++; + if(!music_player_worker_parse_notes(instance, cursor)) { + return false; + } + + return true; +} + +void music_player_worker_set_callback( + MusicPlayerWorker* instance, + MusicPlayerWorkerCallback callback, + void* context) { + furi_assert(instance); + instance->callback = callback; + instance->callback_context = context; +} + +void music_player_worker_set_volume(MusicPlayerWorker* instance, float volume) { + furi_assert(instance); + instance->volume = volume; +} + +void music_player_worker_start(MusicPlayerWorker* instance) { + furi_assert(instance); + furi_assert(instance->should_work == false); + + instance->should_work = true; + furi_thread_start(instance->thread); +} + +void music_player_worker_stop(MusicPlayerWorker* instance) { + furi_assert(instance); + furi_assert(instance->should_work == true); + + instance->should_work = false; + furi_thread_join(instance->thread); +} diff --git a/applications/music_player/music_player_worker.h b/applications/music_player/music_player_worker.h new file mode 100644 index 00000000000..3aa99ea370e --- /dev/null +++ b/applications/music_player/music_player_worker.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +typedef void (*MusicPlayerWorkerCallback)( + uint8_t semitone, + uint8_t dots, + uint8_t duration, + float position, + void* context); + +typedef struct MusicPlayerWorker MusicPlayerWorker; + +MusicPlayerWorker* music_player_worker_alloc(); + +void music_player_worker_free(MusicPlayerWorker* instance); + +bool music_player_worker_load(MusicPlayerWorker* instance, const char* file_path); + +bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const char* file_path); + +bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const char* file_path); + +bool music_player_worker_load_rtttl_from_string(MusicPlayerWorker* instance, const char* string); + +void music_player_worker_set_callback( + MusicPlayerWorker* instance, + MusicPlayerWorkerCallback callback, + void* context); + +void music_player_worker_set_volume(MusicPlayerWorker* instance, float volume); + +void music_player_worker_start(MusicPlayerWorker* instance); + +void music_player_worker_stop(MusicPlayerWorker* instance); diff --git a/assets/resources/Manifest b/assets/resources/Manifest index f19edd7dee0..08d95044144 100644 --- a/assets/resources/Manifest +++ b/assets/resources/Manifest @@ -1,8 +1,9 @@ V:0 -T:1651076680 +T:1651524332 D:badusb D:dolphin D:infrared +D:music_player D:nfc D:subghz D:u2f @@ -223,6 +224,7 @@ F:f267f0654781049ca323b11bb4375519:581:dolphin/L3_Lab_research_128x54/frame_9.bm F:41106c0cbc5144f151b2b2d3daaa0527:727:dolphin/L3_Lab_research_128x54/meta.txt D:infrared/assets F:d895fda2f48c6cc4c55e8a398ff52e43:74300:infrared/assets/tv.ir +F:a157a80f5a668700403d870c23b9567d:470:music_player/Marble_Machine.fmf D:nfc/assets F:c6826a621d081d68309e4be424d3d974:4715:nfc/assets/aid.nfc F:86efbebdf41bb6bf15cc51ef88f069d5:2565:nfc/assets/country_code.nfc diff --git a/assets/resources/music_player/Marble_Machine.fmf b/assets/resources/music_player/Marble_Machine.fmf new file mode 100644 index 00000000000..7403c9a0f15 --- /dev/null +++ b/assets/resources/music_player/Marble_Machine.fmf @@ -0,0 +1,6 @@ +Filetype: Flipper Music Format +Version: 0 +BPM: 130 +Duration: 8 +Octave: 5 +Notes: E6, P, E, B, 4P, E, A, G, A, E, B, P, G, A, D6, 4P, D, B, 4P, D, A, G, A, D, F#, P, G, A, D6, 4P, F#, B, 4P, F#, D6, C6, B, F#, A, P, G, F#, E, P, C, E, B, B4, C, D, D6, C6, B, F#, A, P, G, A, E6, 4P, E, B, 4P, E, A, G, A, E, B, P, G, A, D6, 4P, D, B, 4P, D, A, G, A, D, F#, P, G, A, D6, 4P, F#, B, 4P, F#, D6, C6, B, F#, A, P, G, F#, E, P, C, E, B, B4, C, D, D6, C6, B, F#, A, P, G, A, E6 diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index e548ffaf3d4..4209e0cf861 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -87,10 +88,19 @@ void furi_hal_resources_init_early() { SET_BIT(PWR->CR3, PWR_CR3_APC); // Hard reset USB + furi_hal_gpio_write(&gpio_usb_dm, 1); + furi_hal_gpio_write(&gpio_usb_dp, 1); furi_hal_gpio_init_simple(&gpio_usb_dm, GpioModeOutputOpenDrain); furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeOutputOpenDrain); furi_hal_gpio_write(&gpio_usb_dm, 0); furi_hal_gpio_write(&gpio_usb_dp, 0); + furi_hal_delay_us(5); // Device Driven disconnect: 2.5us + extra to compensate cables + furi_hal_gpio_write(&gpio_usb_dm, 1); + furi_hal_gpio_write(&gpio_usb_dp, 1); + furi_hal_gpio_init_simple(&gpio_usb_dm, GpioModeAnalog); + furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeAnalog); + furi_hal_gpio_write(&gpio_usb_dm, 0); + furi_hal_gpio_write(&gpio_usb_dp, 0); // External header pins furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); diff --git a/firmware/targets/f7/furi_hal/furi_hal_speaker.c b/firmware/targets/f7/furi_hal/furi_hal_speaker.c index 001861986e6..03a7f094bba 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_speaker.c +++ b/firmware/targets/f7/furi_hal/furi_hal_speaker.c @@ -20,15 +20,7 @@ void furi_hal_speaker_init() { &gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16); } -void furi_hal_speaker_start(float frequency, float volume) { - if(volume == 0) { - return; - } - - if(volume < 0) volume = 0; - if(volume > 1) volume = 1; - volume = volume * volume * volume; - +static inline uint32_t furi_hal_speaker_calculate_autoreload(float frequency) { uint32_t autoreload = (SystemCoreClock / FURI_HAL_SPEAKER_PRESCALER / frequency) - 1; if(autoreload < 2) { autoreload = 2; @@ -36,35 +28,65 @@ void furi_hal_speaker_start(float frequency, float volume) { autoreload = UINT16_MAX; } - LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = FURI_HAL_SPEAKER_PRESCALER - 1; - TIM_InitStruct.Autoreload = autoreload; - LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct); + return autoreload; +} + +static inline uint32_t furi_hal_speaker_calculate_compare(float volume) { + if(volume < 0) volume = 0; + if(volume > 1) volume = 1; + volume = volume * volume * volume; #ifdef FURI_HAL_SPEAKER_NEW_VOLUME uint32_t compare_value = volume * FURI_HAL_SPEAKER_MAX_VOLUME; - uint32_t clip_value = volume * TIM_InitStruct.Autoreload / 2; + uint32_t clip_value = volume * LL_TIM_GetAutoReload(FURI_HAL_SPEAKER_TIMER) / 2; if(compare_value > clip_value) { compare_value = clip_value; } #else - uint32_t compare_value = volume * autoreload / 2; + uint32_t compare_value = volume * LL_TIM_GetAutoReload(FURI_HAL_SPEAKER_TIMER) / 2; #endif if(compare_value == 0) { compare_value = 1; } + return compare_value; +} + +void furi_hal_speaker_start(float frequency, float volume) { + if(volume <= 0) { + furi_hal_speaker_stop(); + return; + } + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + TIM_InitStruct.Prescaler = FURI_HAL_SPEAKER_PRESCALER - 1; + TIM_InitStruct.Autoreload = furi_hal_speaker_calculate_autoreload(frequency); + LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct); + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE; - TIM_OC_InitStruct.CompareValue = compare_value; + TIM_OC_InitStruct.CompareValue = furi_hal_speaker_calculate_compare(volume); LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct); LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER); LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER); } +void furi_hal_speaker_set_volume(float volume) { + if(volume <= 0) { + furi_hal_speaker_stop(); + return; + } + +#if FURI_HAL_SPEAKER_CHANNEL == LL_TIM_CHANNEL_CH1 + LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, furi_hal_speaker_calculate_compare(volume)); +#else +#error Invalid channel +#endif +} + void furi_hal_speaker_stop() { LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER); LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER); diff --git a/firmware/targets/furi_hal_include/furi_hal_speaker.h b/firmware/targets/furi_hal_include/furi_hal_speaker.h index 35c89fb6923..67de41d9227 100644 --- a/firmware/targets/furi_hal_include/furi_hal_speaker.h +++ b/firmware/targets/furi_hal_include/furi_hal_speaker.h @@ -12,6 +12,8 @@ void furi_hal_speaker_init(); void furi_hal_speaker_start(float frequency, float volume); +void furi_hal_speaker_set_volume(float volume); + void furi_hal_speaker_stop(); #ifdef __cplusplus From 1ca98170d9ea9ea49ce30046ce99ade01bd0ca08 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 5 May 2022 17:42:50 +0400 Subject: [PATCH 05/24] SubGhz: add protocol Security+ 1.0 (#1197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: add protocol Security+ 1.0 * SubGhz: Fix unit_test Co-authored-by: あく --- applications/unit_tests/subghz/subghz_test.c | 3 +- lib/subghz/protocols/princeton.c | 1 + lib/subghz/protocols/registry.c | 1 + lib/subghz/protocols/registry.h | 1 + lib/subghz/protocols/secplus_v1.c | 369 +++++++++++++++++++ lib/subghz/protocols/secplus_v1.h | 74 ++++ 6 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 lib/subghz/protocols/secplus_v1.c create mode 100644 lib/subghz/protocols/secplus_v1.h diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index 48613868d30..6dc0f964ea8 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -13,7 +13,7 @@ #define CAME_ATOMO_DIR_NAME "/ext/subghz/assets/came_atomo" #define NICE_FLOR_S_DIR_NAME "/ext/subghz/assets/nice_flor_s" #define TEST_RANDOM_DIR_NAME "/ext/unit_tests/subghz/test_random_raw.sub" -#define TEST_RANDOM_COUNT_PARSE 101 +#define TEST_RANDOM_COUNT_PARSE 59 #define TEST_TIMEOUT 10000 static SubGhzEnvironment* environment_handler; @@ -29,6 +29,7 @@ static void subghz_test_rx_callback( string_t text; string_init(text); subghz_protocol_decoder_base_get_string(decoder_base, text); + subghz_receiver_reset(receiver_handler); FURI_LOG_I(TAG, "\r\n%s", string_get_cstr(text)); string_clear(text); subghz_test_decoder_count++; diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index 49d9a9cd3bc..42f035e6d93 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -210,6 +210,7 @@ void subghz_protocol_decoder_princeton_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderPrinceton* instance = context; instance->decoder.parser_step = PrincetonDecoderStepReset; + instance->last_data = 0; } void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t duration) { diff --git a/lib/subghz/protocols/registry.c b/lib/subghz/protocols/registry.c index 2c6ad7e7d15..a88603b64ac 100644 --- a/lib/subghz/protocols/registry.c +++ b/lib/subghz/protocols/registry.c @@ -8,6 +8,7 @@ const SubGhzProtocol* subghz_protocol_registry[] = { &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis, &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_gate_tx, &subghz_protocol_raw, &subghz_protocol_firefly, &subghz_protocol_secplus_v2, + &subghz_protocol_secplus_v1, }; diff --git a/lib/subghz/protocols/registry.h b/lib/subghz/protocols/registry.h index 33f676141fa..8d904fe1f59 100644 --- a/lib/subghz/protocols/registry.h +++ b/lib/subghz/protocols/registry.h @@ -23,6 +23,7 @@ #include "raw.h" #include "firefly.h" #include "secplus_v2.h" +#include "secplus_v1.h" /** * Registration by name SubGhzProtocol. diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c new file mode 100644 index 00000000000..1ad605b2f6f --- /dev/null +++ b/lib/subghz/protocols/secplus_v1.c @@ -0,0 +1,369 @@ +#include "secplus_v1.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +/* +* Help +* https://github.com/argilo/secplus +* https://github.com/merbanan/rtl_433/blob/master/src/devices/secplus_v1.c +*/ + +#define TAG "SubGhzProtocoSecPlus_v1" + +#define SECPLUS_V1_BIT_ERR -1 //0b0000 +#define SECPLUS_V1_BIT_0 0 //0b0001 +#define SECPLUS_V1_BIT_1 1 //0b0011 +#define SECPLUS_V1_BIT_2 2 //0b0111 + +#define SECPLUS_V1_PACKET_1_HEADER 0x00 +#define SECPLUS_V1_PACKET_2_HEADER 0x02 +#define SECPLUS_V1_PACKET_1_INDEX_BASE 0 +#define SECPLUS_V1_PACKET_2_INDEX_BASE 21 +#define SECPLUS_V1_PACKET_1_ACCEPTED (1 << 0) +#define SECPLUS_V1_PACKET_2_ACCEPTED (1 << 1) + +static const SubGhzBlockConst subghz_protocol_secplus_v1_const = { + .te_short = 500, + .te_long = 1500, + .te_delta = 100, + .min_count_bit_for_found = 21, +}; + +struct SubGhzProtocolDecoderSecPlus_v1 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + + uint8_t packet_accepted; + uint8_t base_packet_index; + uint8_t data_array[44]; +}; + +struct SubGhzProtocolEncoderSecPlus_v1 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + SecPlus_v1DecoderStepReset = 0, + SecPlus_v1DecoderStepSearchStartBit, + SecPlus_v1DecoderStepSaveDuration, + SecPlus_v1DecoderStepDecoderData, +} SecPlus_v1DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_secplus_v1_decoder = { + .alloc = subghz_protocol_decoder_secplus_v1_alloc, + .free = subghz_protocol_decoder_secplus_v1_free, + + .feed = subghz_protocol_decoder_secplus_v1_feed, + .reset = subghz_protocol_decoder_secplus_v1_reset, + + .get_hash_data = subghz_protocol_decoder_secplus_v1_get_hash_data, + .serialize = subghz_protocol_decoder_secplus_v1_serialize, + .deserialize = subghz_protocol_decoder_secplus_v1_deserialize, + .get_string = subghz_protocol_decoder_secplus_v1_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_secplus_v1_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol subghz_protocol_secplus_v1 = { + .name = SUBGHZ_PROTOCOL_SECPLUS_V1_NAME, + .type = SubGhzProtocolTypeDynamic, + .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &subghz_protocol_secplus_v1_decoder, + .encoder = &subghz_protocol_secplus_v1_encoder, +}; + +void* subghz_protocol_decoder_secplus_v1_alloc(SubGhzEnvironment* environment) { + SubGhzProtocolDecoderSecPlus_v1* instance = malloc(sizeof(SubGhzProtocolDecoderSecPlus_v1)); + instance->base.protocol = &subghz_protocol_secplus_v1; + instance->generic.protocol_name = instance->base.protocol->name; + + return instance; +} + +void subghz_protocol_decoder_secplus_v1_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v1* instance = context; + free(instance); +} + +void subghz_protocol_decoder_secplus_v1_reset(void* context) { + furi_assert(context); + // SubGhzProtocolDecoderSecPlus_v1* instance = context; + // does not reset the decoder because you need to get 2 parts of the package +} + +/** + * Security+ 1.0 half-message decoding + * @param instance SubGhzProtocolDecoderSecPlus_v1* + */ + +static void subghz_protocol_secplus_v1_decode(SubGhzProtocolDecoderSecPlus_v1* instance) { + uint32_t rolling = 0; + uint32_t fixed = 0; + uint32_t acc = 0; + uint8_t digit = 0; + + //decode packet 1 + for(uint8_t i = 1; i < 21; i += 2) { + digit = instance->data_array[i]; + rolling = (rolling * 3) + digit; + acc += digit; + + digit = (60 + instance->data_array[i + 1] - acc) % 3; + fixed = (fixed * 3) + digit; + acc += digit; + } + + acc = 0; + //decode packet 2 + for(uint8_t i = 22; i < 42; i += 2) { + digit = instance->data_array[i]; + rolling = (rolling * 3) + digit; + acc += digit; + + digit = (60 + instance->data_array[i + 1] - acc) % 3; + fixed = (fixed * 3) + digit; + acc += digit; + } + + rolling = subghz_protocol_blocks_reverse_key(rolling, 32); + instance->generic.data = (uint64_t)fixed << 32 | rolling; + + instance->generic.data_count_bit = + subghz_protocol_secplus_v1_const.min_count_bit_for_found * 2; +} + +void subghz_protocol_decoder_secplus_v1_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v1* instance = context; + + switch(instance->decoder.parser_step) { + case SecPlus_v1DecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 120) < + subghz_protocol_secplus_v1_const.te_delta * 120)) { + //Found header Security+ 1.0 + instance->decoder.parser_step = SecPlus_v1DecoderStepSearchStartBit; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->packet_accepted = 0; + memset(instance->data_array, 0, sizeof(instance->data_array)); + } + break; + case SecPlus_v1DecoderStepSearchStartBit: + if(level) { + if(DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short) < + subghz_protocol_secplus_v1_const.te_delta) { + instance->base_packet_index = SECPLUS_V1_PACKET_1_INDEX_BASE; + instance + ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = + SECPLUS_V1_BIT_0; + instance->decoder.decode_count_bit++; + instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; + } else if( + DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_long) < + subghz_protocol_secplus_v1_const.te_delta) { + instance->base_packet_index = SECPLUS_V1_PACKET_2_INDEX_BASE; + instance + ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = + SECPLUS_V1_BIT_2; + instance->decoder.decode_count_bit++; + instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = SecPlus_v1DecoderStepReset; + } + } else { + instance->decoder.parser_step = SecPlus_v1DecoderStepReset; + } + break; + case SecPlus_v1DecoderStepSaveDuration: + if(!level) { //save interval + if(DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 120) < + subghz_protocol_secplus_v1_const.te_delta * 120) { + if(instance->decoder.decode_count_bit == + subghz_protocol_secplus_v1_const.min_count_bit_for_found) { + if(instance->base_packet_index == SECPLUS_V1_PACKET_1_INDEX_BASE) + instance->packet_accepted |= SECPLUS_V1_PACKET_1_ACCEPTED; + if(instance->base_packet_index == SECPLUS_V1_PACKET_2_INDEX_BASE) + instance->packet_accepted |= SECPLUS_V1_PACKET_2_ACCEPTED; + + if(instance->packet_accepted == + (SECPLUS_V1_PACKET_1_ACCEPTED | SECPLUS_V1_PACKET_2_ACCEPTED)) { + subghz_protocol_secplus_v1_decode(instance); + + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + instance->decoder.parser_step = SecPlus_v1DecoderStepReset; + } + } + instance->decoder.parser_step = SecPlus_v1DecoderStepSearchStartBit; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + } else { + instance->decoder.te_last = duration; + instance->decoder.parser_step = SecPlus_v1DecoderStepDecoderData; + } + } else { + instance->decoder.parser_step = SecPlus_v1DecoderStepReset; + } + break; + case SecPlus_v1DecoderStepDecoderData: + if(level && (instance->decoder.decode_count_bit <= + subghz_protocol_secplus_v1_const.min_count_bit_for_found)) { + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_secplus_v1_const.te_short * 3) < + subghz_protocol_secplus_v1_const.te_delta * 3) && + (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short) < + subghz_protocol_secplus_v1_const.te_delta)) { + instance + ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = + SECPLUS_V1_BIT_0; + instance->decoder.decode_count_bit++; + instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_secplus_v1_const.te_short * 2) < + subghz_protocol_secplus_v1_const.te_delta * 2) && + (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 2) < + subghz_protocol_secplus_v1_const.te_delta * 2)) { + instance + ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = + SECPLUS_V1_BIT_1; + instance->decoder.decode_count_bit++; + instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_secplus_v1_const.te_short) < + subghz_protocol_secplus_v1_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 3) < + subghz_protocol_secplus_v1_const.te_delta * 3)) { + instance + ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = + SECPLUS_V1_BIT_2; + instance->decoder.decode_count_bit++; + instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = SecPlus_v1DecoderStepReset; + } + } else { + instance->decoder.parser_step = SecPlus_v1DecoderStepReset; + } + break; + } +} + +uint8_t subghz_protocol_decoder_secplus_v1_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v1* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +bool subghz_protocol_decoder_secplus_v1_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v1* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); +} + +bool subghz_protocol_decoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v1* instance = context; + return subghz_block_generic_deserialize(&instance->generic, flipper_format); +} + +void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t output) { + furi_assert(context); + SubGhzProtocolDecoderSecPlus_v1* instance = context; + + uint32_t fixed = (instance->generic.data >> 32) & 0xFFFFFFFF; + instance->generic.cnt = instance->generic.data & 0xFFFFFFFF; + + instance->generic.btn = fixed % 3; + uint8_t id0 = (fixed / 3) % 3; + uint8_t id1 = (fixed / 9) % 3; + uint16_t pin = 0; + + string_cat_printf( + output, + "%s %db\r\n" + "Key:0x%lX%08lX\r\n" + "id1:%d id0:%d", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)instance->generic.data, + id1, + id0); + + if(id1 == 0) { + // (fixed // 3**3) % (3**7) 3^3=27 3^73=72187 + + instance->generic.serial = (fixed / 27) % 2187; + // pin = (fixed // 3**10) % (3**9) 3^10=59049 3^9=19683 + pin = (fixed / 59049) % 19683; + + if(0 <= pin && pin <= 9999) { + string_cat_printf(output, " pin:%d", pin); + } else if(10000 <= pin && pin <= 11029) { + string_cat_printf(output, " pin:enter"); + } + + int pin_suffix = 0; + // pin_suffix = (fixed // 3**19) % 3 3^19=1162261467 + pin_suffix = (fixed / 1162261467) % 3; + + if(pin_suffix == 1) { + string_cat_printf(output, " #\r\n"); + } else if(pin_suffix == 2) { + string_cat_printf(output, " *\r\n"); + } else { + string_cat_printf(output, "\r\n"); + } + string_cat_printf( + output, + "Sn:0x%08lX\r\n" + "Cnt:0x%03X\r\n" + "Sw_id:0x%X\r\n", + instance->generic.serial, + instance->generic.cnt, + instance->generic.btn); + } else { + //id = fixed / 27; + instance->generic.serial = fixed / 27; + if(instance->generic.btn == 1) { + string_cat_printf(output, " Btn:left\r\n"); + } else if(instance->generic.btn == 0) { + string_cat_printf(output, " Btn:middle\r\n"); + } else if(instance->generic.btn == 2) { + string_cat_printf(output, " Btn:right\r\n"); + } + + string_cat_printf( + output, + "Sn:0x%08lX\r\n" + "Cnt:0x%03X\r\n" + "Sw_id:0x%X\r\n", + instance->generic.serial, + instance->generic.cnt, + instance->generic.btn); + } +} diff --git a/lib/subghz/protocols/secplus_v1.h b/lib/subghz/protocols/secplus_v1.h new file mode 100644 index 00000000000..891f751cd4c --- /dev/null +++ b/lib/subghz/protocols/secplus_v1.h @@ -0,0 +1,74 @@ +#pragma once +#include "base.h" + +#define SUBGHZ_PROTOCOL_SECPLUS_V1_NAME "Security+ 1.0" + +typedef struct SubGhzProtocolDecoderSecPlus_v1 SubGhzProtocolDecoderSecPlus_v1; +typedef struct SubGhzProtocolEncoderSecPlus_v1 SubGhzProtocolEncoderSecPlus_v1; + +extern const SubGhzProtocolDecoder subghz_protocol_secplus_v1_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_secplus_v1_encoder; +extern const SubGhzProtocol subghz_protocol_secplus_v1; + +/** + * Allocate SubGhzProtocolDecoderSecPlus_v1. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderSecPlus_v1* pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + */ +void* subghz_protocol_decoder_secplus_v1_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderSecPlus_v1. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + */ +void subghz_protocol_decoder_secplus_v1_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderSecPlus_v1. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + */ +void subghz_protocol_decoder_secplus_v1_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_secplus_v1_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_secplus_v1_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderSecPlus_v1. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param frequency The frequency at which the signal was received, Hz + * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @return true On success + */ +bool subghz_protocol_decoder_secplus_v1_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset); + +/** + * Deserialize data SubGhzProtocolDecoderSecPlus_v1. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_decoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t output); From 4d6b170769a33711e62deaf1c2a6b3bdda37e665 Mon Sep 17 00:00:00 2001 From: hedger Date: Fri, 6 May 2022 16:37:10 +0300 Subject: [PATCH 06/24] [FL-2520] FW build with -Wextra (#1185) * Fixing compiler warnings with -Wextra * More warnings suppression, WIP * Even more warning fixes * Added new lines at end of text files. * Padding fix * Additional fixes to warnings on different build configurations; added -Wextra to default build pipeline * Fixes for Secplus v1 * -additional warnings * +-Wredundant-decls fixes * FuriHal: print stack overflow task name in console * FuriHal: add missing include Co-authored-by: Aleksandr Kutuzov --- .clang-format | 2 +- .github/workflows/build_toolchain.yml | 2 +- .github/workflows/check_submodules.yml | 2 +- applications/about/about.c | 1 + applications/accessor/accessor.cpp | 3 +- applications/accessor/accessor_app.h | 2 +- .../accessor/accessor_view_manager.cpp | 4 +- applications/accessor/accessor_view_manager.h | 2 +- applications/accessor/helpers/wiegand.h | 2 +- .../accessor/scene/accessor_scene_generic.h | 2 +- .../accessor/scene/accessor_scene_start.h | 2 +- applications/archive/archive.c | 1 + applications/archive/helpers/archive_apps.c | 5 +- applications/archive/helpers/archive_apps.h | 2 +- .../archive/helpers/archive_browser.c | 24 +++++---- .../archive/helpers/archive_browser.h | 2 +- applications/archive/helpers/archive_files.c | 2 +- .../archive/scenes/archive_scene_browser.c | 1 + .../archive/views/archive_browser_view.c | 12 ++--- .../archive/views/archive_browser_view.h | 4 +- .../scenes/bad_usb_scene_file_select.c | 3 ++ applications/bad_usb/views/bad_usb_view.c | 1 + applications/bt/bt_cli.c | 10 ++++ applications/bt/bt_debug_app/bt_debug_app.c | 3 ++ .../bt/bt_debug_app/views/bt_carrier_test.c | 6 +-- .../bt/bt_debug_app/views/bt_packet_test.c | 6 +-- applications/bt/bt_hid_app/bt_hid.c | 3 ++ .../bt/bt_settings_app/bt_settings_app.c | 1 + applications/cli/cli.c | 3 ++ applications/cli/cli_commands.c | 39 +++++++++++++- applications/cli/cli_commands.h | 2 +- applications/cli/cli_vcp.c | 8 ++- applications/crypto/crypto_cli.c | 3 ++ applications/debug_tools/blink_test.c | 2 + .../debug_tools/display_test/display_test.c | 5 ++ .../display_test/view_display_test.c | 1 + applications/debug_tools/keypad_test.c | 1 + applications/debug_tools/text_box_test.c | 3 +- applications/debug_tools/uart_echo.c | 12 +++-- applications/debug_tools/usb_mouse.c | 2 + applications/debug_tools/usb_test.c | 2 + applications/debug_tools/vibro_test.c | 2 + .../desktop/animations/animation_manager.c | 1 + .../desktop/animations/animation_storage.c | 10 ++-- applications/desktop/desktop.c | 2 + .../desktop_settings_scene_pin_disable.c | 1 + .../scenes/desktop_settings_scene_pin_error.c | 1 + .../desktop_settings_scene_pin_setup_howto.c | 1 + .../desktop/scenes/desktop_scene_fault.c | 1 + .../scenes/desktop_scene_first_start.c | 1 + .../desktop/scenes/desktop_scene_lock_menu.c | 1 + .../desktop/scenes/desktop_scene_locked.c | 1 + .../scenes/desktop_scene_pin_timeout.c | 1 + .../desktop/views/desktop_view_pin_timeout.c | 2 + applications/dialogs/dialogs.c | 2 + applications/dialogs/dialogs.h | 2 +- applications/dialogs/dialogs_api.c | 2 +- applications/dialogs/dialogs_i.h | 2 +- applications/dialogs/dialogs_message.h | 2 +- .../dialogs/dialogs_module_file_select.h | 2 +- applications/dialogs/dialogs_module_message.h | 2 +- applications/dialogs/view_holder.h | 2 +- applications/dolphin/dolphin.c | 2 + applications/dolphin/helpers/dolphin_state.h | 2 +- applications/dolphin/passport/passport.c | 1 + applications/gpio/gpio_app.c | 1 + applications/gpio/scenes/gpio_scene_test.c | 3 ++ .../gpio/scenes/gpio_scene_usb_uart_config.c | 9 ++-- applications/gpio/usb_uart_bridge.c | 14 +++-- applications/gpio/views/gpio_test.c | 1 + applications/gpio/views/gpio_usb_uart.c | 1 + applications/gui/gui.c | 1 + applications/gui/icon.c | 2 +- applications/gui/icon.h | 2 +- applications/gui/modules/button_menu.c | 2 +- applications/gui/modules/button_panel.c | 8 +-- applications/gui/modules/byte_input.h | 2 +- applications/gui/modules/empty_screen.c | 3 ++ applications/gui/modules/empty_screen.h | 2 +- applications/gui/modules/file_select.h | 2 +- applications/gui/modules/loading.c | 1 + applications/gui/modules/text_box.c | 2 +- applications/gui/modules/text_input.c | 10 ++-- applications/gui/modules/validators.h | 2 +- applications/gui/modules/variable_item_list.c | 1 + applications/gui/view.c | 1 + applications/ibutton/ibutton.cpp | 2 +- applications/ibutton/ibutton_app.h | 2 +- applications/ibutton/ibutton_cli.c | 5 +- applications/ibutton/ibutton_event.h | 1 + applications/ibutton/ibutton_view_manager.cpp | 4 +- applications/ibutton/ibutton_view_manager.h | 2 +- .../ibutton/scene/ibutton_scene_add_type.h | 2 +- .../ibutton/scene/ibutton_scene_add_value.cpp | 2 +- .../ibutton/scene/ibutton_scene_add_value.h | 2 +- .../scene/ibutton_scene_delete_confirm.h | 2 +- .../scene/ibutton_scene_delete_success.cpp | 2 +- .../scene/ibutton_scene_delete_success.h | 2 +- .../ibutton/scene/ibutton_scene_emulate.cpp | 5 +- .../ibutton/scene/ibutton_scene_emulate.h | 2 +- .../scene/ibutton_scene_exit_confirm.h | 2 +- .../ibutton/scene/ibutton_scene_info.cpp | 5 +- .../ibutton/scene/ibutton_scene_info.h | 2 +- .../ibutton/scene/ibutton_scene_read.cpp | 5 +- .../ibutton/scene/ibutton_scene_read.h | 2 +- .../scene/ibutton_scene_read_crc_error.cpp | 2 +- .../scene/ibutton_scene_read_crc_error.h | 2 +- .../scene/ibutton_scene_read_key_menu.h | 2 +- .../ibutton_scene_read_not_key_error.cpp | 2 +- .../scene/ibutton_scene_read_not_key_error.h | 2 +- .../scene/ibutton_scene_read_success.h | 2 +- .../scene/ibutton_scene_retry_confirm.h | 2 +- .../ibutton/scene/ibutton_scene_save_name.h | 2 +- .../scene/ibutton_scene_save_success.cpp | 2 +- .../scene/ibutton_scene_save_success.h | 2 +- .../scene/ibutton_scene_saved_key_menu.h | 2 +- .../scene/ibutton_scene_select_key.cpp | 4 +- .../ibutton/scene/ibutton_scene_select_key.h | 2 +- .../ibutton/scene/ibutton_scene_start.h | 2 +- .../ibutton/scene/ibutton_scene_write.cpp | 2 +- .../ibutton/scene/ibutton_scene_write.h | 2 +- .../scene/ibutton_scene_write_success.cpp | 2 +- .../scene/ibutton_scene_write_success.h | 2 +- applications/infrared/cli/infrared_cli.cpp | 4 ++ applications/infrared/infrared_app_event.h | 1 + .../infrared/infrared_app_view_manager.cpp | 2 +- .../scene/infrared_app_scene_ask_back.cpp | 2 +- .../scene/infrared_app_scene_edit_delete.cpp | 2 +- .../infrared_app_scene_edit_rename_done.cpp | 2 +- .../infrared_app_scene_learn_enter_name.cpp | 2 +- .../scene/infrared_app_scene_remote_list.cpp | 8 ++- .../infrared_app_scene_universal_common.cpp | 6 ++- applications/input/input.c | 1 + applications/input/input_cli.c | 2 + .../lfrfid/helpers/decoder_analyzer.cpp | 4 +- .../lfrfid/helpers/decoder_gpio_out.cpp | 2 +- applications/lfrfid/helpers/decoder_hid26.h | 2 +- .../lfrfid/helpers/decoder_indala.cpp | 2 +- applications/lfrfid/helpers/decoder_indala.h | 2 +- applications/lfrfid/helpers/emmarin.h | 2 +- applications/lfrfid/helpers/encoder_emmarin.h | 2 +- .../lfrfid/helpers/encoder_hid_h10301.h | 2 +- .../lfrfid/helpers/encoder_indala_40134.h | 2 +- applications/lfrfid/helpers/key_info.cpp | 2 +- applications/lfrfid/helpers/key_info.h | 2 +- applications/lfrfid/helpers/osc_fsk.h | 2 +- .../helpers/protocols/protocol_generic.h | 2 +- .../helpers/protocols/protocol_hid_h10301.h | 2 +- .../protocols/protocol_indala_40134.cpp | 2 +- applications/lfrfid/helpers/pulse_joiner.h | 2 +- applications/lfrfid/helpers/rfid_key.cpp | 2 +- applications/lfrfid/helpers/rfid_key.h | 2 +- applications/lfrfid/helpers/rfid_worker.h | 2 +- applications/lfrfid/helpers/rfid_writer.h | 2 +- applications/lfrfid/helpers/state_sequencer.h | 2 +- applications/lfrfid/lfrfid_cli.cpp | 3 ++ .../scene/lfrfid_app_scene_delete_confirm.cpp | 2 +- .../scene/lfrfid_app_scene_delete_confirm.h | 2 +- .../scene/lfrfid_app_scene_delete_success.cpp | 4 +- .../scene/lfrfid_app_scene_delete_success.h | 2 +- .../lfrfid/scene/lfrfid_app_scene_emulate.cpp | 2 +- .../lfrfid/scene/lfrfid_app_scene_emulate.h | 2 +- .../scene/lfrfid_app_scene_exit_confirm.cpp | 2 +- .../scene/lfrfid_app_scene_exit_confirm.h | 2 +- .../lfrfid/scene/lfrfid_app_scene_read.cpp | 2 +- .../lfrfid/scene/lfrfid_app_scene_read.h | 2 +- .../lfrfid/scene/lfrfid_app_scene_read_menu.h | 2 +- .../scene/lfrfid_app_scene_read_success.cpp | 2 +- .../scene/lfrfid_app_scene_read_success.h | 2 +- .../scene/lfrfid_app_scene_retry_confirm.cpp | 2 +- .../scene/lfrfid_app_scene_retry_confirm.h | 2 +- .../lfrfid/scene/lfrfid_app_scene_save_data.h | 2 +- .../scene/lfrfid_app_scene_save_name.cpp | 2 +- .../lfrfid/scene/lfrfid_app_scene_save_name.h | 2 +- .../scene/lfrfid_app_scene_save_success.cpp | 2 +- .../scene/lfrfid_app_scene_save_success.h | 2 +- .../lfrfid/scene/lfrfid_app_scene_save_type.h | 2 +- .../scene/lfrfid_app_scene_saved_info.cpp | 8 ++- .../scene/lfrfid_app_scene_saved_info.h | 2 +- .../scene/lfrfid_app_scene_saved_key_menu.h | 2 +- .../scene/lfrfid_app_scene_select_key.cpp | 10 ++-- .../scene/lfrfid_app_scene_select_key.h | 2 +- .../lfrfid/scene/lfrfid_app_scene_start.h | 2 +- .../lfrfid/scene/lfrfid_app_scene_write.cpp | 2 +- .../lfrfid/scene/lfrfid_app_scene_write.h | 2 +- .../scene/lfrfid_app_scene_write_success.cpp | 2 +- .../scene/lfrfid_app_scene_write_success.h | 2 +- applications/lfrfid/view/container_vm.cpp | 2 +- .../lfrfid/view/elements/generic_element.h | 2 +- .../lfrfid/view/elements/icon_element.cpp | 2 +- .../lfrfid/view/elements/string_element.cpp | 4 +- .../lfrfid_debug/lfrfid_debug_app.cpp | 2 +- .../lfrfid_debug_app_launcher.cpp | 1 + .../scene/lfrfid_debug_app_scene_start.h | 2 +- .../scene/lfrfid_debug_app_scene_tune.cpp | 7 +-- .../scene/lfrfid_debug_app_scene_tune.h | 2 +- applications/loader/loader.c | 9 ++++ applications/music_player/music_player_cli.c | 1 + .../music_player/music_player_worker.c | 4 +- applications/nfc/helpers/nfc_custom_event.h | 2 +- applications/nfc/nfc_cli.c | 4 ++ applications/nfc/nfc_device.c | 4 +- .../nfc/scenes/nfc_scene_delete_success.c | 2 +- .../nfc/scenes/nfc_scene_device_info.c | 1 + .../nfc/scenes/nfc_scene_emulate_mifare_ul.c | 1 + .../nfc/scenes/nfc_scene_emulate_uid.c | 1 + applications/nfc/scenes/nfc_scene_field.c | 2 + .../nfc/scenes/nfc_scene_file_select.c | 3 ++ .../nfc/scenes/nfc_scene_mifare_desfire_app.c | 2 +- applications/nfc/scenes/nfc_scene_read_card.c | 1 + .../nfc/scenes/nfc_scene_read_emv_app.c | 1 + .../nfc/scenes/nfc_scene_read_emv_data.c | 1 + .../scenes/nfc_scene_read_mifare_desfire.c | 1 + .../nfc/scenes/nfc_scene_read_mifare_ul.c | 1 + applications/notification/notification_app.c | 2 +- .../notification/notification_app_api.c | 2 +- .../notification/notification_settings_app.c | 2 + .../power/battery_test_app/battery_test_app.c | 1 + applications/power/power_cli.c | 15 ++++++ .../power_settings_app/power_settings_app.c | 1 + .../power_settings_scene_battery_info.c | 1 + .../scenes/power_settings_scene_reboot.c | 1 + applications/rpc/rpc.c | 11 ++-- applications/rpc/rpc_cli.c | 1 + applications/rpc/rpc_storage.c | 2 - .../scene/scened_app_scene_byte_input.cpp | 2 +- .../scene/scened_app_scene_byte_input.h | 2 +- .../scene/scened_app_scene_start.h | 2 +- .../scened_app_example/scened_app.cpp | 2 +- .../scened_app_launcher.cpp | 1 + applications/snake_game/snake_game.c | 1 + applications/storage/filesystem_api.c | 2 +- applications/storage/filesystem_api_defines.h | 2 +- applications/storage/storage.c | 1 + applications/storage/storage.h | 2 +- applications/storage/storage_cli.c | 12 +++++ applications/storage/storage_glue.h | 2 +- applications/storage/storage_internal_api.c | 2 +- applications/storage/storage_message.h | 2 +- applications/storage/storage_processing.c | 2 +- applications/storage/storage_processing.h | 2 +- applications/storage/storage_sd_api.c | 2 +- applications/storage/storage_sd_api.h | 2 +- applications/storage/storage_test_app.c | 1 + applications/storage/storages/sd_notify.c | 2 +- applications/storage/storages/sd_notify.h | 2 +- applications/storage/storages/storage_ext.c | 20 ++++++- applications/storage/storages/storage_ext.h | 2 +- applications/storage/storages/storage_int.c | 2 + applications/storage/storages/storage_int.h | 2 +- .../scenes/storage_settings_scene_config.h | 2 +- .../storage_settings/storage_settings.c | 1 + .../storage_settings/storage_settings.h | 2 +- .../subghz_frequency_analyzer_worker.c | 2 +- applications/subghz/helpers/subghz_testing.h | 2 +- .../subghz/scenes/subghz_scene_config.h | 2 +- .../subghz/scenes/subghz_scene_receiver.c | 2 +- .../scenes/subghz_scene_receiver_config.c | 4 +- .../subghz/scenes/subghz_scene_saved.c | 5 +- .../subghz/scenes/subghz_scene_show_only_rx.c | 2 +- .../subghz/scenes/subghz_scene_test_carrier.c | 2 +- .../subghz/scenes/subghz_scene_test_packet.c | 2 +- .../subghz/scenes/subghz_scene_test_static.c | 2 +- applications/subghz/subghz.h | 2 +- applications/subghz/subghz_cli.c | 7 +++ applications/subghz/views/receiver.c | 11 ++-- .../subghz/views/subghz_test_packet.c | 1 + applications/system/system_settings.c | 2 + applications/u2f/scenes/u2f_scene_main.c | 1 + applications/u2f/u2f_app.c | 1 + applications/u2f/views/u2f_view.c | 1 + .../flipper_format_string_test.c | 2 +- applications/unit_tests/furi_pubsub_test.c | 2 +- .../infrared_decoder_encoder_test.c | 6 +-- applications/unit_tests/minunit_vars.h | 2 +- applications/unit_tests/minunit_vars_ex.h | 2 +- applications/unit_tests/rpc/rpc_test.c | 13 +++-- .../unit_tests/storage/storage_test.c | 2 +- applications/unit_tests/stream/stream_test.c | 2 +- applications/unit_tests/subghz/subghz_test.c | 2 + applications/unit_tests/test_index.c | 3 ++ applications/updater/cli/updater_cli.c | 3 ++ .../updater/scenes/updater_scene_config.h | 2 +- .../updater/scenes/updater_scene_loadcfg.c | 2 +- applications/updater/updater.c | 2 +- applications/updater/updater_i.h | 2 +- applications/updater/util/update_task.c | 2 +- applications/updater/util/update_task.h | 2 +- .../updater/util/update_task_worker_flasher.c | 2 +- applications/updater/views/updater_main.h | 2 +- core/furi/check.c | 2 +- core/furi/check.h | 5 +- core/furi/common_defines.h | 5 -- core/furi/memmgr.c | 5 ++ core/furi/memmgr_heap.c | 1 + core/furi/stdglue.c | 2 + core/furi/thread.h | 2 +- core/furi/valuemutex.c | 2 +- core/furi/valuemutex.h | 2 +- docker-compose.yml | 2 +- firmware/targets/f7/Inc/FreeRTOSConfig.h | 1 + firmware/targets/f7/Inc/stm32_assert.h | 52 +++++++++++++++++++ firmware/targets/f7/Src/main.c | 13 ----- firmware/targets/f7/ble_glue/app_debug.h | 2 +- firmware/targets/f7/ble_glue/ble_app.c | 4 ++ firmware/targets/f7/ble_glue/ble_glue.c | 1 + firmware/targets/f7/ble_glue/ble_glue.h | 2 +- firmware/targets/f7/ble_glue/gap.c | 2 + firmware/targets/f7/fatfs/stm32_adafruit_sd.c | 2 + firmware/targets/f7/fatfs/user_diskio.c | 7 ++- firmware/targets/f7/furi_hal/furi_hal_crc.h | 2 +- .../targets/f7/furi_hal/furi_hal_i2c_config.h | 2 +- .../targets/f7/furi_hal/furi_hal_i2c_types.h | 2 +- firmware/targets/f7/furi_hal/furi_hal_info.c | 2 +- firmware/targets/f7/furi_hal/furi_hal_nfc.c | 3 +- firmware/targets/f7/furi_hal/furi_hal_os.c | 5 ++ .../targets/f7/furi_hal/furi_hal_random.c | 1 + firmware/targets/f7/furi_hal/furi_hal_rfid.c | 1 + firmware/targets/f7/furi_hal/furi_hal_spi.c | 1 + .../targets/f7/furi_hal/furi_hal_spi_config.h | 2 +- .../targets/f7/furi_hal/furi_hal_spi_types.h | 2 +- firmware/targets/f7/furi_hal/furi_hal_usb.c | 10 ++++ .../targets/f7/furi_hal/furi_hal_usb_cdc.c | 8 +++ .../targets/f7/furi_hal/furi_hal_usb_hid.c | 17 ++++-- .../targets/f7/furi_hal/furi_hal_usb_u2f.c | 37 ++++++++++--- .../targets/f7/furi_hal/furi_hal_version.c | 18 +++---- firmware/targets/f7/target.mk | 6 ++- .../furi_hal_include/furi_hal_random.h | 2 +- .../targets/furi_hal_include/furi_hal_sd.h | 1 + .../furi_hal_include/furi_hal_usb_hid.h | 2 +- lib/ST25RFAL002/platform.c | 1 + lib/ST25RFAL002/source/rfal_t4t.c | 1 + .../source/st25r3916/st25r3916_com.c | 3 +- lib/ST25RFAL002/timer.h | 4 +- lib/app-scened-template/file_worker.c | 3 ++ lib/app-scened-template/generic_scene.hpp | 2 +- lib/app-scened-template/record_controller.hpp | 2 +- lib/app-scened-template/scene_controller.hpp | 4 +- lib/app-scened-template/text_store.h | 2 +- lib/app-scened-template/typeindex_no_rtti.hpp | 2 +- .../view_modules/byte_input_vm.h | 2 +- .../view_modules/dialog_ex_vm.h | 2 +- .../view_modules/generic_view_module.h | 2 +- .../view_modules/popup_vm.h | 2 +- .../view_modules/submenu_vm.h | 2 +- .../view_modules/text_input_vm.h | 2 +- lib/app-template/app_template.h | 2 +- lib/callback-connector/callback-connector.h | 2 +- lib/drivers/bq27220.c | 6 +-- lib/drivers/cc1101.h | 9 +--- lib/drivers/cc1101_regs.h | 2 +- lib/fatfs/ff.c | 4 +- lib/fatfs/ff_gen_drv.c | 1 + lib/flipper_format/flipper_format.c | 2 +- lib/flipper_format/flipper_format.h | 2 +- lib/flipper_format/flipper_format_i.h | 2 +- lib/flipper_format/flipper_format_stream.c | 6 +-- lib/flipper_format/flipper_format_stream.h | 2 +- lib/flipper_format/flipper_format_stream_i.h | 2 +- lib/fnv1a-hash/fnv1a-hash.c | 2 +- lib/fnv1a-hash/fnv1a-hash.h | 2 +- lib/heatshrink/heatshrink_encoder.c | 1 + .../common/infrared_common_decoder.c | 16 +++--- .../common/infrared_common_encoder.c | 4 +- lib/infrared/encoder_decoder/infrared.c | 12 ++--- .../nec/infrared_decoder_nec.c | 4 +- .../rc6/infrared_decoder_rc6.c | 4 +- .../samsung/infrared_decoder_samsung.c | 3 +- .../sirc/infrared_encoder_sirc.c | 2 +- lib/infrared/worker/infrared_worker.c | 1 + lib/lfs_config.h | 4 +- lib/libusb_stm32 | 2 +- lib/micro-ecc/asm_arm.inc | 1 + lib/micro-ecc/curve-specific.inc | 1 + lib/nfc_protocols/mifare_classic.c | 3 +- lib/nfc_protocols/mifare_desfire.c | 2 +- lib/nfc_protocols/mifare_ultralight.h | 2 +- lib/nfc_protocols/nfc_util.c | 16 ------ lib/nfc_protocols/nfc_util.h | 16 ------ lib/nfc_protocols/nfca.c | 2 +- lib/one_wire/ibutton/encoder/encoder_cyfral.h | 2 +- .../ibutton/encoder/encoder_metakom.h | 2 +- lib/one_wire/ibutton/ibutton_key.c | 2 +- lib/one_wire/ibutton/ibutton_key.h | 2 +- lib/one_wire/ibutton/ibutton_key_command.h | 2 +- lib/one_wire/ibutton/ibutton_worker.h | 2 +- lib/one_wire/ibutton/ibutton_worker_i.h | 8 +-- lib/one_wire/ibutton/ibutton_worker_modes.c | 9 +++- lib/one_wire/ibutton/ibutton_writer.h | 2 +- .../ibutton/pulse_protocols/protocol_cyfral.h | 2 +- .../pulse_protocols/protocol_metakom.h | 2 +- lib/one_wire/maxim_crc.c | 2 +- lib/one_wire/maxim_crc.h | 2 +- lib/one_wire/one_wire_device.h | 2 +- lib/one_wire/one_wire_host.c | 5 ++ lib/one_wire/one_wire_host.h | 2 +- lib/one_wire/one_wire_slave.c | 2 + lib/one_wire/pulse_protocols/pulse_decoder.h | 2 +- lib/one_wire/pulse_protocols/pulse_glue.h | 2 +- lib/one_wire/pulse_protocols/pulse_protocol.c | 2 +- lib/one_wire/pulse_protocols/pulse_protocol.h | 2 +- lib/qrcode/qrcode.c | 2 +- lib/qrcode/qrcode.h | 2 +- lib/subghz/protocols/came.c | 2 + lib/subghz/protocols/came_atomo.c | 2 +- lib/subghz/protocols/came_twee.c | 4 +- lib/subghz/protocols/faac_slh.c | 3 +- lib/subghz/protocols/firefly.c | 2 + lib/subghz/protocols/gate_tx.c | 4 +- lib/subghz/protocols/hormann.c | 2 + lib/subghz/protocols/ido.c | 5 +- lib/subghz/protocols/ido.h | 2 +- lib/subghz/protocols/keeloq.c | 2 +- lib/subghz/protocols/keeloq_common.c | 2 +- lib/subghz/protocols/kia.c | 3 +- lib/subghz/protocols/nero_radio.c | 4 +- lib/subghz/protocols/nero_sketch.c | 2 + lib/subghz/protocols/nice_flo.c | 2 + lib/subghz/protocols/nice_flo.h | 2 +- lib/subghz/protocols/princeton.c | 4 +- lib/subghz/protocols/princeton_for_testing.c | 2 +- lib/subghz/protocols/raw.c | 2 + lib/subghz/protocols/scher_khan.c | 3 +- lib/subghz/protocols/secplus_v1.c | 3 +- lib/subghz/protocols/secplus_v2.c | 3 +- lib/subghz/protocols/somfy_keytis.c | 1 + lib/subghz/protocols/somfy_telis.c | 1 + lib/subghz/subghz_keystore.c | 4 +- lib/toolbox/args.c | 2 +- lib/toolbox/args.h | 2 +- lib/toolbox/hex.c | 2 +- lib/toolbox/hex.h | 2 +- lib/toolbox/level_duration.h | 2 +- lib/toolbox/manchester_decoder.h | 2 +- lib/toolbox/manchester_encoder.c | 2 +- lib/toolbox/manchester_encoder.h | 2 +- lib/toolbox/md5.c | 2 +- lib/toolbox/md5.h | 2 +- lib/toolbox/random_name.c | 4 +- lib/toolbox/stream/file_stream.c | 2 +- lib/toolbox/stream/file_stream.h | 2 +- lib/toolbox/stream/stream.c | 4 +- lib/toolbox/stream/stream.h | 2 +- lib/toolbox/stream/stream_i.h | 2 +- lib/toolbox/stream/string_stream.c | 2 +- lib/toolbox/stream/string_stream.h | 2 +- lib/toolbox/tar/tar_archive.c | 2 +- lib/toolbox/tar/tar_archive.h | 2 +- lib/toolbox/version.c | 2 +- lib/toolbox/version.h | 2 +- lib/u8g2/u8g2_glue.c | 3 ++ lib/u8g2/u8x8_display.c | 2 +- lib/u8g2/u8x8_gpio.c | 2 +- lib/update_util/update_manifest.c | 2 +- lib/update_util/update_manifest.h | 2 +- lib/update_util/update_operation.c | 2 +- lib/update_util/update_operation.h | 2 +- make/base.mk | 2 +- make/defaults.mk | 2 +- make/freertos-heap.mk | 2 +- scripts/ReadMe.md | 2 +- 461 files changed, 940 insertions(+), 519 deletions(-) create mode 100644 firmware/targets/f7/Inc/stm32_assert.h diff --git a/.clang-format b/.clang-format index ad9757abf0f..3337a7409cf 100644 --- a/.clang-format +++ b/.clang-format @@ -83,4 +83,4 @@ SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Cpp03 TabWidth: 4 -UseTab: Never \ No newline at end of file +UseTab: Never diff --git a/.github/workflows/build_toolchain.yml b/.github/workflows/build_toolchain.yml index 2068730c1dd..452dfbee6b7 100644 --- a/.github/workflows/build_toolchain.yml +++ b/.github/workflows/build_toolchain.yml @@ -43,4 +43,4 @@ jobs: labels: ${{ steps.meta.outputs.labels }} platforms: linux/amd64,linux/arm64 cache-from: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache - cache-to: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache,mode=max \ No newline at end of file + cache-to: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache,mode=max diff --git a/.github/workflows/check_submodules.yml b/.github/workflows/check_submodules.yml index db3a3afbda9..b02f9a8d0b7 100644 --- a/.github/workflows/check_submodules.yml +++ b/.github/workflows/check_submodules.yml @@ -14,4 +14,4 @@ jobs: with: path: assets/protobuf branch: dev - fetch_depth: 50 \ No newline at end of file + fetch_depth: 50 diff --git a/applications/about/about.c b/applications/about/about.c index 9e3fd34eb2f..7c8a4c6970e 100644 --- a/applications/about/about.c +++ b/applications/about/about.c @@ -149,6 +149,7 @@ const AboutDialogScreen about_screens[] = { const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen); int32_t about_settings_app(void* p) { + UNUSED(p); DialogsApp* dialogs = furi_record_open("dialogs"); DialogMessage* message = dialog_message_alloc(); diff --git a/applications/accessor/accessor.cpp b/applications/accessor/accessor.cpp index 000c214b1f8..d7b687ede94 100644 --- a/applications/accessor/accessor.cpp +++ b/applications/accessor/accessor.cpp @@ -2,9 +2,10 @@ // app enter function extern "C" int32_t accessor_app(void* p) { + UNUSED(p); AccessorApp* app = new AccessorApp(); app->run(); delete app; return 255; -} \ No newline at end of file +} diff --git a/applications/accessor/accessor_app.h b/applications/accessor/accessor_app.h index ce18c177ae2..2afd796d5a9 100644 --- a/applications/accessor/accessor_app.h +++ b/applications/accessor/accessor_app.h @@ -51,4 +51,4 @@ class AccessorApp { OneWireHost* onewire_host; NotificationApp* notification; -}; \ No newline at end of file +}; diff --git a/applications/accessor/accessor_view_manager.cpp b/applications/accessor/accessor_view_manager.cpp index 604e4304969..f54ad62f7e1 100644 --- a/applications/accessor/accessor_view_manager.cpp +++ b/applications/accessor/accessor_view_manager.cpp @@ -64,7 +64,7 @@ void AccessorAppViewManager::send_event(AccessorEvent* event) { furi_check(result == osOK); } -uint32_t AccessorAppViewManager::previous_view_callback(void* context) { +uint32_t AccessorAppViewManager::previous_view_callback(void*) { if(event_queue != NULL) { AccessorEvent event; event.type = AccessorEvent::Type::Back; @@ -76,4 +76,4 @@ uint32_t AccessorAppViewManager::previous_view_callback(void* context) { void AccessorAppViewManager::add_view(ViewType view_type, View* view) { view_dispatcher_add_view(view_dispatcher, static_cast(view_type), view); -} \ No newline at end of file +} diff --git a/applications/accessor/accessor_view_manager.h b/applications/accessor/accessor_view_manager.h index 1e9d8e04496..f2c6f2bb288 100644 --- a/applications/accessor/accessor_view_manager.h +++ b/applications/accessor/accessor_view_manager.h @@ -36,4 +36,4 @@ class AccessorAppViewManager { // view elements Submenu* submenu; Popup* popup; -}; \ No newline at end of file +}; diff --git a/applications/accessor/helpers/wiegand.h b/applications/accessor/helpers/wiegand.h index 2822d95a0d8..8127f42865c 100644 --- a/applications/accessor/helpers/wiegand.h +++ b/applications/accessor/helpers/wiegand.h @@ -27,4 +27,4 @@ class WIEGAND { static int _wiegandType; static unsigned long _code; static unsigned long _codeHigh; -}; \ No newline at end of file +}; diff --git a/applications/accessor/scene/accessor_scene_generic.h b/applications/accessor/scene/accessor_scene_generic.h index b403f152d42..62a4eafe692 100644 --- a/applications/accessor/scene/accessor_scene_generic.h +++ b/applications/accessor/scene/accessor_scene_generic.h @@ -10,4 +10,4 @@ class AccessorScene { virtual void on_exit(AccessorApp* app) = 0; private: -}; \ No newline at end of file +}; diff --git a/applications/accessor/scene/accessor_scene_start.h b/applications/accessor/scene/accessor_scene_start.h index 3be88bb3925..1717d1e7970 100644 --- a/applications/accessor/scene/accessor_scene_start.h +++ b/applications/accessor/scene/accessor_scene_start.h @@ -6,4 +6,4 @@ class AccessorSceneStart : public AccessorScene { void on_enter(AccessorApp* app) final; bool on_event(AccessorApp* app, AccessorEvent* event) final; void on_exit(AccessorApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/archive/archive.c b/applications/archive/archive.c index 79f26f0ef92..5a38700b7fe 100644 --- a/applications/archive/archive.c +++ b/applications/archive/archive.c @@ -66,6 +66,7 @@ void archive_free(ArchiveApp* archive) { } int32_t archive_app(void* p) { + UNUSED(p); ArchiveApp* archive = archive_alloc(); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); view_dispatcher_run(archive->view_dispatcher); diff --git a/applications/archive/helpers/archive_apps.c b/applications/archive/helpers/archive_apps.c index e1c429a78ee..f5edbbb32f5 100644 --- a/applications/archive/helpers/archive_apps.c +++ b/applications/archive/helpers/archive_apps.c @@ -7,8 +7,8 @@ static const char* known_apps[] = { }; ArchiveAppTypeEnum archive_get_app_type(const char* path) { - for(size_t i = 0; i < SIZEOF_ARRAY(known_apps); i++) { - if(strncmp(path, known_apps[i], strlen(known_apps[i])) != STRING_FAILURE) { + for(size_t i = 0; i < COUNT_OF(known_apps); i++) { + if(strncmp(path, known_apps[i], strlen(known_apps[i])) == 0) { return i; } } @@ -16,6 +16,7 @@ ArchiveAppTypeEnum archive_get_app_type(const char* path) { } bool archive_app_is_available(void* context, const char* path) { + UNUSED(context); furi_assert(path); ArchiveAppTypeEnum app = archive_get_app_type(path); diff --git a/applications/archive/helpers/archive_apps.h b/applications/archive/helpers/archive_apps.h index 5abc27a5be5..8bc904587bd 100644 --- a/applications/archive/helpers/archive_apps.h +++ b/applications/archive/helpers/archive_apps.h @@ -11,7 +11,7 @@ static const ArchiveFileTypeEnum app_file_types[] = { [ArchiveAppTypeUnknown] = ArchiveFileTypeUnknown, }; -static inline const ArchiveFileTypeEnum archive_get_app_filetype(ArchiveAppTypeEnum app) { +static inline ArchiveFileTypeEnum archive_get_app_filetype(ArchiveAppTypeEnum app) { return app_file_types[app]; } diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c index cbe57c06e2a..faf10de98d2 100644 --- a/applications/archive/helpers/archive_browser.c +++ b/applications/archive/helpers/archive_browser.c @@ -6,7 +6,8 @@ bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx) { size_t array_size = files_array_size(model->files); - if((idx >= model->array_offset + array_size) || (idx < model->array_offset)) { + if((idx >= (uint32_t)model->array_offset + array_size) || + (idx < (uint32_t)model->array_offset)) { return false; } @@ -20,12 +21,14 @@ void archive_update_offset(ArchiveBrowserView* browser) { browser->view, (ArchiveBrowserViewModel * model) { uint16_t bounds = model->item_cnt > 3 ? 2 : model->item_cnt; - if(model->item_cnt > 3 && model->item_idx >= model->item_cnt - 1) { + if((model->item_cnt > 3u) && ((uint32_t)model->item_idx >= (model->item_cnt - 1))) { model->list_offset = model->item_idx - 3; } else if(model->list_offset < model->item_idx - bounds) { - model->list_offset = CLAMP(model->item_idx - 2, model->item_cnt - bounds, 0); + model->list_offset = + CLAMP((uint32_t)model->item_idx - 2, model->item_cnt - bounds, 0u); } else if(model->list_offset > model->item_idx - bounds) { - model->list_offset = CLAMP(model->item_idx - 1, model->item_cnt - bounds, 0); + model->list_offset = + CLAMP((uint32_t)model->item_idx - 1, model->item_cnt - bounds, 0u); } return true; @@ -77,7 +80,7 @@ void archive_set_item_count(ArchiveBrowserView* browser, uint32_t count) { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { model->item_cnt = count; - model->item_idx = CLAMP(model->item_idx, model->item_cnt - 1, 0); + model->item_idx = CLAMP((uint32_t)model->item_idx, model->item_cnt - 1, 0u); return false; }); archive_update_offset(browser); @@ -94,7 +97,7 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) { model->item_idx - model->array_offset, model->item_idx - model->array_offset + 1); model->item_cnt--; - model->item_idx = CLAMP(model->item_idx, model->item_cnt - 1, 0); + model->item_idx = CLAMP((uint32_t)model->item_idx, model->item_cnt - 1, 0u); items_cnt = model->item_cnt; return false; }); @@ -113,14 +116,14 @@ void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir) { browser->view, (ArchiveBrowserViewModel * model) { ArchiveFile_t temp; size_t array_size = files_array_size(model->files) - 1; - uint8_t swap_idx = CLAMP(model->item_idx + dir, array_size, 0); + uint8_t swap_idx = CLAMP((size_t)(model->item_idx + dir), array_size, 0u); if(model->item_idx == 0 && dir < 0) { ArchiveFile_t_init(&temp); files_array_pop_at(&temp, model->files, array_size); files_array_push_at(model->files, model->item_idx, temp); ArchiveFile_t_clear(&temp); - } else if(model->item_idx == array_size && dir > 0) { + } else if(((uint32_t)model->item_idx == array_size) && (dir > 0)) { ArchiveFile_t_init(&temp); files_array_pop_at(&temp, model->files, 0); files_array_push_at(model->files, array_size, temp); @@ -157,7 +160,7 @@ bool archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { } else { offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 1; } - offset_new = CLAMP(offset_new, model->item_cnt - FILE_LIST_BUF_LEN, 0); + offset_new = CLAMP((uint32_t)offset_new, model->item_cnt - FILE_LIST_BUF_LEN, 0u); } return false; }); @@ -196,7 +199,7 @@ ArchiveFile_t* archive_get_file_at(ArchiveBrowserView* browser, size_t idx) { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { - idx = CLAMP(idx - model->array_offset, files_array_size(model->files), 0); + idx = CLAMP(idx - model->array_offset, files_array_size(model->files), 0u); selected = files_array_size(model->files) ? files_array_get(model->files, idx) : NULL; return false; }); @@ -247,6 +250,7 @@ void archive_set_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) { }); } void archive_set_last_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) { + UNUSED(tab); // FIXME? furi_assert(browser); with_view_model( diff --git a/applications/archive/helpers/archive_browser.h b/applications/archive/helpers/archive_browser.h index 593a9be0db7..3395541e3ca 100644 --- a/applications/archive/helpers/archive_browser.h +++ b/applications/archive/helpers/archive_browser.h @@ -42,7 +42,7 @@ static const ArchiveFileTypeEnum known_type[] = { [ArchiveTabBrowser] = ArchiveFileTypeUnknown, }; -static inline const ArchiveFileTypeEnum archive_get_tab_filetype(ArchiveTabEnum tab) { +static inline ArchiveFileTypeEnum archive_get_tab_filetype(ArchiveTabEnum tab) { return known_type[tab]; } diff --git a/applications/archive/helpers/archive_files.c b/applications/archive/helpers/archive_files.c index 156e66f5d4b..3b1e8944678 100644 --- a/applications/archive/helpers/archive_files.c +++ b/applications/archive/helpers/archive_files.c @@ -54,7 +54,7 @@ void archive_set_file_type(ArchiveFile_t* file, FileInfo* file_info, const char* } else { furi_assert(file_info); - for(size_t i = 0; i < SIZEOF_ARRAY(known_ext); i++) { + for(size_t i = 0; i < COUNT_OF(known_ext); i++) { if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue; if(string_search_str(file->name, known_ext[i], 0) != STRING_FAILURE) { if(i == ArchiveFileTypeBadUsb) { diff --git a/applications/archive/scenes/archive_scene_browser.c b/applications/archive/scenes/archive_scene_browser.c index 0091bc9938c..9df3463befe 100644 --- a/applications/archive/scenes/archive_scene_browser.c +++ b/applications/archive/scenes/archive_scene_browser.c @@ -31,6 +31,7 @@ static void archive_loader_callback(const void* message, void* context) { } static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) { + UNUSED(browser); Loader* loader = furi_record_open("loader"); LoaderStatus status; diff --git a/applications/archive/views/archive_browser_view.c b/applications/archive/views/archive_browser_view.c index ed75621d87c..dc6962f21e0 100644 --- a/applications/archive/views/archive_browser_view.c +++ b/applications/archive/views/archive_browser_view.c @@ -106,17 +106,17 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { size_t array_size = files_array_size(model->files); bool scrollbar = model->item_cnt > 4; - for(size_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) { + for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) { string_t str_buff; char cstr_buff[MAX_NAME_LEN]; - size_t idx = CLAMP(i + model->list_offset, model->item_cnt, 0); + int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u); uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0; ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading; if(archive_is_item_in_array(model, idx)) { - ArchiveFile_t* file = - files_array_get(model->files, CLAMP(idx - model->array_offset, array_size - 1, 0)); + ArchiveFile_t* file = files_array_get( + model->files, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0)); strlcpy(cstr_buff, string_get_cstr(file->name), string_size(file->name) + 1); archive_trim_file_path(cstr_buff, archive_is_known_app(file->type)); string_init_set_str(str_buff, cstr_buff); @@ -216,7 +216,7 @@ static bool is_file_list_load_required(ArchiveBrowserViewModel* model) { } if(((model->array_offset + array_size) < model->item_cnt) && - (model->item_idx > (model->array_offset + array_size - FILE_LIST_BUF_LEN / 4))) { + (model->item_idx > (int32_t)(model->array_offset + array_size - FILE_LIST_BUF_LEN / 4))) { return true; } @@ -376,4 +376,4 @@ void browser_free(ArchiveBrowserView* browser) { view_free(browser->view); free(browser); -} \ No newline at end of file +} diff --git a/applications/archive/views/archive_browser_view.h b/applications/archive/views/archive_browser_view.h index 3aabe962eca..db079d6bc1c 100644 --- a/applications/archive/views/archive_browser_view.h +++ b/applications/archive/views/archive_browser_view.h @@ -13,8 +13,8 @@ #define MAX_NAME_LEN 255 #define MAX_EXT_LEN 6 #define FRAME_HEIGHT 12 -#define MENU_ITEMS 4 -#define MOVE_OFFSET 5 +#define MENU_ITEMS 4u +#define MOVE_OFFSET 5u typedef enum { ArchiveTabFavorites, diff --git a/applications/bad_usb/scenes/bad_usb_scene_file_select.c b/applications/bad_usb/scenes/bad_usb_scene_file_select.c index b1ab3194a61..82f03bab08c 100644 --- a/applications/bad_usb/scenes/bad_usb_scene_file_select.c +++ b/applications/bad_usb/scenes/bad_usb_scene_file_select.c @@ -31,10 +31,13 @@ void bad_usb_scene_file_select_on_enter(void* context) { } bool bad_usb_scene_file_select_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); // BadUsbApp* bad_usb = context; return false; } void bad_usb_scene_file_select_on_exit(void* context) { + UNUSED(context); // BadUsbApp* bad_usb = context; } diff --git a/applications/bad_usb/views/bad_usb_view.c b/applications/bad_usb/views/bad_usb_view.c index 22e5143d039..5b6fe6e89c8 100644 --- a/applications/bad_usb/views/bad_usb_view.c +++ b/applications/bad_usb/views/bad_usb_view.c @@ -142,6 +142,7 @@ void bad_usb_set_ok_callback(BadUsb* bad_usb, BadUsbOkCallback callback, void* c furi_assert(callback); with_view_model( bad_usb->view, (BadUsbModel * model) { + UNUSED(model); bad_usb->callback = callback; bad_usb->context = context; return true; diff --git a/applications/bt/bt_cli.c b/applications/bt/bt_cli.c index 64d69a12fc4..122eedf96fa 100644 --- a/applications/bt/bt_cli.c +++ b/applications/bt/bt_cli.c @@ -13,6 +13,9 @@ static const char* bt_cli_address_types[] = { }; static void bt_cli_command_hci_info(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(args); + UNUSED(context); string_t buffer; string_init(buffer); furi_hal_bt_dump_state(buffer); @@ -21,6 +24,7 @@ static void bt_cli_command_hci_info(Cli* cli, string_t args, void* context) { } static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { + UNUSED(context); int channel = 0; int power = 0; @@ -47,6 +51,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { } static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { + UNUSED(context); int channel = 0; do { @@ -72,6 +77,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { } static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { + UNUSED(context); int channel = 0; int pattern = 0; int datarate = 1; @@ -115,6 +121,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { } static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { + UNUSED(context); int channel = 0; int datarate = 1; @@ -152,6 +159,8 @@ static void bt_cli_scan_callback(GapAddress address, void* context) { } static void bt_cli_command_scan(Cli* cli, string_t args, void* context) { + UNUSED(context); + UNUSED(args); osMessageQueueId_t queue = osMessageQueueNew(20, sizeof(GapAddress), NULL); furi_hal_bt_start_scan(bt_cli_scan_callback, queue); @@ -189,6 +198,7 @@ static void bt_cli_print_usage() { } static void bt_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); furi_record_open("bt"); string_t cmd; diff --git a/applications/bt/bt_debug_app/bt_debug_app.c b/applications/bt/bt_debug_app/bt_debug_app.c index a4363b91cf3..58119f5dc8f 100644 --- a/applications/bt/bt_debug_app/bt_debug_app.c +++ b/applications/bt/bt_debug_app/bt_debug_app.c @@ -19,10 +19,12 @@ void bt_debug_submenu_callback(void* context, uint32_t index) { } uint32_t bt_debug_exit(void* context) { + UNUSED(context); return VIEW_NONE; } uint32_t bt_debug_start_view(void* context) { + UNUSED(context); return BtDebugAppViewSubmenu; } @@ -94,6 +96,7 @@ void bt_debug_app_free(BtDebugApp* app) { } int32_t bt_debug_app(void* p) { + UNUSED(p); if(furi_hal_bt_get_radio_stack() != FuriHalBtStackHciLayer) { FURI_LOG_E(TAG, "Incorrect radio stack, replace with HciLayer for tests."); DialogsApp* dialogs = furi_record_open("dialogs"); diff --git a/applications/bt/bt_debug_app/views/bt_carrier_test.c b/applications/bt/bt_debug_app/views/bt_carrier_test.c index 22b80cd888f..0e0b3792bb7 100755 --- a/applications/bt/bt_debug_app/views/bt_carrier_test.c +++ b/applications/bt/bt_debug_app/views/bt_carrier_test.c @@ -141,7 +141,7 @@ BtCarrierTest* bt_carrier_test_alloc() { param = bt_test_param_add( bt_carrier_test->bt_test, "Mode", - SIZEOF_ARRAY(bt_param_mode), + COUNT_OF(bt_param_mode), bt_carrier_test_mode_changed, bt_carrier_test); bt_test_set_current_value_index(param, 0); @@ -151,7 +151,7 @@ BtCarrierTest* bt_carrier_test_alloc() { param = bt_test_param_add( bt_carrier_test->bt_test, "Channel", - SIZEOF_ARRAY(bt_param_channel), + COUNT_OF(bt_param_channel), bt_carrier_test_channel_changed, bt_carrier_test); bt_test_set_current_value_index(param, 0); @@ -162,7 +162,7 @@ BtCarrierTest* bt_carrier_test_alloc() { param = bt_test_param_add( bt_carrier_test->bt_test, "Power", - SIZEOF_ARRAY(bt_param_power), + COUNT_OF(bt_param_power), bt_carrier_test_param_channel, bt_carrier_test); bt_test_set_current_value_index(param, 0); diff --git a/applications/bt/bt_debug_app/views/bt_packet_test.c b/applications/bt/bt_debug_app/views/bt_packet_test.c index e9d3883ad01..e9b3bd75782 100644 --- a/applications/bt/bt_debug_app/views/bt_packet_test.c +++ b/applications/bt/bt_debug_app/views/bt_packet_test.c @@ -109,7 +109,7 @@ BtPacketTest* bt_packet_test_alloc() { param = bt_test_param_add( bt_packet_test->bt_test, "Mode", - SIZEOF_ARRAY(bt_param_mode), + COUNT_OF(bt_param_mode), bt_packet_test_mode_changed, bt_packet_test); bt_test_set_current_value_index(param, 0); @@ -119,7 +119,7 @@ BtPacketTest* bt_packet_test_alloc() { param = bt_test_param_add( bt_packet_test->bt_test, "Channel", - SIZEOF_ARRAY(bt_param_channel), + COUNT_OF(bt_param_channel), bt_packet_test_channel_changed, bt_packet_test); bt_test_set_current_value_index(param, 0); @@ -129,7 +129,7 @@ BtPacketTest* bt_packet_test_alloc() { param = bt_test_param_add( bt_packet_test->bt_test, "Data rate", - SIZEOF_ARRAY(bt_param_data_rate), + COUNT_OF(bt_param_data_rate), bt_packet_test_param_channel, bt_packet_test); bt_test_set_current_value_index(param, 0); diff --git a/applications/bt/bt_hid_app/bt_hid.c b/applications/bt/bt_hid_app/bt_hid.c index ab13f6f35fb..4b1037cdd73 100755 --- a/applications/bt/bt_hid_app/bt_hid.c +++ b/applications/bt/bt_hid_app/bt_hid.c @@ -33,10 +33,12 @@ void bt_hid_dialog_callback(DialogExResult result, void* context) { } uint32_t bt_hid_exit_confirm_view(void* context) { + UNUSED(context); return BtHidViewExitConfirm; } uint32_t bt_hid_exit(void* context) { + UNUSED(context); return VIEW_NONE; } @@ -139,6 +141,7 @@ void bt_hid_app_free(BtHid* app) { } int32_t bt_hid_app(void* p) { + UNUSED(p); // Switch profile to Hid BtHid* app = bt_hid_app_alloc(); bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app); diff --git a/applications/bt/bt_settings_app/bt_settings_app.c b/applications/bt/bt_settings_app/bt_settings_app.c index d9dfa74dcf1..cb55e9310ed 100755 --- a/applications/bt/bt_settings_app/bt_settings_app.c +++ b/applications/bt/bt_settings_app/bt_settings_app.c @@ -76,6 +76,7 @@ void bt_settings_app_free(BtSettingsApp* app) { } extern int32_t bt_settings_app(void* p) { + UNUSED(p); BtSettingsApp* app = bt_settings_app_alloc(); view_dispatcher_run(app->view_dispatcher); bt_settings_save(&app->settings); diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 4e200d6bdee..eefbb305225 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -130,10 +130,12 @@ void cli_motd() { } void cli_nl(Cli* cli) { + UNUSED(cli); printf("\r\n"); } void cli_prompt(Cli* cli) { + UNUSED(cli); printf("\r\n>: %s", string_get_cstr(cli->line)); fflush(stdout); } @@ -451,6 +453,7 @@ void cli_session_close(Cli* cli) { } int32_t cli_srv(void* p) { + UNUSED(p); Cli* cli = cli_alloc(); // Init basic cli commands diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index bdec231b0b1..2d059bd3ffe 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -12,6 +12,8 @@ #define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d" void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) { + UNUSED(context); + UNUSED(last); printf("%-24s: %s\r\n", key, value); } @@ -20,11 +22,14 @@ void cli_command_device_info_callback(const char* key, const char* value, bool l * This command is intended to be used by humans */ void cli_command_device_info(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(args); furi_hal_info_get(cli_command_device_info_callback, context); } void cli_command_help(Cli* cli, string_t args, void* context) { - (void)args; + UNUSED(args); + UNUSED(context); printf("Commands we have:"); // Command count @@ -62,6 +67,9 @@ void cli_command_help(Cli* cli, string_t args, void* context) { } void cli_command_date(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(context); + FuriHalRtcDateTime datetime = {0}; if(string_size(args) > 0) { @@ -135,6 +143,8 @@ void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* conte } void cli_command_log(Cli* cli, string_t args, void* context) { + UNUSED(args); + UNUSED(context); StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1); uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE]; @@ -152,6 +162,8 @@ void cli_command_log(Cli* cli, string_t args, void* context) { } void cli_command_vibro(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(context); if(!string_cmp(args, "0")) { NotificationApp* notification = furi_record_open("notification"); notification_message_block(notification, &sequence_reset_vibro); @@ -166,6 +178,8 @@ void cli_command_vibro(Cli* cli, string_t args, void* context) { } void cli_command_debug(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(context); if(!string_cmp(args, "0")) { furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); loader_update_menu(); @@ -180,6 +194,8 @@ void cli_command_debug(Cli* cli, string_t args, void* context) { } void cli_command_led(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(context); // Get first word as light name NotificationMessage notification_led_message; string_t light_name; @@ -233,6 +249,7 @@ void cli_command_led(Cli* cli, string_t args, void* context) { } void cli_command_gpio_set(Cli* cli, string_t args, void* context) { + UNUSED(context); char pin_names[][4] = { "PC0", "PC1", @@ -313,6 +330,8 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) { return; } } +#else + UNUSED(cli); #endif LL_GPIO_SetPinMode(gpio[num].port, gpio[num].pin, LL_GPIO_MODE_OUTPUT); @@ -325,6 +344,10 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) { } void cli_command_ps(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(args); + UNUSED(context); + const uint8_t threads_num_max = 32; osThreadId_t threads_id[threads_num_max]; uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max); @@ -344,6 +367,10 @@ void cli_command_ps(Cli* cli, string_t args, void* context) { } void cli_command_free(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(args); + UNUSED(context); + printf("Free heap size: %d\r\n", memmgr_get_free_heap()); printf("Total heap size: %d\r\n", memmgr_get_total_heap()); printf("Minimum heap size: %d\r\n", memmgr_get_minimum_free_heap()); @@ -351,10 +378,18 @@ void cli_command_free(Cli* cli, string_t args, void* context) { } void cli_command_free_blocks(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(args); + UNUSED(context); + memmgr_heap_printf_free_blocks(); } void cli_command_i2c(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(args); + UNUSED(context); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); printf("Scanning external i2c on PC0(SCL)/PC1(SDA)\r\n" "Clock: 100khz, 7bit address\r\n" @@ -391,4 +426,4 @@ void cli_commands_init(Cli* cli) { cli_add_command(cli, "led", CliCommandFlagDefault, cli_command_led, NULL); cli_add_command(cli, "gpio_set", CliCommandFlagDefault, cli_command_gpio_set, NULL); cli_add_command(cli, "i2c", CliCommandFlagDefault, cli_command_i2c, NULL); -} +} \ No newline at end of file diff --git a/applications/cli/cli_commands.h b/applications/cli/cli_commands.h index b82dae292c0..184eeb3739e 100644 --- a/applications/cli/cli_commands.h +++ b/applications/cli/cli_commands.h @@ -2,4 +2,4 @@ #include "cli_i.h" -void cli_commands_init(Cli* cli); \ No newline at end of file +void cli_commands_init(Cli* cli); diff --git a/applications/cli/cli_vcp.c b/applications/cli/cli_vcp.c index f570aee158e..84edca1835d 100644 --- a/applications/cli/cli_vcp.c +++ b/applications/cli/cli_vcp.c @@ -86,6 +86,7 @@ static void cli_vcp_deinit() { } static int32_t vcp_worker(void* context) { + UNUSED(context); bool tx_idle = true; size_t missed_rx = 0; uint8_t last_tx_pkt_len = 0; @@ -148,7 +149,7 @@ static int32_t vcp_worker(void* context) { if(len > 0) { furi_check( xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, osWaitForever) == - len); + (size_t)len); } } else { #ifdef CLI_VCP_DEBUG @@ -275,16 +276,19 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) { } static void cli_vcp_tx_stdout(void* _cookie, const char* data, size_t size) { + UNUSED(_cookie); cli_vcp_tx((const uint8_t*)data, size); } static void vcp_state_callback(void* context, uint8_t state) { + UNUSED(context); if(state == 0) { osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtDisconnect); } } static void vcp_on_cdc_control_line(void* context, uint8_t state) { + UNUSED(context); // bit 0: DTR state, bit 1: RTS state bool dtr = state & (1 << 0); @@ -296,11 +300,13 @@ static void vcp_on_cdc_control_line(void* context, uint8_t state) { } static void vcp_on_cdc_rx(void* context) { + UNUSED(context); uint32_t ret = osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtRx); furi_check((ret & osFlagsError) == 0); } static void vcp_on_cdc_tx_complete(void* context) { + UNUSED(context); osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtTx); } diff --git a/applications/crypto/crypto_cli.c b/applications/crypto/crypto_cli.c index 7cd9d5ccb17..a5ea80f8dc8 100644 --- a/applications/crypto/crypto_cli.c +++ b/applications/crypto/crypto_cli.c @@ -164,6 +164,7 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { } void crypto_cli_has_key(Cli* cli, string_t args) { + UNUSED(cli); int key_slot = 0; uint8_t iv[16]; @@ -185,6 +186,7 @@ void crypto_cli_has_key(Cli* cli, string_t args) { } void crypto_cli_store_key(Cli* cli, string_t args) { + UNUSED(cli); int key_slot = 0; int key_size = 0; string_t key_type; @@ -277,6 +279,7 @@ void crypto_cli_store_key(Cli* cli, string_t args) { } static void crypto_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t cmd; string_init(cmd); diff --git a/applications/debug_tools/blink_test.c b/applications/debug_tools/blink_test.c index 35f9f434924..2efaa4dabb2 100644 --- a/applications/debug_tools/blink_test.c +++ b/applications/debug_tools/blink_test.c @@ -27,6 +27,7 @@ static void blink_test_update(void* ctx) { } static void blink_test_draw_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 2, 10, "Blink application"); @@ -41,6 +42,7 @@ static void blink_test_input_callback(InputEvent* input_event, void* ctx) { } int32_t blink_test_app(void* p) { + UNUSED(p); osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(BlinkEvent), NULL); // Configure view port diff --git a/applications/debug_tools/display_test/display_test.c b/applications/debug_tools/display_test/display_test.c index 1a9a0e43870..95aea1deb70 100644 --- a/applications/debug_tools/display_test/display_test.c +++ b/applications/debug_tools/display_test/display_test.c @@ -70,10 +70,12 @@ static void display_test_submenu_callback(void* context, uint32_t index) { } static uint32_t display_test_previous_callback(void* context) { + UNUSED(context); return DisplayTestViewSubmenu; } static uint32_t display_test_exit_callback(void* context) { + UNUSED(context); return VIEW_NONE; } @@ -210,6 +212,7 @@ void display_test_free(DisplayTest* instance) { } int32_t display_test_run(DisplayTest* instance) { + UNUSED(instance); view_dispatcher_switch_to_view(instance->view_dispatcher, DisplayTestViewSubmenu); view_dispatcher_run(instance->view_dispatcher); @@ -217,6 +220,8 @@ int32_t display_test_run(DisplayTest* instance) { } int32_t display_test_app(void* p) { + UNUSED(p); + DisplayTest* instance = display_test_alloc(); int32_t ret = display_test_run(instance); diff --git a/applications/debug_tools/display_test/view_display_test.c b/applications/debug_tools/display_test/view_display_test.c index cc5f5dcfa07..133195d0f62 100644 --- a/applications/debug_tools/display_test/view_display_test.c +++ b/applications/debug_tools/display_test/view_display_test.c @@ -13,6 +13,7 @@ struct ViewDisplayTest { }; static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) { + UNUSED(_model); canvas_draw_str(canvas, 12, 24, "Use < and > to switch tests"); canvas_draw_str(canvas, 12, 36, "Use ^ and v to switch size"); canvas_draw_str(canvas, 32, 48, "Use (o) to flip"); diff --git a/applications/debug_tools/keypad_test.c b/applications/debug_tools/keypad_test.c index ae980317fde..705a1542695 100644 --- a/applications/debug_tools/keypad_test.c +++ b/applications/debug_tools/keypad_test.c @@ -60,6 +60,7 @@ static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { } int32_t keypad_test_app(void* p) { + UNUSED(p); osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL); furi_check(event_queue); diff --git a/applications/debug_tools/text_box_test.c b/applications/debug_tools/text_box_test.c index 1c7ce18b106..bc56e88b88c 100644 --- a/applications/debug_tools/text_box_test.c +++ b/applications/debug_tools/text_box_test.c @@ -70,6 +70,7 @@ static void text_box_test_input_callback(InputEvent* input_event, void* ctx) { } int32_t text_box_test_app(void* p) { + UNUSED(p); osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL); furi_check(event_queue); @@ -90,7 +91,7 @@ int32_t text_box_test_app(void* p) { Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); - uint32_t test_renders_num = SIZEOF_ARRAY(text_box_test_render); + uint32_t test_renders_num = COUNT_OF(text_box_test_render); InputEvent event; while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { TextBoxTestState* state = acquire_mutex_block(&state_mutex); diff --git a/applications/debug_tools/uart_echo.c b/applications/debug_tools/uart_echo.c index 0e4ee1d8976..206c6c06f86 100644 --- a/applications/debug_tools/uart_echo.c +++ b/applications/debug_tools/uart_echo.c @@ -80,11 +80,13 @@ static void uart_echo_view_draw_callback(Canvas* canvas, void* _model) { } static bool uart_echo_view_input_callback(InputEvent* event, void* context) { - bool consumed = false; - return consumed; + UNUSED(event); + UNUSED(context); + return false; } static uint32_t uart_echo_exit(void* context) { + UNUSED(context); return VIEW_NONE; } @@ -170,7 +172,10 @@ static int32_t uart_echo_worker(void* context) { notification_message(app->notification, &sequence_notification); with_view_model( - app->view, (UartDumpModel * model) { return true; }); + app->view, (UartDumpModel * model) { + UNUSED(model); + return true; + }); } } @@ -261,6 +266,7 @@ static void uart_echo_app_free(UartEchoApp* app) { } int32_t uart_echo_app(void* p) { + UNUSED(p); UartEchoApp* app = uart_echo_app_alloc(); view_dispatcher_run(app->view_dispatcher); uart_echo_app_free(app); diff --git a/applications/debug_tools/usb_mouse.c b/applications/debug_tools/usb_mouse.c index 6943e189d5e..a136375ac5f 100644 --- a/applications/debug_tools/usb_mouse.c +++ b/applications/debug_tools/usb_mouse.c @@ -18,6 +18,7 @@ typedef struct { } UsbMouseEvent; static void usb_mouse_render_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); @@ -37,6 +38,7 @@ static void usb_mouse_input_callback(InputEvent* input_event, void* ctx) { } int32_t usb_mouse_app(void* p) { + UNUSED(p); osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(UsbMouseEvent), NULL); furi_check(event_queue); ViewPort* view_port = view_port_alloc(); diff --git a/applications/debug_tools/usb_test.c b/applications/debug_tools/usb_test.c index 0e8f068f5d1..44a17ceb84b 100644 --- a/applications/debug_tools/usb_test.c +++ b/applications/debug_tools/usb_test.c @@ -51,6 +51,7 @@ void usb_test_submenu_callback(void* context, uint32_t index) { } uint32_t usb_test_exit(void* context) { + UNUSED(context); return VIEW_NONE; } @@ -113,6 +114,7 @@ void usb_test_app_free(UsbTestApp* app) { } int32_t usb_test_app(void* p) { + UNUSED(p); UsbTestApp* app = usb_test_app_alloc(); view_dispatcher_run(app->view_dispatcher); diff --git a/applications/debug_tools/vibro_test.c b/applications/debug_tools/vibro_test.c index 07ce93b7a32..af6d336deeb 100644 --- a/applications/debug_tools/vibro_test.c +++ b/applications/debug_tools/vibro_test.c @@ -6,6 +6,7 @@ #include void vibro_test_draw_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 2, 10, "Vibro application"); @@ -22,6 +23,7 @@ void vibro_test_input_callback(InputEvent* input_event, void* ctx) { } int32_t vibro_test_app(void* p) { + UNUSED(p); osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); // Configure view port diff --git a/applications/desktop/animations/animation_manager.c b/applications/desktop/animations/animation_manager.c index ea241ec3397..f8e937162bf 100644 --- a/applications/desktop/animations/animation_manager.c +++ b/applications/desktop/animations/animation_manager.c @@ -364,6 +364,7 @@ static bool animation_manager_is_valid_idle_animation( static StorageAnimation* animation_manager_select_idle_animation(AnimationManager* animation_manager) { + UNUSED(animation_manager); StorageAnimationList_t animation_list; StorageAnimationList_init(animation_list); animation_storage_fill_animation_list(&animation_list); diff --git a/applications/desktop/animations/animation_storage.c b/applications/desktop/animations/animation_storage.c index aa0f274b6d7..8f2740a7f1f 100644 --- a/applications/desktop/animations/animation_storage.c +++ b/applications/desktop/animations/animation_storage.c @@ -130,7 +130,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis flipper_format_free(file); // add hard-coded animations - for(int i = 0; i < dolphin_internal_size; ++i) { + for(size_t i = 0; i < dolphin_internal_size; ++i) { StorageAnimationList_push_back(*animation_list, (StorageAnimation*)&dolphin_internal[i]); } @@ -142,7 +142,7 @@ StorageAnimation* animation_storage_find_animation(const char* name) { furi_assert(strlen(name)); StorageAnimation* storage_animation = NULL; - for(int i = 0; i < dolphin_blocking_size; ++i) { + for(size_t i = 0; i < dolphin_blocking_size; ++i) { if(!strcmp(dolphin_blocking[i].manifest_info.name, name)) { storage_animation = (StorageAnimation*)&dolphin_blocking[i]; break; @@ -150,7 +150,7 @@ StorageAnimation* animation_storage_find_animation(const char* name) { } if(!storage_animation) { - for(int i = 0; i < dolphin_internal_size; ++i) { + for(size_t i = 0; i < dolphin_internal_size; ++i) { if(!strcmp(dolphin_internal[i].manifest_info.name, name)) { storage_animation = (StorageAnimation*)&dolphin_internal[i]; break; @@ -365,7 +365,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo animation->frame_bubble_sequences = malloc(sizeof(FrameBubble*) * animation->frame_bubble_sequences_count); - uint32_t current_slot = 0; + int32_t current_slot = 0; for(int i = 0; i < animation->frame_bubble_sequences_count; ++i) { FURI_CONST_ASSIGN_PTR( animation->frame_bubble_sequences[i], malloc(sizeof(FrameBubble))); @@ -374,7 +374,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo const FrameBubble* bubble = animation->frame_bubble_sequences[0]; int8_t index = -1; for(;;) { - if(!flipper_format_read_uint32(ff, "Slot", ¤t_slot, 1)) break; + if(!flipper_format_read_int32(ff, "Slot", ¤t_slot, 1)) break; if((current_slot != 0) && (index == -1)) break; if(current_slot == index) { diff --git a/applications/desktop/desktop.c b/applications/desktop/desktop.c index 7686a14568f..34c169e07a9 100644 --- a/applications/desktop/desktop.c +++ b/applications/desktop/desktop.c @@ -33,6 +33,7 @@ static void desktop_loader_callback(const void* message, void* context) { } static void desktop_lock_icon_callback(Canvas* canvas, void* context) { + UNUSED(context); furi_assert(canvas); canvas_draw_icon(canvas, 0, 0, &I_Lock_8x8); } @@ -298,6 +299,7 @@ static bool desktop_is_first_start() { } int32_t desktop_srv(void* p) { + UNUSED(p); Desktop* desktop = desktop_alloc(); bool loaded = LOAD_DESKTOP_SETTINGS(&desktop->settings); diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c index 7486d4aa3c2..c0b3190e496 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c @@ -53,4 +53,5 @@ bool desktop_settings_scene_pin_disable_on_event(void* context, SceneManagerEven } void desktop_settings_scene_pin_disable_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c index 882b8f0ac70..a023d6b7aa6 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c @@ -18,6 +18,7 @@ static void pin_error_back_callback(void* context) { } static void pin_error_done_callback(const PinCode* pin_code, void* context) { + UNUSED(pin_code); furi_assert(context); DesktopSettingsApp* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c index 22727a7a096..b8d630f2eed 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto.c @@ -41,4 +41,5 @@ bool desktop_settings_scene_pin_setup_howto_on_event(void* context, SceneManager } void desktop_settings_scene_pin_setup_howto_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/desktop/scenes/desktop_scene_fault.c b/applications/desktop/scenes/desktop_scene_fault.c index b75b32aa63b..36c958af58c 100644 --- a/applications/desktop/scenes/desktop_scene_fault.c +++ b/applications/desktop/scenes/desktop_scene_fault.c @@ -47,5 +47,6 @@ bool desktop_scene_fault_on_event(void* context, SceneManagerEvent event) { } void desktop_scene_fault_on_exit(void* context) { + UNUSED(context); furi_hal_rtc_set_fault_data(0); } diff --git a/applications/desktop/scenes/desktop_scene_first_start.c b/applications/desktop/scenes/desktop_scene_first_start.c index 9563094cf0b..dbdf8919e85 100644 --- a/applications/desktop/scenes/desktop_scene_first_start.c +++ b/applications/desktop/scenes/desktop_scene_first_start.c @@ -50,4 +50,5 @@ bool desktop_scene_first_start_on_event(void* context, SceneManagerEvent event) } void desktop_scene_first_start_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/desktop/scenes/desktop_scene_lock_menu.c b/applications/desktop/scenes/desktop_scene_lock_menu.c index 11478810d15..a86bb184b6c 100644 --- a/applications/desktop/scenes/desktop_scene_lock_menu.c +++ b/applications/desktop/scenes/desktop_scene_lock_menu.c @@ -81,4 +81,5 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { } void desktop_scene_lock_menu_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/desktop/scenes/desktop_scene_locked.c b/applications/desktop/scenes/desktop_scene_locked.c index 90df22269da..f4c08d32563 100644 --- a/applications/desktop/scenes/desktop_scene_locked.c +++ b/applications/desktop/scenes/desktop_scene_locked.c @@ -109,4 +109,5 @@ bool desktop_scene_locked_on_event(void* context, SceneManagerEvent event) { } void desktop_scene_locked_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/desktop/scenes/desktop_scene_pin_timeout.c b/applications/desktop/scenes/desktop_scene_pin_timeout.c index 3c267a0dd55..ebe825e6a91 100644 --- a/applications/desktop/scenes/desktop_scene_pin_timeout.c +++ b/applications/desktop/scenes/desktop_scene_pin_timeout.c @@ -43,4 +43,5 @@ bool desktop_scene_pin_timeout_on_event(void* context, SceneManagerEvent event) } void desktop_scene_pin_timeout_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/desktop/views/desktop_view_pin_timeout.c b/applications/desktop/views/desktop_view_pin_timeout.c index d9827339374..6e1e807fdb1 100644 --- a/applications/desktop/views/desktop_view_pin_timeout.c +++ b/applications/desktop/views/desktop_view_pin_timeout.c @@ -51,6 +51,8 @@ static void desktop_view_pin_timeout_timer_callback(TimerHandle_t timer) { } static bool desktop_view_pin_timeout_input(InputEvent* event, void* context) { + UNUSED(event); + UNUSED(context); return true; } diff --git a/applications/dialogs/dialogs.c b/applications/dialogs/dialogs.c index 2c8d24181ca..cf4a2ad6887 100644 --- a/applications/dialogs/dialogs.c +++ b/applications/dialogs/dialogs.c @@ -11,6 +11,7 @@ static DialogsApp* dialogs_app_alloc() { } static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* message) { + UNUSED(app); switch(message->command) { case DialogsAppCommandFileOpen: message->return_data->bool_value = @@ -25,6 +26,7 @@ static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* mess } int32_t dialogs_srv(void* p) { + UNUSED(p); DialogsApp* app = dialogs_app_alloc(); furi_record_create("dialogs", app); diff --git a/applications/dialogs/dialogs.h b/applications/dialogs/dialogs.h index 2a05ef417d1..9c71c0989f1 100644 --- a/applications/dialogs/dialogs.h +++ b/applications/dialogs/dialogs.h @@ -132,4 +132,4 @@ void dialog_message_show_storage_error(DialogsApp* context, const char* error_te #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/dialogs/dialogs_api.c b/applications/dialogs/dialogs_api.c index 261d9d4e1f7..c4efb287d92 100644 --- a/applications/dialogs/dialogs_api.c +++ b/applications/dialogs/dialogs_api.c @@ -70,4 +70,4 @@ void dialog_message_show_storage_error(DialogsApp* context, const char* error_te dialog_message_set_buttons(message, "Back", NULL, NULL); dialog_message_show(context, message); dialog_message_free(message); -} \ No newline at end of file +} diff --git a/applications/dialogs/dialogs_i.h b/applications/dialogs/dialogs_i.h index 7b601eda745..b61e10ab980 100644 --- a/applications/dialogs/dialogs_i.h +++ b/applications/dialogs/dialogs_i.h @@ -12,4 +12,4 @@ struct DialogsApp { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/dialogs/dialogs_message.h b/applications/dialogs/dialogs_message.h index 48324b15cf0..d7b5fabf4d2 100644 --- a/applications/dialogs/dialogs_message.h +++ b/applications/dialogs/dialogs_message.h @@ -43,4 +43,4 @@ typedef struct { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/dialogs/dialogs_module_file_select.h b/applications/dialogs/dialogs_module_file_select.h index da012fb4e29..749fe9c1d7f 100644 --- a/applications/dialogs/dialogs_module_file_select.h +++ b/applications/dialogs/dialogs_module_file_select.h @@ -9,4 +9,4 @@ bool dialogs_app_process_module_file_select(const DialogsAppMessageDataFileSelec #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/dialogs/dialogs_module_message.h b/applications/dialogs/dialogs_module_message.h index 189870acd89..b4f1b162cb7 100644 --- a/applications/dialogs/dialogs_module_message.h +++ b/applications/dialogs/dialogs_module_message.h @@ -9,4 +9,4 @@ DialogMessageButton dialogs_app_process_module_message(const DialogsAppMessageDa #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/dialogs/view_holder.h b/applications/dialogs/view_holder.h index 785ad20a8f5..8e7db3b857f 100644 --- a/applications/dialogs/view_holder.h +++ b/applications/dialogs/view_holder.h @@ -95,4 +95,4 @@ void view_holder_update(View* view, void* context); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/dolphin/dolphin.c b/applications/dolphin/dolphin.c index 60068afff89..479602868ed 100644 --- a/applications/dolphin/dolphin.c +++ b/applications/dolphin/dolphin.c @@ -118,6 +118,7 @@ void dolphin_event_send_wait(Dolphin* dolphin, DolphinEvent* event) { } void dolphin_event_release(Dolphin* dolphin, DolphinEvent* event) { + UNUSED(dolphin); if(event->flag) { osEventFlagsSet(event->flag, DOLPHIN_LOCK_EVENT_FLAG); } @@ -149,6 +150,7 @@ static void dolphin_update_clear_limits_timer_period(Dolphin* dolphin) { } int32_t dolphin_srv(void* p) { + UNUSED(p); Dolphin* dolphin = dolphin_alloc(); furi_record_create("dolphin", dolphin); diff --git a/applications/dolphin/helpers/dolphin_state.h b/applications/dolphin/helpers/dolphin_state.h index 07d0b427c38..3e02fb87201 100644 --- a/applications/dolphin/helpers/dolphin_state.h +++ b/applications/dolphin/helpers/dolphin_state.h @@ -12,7 +12,7 @@ typedef struct { uint32_t flags; uint32_t icounter; - uint32_t butthurt; + int32_t butthurt; uint64_t timestamp; } DolphinStoreData; diff --git a/applications/dolphin/passport/passport.c b/applications/dolphin/passport/passport.c index 3df88a8355e..13bf086b5dc 100644 --- a/applications/dolphin/passport/passport.c +++ b/applications/dolphin/passport/passport.c @@ -90,6 +90,7 @@ static void render_callback(Canvas* canvas, void* ctx) { } int32_t passport_app(void* p) { + UNUSED(p); osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL); furi_assert(semaphore); diff --git a/applications/gpio/gpio_app.c b/applications/gpio/gpio_app.c index 7dfce83667a..b5f5184a665 100644 --- a/applications/gpio/gpio_app.c +++ b/applications/gpio/gpio_app.c @@ -95,6 +95,7 @@ void gpio_app_free(GpioApp* app) { } int32_t gpio_app(void* p) { + UNUSED(p); GpioApp* gpio_app = gpio_app_alloc(); view_dispatcher_run(gpio_app->view_dispatcher); diff --git a/applications/gpio/scenes/gpio_scene_test.c b/applications/gpio/scenes/gpio_scene_test.c index 009e2ff4300..b015d80902e 100644 --- a/applications/gpio/scenes/gpio_scene_test.c +++ b/applications/gpio/scenes/gpio_scene_test.c @@ -19,9 +19,12 @@ void gpio_scene_test_on_enter(void* context) { } bool gpio_scene_test_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); return false; } void gpio_scene_test_on_exit(void* context) { + UNUSED(context); gpio_item_configure_all_pins(GpioModeAnalog); } diff --git a/applications/gpio/scenes/gpio_scene_usb_uart_config.c b/applications/gpio/scenes/gpio_scene_usb_uart_config.c index 6fba0d1ecdb..653a306aa56 100644 --- a/applications/gpio/scenes/gpio_scene_usb_uart_config.c +++ b/applications/gpio/scenes/gpio_scene_usb_uart_config.c @@ -28,12 +28,9 @@ static const uint32_t baudrate_list[] = { }; bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) { - //GpioApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - } - return consumed; + UNUSED(context); + UNUSED(event); + return false; } static void line_vcp_cb(VariableItem* item) { diff --git a/applications/gpio/usb_uart_bridge.c b/applications/gpio/usb_uart_bridge.c index 8f27340e402..f70cf640d8c 100644 --- a/applications/gpio/usb_uart_bridge.c +++ b/applications/gpio/usb_uart_bridge.c @@ -101,6 +101,7 @@ static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) { } static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) { + UNUSED(usb_uart); furi_hal_cdc_set_callbacks(vcp_ch, NULL, NULL); FURI_LOG_I("", "Deinit %d", vcp_ch); if(vcp_ch != 0) { @@ -120,6 +121,7 @@ static void usb_uart_serial_init(UsbUartBridge* usb_uart, uint8_t uart_ch) { } static void usb_uart_serial_deinit(UsbUartBridge* usb_uart, uint8_t uart_ch) { + UNUSED(usb_uart); furi_hal_uart_set_irq_cb(uart_ch, NULL, NULL); if(uart_ch == FuriHalUartIdUSART1) furi_hal_console_enable(); @@ -143,7 +145,7 @@ static void usb_uart_set_baudrate(UsbUartBridge* usb_uart, uint32_t baudrate) { static void usb_uart_update_ctrl_lines(UsbUartBridge* usb_uart) { if(usb_uart->cfg.flow_pins != 0) { - furi_assert((usb_uart->cfg.flow_pins - 1) < (sizeof(flow_pins) / sizeof(flow_pins[0]))); + furi_assert((size_t)(usb_uart->cfg.flow_pins - 1) < COUNT_OF(flow_pins)); uint8_t state = furi_hal_cdc_get_ctrl_line_state(usb_uart->cfg.vcp_ch); furi_hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][0], !(state & USB_CDC_BIT_RTS)); @@ -171,7 +173,7 @@ static int32_t usb_uart_worker(void* context) { usb_uart_serial_init(usb_uart, usb_uart->cfg.uart_ch); usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate); if(usb_uart->cfg.flow_pins != 0) { - furi_assert((usb_uart->cfg.flow_pins - 1) < (sizeof(flow_pins) / sizeof(flow_pins[0]))); + furi_assert((size_t)(usb_uart->cfg.flow_pins - 1) < COUNT_OF(flow_pins)); furi_hal_gpio_init_simple( flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeOutputPushPull); furi_hal_gpio_init_simple( @@ -238,9 +240,7 @@ static int32_t usb_uart_worker(void* context) { flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); } if(usb_uart->cfg_new.flow_pins != 0) { - furi_assert( - (usb_uart->cfg_new.flow_pins - 1) < - (sizeof(flow_pins) / sizeof(flow_pins[0]))); + furi_assert((size_t)(usb_uart->cfg_new.flow_pins - 1) < COUNT_OF(flow_pins)); furi_hal_gpio_init_simple( flow_pins[usb_uart->cfg_new.flow_pins - 1][0], GpioModeOutputPushPull); furi_hal_gpio_init_simple( @@ -318,14 +318,18 @@ static void vcp_on_cdc_rx(void* context) { } static void vcp_state_callback(void* context, uint8_t state) { + UNUSED(context); + UNUSED(state); } static void vcp_on_cdc_control_line(void* context, uint8_t state) { + UNUSED(state); UsbUartBridge* usb_uart = (UsbUartBridge*)context; osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtCtrlLineSet); } static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) { + UNUSED(config); UsbUartBridge* usb_uart = (UsbUartBridge*)context; osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtLineCfgSet); } diff --git a/applications/gpio/views/gpio_test.c b/applications/gpio/views/gpio_test.c index cf05dafadea..37c2f408326 100755 --- a/applications/gpio/views/gpio_test.c +++ b/applications/gpio/views/gpio_test.c @@ -123,6 +123,7 @@ void gpio_test_set_ok_callback(GpioTest* gpio_test, GpioTestOkCallback callback, furi_assert(callback); with_view_model( gpio_test->view, (GpioTestModel * model) { + UNUSED(model); gpio_test->callback = callback; gpio_test->context = context; return false; diff --git a/applications/gpio/views/gpio_usb_uart.c b/applications/gpio/views/gpio_usb_uart.c index cd507570166..d2d371b6822 100644 --- a/applications/gpio/views/gpio_usb_uart.c +++ b/applications/gpio/views/gpio_usb_uart.c @@ -130,6 +130,7 @@ void gpio_usb_uart_set_callback(GpioUsbUart* usb_uart, GpioUsbUartCallback callb with_view_model( usb_uart->view, (GpioUsbUartModel * model) { + UNUSED(model); usb_uart->callback = callback; usb_uart->context = context; return false; diff --git a/applications/gui/gui.c b/applications/gui/gui.c index 9ecfdebbf96..4fc0935ea8f 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -469,6 +469,7 @@ Gui* gui_alloc() { } int32_t gui_srv(void* p) { + UNUSED(p); Gui* gui = gui_alloc(); furi_record_create("gui", gui); diff --git a/applications/gui/icon.c b/applications/gui/icon.c index bbc77516911..98f35b12a1a 100644 --- a/applications/gui/icon.c +++ b/applications/gui/icon.c @@ -10,4 +10,4 @@ uint8_t icon_get_height(const Icon* instance) { const uint8_t* icon_get_data(const Icon* instance) { return instance->frames[0]; -} \ No newline at end of file +} diff --git a/applications/gui/icon.h b/applications/gui/icon.h index ebe40266b4b..e33c4d34d2b 100644 --- a/applications/gui/icon.h +++ b/applications/gui/icon.h @@ -39,4 +39,4 @@ const uint8_t* icon_get_data(const Icon* instance); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/gui/modules/button_menu.c b/applications/gui/modules/button_menu.c index 8f38efc4651..36fd6f3abca 100644 --- a/applications/gui/modules/button_menu.c +++ b/applications/gui/modules/button_menu.c @@ -331,7 +331,7 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) { ButtonMenuItemArray_it_t it; for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it); ButtonMenuItemArray_next(it), ++item_position) { - if(ButtonMenuItemArray_cref(it)->index == index) { + if((uint32_t)ButtonMenuItemArray_cref(it)->index == index) { model->position = item_position; break; } diff --git a/applications/gui/modules/button_panel.c b/applications/gui/modules/button_panel.c index c2328d20656..e3ae59a3671 100644 --- a/applications/gui/modules/button_panel.c +++ b/applications/gui/modules/button_panel.c @@ -215,8 +215,8 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) { static void button_panel_process_down(ButtonPanel* button_panel) { with_view_model( button_panel->view, (ButtonPanelModel * model) { - size_t new_selected_item_x = model->selected_item_x; - size_t new_selected_item_y = model->selected_item_y; + uint16_t new_selected_item_x = model->selected_item_x; + uint16_t new_selected_item_y = model->selected_item_y; size_t i; if(new_selected_item_y >= (model->reserve_y - 1)) return false; @@ -291,8 +291,8 @@ static void button_panel_process_left(ButtonPanel* button_panel) { static void button_panel_process_right(ButtonPanel* button_panel) { with_view_model( button_panel->view, (ButtonPanelModel * model) { - size_t new_selected_item_x = model->selected_item_x; - size_t new_selected_item_y = model->selected_item_y; + uint16_t new_selected_item_x = model->selected_item_x; + uint16_t new_selected_item_y = model->selected_item_y; size_t i; if(new_selected_item_x >= (model->reserve_x - 1)) return false; diff --git a/applications/gui/modules/byte_input.h b/applications/gui/modules/byte_input.h index b2f94f3cacc..42c4b5d65f9 100644 --- a/applications/gui/modules/byte_input.h +++ b/applications/gui/modules/byte_input.h @@ -66,4 +66,4 @@ void byte_input_set_header_text(ByteInput* byte_input, const char* text); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/gui/modules/empty_screen.c b/applications/gui/modules/empty_screen.c index 61b4af36c39..0a51bc71c6a 100644 --- a/applications/gui/modules/empty_screen.c +++ b/applications/gui/modules/empty_screen.c @@ -6,10 +6,13 @@ struct EmptyScreen { }; static void empty_screen_view_draw_callback(Canvas* canvas, void* _model) { + UNUSED(_model); canvas_clear(canvas); } static bool empty_screen_view_input_callback(InputEvent* event, void* context) { + UNUSED(event); + UNUSED(context); return false; } diff --git a/applications/gui/modules/empty_screen.h b/applications/gui/modules/empty_screen.h index 43d2fe04995..23ebeb3a05d 100644 --- a/applications/gui/modules/empty_screen.h +++ b/applications/gui/modules/empty_screen.h @@ -38,4 +38,4 @@ View* empty_screen_get_view(EmptyScreen* empty_screen); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/gui/modules/file_select.h b/applications/gui/modules/file_select.h index 7318c87c7cf..ed3d5b60c3f 100644 --- a/applications/gui/modules/file_select.h +++ b/applications/gui/modules/file_select.h @@ -28,4 +28,4 @@ void file_select_set_selected_file(FileSelect* file_select, const char* filename #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/gui/modules/loading.c b/applications/gui/modules/loading.c index 7f623e24549..60dc8338d1a 100644 --- a/applications/gui/modules/loading.c +++ b/applications/gui/modules/loading.c @@ -34,6 +34,7 @@ static void loading_draw_callback(Canvas* canvas, void* _model) { } static bool loading_input_callback(InputEvent* event, void* context) { + UNUSED(event); furi_assert(context); return true; } diff --git a/applications/gui/modules/text_box.c b/applications/gui/modules/text_box.c index a7d0d7630cc..52307ec25d5 100755 --- a/applications/gui/modules/text_box.c +++ b/applications/gui/modules/text_box.c @@ -87,7 +87,7 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) { model->scroll_num = line_num - 4; model->scroll_pos = line_num - 5; } else { - model->scroll_num = MAX(line_num - 4, 0); + model->scroll_num = MAX(line_num - 4, 0u); model->scroll_pos = 0; } } diff --git a/applications/gui/modules/text_input.c b/applications/gui/modules/text_input.c index 058762adf5d..04cd2d7f843 100644 --- a/applications/gui/modules/text_input.c +++ b/applications/gui/modules/text_input.c @@ -122,15 +122,15 @@ static const TextInputKey* get_row(uint8_t row_index) { return row; } -static const char get_selected_char(TextInputModel* model) { +static char get_selected_char(TextInputModel* model) { return get_row(model->selected_row)[model->selected_column].text; } -static const bool char_is_lowercase(char letter) { +static bool char_is_lowercase(char letter) { return (letter >= 0x61 && letter <= 0x7A); } -static const char char_to_uppercase(const char letter) { +static char char_to_uppercase(const char letter) { if(isalpha(letter)) { return (letter - 0x20); } else { @@ -260,6 +260,7 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { } static void text_input_handle_up(TextInput* text_input, TextInputModel* model) { + UNUSED(text_input); if(model->selected_row > 0) { model->selected_row--; if(model->selected_column > get_row_size(model->selected_row) - 6) { @@ -269,6 +270,7 @@ static void text_input_handle_up(TextInput* text_input, TextInputModel* model) { } static void text_input_handle_down(TextInput* text_input, TextInputModel* model) { + UNUSED(text_input); if(model->selected_row < keyboard_row_count - 1) { model->selected_row++; if(model->selected_column > get_row_size(model->selected_row) - 4) { @@ -278,6 +280,7 @@ static void text_input_handle_down(TextInput* text_input, TextInputModel* model) } static void text_input_handle_left(TextInput* text_input, TextInputModel* model) { + UNUSED(text_input); if(model->selected_column > 0) { model->selected_column--; } else { @@ -286,6 +289,7 @@ static void text_input_handle_left(TextInput* text_input, TextInputModel* model) } static void text_input_handle_right(TextInput* text_input, TextInputModel* model) { + UNUSED(text_input); if(model->selected_column < get_row_size(model->selected_row) - 1) { model->selected_column++; } else { diff --git a/applications/gui/modules/validators.h b/applications/gui/modules/validators.h index 3a834a8a606..15dbe901f67 100644 --- a/applications/gui/modules/validators.h +++ b/applications/gui/modules/validators.h @@ -19,4 +19,4 @@ bool validator_is_file_callback(const char* text, string_t error, void* context) #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/gui/modules/variable_item_list.c b/applications/gui/modules/variable_item_list.c index ebbdd434cd8..4e5e4664f2c 100644 --- a/applications/gui/modules/variable_item_list.c +++ b/applications/gui/modules/variable_item_list.c @@ -364,6 +364,7 @@ void variable_item_list_set_enter_callback( furi_assert(callback); with_view_model( variable_item_list->view, (VariableItemListModel * model) { + UNUSED(model); variable_item_list->callback = callback; variable_item_list->context = context; return false; diff --git a/applications/gui/view.c b/applications/gui/view.c index e9642d9b85e..ec73882de55 100644 --- a/applications/gui/view.c +++ b/applications/gui/view.c @@ -126,6 +126,7 @@ void view_commit_model(View* view, bool update) { } void view_icon_animation_callback(IconAnimation* instance, void* context) { + UNUSED(instance); furi_assert(context); View* view = context; if(view->update_callback) { diff --git a/applications/ibutton/ibutton.cpp b/applications/ibutton/ibutton.cpp index 35dc2ce6c9f..aae0d31738c 100644 --- a/applications/ibutton/ibutton.cpp +++ b/applications/ibutton/ibutton.cpp @@ -7,4 +7,4 @@ extern "C" int32_t ibutton_app(void* p) { delete app; return 255; -} \ No newline at end of file +} diff --git a/applications/ibutton/ibutton_app.h b/applications/ibutton/ibutton_app.h index d3d8cac68e2..08af38573a8 100644 --- a/applications/ibutton/ibutton_app.h +++ b/applications/ibutton/ibutton_app.h @@ -141,4 +141,4 @@ class iButtonApp { bool load_key_data(string_t key_path); void make_app_folder(); -}; \ No newline at end of file +}; diff --git a/applications/ibutton/ibutton_cli.c b/applications/ibutton/ibutton_cli.c index c50ec210e8d..4592cdad9ee 100644 --- a/applications/ibutton/ibutton_cli.c +++ b/applications/ibutton/ibutton_cli.c @@ -240,6 +240,7 @@ void ibutton_cli_emulate(Cli* cli, string_t args) { }; static void ibutton_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t cmd; string_init(cmd); @@ -268,6 +269,7 @@ void onewire_cli_print_usage() { }; static void onewire_cli_search(Cli* cli) { + UNUSED(cli); OneWireHost* onewire = onewire_host_alloc(); uint8_t address[8]; bool done = false; @@ -297,6 +299,7 @@ static void onewire_cli_search(Cli* cli) { } void onewire_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t cmd; string_init(cmd); @@ -311,4 +314,4 @@ void onewire_cli(Cli* cli, string_t args, void* context) { } string_clear(cmd); -} \ No newline at end of file +} diff --git a/applications/ibutton/ibutton_event.h b/applications/ibutton/ibutton_event.h index b4dac2f4bfa..8b1775c1b4d 100644 --- a/applications/ibutton/ibutton_event.h +++ b/applications/ibutton/ibutton_event.h @@ -24,6 +24,7 @@ class iButtonEvent { // payload union { + uint32_t dummy; uint32_t menu_index; DialogExResult dialog_result; GuiButtonType widget_button_result; diff --git a/applications/ibutton/ibutton_view_manager.cpp b/applications/ibutton/ibutton_view_manager.cpp index efaa6f817d5..5a2c94f1e0b 100755 --- a/applications/ibutton/ibutton_view_manager.cpp +++ b/applications/ibutton/ibutton_view_manager.cpp @@ -129,7 +129,7 @@ void iButtonAppViewManager::send_event(iButtonEvent* event) { furi_check(result == osOK); } -uint32_t iButtonAppViewManager::previous_view_callback(void* context) { +uint32_t iButtonAppViewManager::previous_view_callback(void*) { if(event_queue != NULL) { iButtonEvent event; event.type = iButtonEvent::Type::EventTypeBack; @@ -137,4 +137,4 @@ uint32_t iButtonAppViewManager::previous_view_callback(void* context) { } return VIEW_IGNORE; -} \ No newline at end of file +} diff --git a/applications/ibutton/ibutton_view_manager.h b/applications/ibutton/ibutton_view_manager.h index 89d084baf18..336ba6e2fa2 100644 --- a/applications/ibutton/ibutton_view_manager.h +++ b/applications/ibutton/ibutton_view_manager.h @@ -48,4 +48,4 @@ class iButtonAppViewManager { Gui* gui; uint32_t previous_view_callback(void* context); -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_add_type.h b/applications/ibutton/scene/ibutton_scene_add_type.h index d49ac128de3..6a3d07e591f 100644 --- a/applications/ibutton/scene/ibutton_scene_add_type.h +++ b/applications/ibutton/scene/ibutton_scene_add_type.h @@ -9,4 +9,4 @@ class iButtonSceneAddType : public iButtonScene { private: uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_add_value.cpp b/applications/ibutton/scene/ibutton_scene_add_value.cpp index cb1e287cb6c..d0108ae5764 100755 --- a/applications/ibutton/scene/ibutton_scene_add_value.cpp +++ b/applications/ibutton/scene/ibutton_scene_add_value.cpp @@ -50,4 +50,4 @@ void iButtonSceneAddValue::on_exit(iButtonApp* app) { byte_input_set_result_callback(byte_input, NULL, NULL, NULL, NULL, 0); byte_input_set_header_text(byte_input, {0}); -} \ No newline at end of file +} diff --git a/applications/ibutton/scene/ibutton_scene_add_value.h b/applications/ibutton/scene/ibutton_scene_add_value.h index ff6de577588..7a734160397 100644 --- a/applications/ibutton/scene/ibutton_scene_add_value.h +++ b/applications/ibutton/scene/ibutton_scene_add_value.h @@ -10,4 +10,4 @@ class iButtonSceneAddValue : public iButtonScene { private: uint8_t new_key_data[IBUTTON_KEY_DATA_SIZE] = {}; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.h b/applications/ibutton/scene/ibutton_scene_delete_confirm.h index d82c376d0d3..cacbb7fe5e6 100644 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.h +++ b/applications/ibutton/scene/ibutton_scene_delete_confirm.h @@ -6,4 +6,4 @@ class iButtonSceneDeleteConfirm : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.cpp b/applications/ibutton/scene/ibutton_scene_delete_success.cpp index 8c645a5f5e5..ba1381610fc 100644 --- a/applications/ibutton/scene/ibutton_scene_delete_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_delete_success.cpp @@ -44,4 +44,4 @@ void iButtonSceneDeleteSuccess::on_exit(iButtonApp* app) { popup_disable_timeout(popup); popup_set_context(popup, NULL); popup_set_callback(popup, NULL); -} \ No newline at end of file +} diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.h b/applications/ibutton/scene/ibutton_scene_delete_success.h index 0c17c7ed80d..1fbe5230aed 100644 --- a/applications/ibutton/scene/ibutton_scene_delete_success.h +++ b/applications/ibutton/scene/ibutton_scene_delete_success.h @@ -6,4 +6,4 @@ class iButtonSceneDeleteSuccess : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_emulate.cpp b/applications/ibutton/scene/ibutton_scene_emulate.cpp index da6021fe38b..c00535f8c87 100644 --- a/applications/ibutton/scene/ibutton_scene_emulate.cpp +++ b/applications/ibutton/scene/ibutton_scene_emulate.cpp @@ -6,7 +6,10 @@ static void emulate_callback(void* context, bool emulated) { furi_assert(context); if(emulated) { iButtonApp* app = static_cast(context); - iButtonEvent event = {.type = iButtonEvent::Type::EventTypeWorkerEmulated}; + iButtonEvent event = { + .payload = {.worker_write_result = iButtonWorkerWriteOK}, + .type = iButtonEvent::Type::EventTypeWorkerEmulated, + }; app->get_view_manager()->send_event(&event); } } diff --git a/applications/ibutton/scene/ibutton_scene_emulate.h b/applications/ibutton/scene/ibutton_scene_emulate.h index c2bedcc511c..61107b94bb0 100644 --- a/applications/ibutton/scene/ibutton_scene_emulate.h +++ b/applications/ibutton/scene/ibutton_scene_emulate.h @@ -6,4 +6,4 @@ class iButtonSceneEmulate : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_exit_confirm.h b/applications/ibutton/scene/ibutton_scene_exit_confirm.h index dc5981e13e9..f621a59a5ee 100644 --- a/applications/ibutton/scene/ibutton_scene_exit_confirm.h +++ b/applications/ibutton/scene/ibutton_scene_exit_confirm.h @@ -6,4 +6,4 @@ class iButtonSceneExitConfirm : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_info.cpp b/applications/ibutton/scene/ibutton_scene_info.cpp index e51b2095f51..dd779789293 100755 --- a/applications/ibutton/scene/ibutton_scene_info.cpp +++ b/applications/ibutton/scene/ibutton_scene_info.cpp @@ -44,9 +44,8 @@ void iButtonSceneInfo::on_enter(iButtonApp* app) { view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); } -bool iButtonSceneInfo::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - return consumed; +bool iButtonSceneInfo::on_event(iButtonApp*, iButtonEvent*) { + return false; } void iButtonSceneInfo::on_exit(iButtonApp* app) { diff --git a/applications/ibutton/scene/ibutton_scene_info.h b/applications/ibutton/scene/ibutton_scene_info.h index e2c6b2cfa73..bbfb0c607c0 100644 --- a/applications/ibutton/scene/ibutton_scene_info.h +++ b/applications/ibutton/scene/ibutton_scene_info.h @@ -6,4 +6,4 @@ class iButtonSceneInfo : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_read.cpp b/applications/ibutton/scene/ibutton_scene_read.cpp index 7162652d57f..1cfdbfe320f 100644 --- a/applications/ibutton/scene/ibutton_scene_read.cpp +++ b/applications/ibutton/scene/ibutton_scene_read.cpp @@ -5,7 +5,10 @@ static void read_callback(void* context) { furi_assert(context); iButtonApp* app = static_cast(context); - iButtonEvent event = {.type = iButtonEvent::Type::EventTypeWorkerRead}; + iButtonEvent event = { + .payload = {.dummy = 0}, + .type = iButtonEvent::Type::EventTypeWorkerRead, + }; app->get_view_manager()->send_event(&event); } diff --git a/applications/ibutton/scene/ibutton_scene_read.h b/applications/ibutton/scene/ibutton_scene_read.h index b9fefb0c7f5..5654777847d 100644 --- a/applications/ibutton/scene/ibutton_scene_read.h +++ b/applications/ibutton/scene/ibutton_scene_read.h @@ -6,4 +6,4 @@ class iButtonSceneRead : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp index 213266cbb4e..d9d3ffd5cc4 100644 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp @@ -71,4 +71,4 @@ void iButtonSceneReadCRCError::on_exit(iButtonApp* app) { dialog_ex_set_context(dialog_ex, NULL); app->notify_red_off(); -} \ No newline at end of file +} diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.h b/applications/ibutton/scene/ibutton_scene_read_crc_error.h index 43a4dfac449..db72d068a32 100644 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.h +++ b/applications/ibutton/scene/ibutton_scene_read_crc_error.h @@ -6,4 +6,4 @@ class iButtonSceneReadCRCError : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_read_key_menu.h b/applications/ibutton/scene/ibutton_scene_read_key_menu.h index e85ad815d4d..d68a4d1db38 100644 --- a/applications/ibutton/scene/ibutton_scene_read_key_menu.h +++ b/applications/ibutton/scene/ibutton_scene_read_key_menu.h @@ -9,4 +9,4 @@ class iButtonSceneReadKeyMenu : public iButtonScene { private: uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp index 7d0a235f1dd..58ea853c181 100644 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp @@ -71,4 +71,4 @@ void iButtonSceneReadNotKeyError::on_exit(iButtonApp* app) { dialog_ex_set_context(dialog_ex, NULL); app->notify_red_off(); -} \ No newline at end of file +} diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h b/applications/ibutton/scene/ibutton_scene_read_not_key_error.h index 6643a206ac3..30d20033eaa 100644 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h +++ b/applications/ibutton/scene/ibutton_scene_read_not_key_error.h @@ -6,4 +6,4 @@ class iButtonSceneReadNotKeyError : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_read_success.h b/applications/ibutton/scene/ibutton_scene_read_success.h index 9548d6b4bd7..bf9003c2328 100644 --- a/applications/ibutton/scene/ibutton_scene_read_success.h +++ b/applications/ibutton/scene/ibutton_scene_read_success.h @@ -6,4 +6,4 @@ class iButtonSceneReadSuccess : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_retry_confirm.h b/applications/ibutton/scene/ibutton_scene_retry_confirm.h index 2f96e13f1ee..0fa71ad1110 100644 --- a/applications/ibutton/scene/ibutton_scene_retry_confirm.h +++ b/applications/ibutton/scene/ibutton_scene_retry_confirm.h @@ -6,4 +6,4 @@ class iButtonSceneRetryConfirm : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_save_name.h b/applications/ibutton/scene/ibutton_scene_save_name.h index 8be593da728..2d7f102e14a 100644 --- a/applications/ibutton/scene/ibutton_scene_save_name.h +++ b/applications/ibutton/scene/ibutton_scene_save_name.h @@ -6,4 +6,4 @@ class iButtonSceneSaveName : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_save_success.cpp b/applications/ibutton/scene/ibutton_scene_save_success.cpp index 13e173d2d9c..92c0e695685 100644 --- a/applications/ibutton/scene/ibutton_scene_save_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_save_success.cpp @@ -49,4 +49,4 @@ void iButtonSceneSaveSuccess::on_exit(iButtonApp* app) { popup_disable_timeout(popup); popup_set_context(popup, NULL); popup_set_callback(popup, NULL); -} \ No newline at end of file +} diff --git a/applications/ibutton/scene/ibutton_scene_save_success.h b/applications/ibutton/scene/ibutton_scene_save_success.h index 95742bda7e0..14c7412dc9b 100644 --- a/applications/ibutton/scene/ibutton_scene_save_success.h +++ b/applications/ibutton/scene/ibutton_scene_save_success.h @@ -6,4 +6,4 @@ class iButtonSceneSaveSuccess : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h b/applications/ibutton/scene/ibutton_scene_saved_key_menu.h index 399ed1ce33a..08809779d11 100644 --- a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h +++ b/applications/ibutton/scene/ibutton_scene_saved_key_menu.h @@ -9,4 +9,4 @@ class iButtonSceneSavedKeyMenu : public iButtonScene { private: uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_select_key.cpp b/applications/ibutton/scene/ibutton_scene_select_key.cpp index 1f1ece352b1..6a1246a49f2 100644 --- a/applications/ibutton/scene/ibutton_scene_select_key.cpp +++ b/applications/ibutton/scene/ibutton_scene_select_key.cpp @@ -10,9 +10,9 @@ void iButtonSceneSelectKey::on_enter(iButtonApp* app) { } } -bool iButtonSceneSelectKey::on_event(iButtonApp* app, iButtonEvent* event) { +bool iButtonSceneSelectKey::on_event(iButtonApp*, iButtonEvent*) { return false; } -void iButtonSceneSelectKey::on_exit(iButtonApp* app) { +void iButtonSceneSelectKey::on_exit(iButtonApp*) { } diff --git a/applications/ibutton/scene/ibutton_scene_select_key.h b/applications/ibutton/scene/ibutton_scene_select_key.h index 39e8d9a369c..d6819909973 100644 --- a/applications/ibutton/scene/ibutton_scene_select_key.h +++ b/applications/ibutton/scene/ibutton_scene_select_key.h @@ -6,4 +6,4 @@ class iButtonSceneSelectKey : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_start.h b/applications/ibutton/scene/ibutton_scene_start.h index be1ce79fbb9..28ef28d3513 100644 --- a/applications/ibutton/scene/ibutton_scene_start.h +++ b/applications/ibutton/scene/ibutton_scene_start.h @@ -9,4 +9,4 @@ class iButtonSceneStart : public iButtonScene { private: uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_write.cpp b/applications/ibutton/scene/ibutton_scene_write.cpp index 31da6dbe59e..d4f84e11c9c 100644 --- a/applications/ibutton/scene/ibutton_scene_write.cpp +++ b/applications/ibutton/scene/ibutton_scene_write.cpp @@ -108,4 +108,4 @@ void iButtonSceneWrite::on_exit(iButtonApp* app) { popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); -} \ No newline at end of file +} diff --git a/applications/ibutton/scene/ibutton_scene_write.h b/applications/ibutton/scene/ibutton_scene_write.h index bd99b377695..8b52473af54 100644 --- a/applications/ibutton/scene/ibutton_scene_write.h +++ b/applications/ibutton/scene/ibutton_scene_write.h @@ -9,4 +9,4 @@ class iButtonSceneWrite : public iButtonScene { private: bool blink_yellow; -}; \ No newline at end of file +}; diff --git a/applications/ibutton/scene/ibutton_scene_write_success.cpp b/applications/ibutton/scene/ibutton_scene_write_success.cpp index 397347046ec..3f27c672417 100644 --- a/applications/ibutton/scene/ibutton_scene_write_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_write_success.cpp @@ -49,4 +49,4 @@ void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) { popup_disable_timeout(popup); popup_set_context(popup, NULL); popup_set_callback(popup, NULL); -} \ No newline at end of file +} diff --git a/applications/ibutton/scene/ibutton_scene_write_success.h b/applications/ibutton/scene/ibutton_scene_write_success.h index c6e7688567c..99680c7dd2c 100644 --- a/applications/ibutton/scene/ibutton_scene_write_success.h +++ b/applications/ibutton/scene/ibutton_scene_write_success.h @@ -6,4 +6,4 @@ class iButtonSceneWriteSuccess : public iButtonScene { void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/infrared/cli/infrared_cli.cpp b/applications/infrared/cli/infrared_cli.cpp index 15de2d852bf..b60e459958b 100644 --- a/applications/infrared/cli/infrared_cli.cpp +++ b/applications/infrared/cli/infrared_cli.cpp @@ -60,6 +60,8 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv } static void infrared_cli_start_ir_rx(Cli* cli, string_t args) { + UNUSED(cli); + UNUSED(args); InfraredWorker* worker = infrared_worker_alloc(); infrared_worker_rx_start(worker); infrared_worker_rx_set_received_signal_callback(worker, signal_received_callback, cli); @@ -140,6 +142,7 @@ static bool parse_signal_raw( } static void infrared_cli_start_ir_tx(Cli* cli, string_t args) { + UNUSED(cli); InfraredMessage message; const char* str = string_get_cstr(args); uint32_t frequency; @@ -160,6 +163,7 @@ static void infrared_cli_start_ir_tx(Cli* cli, string_t args) { } static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) { + UNUSED(context); if(furi_hal_infrared_is_busy()) { printf("INFRARED is busy. Exit."); return; diff --git a/applications/infrared/infrared_app_event.h b/applications/infrared/infrared_app_event.h index fdea826acb6..168ba0b1cbb 100644 --- a/applications/infrared/infrared_app_event.h +++ b/applications/infrared/infrared_app_event.h @@ -36,6 +36,7 @@ class InfraredAppEvent { }; union { + int32_t dummy; /** Menu selected event type payload. Selected index. */ int32_t menu_index; /** DialogEx view module event type payload */ diff --git a/applications/infrared/infrared_app_view_manager.cpp b/applications/infrared/infrared_app_view_manager.cpp index 1e08471d453..f1e48ed4aba 100644 --- a/applications/infrared/infrared_app_view_manager.cpp +++ b/applications/infrared/infrared_app_view_manager.cpp @@ -148,7 +148,7 @@ void InfraredAppViewManager::send_event(InfraredAppEvent* event) { osMessageQueuePut(event_queue, event, 0, timeout); } -uint32_t InfraredAppViewManager::previous_view_callback(void* context) { +uint32_t InfraredAppViewManager::previous_view_callback(void*) { if(event_queue != NULL) { InfraredAppEvent event; event.type = InfraredAppEvent::Type::Back; diff --git a/applications/infrared/scene/infrared_app_scene_ask_back.cpp b/applications/infrared/scene/infrared_app_scene_ask_back.cpp index 751816af80b..65d7ca578ce 100644 --- a/applications/infrared/scene/infrared_app_scene_ask_back.cpp +++ b/applications/infrared/scene/infrared_app_scene_ask_back.cpp @@ -69,5 +69,5 @@ bool InfraredAppSceneAskBack::on_event(InfraredApp* app, InfraredAppEvent* event return consumed; } -void InfraredAppSceneAskBack::on_exit(InfraredApp* app) { +void InfraredAppSceneAskBack::on_exit(InfraredApp*) { } diff --git a/applications/infrared/scene/infrared_app_scene_edit_delete.cpp b/applications/infrared/scene/infrared_app_scene_edit_delete.cpp index d49acec528d..e17cfee076e 100644 --- a/applications/infrared/scene/infrared_app_scene_edit_delete.cpp +++ b/applications/infrared/scene/infrared_app_scene_edit_delete.cpp @@ -96,5 +96,5 @@ bool InfraredAppSceneEditDelete::on_event(InfraredApp* app, InfraredAppEvent* ev return consumed; } -void InfraredAppSceneEditDelete::on_exit(InfraredApp* app) { +void InfraredAppSceneEditDelete::on_exit(InfraredApp*) { } diff --git a/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp b/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp index 2b6afafd675..803481f6b3c 100644 --- a/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp +++ b/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp @@ -26,5 +26,5 @@ bool InfraredAppSceneEditRenameDone::on_event(InfraredApp* app, InfraredAppEvent return consumed; } -void InfraredAppSceneEditRenameDone::on_exit(InfraredApp* app) { +void InfraredAppSceneEditRenameDone::on_exit(InfraredApp*) { } diff --git a/applications/infrared/scene/infrared_app_scene_learn_enter_name.cpp b/applications/infrared/scene/infrared_app_scene_learn_enter_name.cpp index 0f148e8076b..7d15a7c5660 100644 --- a/applications/infrared/scene/infrared_app_scene_learn_enter_name.cpp +++ b/applications/infrared/scene/infrared_app_scene_learn_enter_name.cpp @@ -56,5 +56,5 @@ bool InfraredAppSceneLearnEnterName::on_event(InfraredApp* app, InfraredAppEvent return consumed; } -void InfraredAppSceneLearnEnterName::on_exit(InfraredApp* app) { +void InfraredAppSceneLearnEnterName::on_exit(InfraredApp*) { } diff --git a/applications/infrared/scene/infrared_app_scene_remote_list.cpp b/applications/infrared/scene/infrared_app_scene_remote_list.cpp index 95ef2e4112d..f59ff3e91e2 100644 --- a/applications/infrared/scene/infrared_app_scene_remote_list.cpp +++ b/applications/infrared/scene/infrared_app_scene_remote_list.cpp @@ -40,11 +40,9 @@ void InfraredAppSceneRemoteList::on_enter(InfraredApp* app) { } } -bool InfraredAppSceneRemoteList::on_event(InfraredApp* app, InfraredAppEvent* event) { - bool consumed = false; - - return consumed; +bool InfraredAppSceneRemoteList::on_event(InfraredApp*, InfraredAppEvent*) { + return false; } -void InfraredAppSceneRemoteList::on_exit(InfraredApp* app) { +void InfraredAppSceneRemoteList::on_exit(InfraredApp*) { } diff --git a/applications/infrared/scene/infrared_app_scene_universal_common.cpp b/applications/infrared/scene/infrared_app_scene_universal_common.cpp index a9220eaf769..9e7a18f40c1 100644 --- a/applications/infrared/scene/infrared_app_scene_universal_common.cpp +++ b/applications/infrared/scene/infrared_app_scene_universal_common.cpp @@ -25,6 +25,7 @@ static void infrared_progress_back_callback(void* context) { auto app = static_cast(context); InfraredAppEvent infrared_event = { + .payload = {.dummy = 0}, .type = InfraredAppEvent::Type::Back, }; app->get_view_manager()->clear_events(); @@ -57,7 +58,10 @@ bool InfraredAppSceneUniversalCommon::on_event(InfraredApp* app, InfraredAppEven if(event->type == InfraredAppEvent::Type::Tick) { auto view_manager = app->get_view_manager(); app->notify_blink_send(); - InfraredAppEvent tick_event = {.type = InfraredAppEvent::Type::Tick}; + InfraredAppEvent tick_event = { + .payload = {.dummy = 0}, + .type = InfraredAppEvent::Type::Tick, + }; view_manager->send_event(&tick_event); bool result = brute_force.send_next_bruteforce(); if(result) { diff --git a/applications/input/input.c b/applications/input/input.c index a2dd62f74ea..dd824dcbc00 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -35,6 +35,7 @@ void input_press_timer_callback(void* arg) { } void input_isr(void* _ctx) { + UNUSED(_ctx); osThreadFlagsSet(input->thread, INPUT_THREAD_FLAG_ISR); } diff --git a/applications/input/input_cli.c b/applications/input/input_cli.c index 00591a75c01..afb05afd433 100644 --- a/applications/input/input_cli.c +++ b/applications/input/input_cli.c @@ -20,6 +20,7 @@ static void input_cli_dump_events_callback(const void* value, void* ctx) { } static void input_cli_dump(Cli* cli, string_t args, Input* input) { + UNUSED(args); osMessageQueueId_t input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); FuriPubSubSubscription* input_subscription = furi_pubsub_subscribe(input->event_pubsub, input_cli_dump_events_callback, input_queue); @@ -47,6 +48,7 @@ static void input_cli_send_print_usage() { } static void input_cli_send(Cli* cli, string_t args, Input* input) { + UNUSED(cli); InputEvent event; string_t key_str; string_init(key_str); diff --git a/applications/lfrfid/helpers/decoder_analyzer.cpp b/applications/lfrfid/helpers/decoder_analyzer.cpp index 8142f14cf7b..8d344b8809a 100644 --- a/applications/lfrfid/helpers/decoder_analyzer.cpp +++ b/applications/lfrfid/helpers/decoder_analyzer.cpp @@ -2,7 +2,8 @@ #include #include -bool DecoderAnalyzer::read(uint8_t* _data, uint8_t _data_size) { +// FIXME: unused args? +bool DecoderAnalyzer::read(uint8_t* /* _data */, uint8_t /* _data_size */) { bool result = false; if(ready) { @@ -21,6 +22,7 @@ bool DecoderAnalyzer::read(uint8_t* _data, uint8_t _data_size) { } void DecoderAnalyzer::process_front(bool polarity, uint32_t time) { + UNUSED(polarity); if(ready) return; data[data_index] = time; diff --git a/applications/lfrfid/helpers/decoder_gpio_out.cpp b/applications/lfrfid/helpers/decoder_gpio_out.cpp index 03e0399467d..dfb43426725 100644 --- a/applications/lfrfid/helpers/decoder_gpio_out.cpp +++ b/applications/lfrfid/helpers/decoder_gpio_out.cpp @@ -2,7 +2,7 @@ #include #include -void DecoderGpioOut::process_front(bool polarity, uint32_t time) { +void DecoderGpioOut::process_front(bool polarity, uint32_t /* time */) { furi_hal_gpio_write(&gpio_ext_pa7, polarity); } diff --git a/applications/lfrfid/helpers/decoder_hid26.h b/applications/lfrfid/helpers/decoder_hid26.h index b409ca433b0..c73ff88c400 100644 --- a/applications/lfrfid/helpers/decoder_hid26.h +++ b/applications/lfrfid/helpers/decoder_hid26.h @@ -21,4 +21,4 @@ class DecoderHID26 { void reset_state(); ProtocolHID10301 hid; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/decoder_indala.cpp b/applications/lfrfid/helpers/decoder_indala.cpp index eb711fa2a4b..100dde73bdf 100644 --- a/applications/lfrfid/helpers/decoder_indala.cpp +++ b/applications/lfrfid/helpers/decoder_indala.cpp @@ -73,4 +73,4 @@ void DecoderIndala::reset_state() { cursed_raw_data = 0; ready = false; cursed_data_valid = false; -} \ No newline at end of file +} diff --git a/applications/lfrfid/helpers/decoder_indala.h b/applications/lfrfid/helpers/decoder_indala.h index 94ad8b16303..5fbde7b6bdf 100644 --- a/applications/lfrfid/helpers/decoder_indala.h +++ b/applications/lfrfid/helpers/decoder_indala.h @@ -22,4 +22,4 @@ class DecoderIndala { std::atomic ready; std::atomic cursed_data_valid; ProtocolIndala40134 indala; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/emmarin.h b/applications/lfrfid/helpers/emmarin.h index 5d2e2439c22..ff8273bf767 100644 --- a/applications/lfrfid/helpers/emmarin.h +++ b/applications/lfrfid/helpers/emmarin.h @@ -12,4 +12,4 @@ #define EM_STOP_MASK (0x1LLU << EM_STOP_POS) #define EM_HEADER_AND_STOP_MASK (EM_HEADER_MASK | EM_STOP_MASK) -#define EM_HEADER_AND_STOP_DATA (EM_HEADER_MASK) \ No newline at end of file +#define EM_HEADER_AND_STOP_DATA (EM_HEADER_MASK) diff --git a/applications/lfrfid/helpers/encoder_emmarin.h b/applications/lfrfid/helpers/encoder_emmarin.h index fa78122f345..560daec1b5a 100644 --- a/applications/lfrfid/helpers/encoder_emmarin.h +++ b/applications/lfrfid/helpers/encoder_emmarin.h @@ -19,4 +19,4 @@ class EncoderEM : public EncoderGeneric { uint64_t card_data; uint8_t card_data_index; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/encoder_hid_h10301.h b/applications/lfrfid/helpers/encoder_hid_h10301.h index e5edd0a0878..8cc5aa5cbfa 100644 --- a/applications/lfrfid/helpers/encoder_hid_h10301.h +++ b/applications/lfrfid/helpers/encoder_hid_h10301.h @@ -23,4 +23,4 @@ class EncoderHID_H10301 : public EncoderGeneric { void write_raw_bit(bool bit, uint8_t position); OscFSK* fsk; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/encoder_indala_40134.h b/applications/lfrfid/helpers/encoder_indala_40134.h index 8bdb3acdf6c..eda29457f37 100644 --- a/applications/lfrfid/helpers/encoder_indala_40134.h +++ b/applications/lfrfid/helpers/encoder_indala_40134.h @@ -20,4 +20,4 @@ class EncoderIndala_40134 : public EncoderGeneric { bool last_bit; bool current_polarity; static const uint8_t clock_per_bit = 16; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/key_info.cpp b/applications/lfrfid/helpers/key_info.cpp index 74b4fa5ca04..ed2b20a90b4 100644 --- a/applications/lfrfid/helpers/key_info.cpp +++ b/applications/lfrfid/helpers/key_info.cpp @@ -63,4 +63,4 @@ uint8_t lfrfid_key_get_type_data_count(LfrfidKeyType type) { } return 0; -} \ No newline at end of file +} diff --git a/applications/lfrfid/helpers/key_info.h b/applications/lfrfid/helpers/key_info.h index 277ede08122..e465011d01f 100644 --- a/applications/lfrfid/helpers/key_info.h +++ b/applications/lfrfid/helpers/key_info.h @@ -13,4 +13,4 @@ enum class LfrfidKeyType : uint8_t { const char* lfrfid_key_get_type_string(LfrfidKeyType type); const char* lfrfid_key_get_manufacturer_string(LfrfidKeyType type); bool lfrfid_key_get_string_type(const char* string, LfrfidKeyType* type); -uint8_t lfrfid_key_get_type_data_count(LfrfidKeyType type); \ No newline at end of file +uint8_t lfrfid_key_get_type_data_count(LfrfidKeyType type); diff --git a/applications/lfrfid/helpers/osc_fsk.h b/applications/lfrfid/helpers/osc_fsk.h index e9bd322bf13..eaaaa10ad0e 100644 --- a/applications/lfrfid/helpers/osc_fsk.h +++ b/applications/lfrfid/helpers/osc_fsk.h @@ -27,4 +27,4 @@ class OscFSK { const uint16_t freq[2]; const uint16_t osc_phase_max; int32_t osc_phase_current; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/protocols/protocol_generic.h b/applications/lfrfid/helpers/protocols/protocol_generic.h index 8d8edfb2942..d593f708995 100644 --- a/applications/lfrfid/helpers/protocols/protocol_generic.h +++ b/applications/lfrfid/helpers/protocols/protocol_generic.h @@ -57,4 +57,4 @@ class ProtocolGeneric { virtual bool can_be_decoded(const uint8_t* encoded_data, const uint8_t encoded_data_size) = 0; virtual ~ProtocolGeneric(){}; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/protocols/protocol_hid_h10301.h b/applications/lfrfid/helpers/protocols/protocol_hid_h10301.h index d769e8744b3..fbd6e0b2bf9 100644 --- a/applications/lfrfid/helpers/protocols/protocol_hid_h10301.h +++ b/applications/lfrfid/helpers/protocols/protocol_hid_h10301.h @@ -19,4 +19,4 @@ class ProtocolHID10301 : public ProtocolGeneric { const uint8_t decoded_data_size) final; bool can_be_decoded(const uint8_t* encoded_data, const uint8_t encoded_data_size) final; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/protocols/protocol_indala_40134.cpp b/applications/lfrfid/helpers/protocols/protocol_indala_40134.cpp index e77c808f969..482339def33 100644 --- a/applications/lfrfid/helpers/protocols/protocol_indala_40134.cpp +++ b/applications/lfrfid/helpers/protocols/protocol_indala_40134.cpp @@ -234,4 +234,4 @@ bool ProtocolIndala40134::can_be_decoded( } while(false); return can_be_decoded; -} \ No newline at end of file +} diff --git a/applications/lfrfid/helpers/pulse_joiner.h b/applications/lfrfid/helpers/pulse_joiner.h index 96d4482e9ba..1639d837167 100644 --- a/applications/lfrfid/helpers/pulse_joiner.h +++ b/applications/lfrfid/helpers/pulse_joiner.h @@ -33,4 +33,4 @@ class PulseJoiner { uint8_t pulse_index = 0; static const uint8_t pulse_max = 6; Pulse pulses[pulse_max]; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/rfid_key.cpp b/applications/lfrfid/helpers/rfid_key.cpp index 4a54e470b3f..02e45e6867e 100644 --- a/applications/lfrfid/helpers/rfid_key.cpp +++ b/applications/lfrfid/helpers/rfid_key.cpp @@ -36,7 +36,7 @@ const char* RfidKey::get_type_text() { return lfrfid_key_get_type_string(type); } -const uint8_t RfidKey::get_type_data_count() { +uint8_t RfidKey::get_type_data_count() const { return lfrfid_key_get_type_data_count(type); } diff --git a/applications/lfrfid/helpers/rfid_key.h b/applications/lfrfid/helpers/rfid_key.h index 83251625fe3..29b87cf9c0b 100644 --- a/applications/lfrfid/helpers/rfid_key.h +++ b/applications/lfrfid/helpers/rfid_key.h @@ -14,7 +14,7 @@ class RfidKey { LfrfidKeyType get_type(); const uint8_t* get_data(); const char* get_type_text(); - const uint8_t get_type_data_count(); + uint8_t get_type_data_count() const; char* get_name(); uint8_t get_name_length(); void clear(); diff --git a/applications/lfrfid/helpers/rfid_worker.h b/applications/lfrfid/helpers/rfid_worker.h index 27ec145cad2..2c49ad14e06 100644 --- a/applications/lfrfid/helpers/rfid_worker.h +++ b/applications/lfrfid/helpers/rfid_worker.h @@ -45,4 +45,4 @@ class RfidWorker { void sq_write_validate(); uint16_t validate_counts; void sq_write_stop_validate(); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/rfid_writer.h b/applications/lfrfid/helpers/rfid_writer.h index 3ec3c1dd25e..38329877b19 100644 --- a/applications/lfrfid/helpers/rfid_writer.h +++ b/applications/lfrfid/helpers/rfid_writer.h @@ -17,4 +17,4 @@ class RfidWriter { void write_byte(uint8_t value); void write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data); void write_reset(); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/helpers/state_sequencer.h b/applications/lfrfid/helpers/state_sequencer.h index e0ad135f905..12512ab5172 100644 --- a/applications/lfrfid/helpers/state_sequencer.h +++ b/applications/lfrfid/helpers/state_sequencer.h @@ -22,4 +22,4 @@ class TickSequencer { uint32_t tick_count; void do_nothing(); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/lfrfid_cli.cpp b/applications/lfrfid/lfrfid_cli.cpp index 235dd68fc60..dbd37ddc889 100644 --- a/applications/lfrfid/lfrfid_cli.cpp +++ b/applications/lfrfid/lfrfid_cli.cpp @@ -100,6 +100,8 @@ static void lfrfid_cli_read(Cli* cli, string_t args) { } static void lfrfid_cli_write(Cli* cli, string_t args) { + UNUSED(cli); + UNUSED(args); // TODO implement rfid write printf("Not implemented :(\r\n"); } @@ -147,6 +149,7 @@ static void lfrfid_cli_emulate(Cli* cli, string_t args) { } static void lfrfid_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t cmd; string_init(cmd); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp index 5b7ac0f95ea..40bd9e3609d 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp @@ -3,7 +3,7 @@ #include "../view/elements/icon_element.h" #include "../view/elements/string_element.h" -void LfRfidAppSceneDeleteConfirm::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneDeleteConfirm::on_enter(LfRfidApp* app, bool /* need_restore */) { string_init(string_data); string_init(string_decrypted); string_init(string_header); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h index 36d436a4a1d..e30764f0232 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.h @@ -14,4 +14,4 @@ class LfRfidAppSceneDeleteConfirm : public GenericScene { string_t string_header; string_t string_data; string_t string_decrypted; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp index a4f2bf38dc2..9820338d126 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp @@ -1,6 +1,6 @@ #include "lfrfid_app_scene_delete_success.h" -void LfRfidAppSceneDeleteSuccess::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneDeleteSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { auto popup = app->view_controller.get(); popup->set_icon(0, 2, &I_DolphinMafia_115x62); @@ -35,4 +35,4 @@ void LfRfidAppSceneDeleteSuccess::timeout_callback(void* context) { LfRfidApp::Event event; event.type = LfRfidApp::EventType::Back; app->view_controller.send_event(&event); -} \ No newline at end of file +} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.h b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.h index 01f929e715c..009b9f25dba 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.h @@ -9,4 +9,4 @@ class LfRfidAppSceneDeleteSuccess : public GenericScene { private: static void timeout_callback(void* context); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp b/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp index 17472e1674a..f1118a481c7 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp @@ -1,7 +1,7 @@ #include "lfrfid_app_scene_emulate.h" #include -void LfRfidAppSceneEmulate::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneEmulate::on_enter(LfRfidApp* app, bool /* need_restore */) { string_init(data_string); DOLPHIN_DEED(DolphinDeedRfidEmulate); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_emulate.h b/applications/lfrfid/scene/lfrfid_app_scene_emulate.h index ad5c8418054..937e49af9b1 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_emulate.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_emulate.h @@ -9,4 +9,4 @@ class LfRfidAppSceneEmulate : public GenericScene { private: string_t data_string; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp index 262dfca1cb3..d423cec9b7f 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp @@ -3,7 +3,7 @@ #include "../view/elements/icon_element.h" #include "../view/elements/string_element.h" -void LfRfidAppSceneExitConfirm::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneExitConfirm::on_enter(LfRfidApp* app, bool /* need_restore */) { auto container = app->view_controller.get(); auto button = container->add(); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h index 4f960d22f89..a0a1023258b 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h @@ -10,4 +10,4 @@ class LfRfidAppSceneExitConfirm : public GenericScene { private: static void exit_callback(void* context); static void stay_callback(void* context); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read.cpp index 481755903f6..f87aa200a4d 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_read.cpp @@ -1,7 +1,7 @@ #include "lfrfid_app_scene_read.h" #include -void LfRfidAppSceneRead::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneRead::on_enter(LfRfidApp* app, bool /* need_restore */) { auto popup = app->view_controller.get(); DOLPHIN_DEED(DolphinDeedRfidRead); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read.h b/applications/lfrfid/scene/lfrfid_app_scene_read.h index b978270c2cc..b5035b72a02 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_read.h @@ -6,4 +6,4 @@ class LfRfidAppSceneRead : public GenericScene { void on_enter(LfRfidApp* app, bool need_restore) final; bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; void on_exit(LfRfidApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h index 43d68a81ab7..2b50b96f9a9 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h @@ -10,4 +10,4 @@ class LfRfidAppSceneReadKeyMenu : public GenericScene { private: static void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp index 8f6a0b57ee3..2b81a58a0b9 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp @@ -3,7 +3,7 @@ #include "../view/elements/icon_element.h" #include "../view/elements/string_element.h" -void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { string_init(string[0]); string_init(string[1]); string_init(string[2]); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_success.h b/applications/lfrfid/scene/lfrfid_app_scene_read_success.h index e2c182ea2bd..ac0e3c1b5c1 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_success.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_read_success.h @@ -12,4 +12,4 @@ class LfRfidAppSceneReadSuccess : public GenericScene { static void more_callback(void* context); string_t string[3]; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp index 092a5f02008..e62b91bd430 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp @@ -3,7 +3,7 @@ #include "../view/elements/icon_element.h" #include "../view/elements/string_element.h" -void LfRfidAppSceneRetryConfirm::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneRetryConfirm::on_enter(LfRfidApp* app, bool /* need_restore */) { auto container = app->view_controller.get(); auto button = container->add(); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h index af2373f0356..01b7329c90a 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h @@ -10,4 +10,4 @@ class LfRfidAppSceneRetryConfirm : public GenericScene { private: static void exit_callback(void* context); static void stay_callback(void* context); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_data.h b/applications/lfrfid/scene/lfrfid_app_scene_save_data.h index d735fba10c3..6458ae649e4 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_data.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_data.h @@ -30,4 +30,4 @@ class LfRfidAppSceneSaveData : public GenericScene { 0xBB, 0xBB, }; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp index f755f0e3278..d460724e222 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp @@ -1,7 +1,7 @@ #include "lfrfid_app_scene_save_name.h" #include -void LfRfidAppSceneSaveName::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneSaveName::on_enter(LfRfidApp* app, bool /* need_restore */) { const char* key_name = app->worker.key.get_name(); bool key_name_empty = !strcmp(key_name, ""); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_name.h b/applications/lfrfid/scene/lfrfid_app_scene_save_name.h index 39201c34e0b..ced42cc0e45 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_name.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_name.h @@ -9,4 +9,4 @@ class LfRfidAppSceneSaveName : public GenericScene { private: static void save_callback(void* context); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp index 184a445ad5d..64efafa7314 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp @@ -3,7 +3,7 @@ #include #include -void LfRfidAppSceneSaveSuccess::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneSaveSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { auto popup = app->view_controller.get(); DOLPHIN_DEED(DolphinDeedRfidSave); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_success.h b/applications/lfrfid/scene/lfrfid_app_scene_save_success.h index 36aebf3efe0..62273a76be3 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_success.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_success.h @@ -9,4 +9,4 @@ class LfRfidAppSceneSaveSuccess : public GenericScene { private: static void timeout_callback(void* context); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_type.h b/applications/lfrfid/scene/lfrfid_app_scene_save_type.h index 7e57a93d83f..1f6f6d742d8 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_type.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_type.h @@ -12,4 +12,4 @@ class LfRfidAppSceneSaveType : public GenericScene { uint32_t submenu_item_selected = 0; static const uint8_t keys_count = static_cast(LfrfidKeyType::KeyI40134); string_t submenu_name[keys_count + 1]; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp index b054e141f88..73c9a403e75 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp @@ -3,7 +3,7 @@ #include "../view/elements/icon_element.h" #include "../view/elements/string_element.h" -void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool /* need_restore */) { string_init(string_data); string_init(string_decrypted); @@ -59,10 +59,8 @@ void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool need_restore) { app->view_controller.switch_to(); } -bool LfRfidAppSceneSavedInfo::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - return consumed; +bool LfRfidAppSceneSavedInfo::on_event(LfRfidApp* /* app */, LfRfidApp::Event* /* event */) { + return false; } void LfRfidAppSceneSavedInfo::on_exit(LfRfidApp* app) { diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.h b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.h index ec15c6dcd5e..5aa33e8ad7b 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.h @@ -12,4 +12,4 @@ class LfRfidAppSceneSavedInfo : public GenericScene { string_t string_data; string_t string_decrypted; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h b/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h index b3ad10ec7dd..69a6e5e58b4 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_saved_key_menu.h @@ -10,4 +10,4 @@ class LfRfidAppSceneSavedKeyMenu : public GenericScene { private: static void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp b/applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp index d376056b8ee..6d5df73cb8c 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_select_key.cpp @@ -8,11 +8,9 @@ void LfRfidAppSceneSelectKey::on_enter(LfRfidApp* app, bool need_restore) { } } -bool LfRfidAppSceneSelectKey::on_event(LfRfidApp* app, LfRfidApp::Event* event) { - bool consumed = false; - - return consumed; +bool LfRfidAppSceneSelectKey::on_event(LfRfidApp* /* app */, LfRfidApp::Event* /* event */) { + return false; } -void LfRfidAppSceneSelectKey::on_exit(LfRfidApp* app) { -} \ No newline at end of file +void LfRfidAppSceneSelectKey::on_exit(LfRfidApp* /* app */) { +} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_select_key.h b/applications/lfrfid/scene/lfrfid_app_scene_select_key.h index 10f11c61452..be565a91c56 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_select_key.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_select_key.h @@ -6,4 +6,4 @@ class LfRfidAppSceneSelectKey : public GenericScene { void on_enter(LfRfidApp* app, bool need_restore) final; bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; void on_exit(LfRfidApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_start.h b/applications/lfrfid/scene/lfrfid_app_scene_start.h index 3f48db707ea..255590d6acc 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_start.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_start.h @@ -10,4 +10,4 @@ class LfRfidAppSceneStart : public GenericScene { private: static void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp b/applications/lfrfid/scene/lfrfid_app_scene_write.cpp index 24f9fd0c5b1..d6c9e9f4fee 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_write.cpp @@ -1,6 +1,6 @@ #include "lfrfid_app_scene_write.h" -void LfRfidAppSceneWrite::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneWrite::on_enter(LfRfidApp* app, bool /* need_restore */) { card_not_supported = false; string_init(data_string); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write.h b/applications/lfrfid/scene/lfrfid_app_scene_write.h index 603f59d8e07..3abadebab5a 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_write.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_write.h @@ -10,4 +10,4 @@ class LfRfidAppSceneWrite : public GenericScene { private: string_t data_string; bool card_not_supported; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp index 0539e623504..3cf00183d71 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp @@ -1,6 +1,6 @@ #include "lfrfid_app_scene_write_success.h" -void LfRfidAppSceneWriteSuccess::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneWriteSuccess::on_enter(LfRfidApp* app, bool /* need_restore */) { auto popup = app->view_controller.get(); popup->set_header("Successfully\nwritten!", 94, 3, AlignCenter, AlignTop); popup->set_icon(0, 6, &I_RFIDDolphinSuccess_108x57); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write_success.h b/applications/lfrfid/scene/lfrfid_app_scene_write_success.h index 94b8efc1758..4ac9f0892f8 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_write_success.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_write_success.h @@ -9,4 +9,4 @@ class LfRfidAppSceneWriteSuccess : public GenericScene { private: static void timeout_callback(void* context); -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/view/container_vm.cpp b/applications/lfrfid/view/container_vm.cpp index 8c0e72e2bf8..3c01ba30423 100644 --- a/applications/lfrfid/view/container_vm.cpp +++ b/applications/lfrfid/view/container_vm.cpp @@ -112,4 +112,4 @@ bool ContainerVM::view_input_callback(InputEvent* event, void* context) { template StringElement* ContainerVM::add(); template IconElement* ContainerVM::add(); -template ButtonElement* ContainerVM::add(); \ No newline at end of file +template ButtonElement* ContainerVM::add(); diff --git a/applications/lfrfid/view/elements/generic_element.h b/applications/lfrfid/view/elements/generic_element.h index 269373f16c0..f5a58b2d923 100644 --- a/applications/lfrfid/view/elements/generic_element.h +++ b/applications/lfrfid/view/elements/generic_element.h @@ -18,4 +18,4 @@ class GenericElement { private: View* view = nullptr; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid/view/elements/icon_element.cpp b/applications/lfrfid/view/elements/icon_element.cpp index e4cb19ade72..0b6fba7dad4 100644 --- a/applications/lfrfid/view/elements/icon_element.cpp +++ b/applications/lfrfid/view/elements/icon_element.cpp @@ -12,7 +12,7 @@ void IconElement::draw(Canvas* canvas) { } } -bool IconElement::input(InputEvent* event) { +bool IconElement::input(InputEvent* /* event */) { return false; } diff --git a/applications/lfrfid/view/elements/string_element.cpp b/applications/lfrfid/view/elements/string_element.cpp index 028bd7fdae7..44c11e01a4c 100644 --- a/applications/lfrfid/view/elements/string_element.cpp +++ b/applications/lfrfid/view/elements/string_element.cpp @@ -23,7 +23,7 @@ void StringElement::draw(Canvas* canvas) { } } -bool StringElement::input(InputEvent* event) { +bool StringElement::input(InputEvent* /* event */) { return false; } @@ -44,4 +44,4 @@ void StringElement::set_text( vertical = _vertical; font = _font; unlock_model(true); -} \ No newline at end of file +} diff --git a/applications/lfrfid_debug/lfrfid_debug_app.cpp b/applications/lfrfid_debug/lfrfid_debug_app.cpp index 5de1de71d50..9cd9dcad8fb 100644 --- a/applications/lfrfid_debug/lfrfid_debug_app.cpp +++ b/applications/lfrfid_debug/lfrfid_debug_app.cpp @@ -13,4 +13,4 @@ void LfRfidDebugApp::run() { scene_controller.add_scene(SceneType::Start, new LfRfidDebugAppSceneStart()); scene_controller.add_scene(SceneType::TuneScene, new LfRfidDebugAppSceneTune()); scene_controller.process(100); -} \ No newline at end of file +} diff --git a/applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp b/applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp index 0ee458f4684..4551a17cb4f 100644 --- a/applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp +++ b/applications/lfrfid_debug/lfrfid_debug_app_launcher.cpp @@ -2,6 +2,7 @@ // app enter function extern "C" int32_t lfrfid_debug_app(void* p) { + UNUSED(p); LfRfidDebugApp* app = new LfRfidDebugApp(); app->run(); delete app; diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h index b8f811d07c9..7fc0b07d97d 100644 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h +++ b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_start.h @@ -10,4 +10,4 @@ class LfRfidDebugAppSceneStart : public GenericScene { private: void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp index 536794026f7..4b6276497f5 100644 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp +++ b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp @@ -2,10 +2,11 @@ #include static void comparator_trigger_callback(bool level, void* comp_ctx) { + UNUSED(comp_ctx); furi_hal_gpio_write(&gpio_ext_pa7, !level); } -void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool need_restore) { +void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool /* need_restore */) { app->view_controller.switch_to(); furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); @@ -17,7 +18,7 @@ void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool need_restore) { furi_hal_rfid_tim_read_start(); } -bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) { +bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* /* event */) { bool consumed = false; LfRfidViewTuneVM* tune = app->view_controller; @@ -30,7 +31,7 @@ bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Even return consumed; } -void LfRfidDebugAppSceneTune::on_exit(LfRfidDebugApp* app) { +void LfRfidDebugAppSceneTune::on_exit(LfRfidDebugApp* /* app */) { furi_hal_rfid_comp_stop(); furi_hal_rfid_comp_set_callback(NULL, NULL); diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h index 94dfea973bd..53399efc9b7 100644 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h +++ b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.h @@ -6,4 +6,4 @@ class LfRfidDebugAppSceneTune : public GenericScene { void on_enter(LfRfidDebugApp* app, bool need_restore) final; bool on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) final; void on_exit(LfRfidDebugApp* app) final; -}; \ No newline at end of file +}; diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 43e275ab988..e5d5970292d 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -39,6 +39,7 @@ static bool } static void loader_menu_callback(void* _ctx, uint32_t index) { + UNUSED(index); const FlipperApplication* application = _ctx; furi_assert(application->app); @@ -53,6 +54,7 @@ static void loader_menu_callback(void* _ctx, uint32_t index) { } static void loader_submenu_callback(void* context, uint32_t index) { + UNUSED(index); uint32_t view_id = (uint32_t)context; view_dispatcher_switch_to_view(loader_instance->view_dispatcher, view_id); } @@ -101,6 +103,7 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { } void loader_cli_open(Cli* cli, string_t args, Loader* instance) { + UNUSED(cli); if(loader_is_locked(instance)) { printf("Can't start, furi application is running"); return; @@ -139,6 +142,9 @@ void loader_cli_open(Cli* cli, string_t args, Loader* instance) { } void loader_cli_list(Cli* cli, string_t args, Loader* instance) { + UNUSED(cli); + UNUSED(args); + UNUSED(instance); printf("Applications:\r\n"); for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { printf("\t%s\r\n", FLIPPER_APPS[i].name); @@ -187,6 +193,7 @@ static void loader_cli(Cli* cli, string_t args, void* _ctx) { } LoaderStatus loader_start(Loader* instance, const char* name, const char* args) { + UNUSED(instance); furi_assert(name); const FlipperApplication* application = loader_find_application_by_name(name); @@ -265,6 +272,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con } static uint32_t loader_hide_menu(void* context) { + UNUSED(context); return VIEW_NONE; } @@ -445,6 +453,7 @@ void loader_update_menu() { } int32_t loader_srv(void* p) { + UNUSED(p); FURI_LOG_I(TAG, "Executing system start hooks"); for(size_t i = 0; i < FLIPPER_ON_SYSTEM_START_COUNT; i++) { FLIPPER_ON_SYSTEM_START[i](); diff --git a/applications/music_player/music_player_cli.c b/applications/music_player/music_player_cli.c index 3c76cb84057..0d98101e73b 100644 --- a/applications/music_player/music_player_cli.c +++ b/applications/music_player/music_player_cli.c @@ -4,6 +4,7 @@ #include "music_player_worker.h" static void music_player_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); MusicPlayerWorker* music_player_worker = music_player_worker_alloc(); Storage* storage = furi_record_open("storage"); diff --git a/applications/music_player/music_player_worker.c b/applications/music_player/music_player_worker.c index 2c80e6f5e8f..9a0087aa6a9 100644 --- a/applications/music_player/music_player_worker.c +++ b/applications/music_player/music_player_worker.c @@ -250,8 +250,8 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c is_valid &= (duration >= 1 && duration <= 128); is_valid &= ((note_char >= 'A' && note_char <= 'G') || note_char == 'P'); is_valid &= (sharp_char == '#' || sharp_char == '\0'); - is_valid &= (octave >= 0 && octave <= 16); - is_valid &= (dots >= 0 && dots <= 16); + is_valid &= (octave <= 16); + is_valid &= (dots <= 16); if(!is_valid) { FURI_LOG_E( TAG, diff --git a/applications/nfc/helpers/nfc_custom_event.h b/applications/nfc/helpers/nfc_custom_event.h index bab7c0aac37..5de44001730 100644 --- a/applications/nfc/helpers/nfc_custom_event.h +++ b/applications/nfc/helpers/nfc_custom_event.h @@ -9,4 +9,4 @@ enum NfcCustomEvent { NfcCustomEventByteInputDone, NfcCustomEventTextInputDone, NfcCustomEventDictAttackDone, -}; \ No newline at end of file +}; diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index 52c971ef4a1..9b77a29f3d1 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -17,6 +17,7 @@ static void nfc_cli_print_usage() { } static void nfc_cli_detect(Cli* cli, string_t args) { + UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { printf("Nfc is busy\r\n"); @@ -45,6 +46,7 @@ static void nfc_cli_detect(Cli* cli, string_t args) { } static void nfc_cli_emulate(Cli* cli, string_t args) { + UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { printf("Nfc is busy\r\n"); @@ -74,6 +76,7 @@ static void nfc_cli_emulate(Cli* cli, string_t args) { } static void nfc_cli_field(Cli* cli, string_t args) { + UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { printf("Nfc is busy\r\n"); @@ -95,6 +98,7 @@ static void nfc_cli_field(Cli* cli, string_t args) { } static void nfc_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t cmd; string_init(cmd); diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index 6b769803cc9..14fdb67b7c2 100644 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -373,7 +373,7 @@ bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication if(!flipper_format_read_hex(file, string_get_cstr(key), tmp, n_files)) break; MifareDesfireFile** file_head = &app->file_head; bool parsed_files = true; - for(int i = 0; i < n_files; i++) { + for(uint32_t i = 0; i < n_files; i++) { parsed_files = false; f = malloc(sizeof(MifareDesfireFile)); memset(f, 0, sizeof(MifareDesfireFile)); @@ -528,7 +528,7 @@ bool nfc_device_load_mifare_df_data(FlipperFormat* file, NfcDevice* dev) { if(!flipper_format_read_hex(file, "Application IDs", tmp, n_apps * 3)) break; bool parsed_apps = true; MifareDesfireApplication** app_head = &data->app_head; - for(int i = 0; i < n_apps; i++) { + for(uint32_t i = 0; i < n_apps; i++) { MifareDesfireApplication* app = malloc(sizeof(MifareDesfireApplication)); memset(app, 0, sizeof(MifareDesfireApplication)); memcpy(app->id, &tmp[i * 3], 3); diff --git a/applications/nfc/scenes/nfc_scene_delete_success.c b/applications/nfc/scenes/nfc_scene_delete_success.c index a52c40d867e..547aeab7e0c 100755 --- a/applications/nfc/scenes/nfc_scene_delete_success.c +++ b/applications/nfc/scenes/nfc_scene_delete_success.c @@ -37,4 +37,4 @@ void nfc_scene_delete_success_on_exit(void* context) { // Clear view popup_reset(nfc->popup); -} \ No newline at end of file +} diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c index 10851e860b9..03464c6625f 100644 --- a/applications/nfc/scenes/nfc_scene_device_info.c +++ b/applications/nfc/scenes/nfc_scene_device_info.c @@ -21,6 +21,7 @@ void nfc_scene_device_info_dialog_callback(DialogExResult result, void* context) } void nfc_scene_device_info_bank_card_callback(GuiButtonType result, InputType type, void* context) { + UNUSED(result); Nfc* nfc = context; if(type == InputTypeShort) { view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); diff --git a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c index 871ca636432..eda7637c2a6 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c +++ b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c @@ -5,6 +5,7 @@ #define NFC_MF_UL_DATA_CHANGED (1UL) void nfc_emulate_mifare_ul_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); Nfc* nfc = context; scene_manager_set_scene_state( diff --git a/applications/nfc/scenes/nfc_scene_emulate_uid.c b/applications/nfc/scenes/nfc_scene_emulate_uid.c index 58ac138e7ef..e67b727401d 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/nfc/scenes/nfc_scene_emulate_uid.c @@ -9,6 +9,7 @@ enum { }; void nfc_emulate_uid_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); furi_assert(context); Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); diff --git a/applications/nfc/scenes/nfc_scene_field.c b/applications/nfc/scenes/nfc_scene_field.c index 31cf74b8e75..e3eb6a7088b 100644 --- a/applications/nfc/scenes/nfc_scene_field.c +++ b/applications/nfc/scenes/nfc_scene_field.c @@ -19,6 +19,8 @@ void nfc_scene_field_on_enter(void* context) { } bool nfc_scene_field_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); return false; } diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c index a8126456f2d..36614bb8fb2 100755 --- a/applications/nfc/scenes/nfc_scene_file_select.c +++ b/applications/nfc/scenes/nfc_scene_file_select.c @@ -11,8 +11,11 @@ void nfc_scene_file_select_on_enter(void* context) { } bool nfc_scene_file_select_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); return false; } void nfc_scene_file_select_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c b/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c index 0974c062cea..fdfbd2ecb98 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c +++ b/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c @@ -11,7 +11,7 @@ MifareDesfireApplication* nfc_scene_mifare_desfire_app_get_app(Nfc* nfc) { uint32_t app_idx = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp) >> 1; MifareDesfireApplication* app = nfc->dev->dev_data.mf_df_data.app_head; - for(int i = 0; i < app_idx && app; i++) { + for(uint32_t i = 0; i < app_idx && app; i++) { app = app->next; } return app; diff --git a/applications/nfc/scenes/nfc_scene_read_card.c b/applications/nfc/scenes/nfc_scene_read_card.c index 4d151c08ee6..645b8deb223 100755 --- a/applications/nfc/scenes/nfc_scene_read_card.c +++ b/applications/nfc/scenes/nfc_scene_read_card.c @@ -2,6 +2,7 @@ #include void nfc_read_card_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app.c b/applications/nfc/scenes/nfc_scene_read_emv_app.c index f0192cb9a2a..4a64622dc78 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_app.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_app.c @@ -2,6 +2,7 @@ #include void nfc_read_emv_app_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data.c b/applications/nfc/scenes/nfc_scene_read_emv_data.c index b72c873e4b4..85df4121212 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data.c @@ -2,6 +2,7 @@ #include void nfc_read_emv_data_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c b/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c index ebd7289b911..f14f81bad09 100644 --- a/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c @@ -2,6 +2,7 @@ #include void nfc_read_mifare_desfire_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c index 8903e2c433e..659e08fbe10 100755 --- a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c @@ -2,6 +2,7 @@ #include void nfc_read_mifare_ul_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } diff --git a/applications/notification/notification_app.c b/applications/notification/notification_app.c index 4db12bbf23e..7db4986d5ae 100644 --- a/applications/notification/notification_app.c +++ b/applications/notification/notification_app.c @@ -298,7 +298,6 @@ void notification_process_notification_message( need_minimal_delay = true; } - led_active = false; notification_apply_notification_leds(app, led_values); reset_mask |= reset_red_mask; reset_mask |= reset_green_mask; @@ -489,6 +488,7 @@ static NotificationApp* notification_app_alloc() { // App int32_t notification_srv(void* p) { + UNUSED(p); NotificationApp* app = notification_app_alloc(); if(!notification_load_settings(app)) { diff --git a/applications/notification/notification_app_api.c b/applications/notification/notification_app_api.c index ed39b7d6848..d11a289ba03 100644 --- a/applications/notification/notification_app_api.c +++ b/applications/notification/notification_app_api.c @@ -34,4 +34,4 @@ void notification_internal_message_block( furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); osEventFlagsWait(m.back_event, NOTIFICATION_EVENT_COMPLETE, osFlagsWaitAny, osWaitForever); osEventFlagsDelete(m.back_event); -}; \ No newline at end of file +}; diff --git a/applications/notification/notification_settings_app.c b/applications/notification/notification_settings_app.c index eef14ebf5e3..bcb1b6a2735 100644 --- a/applications/notification/notification_settings_app.c +++ b/applications/notification/notification_settings_app.c @@ -120,6 +120,7 @@ static void vibro_changed(VariableItem* item) { } static uint32_t notification_app_settings_exit(void* context) { + UNUSED(context); return VIEW_NONE; } @@ -189,6 +190,7 @@ static void free_settings(NotificationAppSettings* app) { } int32_t notification_settings_app(void* p) { + UNUSED(p); NotificationAppSettings* app = alloc_settings(); view_dispatcher_run(app->view_dispatcher); notification_message_save_settings(app->notification); diff --git a/applications/power/battery_test_app/battery_test_app.c b/applications/power/battery_test_app/battery_test_app.c index 1588a525fc2..f24de32ba87 100755 --- a/applications/power/battery_test_app/battery_test_app.c +++ b/applications/power/battery_test_app/battery_test_app.c @@ -89,6 +89,7 @@ void battery_test_free(BatteryTestApp* app) { } int32_t battery_test_app(void* p) { + UNUSED(p); BatteryTestApp* app = battery_test_alloc(); // Disable battery low level notification power_enable_low_battery_level_notification(app->power, false); diff --git a/applications/power/power_cli.c b/applications/power/power_cli.c index 09e75fa90b6..d474a729ce5 100644 --- a/applications/power/power_cli.c +++ b/applications/power/power_cli.c @@ -6,6 +6,8 @@ #include void power_cli_off(Cli* cli, string_t args) { + UNUSED(cli); + UNUSED(args); Power* power = furi_record_open("power"); printf("It's now safe to disconnect USB from your flipper\r\n"); osDelay(666); @@ -13,26 +15,37 @@ void power_cli_off(Cli* cli, string_t args) { } void power_cli_reboot(Cli* cli, string_t args) { + UNUSED(cli); + UNUSED(args); power_reboot(PowerBootModeNormal); } void power_cli_reboot2dfu(Cli* cli, string_t args) { + UNUSED(cli); + UNUSED(args); power_reboot(PowerBootModeDfu); } static void power_cli_info_callback(const char* key, const char* value, bool last, void* context) { + UNUSED(last); + UNUSED(context); printf("%-24s: %s\r\n", key, value); } void power_cli_info(Cli* cli, string_t args) { + UNUSED(cli); + UNUSED(args); furi_hal_power_info_get(power_cli_info_callback, NULL); } void power_cli_debug(Cli* cli, string_t args) { + UNUSED(cli); + UNUSED(args); furi_hal_power_dump_state(); } void power_cli_5v(Cli* cli, string_t args) { + UNUSED(cli); if(!string_cmp(args, "0")) { furi_hal_power_disable_otg(); } else if(!string_cmp(args, "1")) { @@ -43,6 +56,7 @@ void power_cli_5v(Cli* cli, string_t args) { } void power_cli_3v3(Cli* cli, string_t args) { + UNUSED(cli); if(!string_cmp(args, "0")) { furi_hal_power_disable_external_3_3v(); } else if(!string_cmp(args, "1")) { @@ -69,6 +83,7 @@ static void power_cli_command_print_usage() { } void power_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t cmd; string_init(cmd); diff --git a/applications/power/power_settings_app/power_settings_app.c b/applications/power/power_settings_app/power_settings_app.c index 1e87e7d619f..822c51bcccf 100755 --- a/applications/power/power_settings_app/power_settings_app.c +++ b/applications/power/power_settings_app/power_settings_app.c @@ -75,6 +75,7 @@ void power_settings_app_free(PowerSettingsApp* app) { } int32_t power_settings_app(void* p) { + UNUSED(p); PowerSettingsApp* app = power_settings_app_alloc(); view_dispatcher_run(app->view_dispatcher); power_settings_app_free(app); diff --git a/applications/power/power_settings_app/scenes/power_settings_scene_battery_info.c b/applications/power/power_settings_app/scenes/power_settings_scene_battery_info.c index 4dd04f8c349..0085c31dce2 100755 --- a/applications/power/power_settings_app/scenes/power_settings_scene_battery_info.c +++ b/applications/power/power_settings_app/scenes/power_settings_scene_battery_info.c @@ -31,4 +31,5 @@ bool power_settings_scene_battery_info_on_event(void* context, SceneManagerEvent } void power_settings_scene_battery_info_on_exit(void* context) { + UNUSED(context); } diff --git a/applications/power/power_settings_app/scenes/power_settings_scene_reboot.c b/applications/power/power_settings_app/scenes/power_settings_scene_reboot.c index 8edc8138dca..2d879612e77 100755 --- a/applications/power/power_settings_app/scenes/power_settings_scene_reboot.c +++ b/applications/power/power_settings_app/scenes/power_settings_scene_reboot.c @@ -33,6 +33,7 @@ void power_settings_scene_reboot_on_enter(void* context) { } bool power_settings_scene_reboot_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { diff --git a/applications/rpc/rpc.c b/applications/rpc/rpc.c index efd5ed876cd..7d51defd762 100644 --- a/applications/rpc/rpc.c +++ b/applications/rpc/rpc.c @@ -102,7 +102,7 @@ static size_t rpc_sprintf_msg_file( size_t msg_files_size) { size_t cnt = 0; - for(int i = 0; i < msg_files_size; ++i, ++msg_file) { + for(size_t i = 0; i < msg_files_size; ++i, ++msg_file) { string_cat_printf( str, "%s[%c] size: %5ld", @@ -136,7 +136,7 @@ void rpc_print_data(const char* prefix, uint8_t* buffer, size_t size) { string_reserve(str, 100 + size * 5); string_cat_printf(str, "\r\n%s DEC(%d): {", prefix, size); - for(int i = 0; i < size; ++i) { + for(size_t i = 0; i < size; ++i) { string_cat_printf(str, "%d, ", buffer[i]); } string_cat_printf(str, "}\r\n"); @@ -146,7 +146,7 @@ void rpc_print_data(const char* prefix, uint8_t* buffer, size_t size) { string_reserve(str, 100 + size * 3); string_cat_printf(str, "%s HEX(%d): {", prefix, size); - for(int i = 0; i < size; ++i) { + for(size_t i = 0; i < size; ++i) { string_cat_printf(str, "%02X", buffer[i]); } string_cat_printf(str, "}\r\n\r\n"); @@ -573,7 +573,7 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex RpcSession* session = (RpcSession*)context; if(thread_state == FuriThreadStateStopped) { - for(int i = 0; i < COUNT_OF(rpc_systems); ++i) { + for(size_t i = 0; i < COUNT_OF(rpc_systems); ++i) { if(rpc_systems[i].free) { rpc_systems[i].free(session->system_contexts[i]); } @@ -611,7 +611,7 @@ RpcSession* rpc_session_open(Rpc* rpc) { session->decoded_message->cb_content.arg = session; session->system_contexts = malloc(COUNT_OF(rpc_systems) * sizeof(void*)); - for(int i = 0; i < COUNT_OF(rpc_systems); ++i) { + for(size_t i = 0; i < COUNT_OF(rpc_systems); ++i) { session->system_contexts[i] = rpc_systems[i].alloc(session); } @@ -647,6 +647,7 @@ void rpc_session_close(RpcSession* session) { } int32_t rpc_srv(void* p) { + UNUSED(p); Rpc* rpc = malloc(sizeof(Rpc)); rpc->busy_mutex = osMutexNew(NULL); diff --git a/applications/rpc/rpc_cli.c b/applications/rpc/rpc_cli.c index b9304367876..1c8991bc630 100644 --- a/applications/rpc/rpc_cli.c +++ b/applications/rpc/rpc_cli.c @@ -38,6 +38,7 @@ static void rpc_session_terminated_callback(void* context) { } void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) { + UNUSED(args); Rpc* rpc = context; uint32_t mem_before = memmgr_get_free_heap(); diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index a21fec8ea3d..e6a59ea8de3 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -31,8 +31,6 @@ typedef struct { uint32_t current_command_id; } RpcStorageSystem; -void rpc_print_message(const PB_Main* message); - static void rpc_system_storage_reset_state( RpcStorageSystem* rpc_storage, RpcSession* session, diff --git a/applications/scened_app_example/scene/scened_app_scene_byte_input.cpp b/applications/scened_app_example/scene/scened_app_scene_byte_input.cpp index 6d618748622..200252ad6cd 100644 --- a/applications/scened_app_example/scene/scened_app_scene_byte_input.cpp +++ b/applications/scened_app_example/scene/scened_app_scene_byte_input.cpp @@ -1,6 +1,6 @@ #include "scened_app_scene_byte_input.h" -void ScenedAppSceneByteInput::on_enter(ScenedApp* app, bool need_restore) { +void ScenedAppSceneByteInput::on_enter(ScenedApp* app, bool /* need_restore */) { ByteInputVM* byte_input = app->view_controller; auto callback = cbc::obtain_connector(this, &ScenedAppSceneByteInput::result_callback); diff --git a/applications/scened_app_example/scene/scened_app_scene_byte_input.h b/applications/scened_app_example/scene/scened_app_scene_byte_input.h index 12daf310a7d..0f0b02acb91 100644 --- a/applications/scened_app_example/scene/scened_app_scene_byte_input.h +++ b/applications/scened_app_example/scene/scened_app_scene_byte_input.h @@ -16,4 +16,4 @@ class ScenedAppSceneByteInput : public GenericScene { 0xF4, 0xD3, }; -}; \ No newline at end of file +}; diff --git a/applications/scened_app_example/scene/scened_app_scene_start.h b/applications/scened_app_example/scene/scened_app_scene_start.h index 19e1b78d68e..8324a20fddc 100644 --- a/applications/scened_app_example/scene/scened_app_scene_start.h +++ b/applications/scened_app_example/scene/scened_app_scene_start.h @@ -10,4 +10,4 @@ class ScenedAppSceneStart : public GenericScene { private: void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; -}; \ No newline at end of file +}; diff --git a/applications/scened_app_example/scened_app.cpp b/applications/scened_app_example/scened_app.cpp index e658d6d0185..64040b22d87 100644 --- a/applications/scened_app_example/scened_app.cpp +++ b/applications/scened_app_example/scened_app.cpp @@ -17,4 +17,4 @@ void ScenedApp::run() { notification_message(notification, &sequence_blink_green_10); scene_controller.process(100); -} \ No newline at end of file +} diff --git a/applications/scened_app_example/scened_app_launcher.cpp b/applications/scened_app_example/scened_app_launcher.cpp index 1664b87dfa0..3d0bdfcaf0b 100644 --- a/applications/scened_app_example/scened_app_launcher.cpp +++ b/applications/scened_app_example/scened_app_launcher.cpp @@ -2,6 +2,7 @@ // app enter function extern "C" int32_t scened_app(void* p) { + UNUSED(p); ScenedApp* app = new ScenedApp(); app->run(); delete app; diff --git a/applications/snake_game/snake_game.c b/applications/snake_game/snake_game.c index 2bc0a6a332c..bb9e207de25 100644 --- a/applications/snake_game/snake_game.c +++ b/applications/snake_game/snake_game.c @@ -313,6 +313,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { } int32_t snake_game_app(void* p) { + UNUSED(p); srand(DWT->CYCCNT); osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(SnakeEvent), NULL); diff --git a/applications/storage/filesystem_api.c b/applications/storage/filesystem_api.c index 42a10c6b710..b979967acb5 100644 --- a/applications/storage/filesystem_api.c +++ b/applications/storage/filesystem_api.c @@ -35,4 +35,4 @@ const char* filesystem_api_error_get_desc(FS_Error error_id) { break; } return result; -} \ No newline at end of file +} diff --git a/applications/storage/filesystem_api_defines.h b/applications/storage/filesystem_api_defines.h index cc33de26627..b6f1d8f1306 100644 --- a/applications/storage/filesystem_api_defines.h +++ b/applications/storage/filesystem_api_defines.h @@ -57,4 +57,4 @@ const char* filesystem_api_error_get_desc(FS_Error error_id); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storage.c b/applications/storage/storage.c index 078a136cddf..b280547b7a2 100644 --- a/applications/storage/storage.c +++ b/applications/storage/storage.c @@ -100,6 +100,7 @@ void storage_tick(Storage* app) { } int32_t storage_srv(void* p) { + UNUSED(p); Storage* app = storage_app_alloc(); furi_record_create("storage", app); diff --git a/applications/storage/storage.h b/applications/storage/storage.h index eb51adefa38..eecd1beb4c3 100644 --- a/applications/storage/storage.h +++ b/applications/storage/storage.h @@ -325,4 +325,4 @@ void storage_get_next_filename( #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storage_cli.c b/applications/storage/storage_cli.c index 3cb345bdf69..70da21d216c 100644 --- a/applications/storage/storage_cli.c +++ b/applications/storage/storage_cli.c @@ -37,6 +37,7 @@ static void storage_cli_print_error(FS_Error error) { } static void storage_cli_info(Cli* cli, string_t path) { + UNUSED(cli); Storage* api = furi_record_open("storage"); if(string_cmp_str(path, "/int") == 0) { @@ -101,6 +102,7 @@ static void storage_cli_format(Cli* cli, string_t path) { }; static void storage_cli_list(Cli* cli, string_t path) { + UNUSED(cli); if(string_cmp_str(path, "/") == 0) { printf("\t[D] int\r\n"); printf("\t[D] ext\r\n"); @@ -137,6 +139,7 @@ static void storage_cli_list(Cli* cli, string_t path) { } static void storage_cli_read(Cli* cli, string_t path) { + UNUSED(cli); Storage* api = furi_record_open("storage"); File* file = storage_file_alloc(api); @@ -295,6 +298,7 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { } static void storage_cli_stat(Cli* cli, string_t path) { + UNUSED(cli); Storage* api = furi_record_open("storage"); if(string_cmp_str(path, "/") == 0) { @@ -334,6 +338,7 @@ static void storage_cli_stat(Cli* cli, string_t path) { } static void storage_cli_copy(Cli* cli, string_t old_path, string_t args) { + UNUSED(cli); Storage* api = furi_record_open("storage"); string_t new_path; string_init(new_path); @@ -354,6 +359,7 @@ static void storage_cli_copy(Cli* cli, string_t old_path, string_t args) { } static void storage_cli_remove(Cli* cli, string_t path) { + UNUSED(cli); Storage* api = furi_record_open("storage"); FS_Error error = storage_common_remove(api, string_get_cstr(path)); @@ -365,6 +371,7 @@ static void storage_cli_remove(Cli* cli, string_t path) { } static void storage_cli_rename(Cli* cli, string_t old_path, string_t args) { + UNUSED(cli); Storage* api = furi_record_open("storage"); string_t new_path; string_init(new_path); @@ -385,6 +392,7 @@ static void storage_cli_rename(Cli* cli, string_t old_path, string_t args) { } static void storage_cli_mkdir(Cli* cli, string_t path) { + UNUSED(cli); Storage* api = furi_record_open("storage"); FS_Error error = storage_common_mkdir(api, string_get_cstr(path)); @@ -396,6 +404,7 @@ static void storage_cli_mkdir(Cli* cli, string_t path) { } static void storage_cli_md5(Cli* cli, string_t path) { + UNUSED(cli); Storage* api = furi_record_open("storage"); File* file = storage_file_alloc(api); @@ -433,6 +442,7 @@ static void storage_cli_md5(Cli* cli, string_t path) { } void storage_cli(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t cmd; string_t path; string_init(cmd); @@ -522,6 +532,8 @@ void storage_cli(Cli* cli, string_t args, void* context) { } static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) { + UNUSED(args); + UNUSED(context); printf("All data will be lost. Are you sure (y/n)?\r\n"); char c = cli_getc(cli); if(c == 'y' || c == 'Y') { diff --git a/applications/storage/storage_glue.h b/applications/storage/storage_glue.h index 21147dce95c..0d50e39b0c9 100644 --- a/applications/storage/storage_glue.h +++ b/applications/storage/storage_glue.h @@ -72,4 +72,4 @@ bool storage_pop_storage_file(File* file, StorageData* storage); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storage_internal_api.c b/applications/storage/storage_internal_api.c index 754ae0dd09b..ee49d672301 100644 --- a/applications/storage/storage_internal_api.c +++ b/applications/storage/storage_internal_api.c @@ -19,4 +19,4 @@ FS_Error storage_int_restore(Storage* api, const char* srcname) { tar_archive_unpack_to(archive, INT_PATH); tar_archive_free(archive); return success ? FSE_OK : FSE_INTERNAL; -} \ No newline at end of file +} diff --git a/applications/storage/storage_message.h b/applications/storage/storage_message.h index 0e58fff2f2d..f3aeaf321e7 100644 --- a/applications/storage/storage_message.h +++ b/applications/storage/storage_message.h @@ -131,4 +131,4 @@ typedef struct { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storage_processing.c b/applications/storage/storage_processing.c index 6120a345bbf..30e6b5e7576 100644 --- a/applications/storage/storage_processing.c +++ b/applications/storage/storage_processing.c @@ -40,7 +40,7 @@ static StorageData* get_storage_by_file(File* file, StorageData* storages) { } static const char* remove_vfs(const char* path) { - return path + MIN(4, strlen(path)); + return path + MIN(4u, strlen(path)); } static const char* ext_path = "/ext"; diff --git a/applications/storage/storage_processing.h b/applications/storage/storage_processing.h index fe2cd1a6a32..bb779c7a80e 100644 --- a/applications/storage/storage_processing.h +++ b/applications/storage/storage_processing.h @@ -13,4 +13,4 @@ void storage_process_message(Storage* app, StorageMessage* message); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storage_sd_api.c b/applications/storage/storage_sd_api.c index 780646243e7..9e9ca45ceeb 100644 --- a/applications/storage/storage_sd_api.c +++ b/applications/storage/storage_sd_api.c @@ -18,4 +18,4 @@ const char* sd_api_get_fs_type_text(SDFsType fs_type) { return "UNKNOWN"; break; } -} \ No newline at end of file +} diff --git a/applications/storage/storage_sd_api.h b/applications/storage/storage_sd_api.h index 2db358666e5..f83360955e9 100644 --- a/applications/storage/storage_sd_api.h +++ b/applications/storage/storage_sd_api.h @@ -30,4 +30,4 @@ const char* sd_api_get_fs_type_text(SDFsType fs_type); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storage_test_app.c b/applications/storage/storage_test_app.c index 096276ad23b..f11d2d72ae9 100644 --- a/applications/storage/storage_test_app.c +++ b/applications/storage/storage_test_app.c @@ -316,6 +316,7 @@ static void do_test_end(Storage* api, const char* path) { } int32_t storage_test_app(void* p) { + UNUSED(p); Storage* api = furi_record_open("storage"); do_test_start(api, "/int"); do_test_start(api, "/any"); diff --git a/applications/storage/storages/sd_notify.c b/applications/storage/storages/sd_notify.c index 8c38ac8e465..25ec67c1df5 100644 --- a/applications/storage/storages/sd_notify.c +++ b/applications/storage/storages/sd_notify.c @@ -79,4 +79,4 @@ void sd_notify_eject(NotificationApp* notifications) { void sd_notify_error(NotificationApp* notifications) { notification_message(notifications, &sd_sequence_error); -} \ No newline at end of file +} diff --git a/applications/storage/storages/sd_notify.h b/applications/storage/storages/sd_notify.h index 49e82edf78f..f5aefc74d4e 100644 --- a/applications/storage/storages/sd_notify.h +++ b/applications/storage/storages/sd_notify.h @@ -14,4 +14,4 @@ void sd_notify_error(NotificationApp* notifications); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storages/storage_ext.c b/applications/storage/storages/storage_ext.c index bf201d5657c..49c52f77140 100644 --- a/applications/storage/storages/storage_ext.c +++ b/applications/storage/storages/storage_ext.c @@ -113,6 +113,7 @@ FS_Error sd_unmount_card(StorageData* storage) { FS_Error sd_format_card(StorageData* storage) { #ifdef FURI_RAM_EXEC + UNUSED(storage); return FSE_NOT_READY; #else uint8_t* work_area; @@ -349,6 +350,10 @@ static uint16_t static uint16_t storage_ext_file_write(void* ctx, File* file, const void* buff, uint16_t const bytes_to_write) { #ifdef FURI_RAM_EXEC + UNUSED(ctx); + UNUSED(file); + UNUSED(buff); + UNUSED(bytes_to_write); return FSE_NOT_READY; #else StorageData* storage = ctx; @@ -389,6 +394,8 @@ static uint64_t storage_ext_file_tell(void* ctx, File* file) { static bool storage_ext_file_truncate(void* ctx, File* file) { #ifdef FURI_RAM_EXEC + UNUSED(ctx); + UNUSED(file); return FSE_NOT_READY; #else StorageData* storage = ctx; @@ -402,6 +409,8 @@ static bool storage_ext_file_truncate(void* ctx, File* file) { static bool storage_ext_file_sync(void* ctx, File* file) { #ifdef FURI_RAM_EXEC + UNUSED(ctx); + UNUSED(file); return FSE_NOT_READY; #else StorageData* storage = ctx; @@ -497,6 +506,7 @@ static bool storage_ext_dir_rewind(void* ctx, File* file) { /******************* Common FS Functions *******************/ static FS_Error storage_ext_common_stat(void* ctx, const char* path, FileInfo* fileinfo) { + UNUSED(ctx); SDFileInfo _fileinfo; SDError result = f_stat(path, &_fileinfo); @@ -511,7 +521,9 @@ static FS_Error storage_ext_common_stat(void* ctx, const char* path, FileInfo* f } static FS_Error storage_ext_common_remove(void* ctx, const char* path) { + UNUSED(ctx); #ifdef FURI_RAM_EXEC + UNUSED(path); return FSE_NOT_READY; #else SDError result = f_unlink(path); @@ -520,7 +532,9 @@ static FS_Error storage_ext_common_remove(void* ctx, const char* path) { } static FS_Error storage_ext_common_mkdir(void* ctx, const char* path) { + UNUSED(ctx); #ifdef FURI_RAM_EXEC + UNUSED(path); return FSE_NOT_READY; #else SDError result = f_mkdir(path); @@ -533,7 +547,11 @@ static FS_Error storage_ext_common_fs_info( const char* fs_path, uint64_t* total_space, uint64_t* free_space) { + UNUSED(fs_path); #ifdef FURI_RAM_EXEC + UNUSED(ctx); + UNUSED(total_space); + UNUSED(free_space); return FSE_NOT_READY; #else StorageData* storage = ctx; @@ -610,4 +628,4 @@ void storage_ext_init(StorageData* storage) { // do not notify on first launch, notifications app is waiting for our thread to read settings storage_ext_tick_internal(storage, false); -} \ No newline at end of file +} diff --git a/applications/storage/storages/storage_ext.h b/applications/storage/storages/storage_ext.h index fa5a5ab168e..07ddbcf2f4e 100644 --- a/applications/storage/storages/storage_ext.h +++ b/applications/storage/storages/storage_ext.h @@ -13,4 +13,4 @@ FS_Error sd_format_card(StorageData* storage); FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage/storages/storage_int.c b/applications/storage/storages/storage_int.c index 7f7dd7705d1..291fb426bb5 100644 --- a/applications/storage/storages/storage_int.c +++ b/applications/storage/storages/storage_int.c @@ -129,6 +129,7 @@ static int storage_int_device_erase(const struct lfs_config* c, lfs_block_t bloc } static int storage_int_device_sync(const struct lfs_config* c) { + UNUSED(c); FURI_LOG_D(TAG, "Device sync: skipping, cause "); return 0; } @@ -648,6 +649,7 @@ static FS_Error storage_int_common_fs_info( const char* fs_path, uint64_t* total_space, uint64_t* free_space) { + UNUSED(fs_path); StorageData* storage = ctx; lfs_t* lfs = lfs_get_from_storage(storage); diff --git a/applications/storage/storages/storage_int.h b/applications/storage/storages/storage_int.h index 40588f68c33..456d72408fb 100644 --- a/applications/storage/storages/storage_int.h +++ b/applications/storage/storages/storage_int.h @@ -10,4 +10,4 @@ void storage_int_init(StorageData* storage); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/storage_settings/scenes/storage_settings_scene_config.h b/applications/storage_settings/scenes/storage_settings_scene_config.h index 7628d143288..18e7ba5aa31 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_config.h +++ b/applications/storage_settings/scenes/storage_settings_scene_config.h @@ -6,4 +6,4 @@ ADD_SCENE(storage_settings, formatting, Formatting) ADD_SCENE(storage_settings, sd_info, SDInfo) ADD_SCENE(storage_settings, internal_info, InternalInfo) ADD_SCENE(storage_settings, benchmark, Benchmark) -ADD_SCENE(storage_settings, factory_reset, FactoryReset) \ No newline at end of file +ADD_SCENE(storage_settings, factory_reset, FactoryReset) diff --git a/applications/storage_settings/storage_settings.c b/applications/storage_settings/storage_settings.c index bc982b16045..b89fdf0605c 100644 --- a/applications/storage_settings/storage_settings.c +++ b/applications/storage_settings/storage_settings.c @@ -66,6 +66,7 @@ static void storage_settings_free(StorageSettings* app) { } int32_t storage_settings_app(void* p) { + UNUSED(p); StorageSettings* app = storage_settings_alloc(); view_dispatcher_run(app->view_dispatcher); diff --git a/applications/storage_settings/storage_settings.h b/applications/storage_settings/storage_settings.h index be77a52de9c..f2d071c47c5 100644 --- a/applications/storage_settings/storage_settings.h +++ b/applications/storage_settings/storage_settings.h @@ -44,4 +44,4 @@ typedef enum { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c index 8d8ad0b653d..c0e1fdbaaab 100644 --- a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -44,7 +44,7 @@ static uint32_t subghz_frequency_analyzer_worker_expRunningAverageAdaptive( float k; float newValFloat = newVal; // the sharpness of the filter depends on the absolute value of the difference - if(abs(newValFloat - instance->filVal) > 500000) + if(fabs(newValFloat - instance->filVal) > 500000) k = 0.9; else k = 0.03; diff --git a/applications/subghz/helpers/subghz_testing.h b/applications/subghz/helpers/subghz_testing.h index 3a1549662ef..29ce578a010 100644 --- a/applications/subghz/helpers/subghz_testing.h +++ b/applications/subghz/helpers/subghz_testing.h @@ -3,4 +3,4 @@ extern const uint32_t subghz_frequencies_testing[]; extern const uint32_t subghz_frequencies_count_testing; -extern const uint32_t subghz_frequencies_433_92_testing; \ No newline at end of file +extern const uint32_t subghz_frequencies_433_92_testing; diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h index 71cd2668980..1cb217adc11 100644 --- a/applications/subghz/scenes/subghz_scene_config.h +++ b/applications/subghz/scenes/subghz_scene_config.h @@ -21,4 +21,4 @@ ADD_SCENE(subghz, frequency_analyzer, FrequencyAnalyzer) ADD_SCENE(subghz, read_raw, ReadRAW) ADD_SCENE(subghz, more_raw, MoreRAW) ADD_SCENE(subghz, delete_raw, DeleteRAW) -ADD_SCENE(subghz, need_saving, NeedSaving) \ No newline at end of file +ADD_SCENE(subghz, need_saving, NeedSaving) diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index 19242defbd0..bfc39e91842 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -191,5 +191,5 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { } void subghz_scene_receiver_on_exit(void* context) { - // SubGhz* subghz = context; + UNUSED(context); } diff --git a/applications/subghz/scenes/subghz_scene_receiver_config.c b/applications/subghz/scenes/subghz_scene_receiver_config.c index d98f45af072..7c2d031f0c6 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/subghz/scenes/subghz_scene_receiver_config.c @@ -61,6 +61,7 @@ uint8_t subghz_scene_receiver_config_hopper_value_index( uint8_t values_count, void* context) { furi_assert(context); + UNUSED(values_count); SubGhz* subghz = context; if(value == values[0]) { @@ -188,7 +189,8 @@ void subghz_scene_receiver_config_on_enter(void* context) { } bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent event) { - //SubGhz* subghz = context; + UNUSED(context); + UNUSED(event); return false; } diff --git a/applications/subghz/scenes/subghz_scene_saved.c b/applications/subghz/scenes/subghz_scene_saved.c index ae64b7973dd..62ade3508e7 100644 --- a/applications/subghz/scenes/subghz_scene_saved.c +++ b/applications/subghz/scenes/subghz_scene_saved.c @@ -16,10 +16,11 @@ void subghz_scene_saved_on_enter(void* context) { } bool subghz_scene_saved_on_event(void* context, SceneManagerEvent event) { - // SubGhz* subghz = context; + UNUSED(context); + UNUSED(event); return false; } void subghz_scene_saved_on_exit(void* context) { - // SubGhz* subghz = context; + UNUSED(context); } diff --git a/applications/subghz/scenes/subghz_scene_show_only_rx.c b/applications/subghz/scenes/subghz_scene_show_only_rx.c index d5069940e40..48fa751e020 100644 --- a/applications/subghz/scenes/subghz_scene_show_only_rx.c +++ b/applications/subghz/scenes/subghz_scene_show_only_rx.c @@ -26,7 +26,7 @@ void subghz_scene_show_only_rx_on_enter(void* context) { view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); } -const bool subghz_scene_show_only_rx_on_event(void* context, SceneManagerEvent event) { +bool subghz_scene_show_only_rx_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneShowOnlyRX) { diff --git a/applications/subghz/scenes/subghz_scene_test_carrier.c b/applications/subghz/scenes/subghz_scene_test_carrier.c index c6d336ea2a9..9677792ba31 100644 --- a/applications/subghz/scenes/subghz_scene_test_carrier.c +++ b/applications/subghz/scenes/subghz_scene_test_carrier.c @@ -26,5 +26,5 @@ bool subghz_scene_test_carrier_on_event(void* context, SceneManagerEvent event) } void subghz_scene_test_carrier_on_exit(void* context) { - // SubGhz* subghz = context; + UNUSED(context); } diff --git a/applications/subghz/scenes/subghz_scene_test_packet.c b/applications/subghz/scenes/subghz_scene_test_packet.c index 243dfd558b5..99f0ab1791f 100644 --- a/applications/subghz/scenes/subghz_scene_test_packet.c +++ b/applications/subghz/scenes/subghz_scene_test_packet.c @@ -26,5 +26,5 @@ bool subghz_scene_test_packet_on_event(void* context, SceneManagerEvent event) { } void subghz_scene_test_packet_on_exit(void* context) { - // SubGhz* subghz = context; + UNUSED(context); } diff --git a/applications/subghz/scenes/subghz_scene_test_static.c b/applications/subghz/scenes/subghz_scene_test_static.c index 2ca47a08270..10e6d02a1da 100644 --- a/applications/subghz/scenes/subghz_scene_test_static.c +++ b/applications/subghz/scenes/subghz_scene_test_static.c @@ -26,5 +26,5 @@ bool subghz_scene_test_static_on_event(void* context, SceneManagerEvent event) { } void subghz_scene_test_static_on_exit(void* context) { - // SubGhz* subghz = context; + UNUSED(context); } diff --git a/applications/subghz/subghz.h b/applications/subghz/subghz.h index 16e1e8575a0..54d3017ed4d 100644 --- a/applications/subghz/subghz.h +++ b/applications/subghz/subghz.h @@ -1,3 +1,3 @@ #pragma once -typedef struct SubGhz SubGhz; \ No newline at end of file +typedef struct SubGhz SubGhz; diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 65ea0cf2894..d22b86f201e 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -20,6 +20,7 @@ "299999755...348000000 or 386999938...464000000 or 778999847...928000000" void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { + UNUSED(context); uint32_t frequency = 433920000; if(string_size(args)) { @@ -63,6 +64,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { } void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { + UNUSED(context); uint32_t frequency = 433920000; if(string_size(args)) { @@ -103,6 +105,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { } void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { + UNUSED(context); uint32_t frequency = 433920000; uint32_t key = 0x0074BADE; uint32_t repeat = 10; @@ -218,6 +221,7 @@ static void subghz_cli_command_rx_callback( } void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { + UNUSED(context); uint32_t frequency = 433920000; if(string_size(args)) { @@ -296,6 +300,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { } void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { + UNUSED(context); string_t file_name; string_init(file_name); string_set(file_name, "/any/subghz/test.sub"); @@ -423,6 +428,7 @@ static void subghz_cli_command_print_usage() { } static void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { + UNUSED(cli); uint8_t iv[16]; string_t source; @@ -465,6 +471,7 @@ static void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { } static void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { + UNUSED(cli); uint8_t iv[16]; string_t source; diff --git a/applications/subghz/views/receiver.c b/applications/subghz/views/receiver.c index 03ba5bd28dc..fc66e4fdd89 100644 --- a/applications/subghz/views/receiver.c +++ b/applications/subghz/views/receiver.c @@ -10,7 +10,7 @@ #define FRAME_HEIGHT 12 #define MAX_LEN_PX 100 -#define MENU_ITEMS 4 +#define MENU_ITEMS 4u typedef struct { string_t item_str; @@ -71,9 +71,11 @@ static void subghz_view_receiver_update_offset(SubGhzViewReceiver* subghz_receiv if(history_item > 3 && model->idx >= history_item - 1) { model->list_offset = model->idx - 3; } else if(model->list_offset < model->idx - bounds) { - model->list_offset = CLAMP(model->list_offset + 1, history_item - bounds, 0); + model->list_offset = CLAMP( + (uint16_t)(model->list_offset + 1), (uint16_t)(history_item - bounds), 0); } else if(model->list_offset > model->idx - bounds) { - model->list_offset = CLAMP(model->idx - 1, history_item - bounds, 0); + model->list_offset = + CLAMP((uint16_t)(model->idx - 1), (uint16_t)(history_item - bounds), 0); } return true; }); @@ -157,7 +159,7 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { SubGhzReceiverMenuItem* item_menu; for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { - size_t idx = CLAMP(i + model->list_offset, model->history_item, 0); + size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0); item_menu = SubGhzReceiverMenuItemArray_get(model->history->data, idx); string_set(str_buff, item_menu->item_str); elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX); @@ -218,7 +220,6 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { void subghz_view_receiver_enter(void* context) { furi_assert(context); - //SubGhzViewReceiver* subghz_receiver = context; } void subghz_view_receiver_exit(void* context) { diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c index fea3bd89638..57f8508504f 100644 --- a/applications/subghz/views/subghz_test_packet.c +++ b/applications/subghz/views/subghz_test_packet.c @@ -57,6 +57,7 @@ static void subghz_test_packet_rx_callback(bool level, uint32_t duration, void* //todo static void subghz_test_packet_rx_pt_callback(SubGhzDecoderPrinceton* parser, void* context) { + UNUSED(parser); furi_assert(context); SubGhzTestPacket* instance = context; instance->packet_rx++; diff --git a/applications/system/system_settings.c b/applications/system/system_settings.c index f06292ec309..97017c8dfa8 100644 --- a/applications/system/system_settings.c +++ b/applications/system/system_settings.c @@ -46,6 +46,7 @@ static void debug_changed(VariableItem* item) { } static uint32_t system_settings_exit(void* context) { + UNUSED(context); return VIEW_NONE; } @@ -103,6 +104,7 @@ void system_settings_free(SystemSettings* app) { } int32_t system_settings_app(void* p) { + UNUSED(p); SystemSettings* app = system_settings_alloc(); view_dispatcher_run(app->view_dispatcher); system_settings_free(app); diff --git a/applications/u2f/scenes/u2f_scene_main.c b/applications/u2f/scenes/u2f_scene_main.c index d0957b5915c..f6264338bbd 100644 --- a/applications/u2f/scenes/u2f_scene_main.c +++ b/applications/u2f/scenes/u2f_scene_main.c @@ -8,6 +8,7 @@ #define U2F_SUCCESS_TIMEOUT 3000 static void u2f_scene_main_ok_callback(InputType type, void* context) { + UNUSED(type); furi_assert(context); U2fApp* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, U2fCustomEventConfirm); diff --git a/applications/u2f/u2f_app.c b/applications/u2f/u2f_app.c index 8a673dbcb02..2c3ff562ad8 100644 --- a/applications/u2f/u2f_app.c +++ b/applications/u2f/u2f_app.c @@ -86,6 +86,7 @@ void u2f_app_free(U2fApp* app) { } int32_t u2f_app(void* p) { + UNUSED(p); U2fApp* u2f_app = u2f_app_alloc(); view_dispatcher_run(u2f_app->view_dispatcher); diff --git a/applications/u2f/views/u2f_view.c b/applications/u2f/views/u2f_view.c index d04c656d1f3..11e2c9b0462 100644 --- a/applications/u2f/views/u2f_view.c +++ b/applications/u2f/views/u2f_view.c @@ -86,6 +86,7 @@ void u2f_view_set_ok_callback(U2fView* u2f, U2fOkCallback callback, void* contex furi_assert(callback); with_view_model( u2f->view, (U2fModel * model) { + UNUSED(model); u2f->callback = callback; u2f->context = context; return false; diff --git a/applications/unit_tests/flipper_format/flipper_format_string_test.c b/applications/unit_tests/flipper_format/flipper_format_string_test.c index ebc3008ff47..7158ffd824b 100644 --- a/applications/unit_tests/flipper_format/flipper_format_string_test.c +++ b/applications/unit_tests/flipper_format/flipper_format_string_test.c @@ -334,4 +334,4 @@ MU_TEST_SUITE(flipper_format_string_suite) { int run_minunit_test_flipper_format_string() { MU_RUN_SUITE(flipper_format_string_suite); return MU_EXIT_CODE; -} \ No newline at end of file +} diff --git a/applications/unit_tests/furi_pubsub_test.c b/applications/unit_tests/furi_pubsub_test.c index 010a00ab004..57c970b85db 100644 --- a/applications/unit_tests/furi_pubsub_test.c +++ b/applications/unit_tests/furi_pubsub_test.c @@ -42,4 +42,4 @@ void test_furi_pubsub() { // delete pubsub case furi_pubsub_free(test_pubsub); -} \ No newline at end of file +} diff --git a/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c b/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c index ca9120edbe4..0c3e685da2f 100644 --- a/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c +++ b/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c @@ -55,7 +55,7 @@ static void run_encoder_fill_array( bool level = false; bool level_read; InfraredStatus status = InfraredStatusError; - int i = 0; + size_t i = 0; bool first = true; while(1) { @@ -100,7 +100,7 @@ static void run_encoder( run_encoder_fill_array(encoder_handler, timings, &timings_len, NULL); furi_check(timings_len <= 200); - for(int i = 0; i < timings_len; ++i, ++j) { + for(size_t i = 0; i < timings_len; ++i, ++j) { mu_check(MATCH_TIMING(timings[i], expected_timings[j], 120)); mu_assert(j < expected_timings_len, "encoded more timings than expected"); } @@ -127,7 +127,7 @@ static void furi_check(timings_len <= 200); const InfraredMessage* message_decoded = 0; - for(int i = 0; i < timings_len; ++i) { + for(size_t i = 0; i < timings_len; ++i) { message_decoded = infrared_decode(decoder_handler, level, timings[i]); if((i == timings_len - 2) && level && message_decoded) { /* In case we end with space timing - message can be decoded at last mark */ diff --git a/applications/unit_tests/minunit_vars.h b/applications/unit_tests/minunit_vars.h index 7ef5f825aee..8289fbe2645 100644 --- a/applications/unit_tests/minunit_vars.h +++ b/applications/unit_tests/minunit_vars.h @@ -12,4 +12,4 @@ double minunit_real_timer = 0; double minunit_proc_timer = 0; /* Last message */ -char minunit_last_message[MINUNIT_MESSAGE_LEN]; \ No newline at end of file +char minunit_last_message[MINUNIT_MESSAGE_LEN]; diff --git a/applications/unit_tests/minunit_vars_ex.h b/applications/unit_tests/minunit_vars_ex.h index e2743d1c046..7d6a486ca47 100644 --- a/applications/unit_tests/minunit_vars_ex.h +++ b/applications/unit_tests/minunit_vars_ex.h @@ -12,4 +12,4 @@ extern double minunit_real_timer; extern double minunit_proc_timer; /* Last message */ -extern char minunit_last_message[MINUNIT_MESSAGE_LEN]; \ No newline at end of file +extern char minunit_last_message[MINUNIT_MESSAGE_LEN]; diff --git a/applications/unit_tests/rpc/rpc_test.c b/applications/unit_tests/rpc/rpc_test.c index 2a52ebb0da9..2f97343e939 100644 --- a/applications/unit_tests/rpc/rpc_test.c +++ b/applications/unit_tests/rpc/rpc_test.c @@ -45,7 +45,7 @@ static RpcSessionContext rpc_session[TEST_RPC_SESSIONS]; #define TAG "UnitTestsRpc" #define MAX_RECEIVE_OUTPUT_TIMEOUT 3000 #define MAX_NAME_LENGTH 255 -#define MAX_DATA_SIZE 512 // have to be exact as in rpc_storage.c +#define MAX_DATA_SIZE 512u // have to be exact as in rpc_storage.c #define TEST_DIR TEST_DIR_NAME "/" #define TEST_DIR_NAME "/ext/unit_tests_tmp" #define MD5SUM_SIZE 16 @@ -217,6 +217,8 @@ static void test_rpc_print_message_list(MsgList_t msg_list) { rpc_print_message(msg); } MsgList_reverse(msg_list); +#else + UNUSED(msg_list); #endif } @@ -494,7 +496,7 @@ static void test_rpc_compare_messages(PB_Main* result, PB_Main* expected) { size_t expected_msg_files = expected->content.storage_list_response.file_count; size_t result_msg_files = result->content.storage_list_response.file_count; mu_check(result_msg_files == expected_msg_files); - for(int i = 0; i < expected_msg_files; ++i) { + for(size_t i = 0; i < expected_msg_files; ++i) { PB_Storage_File* result_msg_file = &result->content.storage_list_response.file[i]; PB_Storage_File* expected_msg_file = &expected->content.storage_list_response.file[i]; test_rpc_compare_file(result_msg_file, expected_msg_file); @@ -794,7 +796,7 @@ static void test_create_file(const char* path, size_t size) { if(storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { uint8_t buf[128] = {0}; - for(int i = 0; i < sizeof(buf); ++i) { + for(size_t i = 0; i < sizeof(buf); ++i) { buf[i] = '0' + (i % 10); } while(size) { @@ -928,7 +930,7 @@ static void test_storage_write_run( MsgList_init(expected_msg_list); uint8_t* buf = malloc(write_size); - for(int i = 0; i < write_size; ++i) { + for(size_t i = 0; i < write_size; ++i) { buf[i] = '0' + (i % 10); } @@ -1551,8 +1553,9 @@ MU_TEST_SUITE(test_rpc_app) { static void test_send_rubbish(RpcSession* session, const char* pattern, size_t pattern_size, size_t size) { + UNUSED(session); uint8_t* buf = malloc(size); - for(int i = 0; i < size; ++i) { + for(size_t i = 0; i < size; ++i) { buf[i] = pattern[i % pattern_size]; } diff --git a/applications/unit_tests/storage/storage_test.c b/applications/unit_tests/storage/storage_test.c index 3fccc68f276..adc5f330d30 100644 --- a/applications/unit_tests/storage/storage_test.c +++ b/applications/unit_tests/storage/storage_test.c @@ -168,4 +168,4 @@ int run_minunit_test_storage() { MU_RUN_SUITE(storage_file); MU_RUN_SUITE(storage_dir); return MU_EXIT_CODE; -} \ No newline at end of file +} diff --git a/applications/unit_tests/stream/stream_test.c b/applications/unit_tests/stream/stream_test.c index eed8a7bccfa..b5e8a18b3c3 100644 --- a/applications/unit_tests/stream/stream_test.c +++ b/applications/unit_tests/stream/stream_test.c @@ -378,4 +378,4 @@ MU_TEST_SUITE(stream_suite) { int run_minunit_test_stream() { MU_RUN_SUITE(stream_suite); return MU_EXIT_CODE; -} \ No newline at end of file +} diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index 6dc0f964ea8..e0fb8b6b8fb 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -26,6 +26,8 @@ static void subghz_test_rx_callback( SubGhzReceiver* receiver, SubGhzProtocolDecoderBase* decoder_base, void* context) { + UNUSED(receiver); + UNUSED(context); string_t text; string_init(text); subghz_protocol_decoder_base_get_string(decoder_base, text); diff --git a/applications/unit_tests/test_index.c b/applications/unit_tests/test_index.c index ef12224c013..eda0fe4a05a 100644 --- a/applications/unit_tests/test_index.c +++ b/applications/unit_tests/test_index.c @@ -35,6 +35,9 @@ void minunit_print_fail(const char* str) { } void unit_tests_cli(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(args); + UNUSED(context); uint32_t test_result = 0; minunit_run = 0; minunit_assert = 0; diff --git a/applications/updater/cli/updater_cli.c b/applications/updater/cli/updater_cli.c index aa08bc61391..000ff56cdfb 100644 --- a/applications/updater/cli/updater_cli.c +++ b/applications/updater/cli/updater_cli.c @@ -65,6 +65,8 @@ static const CliSubcommand update_cli_subcommands[] = { }; static void updater_cli_ep(Cli* cli, string_t args, void* context) { + UNUSED(cli); + UNUSED(context); string_t subcommand; string_init(subcommand); if(!args_read_string_and_trim(args, subcommand) || string_empty_p(args)) { @@ -85,6 +87,7 @@ static void updater_cli_ep(Cli* cli, string_t args, void* context) { } static int32_t updater_spawner_thread_worker(void* arg) { + UNUSED(arg); Loader* loader = furi_record_open("loader"); loader_start(loader, "UpdaterApp", NULL); furi_record_close("loader"); diff --git a/applications/updater/scenes/updater_scene_config.h b/applications/updater/scenes/updater_scene_config.h index d2441c597f9..59601965219 100644 --- a/applications/updater/scenes/updater_scene_config.h +++ b/applications/updater/scenes/updater_scene_config.h @@ -2,4 +2,4 @@ ADD_SCENE(updater, main, Main) #ifndef FURI_RAM_EXEC ADD_SCENE(updater, loadcfg, LoadCfg) ADD_SCENE(updater, error, Error) -#endif \ No newline at end of file +#endif diff --git a/applications/updater/scenes/updater_scene_loadcfg.c b/applications/updater/scenes/updater_scene_loadcfg.c index 78423b071a5..8e477b14a6b 100644 --- a/applications/updater/scenes/updater_scene_loadcfg.c +++ b/applications/updater/scenes/updater_scene_loadcfg.c @@ -102,4 +102,4 @@ void updater_scene_loadcfg_on_exit(void* context) { widget_reset(updater->widget); free(updater->pending_update); -} \ No newline at end of file +} diff --git a/applications/updater/updater.c b/applications/updater/updater.c index c1115ce1830..b58c8daa043 100644 --- a/applications/updater/updater.c +++ b/applications/updater/updater.c @@ -133,4 +133,4 @@ int32_t updater_srv(void* p) { updater_free(updater); return 0; -} \ No newline at end of file +} diff --git a/applications/updater/updater_i.h b/applications/updater/updater_i.h index 89201e1e0aa..8a021a08df9 100644 --- a/applications/updater/updater_i.h +++ b/applications/updater/updater_i.h @@ -64,4 +64,4 @@ void updater_free(Updater* updater); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/updater/util/update_task.c b/applications/updater/util/update_task.c index 9fde086a332..6ff61700ae4 100644 --- a/applications/updater/util/update_task.c +++ b/applications/updater/util/update_task.c @@ -227,4 +227,4 @@ UpdateTaskState const* update_task_get_state(UpdateTask* update_task) { UpdateManifest const* update_task_get_manifest(UpdateTask* update_task) { furi_assert(update_task); return update_task->manifest; -} \ No newline at end of file +} diff --git a/applications/updater/util/update_task.h b/applications/updater/util/update_task.h index 8afc3121667..3197c8c19e0 100644 --- a/applications/updater/util/update_task.h +++ b/applications/updater/util/update_task.h @@ -67,4 +67,4 @@ UpdateManifest const* update_task_get_manifest(UpdateTask* update_task); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/updater/util/update_task_worker_flasher.c b/applications/updater/util/update_task_worker_flasher.c index 22e94fd01b1..6b03439dd6e 100644 --- a/applications/updater/util/update_task_worker_flasher.c +++ b/applications/updater/util/update_task_worker_flasher.c @@ -360,4 +360,4 @@ int32_t update_task_worker_flash_writer(void* context) { } while(false); return success ? UPDATE_TASK_NOERR : UPDATE_TASK_FAILED; -} \ No newline at end of file +} diff --git a/applications/updater/views/updater_main.h b/applications/updater/views/updater_main.h index 3c55a8c24bb..d787295696f 100644 --- a/applications/updater/views/updater_main.h +++ b/applications/updater/views/updater_main.h @@ -25,4 +25,4 @@ void updater_main_set_storage_pubsub(UpdaterMainView* main_view, FuriPubSubSubsc FuriPubSubSubscription* updater_main_get_storage_pubsub(UpdaterMainView* main_view); -void updater_main_set_view_dispatcher(UpdaterMainView* main_view, ViewDispatcher* view_dispatcher); \ No newline at end of file +void updater_main_set_view_dispatcher(UpdaterMainView* main_view, ViewDispatcher* view_dispatcher); diff --git a/core/furi/check.c b/core/furi/check.c index 5ea76614321..b59e490c5a3 100644 --- a/core/furi/check.c +++ b/core/furi/check.c @@ -71,4 +71,4 @@ FURI_NORETURN void furi_halt(const char* message) { furi_hal_console_puts("\r\nSystem halted. Bye-bye!\r\n"); furi_hal_console_puts("\033[0m\r\n"); __furi_halt(); -} \ No newline at end of file +} diff --git a/core/furi/check.h b/core/furi/check.h index adea40399b7..4165c3c25dd 100644 --- a/core/furi/check.h +++ b/core/furi/check.h @@ -14,7 +14,10 @@ extern "C" { #ifdef FURI_DEBUG #define furi_assert(__e) ((__e) ? (void)0 : furi_crash("furi_assert failed\r\n")) #else -#define furi_assert(__e) ((void)0) +#define furi_assert(__e) \ + do { \ + ((void)(__e)); \ + } while(0) #endif /** Crash system */ diff --git a/core/furi/common_defines.h b/core/furi/common_defines.h index 9c4f7b18ef0..5b0e6971377 100644 --- a/core/furi/common_defines.h +++ b/core/furi/common_defines.h @@ -40,11 +40,6 @@ extern "C" { #define CLAMP(x, upper, lower) (MIN(upper, MAX(x, lower))) #endif -// need some common semantics for those two -#ifndef SIZEOF_ARRAY -#define SIZEOF_ARRAY(arr) (sizeof(arr) / sizeof(arr[0])) -#endif - #ifndef COUNT_OF #define COUNT_OF(x) (sizeof(x) / sizeof(x[0])) #endif diff --git a/core/furi/memmgr.c b/core/furi/memmgr.c index 457520d92c8..01cf573eb62 100644 --- a/core/furi/memmgr.c +++ b/core/furi/memmgr.c @@ -1,4 +1,5 @@ #include "memmgr.h" +#include "common_defines.h" #include extern void* pvPortMalloc(size_t xSize); @@ -60,17 +61,21 @@ size_t memmgr_get_minimum_free_heap(void) { } void* __wrap__malloc_r(struct _reent* r, size_t size) { + UNUSED(r); return pvPortMalloc(size); } void __wrap__free_r(struct _reent* r, void* ptr) { + UNUSED(r); vPortFree(ptr); } void* __wrap__calloc_r(struct _reent* r, size_t count, size_t size) { + UNUSED(r); return calloc(count, size); } void* __wrap__realloc_r(struct _reent* r, void* ptr, size_t size) { + UNUSED(r); return realloc(ptr, size); } diff --git a/core/furi/memmgr_heap.c b/core/furi/memmgr_heap.c index 8544092eb52..665fe2e1b38 100644 --- a/core/furi/memmgr_heap.c +++ b/core/furi/memmgr_heap.c @@ -205,6 +205,7 @@ static inline void traceMALLOC(void* pointer, size_t size) { #undef traceFREE static inline void traceFREE(void* pointer, size_t size) { + UNUSED(size); osThreadId_t thread_id = osThreadGetId(); if(thread_id && memmgr_heap_thread_trace_depth == 0) { memmgr_heap_thread_trace_depth++; diff --git a/core/furi/stdglue.c b/core/furi/stdglue.c index 4e727202344..1eccafc9a4b 100644 --- a/core/furi/stdglue.c +++ b/core/furi/stdglue.c @@ -93,9 +93,11 @@ bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback) } void __malloc_lock(struct _reent* REENT) { + UNUSED(REENT); vTaskSuspendAll(); } void __malloc_unlock(struct _reent* REENT) { + UNUSED(REENT); xTaskResumeAll(); } diff --git a/core/furi/thread.h b/core/furi/thread.h index ea1da27afce..83e6bb93843 100644 --- a/core/furi/thread.h +++ b/core/furi/thread.h @@ -160,4 +160,4 @@ int32_t furi_thread_get_return_code(FuriThread* thread); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/core/furi/valuemutex.c b/core/furi/valuemutex.c index 77a999371d3..6010c963edf 100644 --- a/core/furi/valuemutex.c +++ b/core/furi/valuemutex.c @@ -55,4 +55,4 @@ bool write_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeou if(!release_mutex(valuemutex, value)) return false; return true; -} \ No newline at end of file +} diff --git a/core/furi/valuemutex.h b/core/furi/valuemutex.h index 84a0809361c..63dfac6111d 100644 --- a/core/furi/valuemutex.h +++ b/core/furi/valuemutex.h @@ -146,4 +146,4 @@ void consumer_app(void* _p) { } } ``` -*/ \ No newline at end of file +*/ diff --git a/docker-compose.yml b/docker-compose.yml index 68aa14c174f..39aca411a19 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,4 +9,4 @@ services: volumes: - .:/project - /dev/bus/usb:/dev/bus/usb - working_dir: '/project' \ No newline at end of file + working_dir: '/project' diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index c3b2117c5a8..0204826ae0e 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -2,6 +2,7 @@ #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) #include +#pragma GCC diagnostic ignored "-Wredundant-decls" extern uint32_t SystemCoreClock; #endif diff --git a/firmware/targets/f7/Inc/stm32_assert.h b/firmware/targets/f7/Inc/stm32_assert.h new file mode 100644 index 00000000000..3b0a543dd48 --- /dev/null +++ b/firmware/targets/f7/Inc/stm32_assert.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file stm32_assert.h + * @author MCD Application Team + * @brief STM32 assert template file. + * This file should be copied to the application folder and renamed + * to stm32_assert.h. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32_ASSERT_H +#define STM32_ASSERT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ + +/* We're confident in the parameters we pass to LL functions, so we can skip asserts + * since they introduce significant bloat to debug builds */ + +#ifdef FURI_LL_DEBUG +#define assert_param furi_assert +#else +#define assert_param(__e) \ + do { \ + ((void)(__e)); \ + } while(0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* STM32_ASSERT_H */ \ No newline at end of file diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c index 1865f8d128a..629c154ed6f 100644 --- a/firmware/targets/f7/Src/main.c +++ b/firmware/targets/f7/Src/main.c @@ -68,16 +68,3 @@ void Error_Handler(void) { void abort() { furi_crash("AbortHandler"); } - -#ifdef USE_FULL_ASSERT -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t* file, uint32_t line) { - furi_crash("HAL assert failed"); -} -#endif /* USE_FULL_ASSERT */ diff --git a/firmware/targets/f7/ble_glue/app_debug.h b/firmware/targets/f7/ble_glue/app_debug.h index e1bd65fc7b3..92a54d75b03 100644 --- a/firmware/targets/f7/ble_glue/app_debug.h +++ b/firmware/targets/f7/ble_glue/app_debug.h @@ -35,4 +35,4 @@ void APPD_EnableCPU2(void); #endif /*__APP_DEBUG_H */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index d76b4e7bf2f..618e2b94826 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -121,6 +121,7 @@ void ble_app_thread_stop() { } static int32_t ble_app_hci_thread(void* arg) { + UNUSED(arg); uint32_t flags = 0; while(1) { @@ -138,6 +139,7 @@ static int32_t ble_app_hci_thread(void* arg) { // Called by WPAN lib void hci_notify_asynch_evt(void* pdata) { + UNUSED(pdata); if(ble_app) { osThreadId_t thread_id = furi_thread_get_thread_id(ble_app->thread); furi_assert(thread_id); @@ -146,12 +148,14 @@ void hci_notify_asynch_evt(void* pdata) { } void hci_cmd_resp_release(uint32_t flag) { + UNUSED(flag); if(ble_app) { osSemaphoreRelease(ble_app->hci_sem); } } void hci_cmd_resp_wait(uint32_t timeout) { + UNUSED(timeout); if(ble_app) { osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); } diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index ec4a617b8a3..6a100bea2dd 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -349,6 +349,7 @@ void ble_glue_thread_stop() { // Wrap functions static int32_t ble_glue_shci_thread(void* context) { + UNUSED(context); uint32_t flags = 0; while(true) { diff --git a/firmware/targets/f7/ble_glue/ble_glue.h b/firmware/targets/f7/ble_glue/ble_glue.h index e5c2738d935..fe43ae09d78 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.h +++ b/firmware/targets/f7/ble_glue/ble_glue.h @@ -121,4 +121,4 @@ BleGlueCommandResult ble_glue_fus_wait_operation(); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 45191a5a5b2..f2a1a96f1f5 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -489,6 +489,7 @@ void gap_stop_advertising() { } static void gap_advetise_timer_callback(void* context) { + UNUSED(context); GapCommand command = GapCommandAdvLowPower; furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); } @@ -587,6 +588,7 @@ void gap_thread_stop() { } static int32_t gap_app(void* context) { + UNUSED(context); GapCommand command; while(1) { osStatus_t status = osMessageQueueGet(gap->command_queue, &command, NULL, osWaitForever); diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c index 246eabf0c52..fc2924d43e8 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c @@ -419,6 +419,7 @@ uint8_t BSP_SD_GetCardInfo(SD_CardInfo* pCardInfo) { */ uint8_t BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout) { + UNUSED(Timeout); // FIXME! uint32_t offset = 0; uint32_t addr; uint8_t retr = BSP_SD_ERROR; @@ -500,6 +501,7 @@ uint8_t BSP_SD_WriteBlocks( uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout) { + UNUSED(Timeout); // FIXME! uint32_t offset = 0; uint32_t addr; uint8_t retr = BSP_SD_ERROR; diff --git a/firmware/targets/f7/fatfs/user_diskio.c b/firmware/targets/f7/fatfs/user_diskio.c index 94a7d4d3515..b504fcd516b 100644 --- a/firmware/targets/f7/fatfs/user_diskio.c +++ b/firmware/targets/f7/fatfs/user_diskio.c @@ -44,6 +44,7 @@ static volatile DSTATUS Stat = STA_NOINIT; static DSTATUS User_CheckStatus(BYTE lun) { + UNUSED(lun); Stat = STA_NOINIT; if(BSP_SD_GetCardState() == MSD_OK) { Stat &= ~STA_NOINIT; @@ -106,6 +107,7 @@ DSTATUS USER_initialize(BYTE pdrv) { */ DSTATUS USER_status(BYTE pdrv) { /* USER CODE BEGIN STATUS */ + UNUSED(pdrv); return Stat; /* USER CODE END STATUS */ } @@ -120,6 +122,7 @@ DSTATUS USER_status(BYTE pdrv) { */ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ + UNUSED(pdrv); DRESULT res = RES_ERROR; furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); @@ -151,6 +154,7 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN WRITE */ /* USER CODE HERE */ + UNUSED(pdrv); DRESULT res = RES_ERROR; furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); @@ -181,6 +185,7 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { #if _USE_IOCTL == 1 DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { /* USER CODE BEGIN IOCTL */ + UNUSED(pdrv); DRESULT res = RES_ERROR; BSP_SD_CardInfo CardInfo; @@ -228,4 +233,4 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { } #endif /* _USE_IOCTL == 1 */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/furi_hal/furi_hal_crc.h b/firmware/targets/f7/furi_hal/furi_hal_crc.h index 110e6c05fa3..8abaaad1d6f 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_crc.h +++ b/firmware/targets/f7/furi_hal/furi_hal_crc.h @@ -32,4 +32,4 @@ uint32_t furi_hal_crc_feed(void* data, uint16_t length); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.h b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.h index 03c0f1ca1c2..a8fb91835fd 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.h +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.h @@ -28,4 +28,4 @@ extern FuriHalI2cBusHandle furi_hal_i2c_handle_external; #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c_types.h b/firmware/targets/f7/furi_hal/furi_hal_i2c_types.h index 0f2b735e4db..13f361054bb 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c_types.h +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c_types.h @@ -48,4 +48,4 @@ struct FuriHalI2cBusHandle { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index bbb3907dbfd..cf7140eb4e3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -132,4 +132,4 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("protobuf_version_minor", string_get_cstr(value), true, context); string_clear(value); -} \ No newline at end of file +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index bf9ea18c482..768a4bac79e 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -240,6 +240,7 @@ void rfal_interrupt_callback_handler() { } void rfal_state_changed_callback(void* context) { + UNUSED(context); osEventFlagsSet(event, EVENT_FLAG_STATE_CHANGED); } @@ -289,7 +290,7 @@ bool furi_hal_nfc_emulate_nfca( buff_rx_len = 0; buff_tx_len = 0; uint32_t flag = osEventFlagsWait(event, EVENT_FLAG_ALL, osFlagsWaitAny, timeout); - if(flag == osErrorTimeout || flag == EVENT_FLAG_STOP) { + if(flag == osFlagsErrorTimeout || flag == EVENT_FLAG_STOP) { break; } bool data_received = false; diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 8beb0d084cb..9dd7191fb9c 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -178,5 +179,9 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { } void vApplicationStackOverflowHook(TaskHandle_t xTask, char* pcTaskName) { + UNUSED(xTask); + furi_hal_console_puts("\r\n\r\n stack overflow in "); + furi_hal_console_puts(pcTaskName); + furi_hal_console_puts("\r\n\r\n"); furi_crash("StackOverflow"); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_random.c b/firmware/targets/f7/furi_hal/furi_hal_random.c index 5dfda2b259b..0f282fac818 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_random.c +++ b/firmware/targets/f7/furi_hal/furi_hal_random.c @@ -51,6 +51,7 @@ void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len) { } void srand(unsigned seed) { + UNUSED(seed); // FIXME! } int rand() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_rfid.c b/firmware/targets/f7/furi_hal/furi_hal_rfid.c index 964bd12b28c..86fecc99490 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rfid.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rfid.c @@ -152,6 +152,7 @@ void furi_hal_rfid_tim_read_stop() { } void furi_hal_rfid_tim_emulate(float freq) { + UNUSED(freq); // FIXME // basic PWM setup with needed freq and internal clock FURI_CRITICAL_ENTER(); LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER); diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi.c b/firmware/targets/f7/furi_hal/furi_hal_spi.c index 01cb3ae68d1..f8c5a2c7820 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi.c @@ -83,6 +83,7 @@ void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { } static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { + UNUSED(timeout); // FIXME while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY) ; while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)) diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_config.h b/firmware/targets/f7/furi_hal/furi_hal_spi_config.h index 3e4296a0584..eab633a1938 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_config.h +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_config.h @@ -58,4 +58,4 @@ extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_types.h b/firmware/targets/f7/furi_hal/furi_hal_spi_types.h index 1fb1c02b6bd..d2273f38ba5 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_types.h +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_types.h @@ -61,4 +61,4 @@ struct FuriHalSpiBusHandle { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index d41414f8730..6a5e534ef3c 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -189,6 +189,9 @@ void furi_hal_usb_set_state_callback(FuriHalUsbStateCallback cb, void* ctx) { } static void reset_evt(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); + UNUSED(event); + UNUSED(ep); osThreadFlagsSet(furi_thread_get_thread_id(usb.thread), EventReset); if(usb.callback != NULL) { usb.callback(FuriHalUsbStateEventReset, usb.cb_ctx); @@ -196,6 +199,9 @@ static void reset_evt(usbd_device* dev, uint8_t event, uint8_t ep) { } static void susp_evt(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); + UNUSED(event); + UNUSED(ep); if((usb.if_cur != NULL) && (usb.connected == true)) { usb.connected = false; usb.if_cur->suspend(&udev); @@ -208,6 +214,9 @@ static void susp_evt(usbd_device* dev, uint8_t event, uint8_t ep) { } static void wkup_evt(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); + UNUSED(event); + UNUSED(ep); if((usb.if_cur != NULL) && (usb.connected == false)) { usb.connected = true; usb.if_cur->wakeup(&udev); @@ -220,6 +229,7 @@ static void wkup_evt(usbd_device* dev, uint8_t event, uint8_t ep) { } static int32_t furi_hal_usb_thread(void* context) { + UNUSED(context); bool usb_request_pending = false; uint8_t usb_wait_time = 0; FuriHalUsbInterface* if_new = NULL; diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb_cdc.c b/firmware/targets/f7/furi_hal/furi_hal_usb_cdc.c index 807f163489d..69a7fb3ce61 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb_cdc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb_cdc.c @@ -429,6 +429,7 @@ FuriHalUsbInterface usb_cdc_dual = { }; static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { + UNUSED(ctx); usb_dev = dev; cdc_if_cur = intf; @@ -515,6 +516,7 @@ int32_t furi_hal_cdc_receive(uint8_t if_num, uint8_t* buf, uint16_t max_len) { } static void cdc_on_wakeup(usbd_device* dev) { + UNUSED(dev); connected = true; for(uint8_t i = 0; i < IF_NUM_MAX; i++) { if(callbacks[i] != NULL) { @@ -524,6 +526,7 @@ static void cdc_on_wakeup(usbd_device* dev) { } static void cdc_on_suspend(usbd_device* dev) { + UNUSED(dev); connected = false; for(uint8_t i = 0; i < IF_NUM_MAX; i++) { cdc_ctrl_line_state[i] = 0; @@ -534,6 +537,8 @@ static void cdc_on_suspend(usbd_device* dev) { } static void cdc_rx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); + UNUSED(event); uint8_t if_num = 0; if(ep == CDC0_RXD_EP) if_num = 0; @@ -547,6 +552,8 @@ static void cdc_rx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { } static void cdc_tx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); + UNUSED(event); uint8_t if_num = 0; if(ep == CDC0_TXD_EP) if_num = 0; @@ -629,6 +636,7 @@ static usbd_respond cdc_ep_config(usbd_device* dev, uint8_t cfg) { /* Control requests handler */ static usbd_respond cdc_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) { + UNUSED(callback); /* CDC control requests */ uint8_t if_num = 0; if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c b/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c index 55825dd9d3c..aae4dd4fb6b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c @@ -375,6 +375,7 @@ static void* hid_set_string_descr(char* str) { } static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { + UNUSED(intf); FuriHalUsbHidConfig* cfg = (FuriHalUsbHidConfig*)ctx; if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL); usb_dev = dev; @@ -419,17 +420,23 @@ static void hid_deinit(usbd_device* dev) { } static void hid_on_wakeup(usbd_device* dev) { - if(hid_connected == false) { + UNUSED(dev); + if(!hid_connected) { hid_connected = true; - if(callback != NULL) callback(true, cb_ctx); + if(callback != NULL) { + callback(true, cb_ctx); + } } } static void hid_on_suspend(usbd_device* dev) { - if(hid_connected == true) { + UNUSED(dev); + if(hid_connected) { hid_connected = false; osSemaphoreRelease(hid_semaphore); - if(callback != NULL) callback(false, cb_ctx); + if(callback != NULL) { + callback(false, cb_ctx); + } } } @@ -450,6 +457,7 @@ static bool hid_send_report(uint8_t report_id) { } static void hid_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); if(event == usbd_evt_eptx) { osSemaphoreRelease(hid_semaphore); } else { @@ -484,6 +492,7 @@ static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg) { /* Control requests handler */ static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) { + UNUSED(callback); /* HID control requests */ if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_CLASS) && diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c b/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c index 37d879ed556..a80410869db 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c @@ -159,14 +159,18 @@ bool furi_hal_hid_u2f_is_connected() { void furi_hal_hid_u2f_set_callback(HidU2fCallback cb, void* ctx) { if(callback != NULL) { - if(hid_u2f_connected == true) callback(HidU2fDisconnected, cb_ctx); + if(hid_u2f_connected == true) { + callback(HidU2fDisconnected, cb_ctx); + } } callback = cb; cb_ctx = ctx; if(callback != NULL) { - if(hid_u2f_connected == true) callback(HidU2fConnected, cb_ctx); + if(hid_u2f_connected == true) { + callback(HidU2fConnected, cb_ctx); + } } } @@ -186,7 +190,11 @@ FuriHalUsbInterface usb_hid_u2f = { }; static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { - if(hid_u2f_semaphore == NULL) hid_u2f_semaphore = osSemaphoreNew(1, 1, NULL); + UNUSED(intf); + UNUSED(ctx); + if(hid_u2f_semaphore == NULL) { + hid_u2f_semaphore = osSemaphoreNew(1, 1, NULL); + } usb_dev = dev; usbd_reg_config(dev, hid_u2f_ep_config); @@ -201,15 +209,21 @@ static void hid_u2f_deinit(usbd_device* dev) { } static void hid_u2f_on_wakeup(usbd_device* dev) { + UNUSED(dev); hid_u2f_connected = true; - if(callback != NULL) callback(HidU2fConnected, cb_ctx); + if(callback != NULL) { + callback(HidU2fConnected, cb_ctx); + } } static void hid_u2f_on_suspend(usbd_device* dev) { - if(hid_u2f_connected == true) { + UNUSED(dev); + if(hid_u2f_connected) { hid_u2f_connected = false; osSemaphoreRelease(hid_u2f_semaphore); - if(callback != NULL) callback(HidU2fDisconnected, cb_ctx); + if(callback != NULL) { + callback(HidU2fDisconnected, cb_ctx); + } } } @@ -227,10 +241,18 @@ uint32_t furi_hal_hid_u2f_get_request(uint8_t* data) { } static void hid_u2f_rx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { - if(callback != NULL) callback(HidU2fRequest, cb_ctx); + UNUSED(dev); + UNUSED(event); + UNUSED(ep); + if(callback != NULL) { + callback(HidU2fRequest, cb_ctx); + } } static void hid_u2f_tx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); + UNUSED(event); + UNUSED(ep); osSemaphoreRelease(hid_u2f_semaphore); } @@ -268,6 +290,7 @@ static usbd_respond hid_u2f_ep_config(usbd_device* dev, uint8_t cfg) { /* Control requests handler */ static usbd_respond hid_u2f_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) { + UNUSED(callback); /* HID control requests */ if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_CLASS) && diff --git a/firmware/targets/f7/furi_hal/furi_hal_version.c b/firmware/targets/f7/furi_hal/furi_hal_version.c index e580c978c57..7abee281f34 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_version.c +++ b/firmware/targets/f7/furi_hal/furi_hal_version.c @@ -205,7 +205,7 @@ const char* furi_hal_version_get_model_name() { return "Flipper Zero"; } -const FuriHalVersionOtpVersion furi_hal_version_get_otp_version() { +FuriHalVersionOtpVersion furi_hal_version_get_otp_version() { if(*(uint64_t*)FURI_HAL_VERSION_OTP_ADDRESS == 0xFFFFFFFF) { return FuriHalVersionOtpVersionEmpty; } else { @@ -228,27 +228,27 @@ const FuriHalVersionOtpVersion furi_hal_version_get_otp_version() { } } -const uint8_t furi_hal_version_get_hw_version() { +uint8_t furi_hal_version_get_hw_version() { return furi_hal_version.board_version; } -const uint8_t furi_hal_version_get_hw_target() { +uint8_t furi_hal_version_get_hw_target() { return furi_hal_version.board_target; } -const uint8_t furi_hal_version_get_hw_body() { +uint8_t furi_hal_version_get_hw_body() { return furi_hal_version.board_body; } -const FuriHalVersionColor furi_hal_version_get_hw_color() { +FuriHalVersionColor furi_hal_version_get_hw_color() { return furi_hal_version.board_color; } -const uint8_t furi_hal_version_get_hw_connect() { +uint8_t furi_hal_version_get_hw_connect() { return furi_hal_version.board_connect; } -const FuriHalVersionRegion furi_hal_version_get_hw_region() { +FuriHalVersionRegion furi_hal_version_get_hw_region() { return furi_hal_version.board_region; } @@ -266,11 +266,11 @@ const char* furi_hal_version_get_hw_region_name() { return "R??"; } -const FuriHalVersionDisplay furi_hal_version_get_hw_display() { +FuriHalVersionDisplay furi_hal_version_get_hw_display() { return furi_hal_version.board_display; } -const uint32_t furi_hal_version_get_hw_timestamp() { +uint32_t furi_hal_version_get_hw_timestamp() { return furi_hal_version.timestamp; } diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index 6410ba13099..d96dd5e665d 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -18,7 +18,10 @@ endif MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -CFLAGS += $(MCU_FLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections +# Warnings configuration +CFLAGS += -Wall -Wextra -Wredundant-decls + +CFLAGS += $(MCU_FLAGS) -DSTM32WB55xx -fdata-sections -ffunction-sections LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions @@ -35,6 +38,7 @@ ASM_SOURCES += $(MXPROJECT_DIR)/startup_stm32wb55xx_cm4.s CUBE_DIR = ../lib/STM32CubeWB CFLAGS += \ -DUSE_FULL_LL_DRIVER \ + -DUSE_FULL_ASSERT \ -DHAVE_FREERTOS CFLAGS += \ -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc \ diff --git a/firmware/targets/furi_hal_include/furi_hal_random.h b/firmware/targets/furi_hal_include/furi_hal_random.h index fa549d23d5b..ee69326f416 100644 --- a/firmware/targets/furi_hal_include/furi_hal_random.h +++ b/firmware/targets/furi_hal_include/furi_hal_random.h @@ -21,4 +21,4 @@ void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/furi_hal_include/furi_hal_sd.h b/firmware/targets/furi_hal_include/furi_hal_sd.h index 307a872126c..e1c08a35ca1 100644 --- a/firmware/targets/furi_hal_include/furi_hal_sd.h +++ b/firmware/targets/furi_hal_include/furi_hal_sd.h @@ -1,3 +1,4 @@ +#pragma once /** * @file furi_hal_sd.h * SD Card HAL API diff --git a/firmware/targets/furi_hal_include/furi_hal_usb_hid.h b/firmware/targets/furi_hal_include/furi_hal_usb_hid.h index 4819e82e9c0..20c76223e99 100644 --- a/firmware/targets/furi_hal_include/furi_hal_usb_hid.h +++ b/firmware/targets/furi_hal_include/furi_hal_usb_hid.h @@ -347,4 +347,4 @@ bool furi_hal_hid_consumer_key_press(uint16_t button); * * @param button key code */ -bool furi_hal_hid_consumer_key_release(uint16_t button); \ No newline at end of file +bool furi_hal_hid_consumer_key_release(uint16_t button); diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index 2c624f6e95e..52ac843e3f0 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -14,6 +14,7 @@ static volatile PlatformIrqCallback platform_irq_callback = NULL; static const GpioPin pin = {ST25R_INT_PORT, ST25R_INT_PIN}; void nfc_isr(void* _ctx) { + UNUSED(_ctx); if(platform_irq_callback && platformGpioIsHigh(ST25R_INT_PORT, ST25R_INT_PIN)) { osThreadFlagsSet(platform_irq_thread_id, 0x1); } diff --git a/lib/ST25RFAL002/source/rfal_t4t.c b/lib/ST25RFAL002/source/rfal_t4t.c index bcc5b8debbf..8592daf8fbb 100644 --- a/lib/ST25RFAL002/source/rfal_t4t.c +++ b/lib/ST25RFAL002/source/rfal_t4t.c @@ -118,6 +118,7 @@ ReturnCode rfalT4TPollerComposeCAPDU(const rfalT4tCApduParam* apduParam) { } /* Check whether requested Lc fits */ +#pragma GCC diagnostic ignored "-Wtype-limits" if((uint16_t)apduParam->Lc > (uint16_t)(RFAL_FEATURE_ISO_DEP_APDU_MAX_LEN - RFAL_T4T_LE_LEN)) { return ERR_PARAM; /* PRQA S 2880 # MISRA 2.1 - Unreachable code due to configuration option being set/unset */ diff --git a/lib/ST25RFAL002/source/st25r3916/st25r3916_com.c b/lib/ST25RFAL002/source/st25r3916/st25r3916_com.c index 71ded38f179..40d65807d17 100644 --- a/lib/ST25RFAL002/source/st25r3916/st25r3916_com.c +++ b/lib/ST25RFAL002/source/st25r3916/st25r3916_com.c @@ -609,7 +609,8 @@ bool st25r3916CheckReg(uint8_t reg, uint8_t mask, uint8_t val) { /*******************************************************************************/ bool st25r3916IsRegValid(uint8_t reg) { - if(!(((int16_t)reg >= (int16_t)ST25R3916_REG_IO_CONF1) && +#pragma GCC diagnostic ignored "-Wtype-limits" + if(!(((int16_t)reg >= (int32_t)ST25R3916_REG_IO_CONF1) && (reg <= (ST25R3916_SPACE_B | ST25R3916_REG_IC_IDENTITY)))) { return false; } diff --git a/lib/ST25RFAL002/timer.h b/lib/ST25RFAL002/timer.h index c6719410eae..b5f5eb329d5 100644 --- a/lib/ST25RFAL002/timer.h +++ b/lib/ST25RFAL002/timer.h @@ -1,3 +1,4 @@ +#pragma once /****************************************************************************** * @attention * @@ -38,7 +39,8 @@ * INCLUDES ****************************************************************************** */ -#include "platform.h" +#include +#include /* ****************************************************************************** diff --git a/lib/app-scened-template/file_worker.c b/lib/app-scened-template/file_worker.c index f32d10d7c2e..3a742ff9693 100644 --- a/lib/app-scened-template/file_worker.c +++ b/lib/app-scened-template/file_worker.c @@ -232,6 +232,7 @@ bool file_worker_write_hex(FileWorker* file_worker, const uint8_t* buffer, uint1 } void file_worker_show_error(FileWorker* file_worker, const char* error_text) { + UNUSED(file_worker); DialogsApp* dialogs = furi_record_open("dialogs"); DialogMessage* message = dialog_message_alloc(); @@ -251,6 +252,7 @@ bool file_worker_file_select( char* result, uint8_t result_size, const char* selected_filename) { + UNUSED(file_worker); DialogsApp* dialogs = furi_record_open("dialogs"); bool ret = dialog_file_select_show(dialogs, path, extension, result, result_size, selected_filename); @@ -259,6 +261,7 @@ bool file_worker_file_select( } bool file_worker_check_common_errors(FileWorker* file_worker) { + UNUSED(file_worker); //TODO remove /* TODO: [FL-1431] Add return value to file_parser.get_sd_api().check_error() and replace get_fs_info(). */ return true; diff --git a/lib/app-scened-template/generic_scene.hpp b/lib/app-scened-template/generic_scene.hpp index c9e823b2b48..979e974787b 100644 --- a/lib/app-scened-template/generic_scene.hpp +++ b/lib/app-scened-template/generic_scene.hpp @@ -6,4 +6,4 @@ template class GenericScene { virtual ~GenericScene(){}; private: -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/record_controller.hpp b/lib/app-scened-template/record_controller.hpp index af8db58c383..9dfa96573d5 100644 --- a/lib/app-scened-template/record_controller.hpp +++ b/lib/app-scened-template/record_controller.hpp @@ -43,4 +43,4 @@ template class RecordController { private: const char* name; TRecordClass* value; -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/scene_controller.hpp b/lib/app-scened-template/scene_controller.hpp index 7e4c5ec0f83..678f6c0df7b 100644 --- a/lib/app-scened-template/scene_controller.hpp +++ b/lib/app-scened-template/scene_controller.hpp @@ -141,7 +141,7 @@ template class SceneController { * @param tick_length_ms tick event length in milliseconds */ void process( - uint32_t tick_length_ms = 100, + uint32_t /* tick_length_ms */ = 100, typename TApp::SceneType start_scene_index = TApp::SceneType::Start) { typename TApp::Event event; bool consumed; @@ -240,4 +240,4 @@ template class SceneController { return scene_index; } -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/text_store.h b/lib/app-scened-template/text_store.h index 95329f6d95e..a01784fdee8 100644 --- a/lib/app-scened-template/text_store.h +++ b/lib/app-scened-template/text_store.h @@ -9,4 +9,4 @@ class TextStore { void set(const char* text...); const uint8_t text_size; char* text; -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/typeindex_no_rtti.hpp b/lib/app-scened-template/typeindex_no_rtti.hpp index be350cc9d67..4ac52725f18 100644 --- a/lib/app-scened-template/typeindex_no_rtti.hpp +++ b/lib/app-scened-template/typeindex_no_rtti.hpp @@ -118,4 +118,4 @@ template <> struct std::hash { result_type operator()(argument_type const& t) const noexcept { return t.hash_code(); } -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/view_modules/byte_input_vm.h b/lib/app-scened-template/view_modules/byte_input_vm.h index 8217b2131a7..9a16101277c 100644 --- a/lib/app-scened-template/view_modules/byte_input_vm.h +++ b/lib/app-scened-template/view_modules/byte_input_vm.h @@ -34,4 +34,4 @@ class ByteInputVM : public GenericViewModule { private: ByteInput* byte_input; -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/view_modules/dialog_ex_vm.h b/lib/app-scened-template/view_modules/dialog_ex_vm.h index 5c3cf124504..66c2b760a01 100644 --- a/lib/app-scened-template/view_modules/dialog_ex_vm.h +++ b/lib/app-scened-template/view_modules/dialog_ex_vm.h @@ -70,4 +70,4 @@ class DialogExVM : public GenericViewModule { private: DialogEx* dialog_ex; -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/view_modules/generic_view_module.h b/lib/app-scened-template/view_modules/generic_view_module.h index 10f04dc3d0e..8b74ea3add2 100644 --- a/lib/app-scened-template/view_modules/generic_view_module.h +++ b/lib/app-scened-template/view_modules/generic_view_module.h @@ -7,4 +7,4 @@ class GenericViewModule { virtual ~GenericViewModule(){}; virtual View* get_view() = 0; virtual void clean() = 0; -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/view_modules/popup_vm.h b/lib/app-scened-template/view_modules/popup_vm.h index 483f33a294b..2665056393a 100644 --- a/lib/app-scened-template/view_modules/popup_vm.h +++ b/lib/app-scened-template/view_modules/popup_vm.h @@ -65,4 +65,4 @@ class PopupVM : public GenericViewModule { private: Popup* popup; -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/view_modules/submenu_vm.h b/lib/app-scened-template/view_modules/submenu_vm.h index 6dba936ff9a..06541527a06 100644 --- a/lib/app-scened-template/view_modules/submenu_vm.h +++ b/lib/app-scened-template/view_modules/submenu_vm.h @@ -39,4 +39,4 @@ class SubmenuVM : public GenericViewModule { private: Submenu* submenu; -}; \ No newline at end of file +}; diff --git a/lib/app-scened-template/view_modules/text_input_vm.h b/lib/app-scened-template/view_modules/text_input_vm.h index 8fafe861c74..81799e48cee 100644 --- a/lib/app-scened-template/view_modules/text_input_vm.h +++ b/lib/app-scened-template/view_modules/text_input_vm.h @@ -38,4 +38,4 @@ class TextInputVM : public GenericViewModule { private: TextInput* text_input; -}; \ No newline at end of file +}; diff --git a/lib/app-template/app_template.h b/lib/app-template/app_template.h index 3af491efe12..7adcf2bf3a0 100644 --- a/lib/app-template/app_template.h +++ b/lib/app-template/app_template.h @@ -110,4 +110,4 @@ template uint8_t AppTemplate::exit( template void AppTemplate::update_gui(void) { view_port_update(view_port); -} \ No newline at end of file +} diff --git a/lib/callback-connector/callback-connector.h b/lib/callback-connector/callback-connector.h index e98ee91428d..10fec3e2d0e 100644 --- a/lib/callback-connector/callback-connector.h +++ b/lib/callback-connector/callback-connector.h @@ -96,4 +96,4 @@ template auto obtain_connector(Functor functor) { } } //end of cbc scope -#endif // CALLBACKCONNECTOR_H \ No newline at end of file +#endif // CALLBACKCONNECTOR_H diff --git a/lib/drivers/bq27220.c b/lib/drivers/bq27220.c index bf654b5d527..18f3f028d00 100644 --- a/lib/drivers/bq27220.c +++ b/lib/drivers/bq27220.c @@ -47,7 +47,7 @@ bool bq27220_set_parameter_u16(FuriHalI2cBusHandle* handle, uint16_t address, ui uint8_t checksum = bq27220_get_checksum(buffer, 4); buffer[0] = checksum; buffer[1] = 6; - ret = furi_hal_i2c_write_mem( + ret &= furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT); furi_hal_delay_us(10000); @@ -62,13 +62,13 @@ bool bq27220_init(FuriHalI2cBusHandle* handle, const ParamCEDV* cedv) { return true; } FURI_LOG_I(TAG, "Start updating battery profile"); - OperationStatus status = {}; + OperationStatus status = {0}; if(!bq27220_control(handle, Control_ENTER_CFG_UPDATE)) { FURI_LOG_E(TAG, "Can't configure update"); return false; }; - while((status.CFGUPDATE != 1) && (timeout-- > 0)) { + while((status.CFGUPDATE != true) && (timeout-- > 0)) { bq27220_get_operation_status(handle, &status); } bq27220_set_parameter_u16(handle, AddressGaugingConfig, cedv->cedv_conf.gauge_conf_raw); diff --git a/lib/drivers/cc1101.h b/lib/drivers/cc1101.h index c35c823c62b..af1f15569d1 100644 --- a/lib/drivers/cc1101.h +++ b/lib/drivers/cc1101.h @@ -148,13 +148,6 @@ uint32_t cc1101_set_intermediate_frequency(FuriHalSpiBusHandle* handle, uint32_t */ void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]); -/** Set Power Amplifier level table, ramp - * - * @param handle - pointer to FuriHalSpiHandle - * @param value - array of power level values - */ -void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]); - /** Write FIFO * * @param handle - pointer to FuriHalSpiHandle @@ -177,4 +170,4 @@ uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* si #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/drivers/cc1101_regs.h b/lib/drivers/cc1101_regs.h index 30a680bebef..a326dc92ce8 100644 --- a/lib/drivers/cc1101_regs.h +++ b/lib/drivers/cc1101_regs.h @@ -209,4 +209,4 @@ typedef struct { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/fatfs/ff.c b/lib/fatfs/ff.c index b0bd4366298..85ab9736eb5 100644 --- a/lib/fatfs/ff.c +++ b/lib/fatfs/ff.c @@ -1059,7 +1059,7 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluste break; } } - /* go to default */ + __attribute__ ((fallthrough)); #endif default: val = 1; /* Internal error */ @@ -5430,7 +5430,7 @@ FRESULT f_mkfs ( ch = 0xFFFF; st = 2; break; /* Compress the no-case block if run is >= 128 */ } st = 1; /* Do not compress short run */ - /* go to next case */ + __attribute__ ((fallthrough)); case 1: ch = si++; /* Fill the short run */ if (--j == 0) st = 0; diff --git a/lib/fatfs/ff_gen_drv.c b/lib/fatfs/ff_gen_drv.c index ccd595bba26..9fb51efa8ef 100644 --- a/lib/fatfs/ff_gen_drv.c +++ b/lib/fatfs/ff_gen_drv.c @@ -79,6 +79,7 @@ uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path) */ uint8_t FATFS_UnLinkDriverEx(char *path, uint8_t lun) { + (void)lun; uint8_t DiskNum = 0; uint8_t ret = 1; diff --git a/lib/flipper_format/flipper_format.c b/lib/flipper_format/flipper_format.c index 01f54632a1c..cee76701749 100644 --- a/lib/flipper_format/flipper_format.c +++ b/lib/flipper_format/flipper_format.c @@ -584,4 +584,4 @@ bool flipper_format_insert_or_update_hex( } return result; -} \ No newline at end of file +} diff --git a/lib/flipper_format/flipper_format.h b/lib/flipper_format/flipper_format.h index 0f3c299dbe5..49e3f936599 100644 --- a/lib/flipper_format/flipper_format.h +++ b/lib/flipper_format/flipper_format.h @@ -622,4 +622,4 @@ bool flipper_format_insert_or_update_hex( #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/flipper_format/flipper_format_i.h b/lib/flipper_format/flipper_format_i.h index a47d413146d..55b06f9ff3c 100644 --- a/lib/flipper_format/flipper_format_i.h +++ b/lib/flipper_format/flipper_format_i.h @@ -16,4 +16,4 @@ Stream* flipper_format_get_raw_stream(FlipperFormat* flipper_format); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index b3a085904b1..93b788a38e1 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -295,7 +295,7 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa furi_crash("Unknown FF type"); } - if((i + 1) < write_data->data_size) { + if((size_t)(i + 1) < write_data->data_size) { string_cat(value, " "); } @@ -340,7 +340,7 @@ bool flipper_format_stream_read_value_line( string_t value; string_init(value); - for(uint16_t i = 0; i < data_size; i++) { + for(size_t i = 0; i < data_size; i++) { bool last = false; result = flipper_format_stream_read_value(stream, value, &last); if(result) { @@ -507,4 +507,4 @@ bool flipper_format_stream_write_comment_cstr(Stream* stream, const char* data) } while(false); return result; -} \ No newline at end of file +} diff --git a/lib/flipper_format/flipper_format_stream.h b/lib/flipper_format/flipper_format_stream.h index dc9fb5b3af2..6ac17322f16 100644 --- a/lib/flipper_format/flipper_format_stream.h +++ b/lib/flipper_format/flipper_format_stream.h @@ -92,4 +92,4 @@ bool flipper_format_stream_write_comment_cstr(Stream* stream, const char* data); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/flipper_format/flipper_format_stream_i.h b/lib/flipper_format/flipper_format_stream_i.h index 74cf8f1a551..f3614900755 100644 --- a/lib/flipper_format/flipper_format_stream_i.h +++ b/lib/flipper_format/flipper_format_stream_i.h @@ -31,4 +31,4 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/fnv1a-hash/fnv1a-hash.c b/lib/fnv1a-hash/fnv1a-hash.c index a5bfa206c96..69c675f310a 100644 --- a/lib/fnv1a-hash/fnv1a-hash.c +++ b/lib/fnv1a-hash/fnv1a-hash.c @@ -7,4 +7,4 @@ uint32_t fnv1a_buffer_hash(const uint8_t* buffer, uint32_t length, uint32_t hash hash = (hash ^ buffer[i]) * 16777619ULL; } return hash; -} \ No newline at end of file +} diff --git a/lib/fnv1a-hash/fnv1a-hash.h b/lib/fnv1a-hash/fnv1a-hash.h index fbbdb5b87c6..3218cc27c75 100644 --- a/lib/fnv1a-hash/fnv1a-hash.h +++ b/lib/fnv1a-hash/fnv1a-hash.h @@ -36,4 +36,4 @@ inline uint32_t fnv1a_string_hash(const char* str) { } return hash; } -#endif \ No newline at end of file +#endif diff --git a/lib/heatshrink/heatshrink_encoder.c b/lib/heatshrink/heatshrink_encoder.c index 9cd2594cdcf..98f27dff872 100644 --- a/lib/heatshrink/heatshrink_encoder.c +++ b/lib/heatshrink/heatshrink_encoder.c @@ -232,6 +232,7 @@ HSE_poll_res heatshrink_encoder_poll(heatshrink_encoder *hse, break; case HSES_FLUSH_BITS: hse->state = st_flush_bit_buffer(hse, &oi); + /* fall through */ case HSES_DONE: return HSER_POLL_EMPTY; default: diff --git a/lib/infrared/encoder_decoder/common/infrared_common_decoder.c b/lib/infrared/encoder_decoder/common/infrared_common_decoder.c index c39de09ee76..1d94428568f 100644 --- a/lib/infrared/encoder_decoder/common/infrared_common_decoder.c +++ b/lib/infrared/encoder_decoder/common/infrared_common_decoder.c @@ -12,7 +12,9 @@ static void infrared_common_decoder_reset_state(InfraredCommonDecoder* decoder); static inline size_t consume_samples(uint32_t* array, size_t len, size_t shift) { furi_assert(len >= shift); len -= shift; - for(int i = 0; i < len; ++i) array[i] = array[i + shift]; + for(size_t i = 0; i < len; ++i) { + array[i] = array[i + shift]; + } return len; } @@ -83,8 +85,8 @@ static InfraredStatus infrared_common_decode_bits(InfraredCommonDecoder* decoder if(timings->min_split_time && !level) { if(timing > timings->min_split_time) { /* long low timing - check if we're ready for any of protocol modification */ - for(int i = 0; decoder->protocol->databit_len[i] && - (i < COUNT_OF(decoder->protocol->databit_len)); + for(size_t i = 0; decoder->protocol->databit_len[i] && + (i < COUNT_OF(decoder->protocol->databit_len)); ++i) { if(decoder->protocol->databit_len[i] == decoder->databit_cnt) { return InfraredStatusReady; @@ -153,8 +155,8 @@ InfraredStatus InfraredStatus infrared_common_decode_manchester(InfraredCommonDecoder* decoder, bool level, uint32_t timing) { furi_assert(decoder); - uint16_t bit = decoder->protocol->timings.bit1_mark; - uint16_t tolerance = decoder->protocol->timings.bit_tolerance; + uint32_t bit = decoder->protocol->timings.bit1_mark; + uint32_t tolerance = decoder->protocol->timings.bit_tolerance; bool* switch_detect = &decoder->switch_detect; furi_assert((*switch_detect == true) || (*switch_detect == false)); @@ -196,7 +198,7 @@ InfraredMessage* infrared_common_decoder_check_ready(InfraredCommonDecoder* deco InfraredMessage* message = NULL; bool found_length = false; - for(int i = 0; + for(size_t i = 0; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) { if(decoder->protocol->databit_len[i] == decoder->databit_cnt) { @@ -280,7 +282,7 @@ void* infrared_common_decoder_alloc(const InfraredCommonProtocolSpec* protocol) furi_assert(protocol); /* protocol->databit_len[0] has to contain biggest value of bits that can be decoded */ - for(int i = 1; i < COUNT_OF(protocol->databit_len); ++i) { + for(size_t i = 1; i < COUNT_OF(protocol->databit_len); ++i) { furi_assert(protocol->databit_len[i] <= protocol->databit_len[0]); } diff --git a/lib/infrared/encoder_decoder/common/infrared_common_encoder.c b/lib/infrared/encoder_decoder/common/infrared_common_encoder.c index 563c1e640a2..f755222d1c4 100644 --- a/lib/infrared/encoder_decoder/common/infrared_common_encoder.c +++ b/lib/infrared/encoder_decoder/common/infrared_common_encoder.c @@ -146,7 +146,7 @@ void* infrared_common_encoder_alloc(const InfraredCommonProtocolSpec* protocol) } /* protocol->databit_len[0] has to contain biggest value of bits that can be decoded */ - for(int i = 1; i < COUNT_OF(protocol->databit_len); ++i) { + for(size_t i = 1; i < COUNT_OF(protocol->databit_len); ++i) { furi_assert(protocol->databit_len[i] <= protocol->databit_len[0]); } @@ -174,7 +174,7 @@ void infrared_common_encoder_reset(InfraredCommonEncoder* encoder) { uint8_t max_databit_len = 0; - for(int i = 0; i < COUNT_OF(encoder->protocol->databit_len); ++i) { + for(size_t i = 0; i < COUNT_OF(encoder->protocol->databit_len); ++i) { max_databit_len = MAX(max_databit_len, encoder->protocol->databit_len[i]); } diff --git a/lib/infrared/encoder_decoder/infrared.c b/lib/infrared/encoder_decoder/infrared.c index 5dfa928134b..59b11d5cedb 100644 --- a/lib/infrared/encoder_decoder/infrared.c +++ b/lib/infrared/encoder_decoder/infrared.c @@ -123,7 +123,7 @@ const InfraredMessage* InfraredMessage* message = NULL; InfraredMessage* result = NULL; - for(int i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { + for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { if(infrared_encoder_decoder[i].decoder.decode) { message = infrared_encoder_decoder[i].decoder.decode(handler->ctx[i], level, duration); if(!result && message) { @@ -139,7 +139,7 @@ InfraredDecoderHandler* infrared_alloc_decoder(void) { InfraredDecoderHandler* handler = malloc(sizeof(InfraredDecoderHandler)); handler->ctx = malloc(sizeof(void*) * COUNT_OF(infrared_encoder_decoder)); - for(int i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { + for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { handler->ctx[i] = 0; if(infrared_encoder_decoder[i].decoder.alloc) handler->ctx[i] = infrared_encoder_decoder[i].decoder.alloc(); @@ -153,7 +153,7 @@ void infrared_free_decoder(InfraredDecoderHandler* handler) { furi_assert(handler); furi_assert(handler->ctx); - for(int i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { + for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { if(infrared_encoder_decoder[i].decoder.free) infrared_encoder_decoder[i].decoder.free(handler->ctx[i]); } @@ -163,7 +163,7 @@ void infrared_free_decoder(InfraredDecoderHandler* handler) { } void infrared_reset_decoder(InfraredDecoderHandler* handler) { - for(int i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { + for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { if(infrared_encoder_decoder[i].decoder.reset) infrared_encoder_decoder[i].decoder.reset(handler->ctx[i]); } @@ -175,7 +175,7 @@ const InfraredMessage* infrared_check_decoder_ready(InfraredDecoderHandler* hand InfraredMessage* message = NULL; InfraredMessage* result = NULL; - for(int i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { + for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { if(infrared_encoder_decoder[i].decoder.check_ready) { message = infrared_encoder_decoder[i].decoder.check_ready(handler->ctx[i]); if(!result && message) { @@ -209,7 +209,7 @@ void infrared_free_encoder(InfraredEncoderHandler* handler) { } static int infrared_find_index_by_protocol(InfraredProtocol protocol) { - for(int i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { + for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) { if(infrared_encoder_decoder[i].get_protocol_spec(protocol)) { return i; } diff --git a/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c b/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c index 10ff56da726..3ad14a7ab1a 100644 --- a/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c +++ b/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c @@ -20,7 +20,9 @@ bool infrared_decoder_nec_interpret(InfraredCommonDecoder* decoder) { uint8_t address_inverse = decoder->data[1]; uint8_t command = decoder->data[2]; uint8_t command_inverse = decoder->data[3]; - if((command == (uint8_t)~command_inverse) && (address == (uint8_t)~address_inverse)) { + uint8_t inverse_command_inverse = (uint8_t)~command_inverse; + uint8_t inverse_address_inverse = (uint8_t)~address_inverse; + if((command == inverse_command_inverse) && (address == inverse_address_inverse)) { decoder->message.protocol = InfraredProtocolNEC; decoder->message.address = address; decoder->message.command = command; diff --git a/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c b/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c index 9101cac1242..13d3e5364dc 100644 --- a/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c +++ b/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c @@ -60,8 +60,8 @@ InfraredStatus infrared_decoder_rc6_decode_manchester( uint32_t timing) { // 4th bit lasts 2x times more InfraredStatus status = InfraredStatusError; - uint16_t bit = decoder->protocol->timings.bit1_mark; - uint16_t tolerance = decoder->protocol->timings.bit_tolerance; + uint32_t bit = decoder->protocol->timings.bit1_mark; + uint32_t tolerance = decoder->protocol->timings.bit_tolerance; bool single_timing = MATCH_TIMING(timing, bit, tolerance); bool double_timing = MATCH_TIMING(timing, 2 * bit, tolerance); diff --git a/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c b/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c index 4450ffd1602..e8cd3b05cb5 100644 --- a/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c +++ b/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c @@ -17,8 +17,9 @@ bool infrared_decoder_samsung32_interpret(InfraredCommonDecoder* decoder) { uint8_t address2 = decoder->data[1]; uint8_t command = decoder->data[2]; uint8_t command_inverse = decoder->data[3]; + uint8_t inverse_command_inverse = (uint8_t)~command_inverse; - if((address1 == address2) && (command == (uint8_t)~command_inverse)) { + if((address1 == address2) && (command == inverse_command_inverse)) { decoder->message.command = command; decoder->message.address = address1; decoder->message.protocol = InfraredProtocolSamsung32; diff --git a/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c b/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c index a6918ceec3c..8ae9e371739 100644 --- a/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c +++ b/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c @@ -38,7 +38,7 @@ InfraredStatus infrared_encoder_sirc_encode_repeat( bool* level) { furi_assert(encoder); - furi_assert(encoder->timings_encoded == (1 + 2 + encoder->bits_to_encode * 2 - 1)); + furi_assert(encoder->timings_encoded == (1u + 2 + encoder->bits_to_encode * 2 - 1)); furi_assert(encoder->timings_sum < INFRARED_SIRC_REPEAT_PERIOD); *duration = INFRARED_SIRC_REPEAT_PERIOD - encoder->timings_sum; diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index 5711d2c0023..71126c86834 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -597,6 +597,7 @@ void infrared_worker_set_raw_signal( InfraredWorkerGetSignalResponse infrared_worker_tx_get_signal_steady_callback(void* context, InfraredWorker* instance) { + UNUSED(context); InfraredWorkerGetSignalResponse response = instance->tx.steady_signal_sent ? InfraredWorkerGetSignalResponseSame : InfraredWorkerGetSignalResponseNew; diff --git a/lib/lfs_config.h b/lib/lfs_config.h index a545551c552..59b3c486e33 100644 --- a/lib/lfs_config.h +++ b/lib/lfs_config.h @@ -4,6 +4,9 @@ #ifdef FURI_NDEBUG #define LFS_NO_ASSERT +#define LFS_ASSERT(x) +#else +#define LFS_ASSERT furi_assert #endif #define LFS_TAG "Lfs" @@ -16,7 +19,6 @@ #define LFS_ERROR(...) FURI_LOG_E(LFS_TAG, __VA_ARGS__); -#define LFS_ASSERT furi_assert // Because crc #undef LFS_CONFIG diff --git a/lib/libusb_stm32 b/lib/libusb_stm32 index fd58c2b0471..6e64179d64e 160000 --- a/lib/libusb_stm32 +++ b/lib/libusb_stm32 @@ -1 +1 @@ -Subproject commit fd58c2b04710554626ac69d9fb5fa1211d1bcaf0 +Subproject commit 6e64179d64e5582014a637a108d0870191f7818d diff --git a/lib/micro-ecc/asm_arm.inc b/lib/micro-ecc/asm_arm.inc index 688fdc75a8f..43844da6a56 100644 --- a/lib/micro-ecc/asm_arm.inc +++ b/lib/micro-ecc/asm_arm.inc @@ -97,6 +97,7 @@ uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, } #define asm_add 1 +#pragma GCC diagnostic ignored "-Wredundant-decls" uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left, const uECC_word_t *right, diff --git a/lib/micro-ecc/curve-specific.inc b/lib/micro-ecc/curve-specific.inc index 0453b212cf0..f5d3da842c8 100644 --- a/lib/micro-ecc/curve-specific.inc +++ b/lib/micro-ecc/curve-specific.inc @@ -542,6 +542,7 @@ static void mod_sqrt_secp224r1_rp(uECC_word_t *d1, /* Compute a = sqrt(a) (mod curve_p). */ /* Routine 3.2.8 mp_mod_sqrt_224; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) { + (void)curve; bitcount_t i; uECC_word_t e1[num_words_secp224r1]; uECC_word_t f1[num_words_secp224r1]; diff --git a/lib/nfc_protocols/mifare_classic.c b/lib/nfc_protocols/mifare_classic.c index c738accc972..ace37bff3c6 100644 --- a/lib/nfc_protocols/mifare_classic.c +++ b/lib/nfc_protocols/mifare_classic.c @@ -36,6 +36,7 @@ uint8_t mf_classic_get_total_sectors_num(MfClassicReader* reader) { } bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { + UNUSED(ATQA1); if((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08)) { return true; } else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) { @@ -52,6 +53,7 @@ bool mf_classic_get_type( uint8_t ATQA1, uint8_t SAK, MfClassicReader* reader) { + UNUSED(ATQA1); furi_assert(uid); furi_assert(reader); memset(reader, 0, sizeof(MfClassicReader)); @@ -204,7 +206,6 @@ bool mf_classic_read_block( MfClassicBlock* block) { furi_assert(tx_rx); furi_assert(crypto); - furi_assert(block_num < MF_CLASSIC_TOTAL_BLOCKS_MAX); furi_assert(block); bool read_block_success = false; diff --git a/lib/nfc_protocols/mifare_desfire.c b/lib/nfc_protocols/mifare_desfire.c index 6a9c13b668d..4f02e839673 100644 --- a/lib/nfc_protocols/mifare_desfire.c +++ b/lib/nfc_protocols/mifare_desfire.c @@ -444,4 +444,4 @@ bool mf_df_parse_read_data_response(uint8_t* buf, uint16_t len, MifareDesfireFil out->contents = malloc(len); memcpy(out->contents, buf, len); return true; -} \ No newline at end of file +} diff --git a/lib/nfc_protocols/mifare_ultralight.h b/lib/nfc_protocols/mifare_ultralight.h index 1947f10a07c..858fc3ecaa9 100644 --- a/lib/nfc_protocols/mifare_ultralight.h +++ b/lib/nfc_protocols/mifare_ultralight.h @@ -123,4 +123,4 @@ bool mf_ul_prepare_emulation_response( uint8_t* buff_tx, uint16_t* buff_tx_len, uint32_t* data_type, - void* context); \ No newline at end of file + void* context); diff --git a/lib/nfc_protocols/nfc_util.c b/lib/nfc_protocols/nfc_util.c index 69c13ed4594..9de6f982b63 100644 --- a/lib/nfc_protocols/nfc_util.c +++ b/lib/nfc_protocols/nfc_util.c @@ -45,19 +45,3 @@ uint8_t nfc_util_even_parity32(uint32_t data) { uint8_t nfc_util_odd_parity8(uint8_t data) { return nfc_util_odd_byte_parity[data]; } - -void nfc_util_merge_data_and_parity( - uint8_t* data, - uint16_t data_len, - uint8_t* parity, - uint16_t parity_len, - uint8_t* res, - uint16_t* res_len); - -void nfc_util_split_data_and_parity( - uint8_t* data, - uint16_t data_len, - uint8_t* parity, - uint16_t parity_len, - uint8_t* res, - uint16_t* res_len); \ No newline at end of file diff --git a/lib/nfc_protocols/nfc_util.h b/lib/nfc_protocols/nfc_util.h index caeb20c904e..d530badc3d7 100644 --- a/lib/nfc_protocols/nfc_util.h +++ b/lib/nfc_protocols/nfc_util.h @@ -9,19 +9,3 @@ uint64_t nfc_util_bytes2num(uint8_t* src, uint8_t len); uint8_t nfc_util_even_parity32(uint32_t data); uint8_t nfc_util_odd_parity8(uint8_t data); - -void nfc_util_merge_data_and_parity( - uint8_t* data, - uint16_t data_len, - uint8_t* parity, - uint16_t parity_len, - uint8_t* res, - uint16_t* res_len); - -void nfc_util_split_data_and_parity( - uint8_t* data, - uint16_t data_len, - uint8_t* parity, - uint16_t parity_len, - uint8_t* res, - uint16_t* res_len); diff --git a/lib/nfc_protocols/nfca.c b/lib/nfc_protocols/nfca.c index fe001f88f87..81a6ddfccbe 100755 --- a/lib/nfc_protocols/nfca.c +++ b/lib/nfc_protocols/nfca.c @@ -52,4 +52,4 @@ bool nfca_emulation_handler( } return sleep; -} \ No newline at end of file +} diff --git a/lib/one_wire/ibutton/encoder/encoder_cyfral.h b/lib/one_wire/ibutton/encoder/encoder_cyfral.h index 1b0c3e12f72..4fc7be5ed8d 100644 --- a/lib/one_wire/ibutton/encoder/encoder_cyfral.h +++ b/lib/one_wire/ibutton/encoder/encoder_cyfral.h @@ -51,4 +51,4 @@ void encoder_cyfral_get_pulse(EncoderCyfral* cyfral, bool* polarity, uint32_t* l #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/ibutton/encoder/encoder_metakom.h b/lib/one_wire/ibutton/encoder/encoder_metakom.h index 2812dc1298f..50ff11a243c 100644 --- a/lib/one_wire/ibutton/encoder/encoder_metakom.h +++ b/lib/one_wire/ibutton/encoder/encoder_metakom.h @@ -51,4 +51,4 @@ void encoder_metakom_get_pulse(EncoderMetakom* metakom, bool* polarity, uint32_t #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/ibutton/ibutton_key.c b/lib/one_wire/ibutton/ibutton_key.c index c90d5f4a9eb..c6d4466f0a5 100644 --- a/lib/one_wire/ibutton/ibutton_key.c +++ b/lib/one_wire/ibutton/ibutton_key.c @@ -118,4 +118,4 @@ bool ibutton_key_dallas_crc_is_valid(iButtonKey* key) { bool ibutton_key_dallas_is_1990_key(iButtonKey* key) { return (key->data[0] == 0x01); -} \ No newline at end of file +} diff --git a/lib/one_wire/ibutton/ibutton_key.h b/lib/one_wire/ibutton/ibutton_key.h index f82861036ad..8d6732bcb7b 100644 --- a/lib/one_wire/ibutton/ibutton_key.h +++ b/lib/one_wire/ibutton/ibutton_key.h @@ -142,4 +142,4 @@ bool ibutton_key_dallas_is_1990_key(iButtonKey* key); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/ibutton/ibutton_key_command.h b/lib/one_wire/ibutton/ibutton_key_command.h index 3978ea51ae2..88049d0643d 100644 --- a/lib/one_wire/ibutton/ibutton_key_command.h +++ b/lib/one_wire/ibutton/ibutton_key_command.h @@ -25,4 +25,4 @@ #define TM01_CMD_SWITCH_TO_CYFRAL 0xCA #define TM01_CMD_SWITCH_TO_METAKOM 0xCB -#define DS1990_CMD_READ_ROM 0x33 \ No newline at end of file +#define DS1990_CMD_READ_ROM 0x33 diff --git a/lib/one_wire/ibutton/ibutton_worker.h b/lib/one_wire/ibutton/ibutton_worker.h index 3350e05f723..5c8b1fc399b 100644 --- a/lib/one_wire/ibutton/ibutton_worker.h +++ b/lib/one_wire/ibutton/ibutton_worker.h @@ -110,4 +110,4 @@ void ibutton_worker_stop(iButtonWorker* worker); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/ibutton/ibutton_worker_i.h b/lib/one_wire/ibutton/ibutton_worker_i.h index 14e5d39d7d2..ae2d4dc38fc 100644 --- a/lib/one_wire/ibutton/ibutton_worker_i.h +++ b/lib/one_wire/ibutton/ibutton_worker_i.h @@ -27,9 +27,9 @@ typedef enum { typedef struct { const uint32_t quant; - const void (*start)(iButtonWorker* worker); - const void (*tick)(iButtonWorker* worker); - const void (*stop)(iButtonWorker* worker); + void (*const start) (iButtonWorker* worker); + void (*const tick) (iButtonWorker* worker); + void (*const stop) (iButtonWorker* worker); } iButtonWorkerModeType; typedef enum { @@ -76,4 +76,4 @@ void ibutton_worker_switch_mode(iButtonWorker* worker, iButtonWorkerMode mode); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c index 7ee3a005c16..ff5ba35129d 100644 --- a/lib/one_wire/ibutton/ibutton_worker_modes.c +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -49,12 +49,15 @@ const iButtonWorkerModeType ibutton_worker_modes[] = { /*********************** IDLE ***********************/ void ibutton_worker_mode_idle_start(iButtonWorker* worker) { + UNUSED(worker); } void ibutton_worker_mode_idle_tick(iButtonWorker* worker) { + UNUSED(worker); } void ibutton_worker_mode_idle_stop(iButtonWorker* worker) { + UNUSED(worker); } /*********************** READ ***********************/ @@ -151,6 +154,7 @@ bool ibutton_worker_read_dallas(iButtonWorker* worker) { } void ibutton_worker_mode_read_start(iButtonWorker* worker) { + UNUSED(worker); furi_hal_power_enable_otg(); } @@ -172,6 +176,7 @@ void ibutton_worker_mode_read_tick(iButtonWorker* worker) { } void ibutton_worker_mode_read_stop(iButtonWorker* worker) { + UNUSED(worker); furi_hal_power_disable_otg(); } @@ -251,6 +256,7 @@ void ibutton_worker_emulate_timer_start(iButtonWorker* worker) { } void ibutton_worker_emulate_timer_stop(iButtonWorker* worker) { + UNUSED(worker); furi_hal_ibutton_emulate_stop(); } @@ -272,6 +278,7 @@ void ibutton_worker_mode_emulate_start(iButtonWorker* worker) { } void ibutton_worker_mode_emulate_tick(iButtonWorker* worker) { + UNUSED(worker); } void ibutton_worker_mode_emulate_stop(iButtonWorker* worker) { @@ -327,4 +334,4 @@ void ibutton_worker_mode_write_tick(iButtonWorker* worker) { void ibutton_worker_mode_write_stop(iButtonWorker* worker) { furi_hal_power_disable_otg(); onewire_host_stop(worker->host); -} \ No newline at end of file +} diff --git a/lib/one_wire/ibutton/ibutton_writer.h b/lib/one_wire/ibutton/ibutton_writer.h index 8e81cfd1f9e..6dbdbb27a10 100644 --- a/lib/one_wire/ibutton/ibutton_writer.h +++ b/lib/one_wire/ibutton/ibutton_writer.h @@ -57,4 +57,4 @@ void ibutton_writer_stop(iButtonWriter* writer); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.h b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.h index 4a7c00e4291..10305da12f5 100644 --- a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.h +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.h @@ -35,4 +35,4 @@ PulseProtocol* protocol_cyfral_get_protocol(ProtocolCyfral* cyfral); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.h b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.h index fbafc235296..fdc45769538 100644 --- a/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.h +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.h @@ -35,4 +35,4 @@ PulseProtocol* protocol_metakom_get_protocol(ProtocolMetakom* metakom); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/maxim_crc.c b/lib/one_wire/maxim_crc.c index bd89d3ad334..a5d099b10fe 100644 --- a/lib/one_wire/maxim_crc.c +++ b/lib/one_wire/maxim_crc.c @@ -13,4 +13,4 @@ uint8_t maxim_crc8(const uint8_t* data, const uint8_t data_size, const uint8_t c } } return crc; -} \ No newline at end of file +} diff --git a/lib/one_wire/maxim_crc.h b/lib/one_wire/maxim_crc.h index 1b7e8498769..4bab5714c83 100644 --- a/lib/one_wire/maxim_crc.h +++ b/lib/one_wire/maxim_crc.h @@ -11,4 +11,4 @@ uint8_t maxim_crc8(const uint8_t* data, const uint8_t data_size, const uint8_t c #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/one_wire_device.h b/lib/one_wire/one_wire_device.h index 4ff16790abf..fc687c7badd 100644 --- a/lib/one_wire/one_wire_device.h +++ b/lib/one_wire/one_wire_device.h @@ -71,4 +71,4 @@ uint8_t* onewire_device_get_id_p(OneWireDevice* device); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/one_wire_host.c b/lib/one_wire/one_wire_host.c index fd8deaf8e2a..1bb0a1ccbbf 100644 --- a/lib/one_wire/one_wire_host.c +++ b/lib/one_wire/one_wire_host.c @@ -23,6 +23,7 @@ void onewire_host_free(OneWireHost* host) { } bool onewire_host_reset(OneWireHost* host) { + UNUSED(host); uint8_t r; uint8_t retries = 125; @@ -52,6 +53,7 @@ bool onewire_host_reset(OneWireHost* host) { } bool onewire_host_read_bit(OneWireHost* host) { + UNUSED(host); bool result; // drive low @@ -88,6 +90,7 @@ void onewire_host_read_bytes(OneWireHost* host, uint8_t* buffer, uint16_t count) } void onewire_host_write_bit(OneWireHost* host, bool value) { + UNUSED(host); if(value) { // drive low furi_hal_ibutton_pin_low(); @@ -120,10 +123,12 @@ void onewire_host_skip(OneWireHost* host) { } void onewire_host_start(OneWireHost* host) { + UNUSED(host); furi_hal_ibutton_start_drive(); } void onewire_host_stop(OneWireHost* host) { + UNUSED(host); furi_hal_ibutton_stop(); } diff --git a/lib/one_wire/one_wire_host.h b/lib/one_wire/one_wire_host.h index 21530640569..5b55ee8dd80 100644 --- a/lib/one_wire/one_wire_host.h +++ b/lib/one_wire/one_wire_host.h @@ -118,4 +118,4 @@ uint8_t onewire_host_search(OneWireHost* host, uint8_t* newAddr, OneWireHostSear #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/one_wire_slave.c b/lib/one_wire/one_wire_slave.c index e8cc5ac12aa..3c9a796d4a3 100644 --- a/lib/one_wire/one_wire_slave.c +++ b/lib/one_wire/one_wire_slave.c @@ -37,6 +37,7 @@ struct OneWireSlave { /*********************** PRIVATE ***********************/ uint32_t onewire_slave_wait_while_gpio_is(OneWireSlave* bus, uint32_t time, const bool pin_value) { + UNUSED(bus); uint32_t start = DWT->CYCCNT; uint32_t time_ticks = time * furi_hal_delay_instructions_per_microsecond(); uint32_t time_captured; @@ -253,6 +254,7 @@ void onewire_slave_start(OneWireSlave* bus) { } void onewire_slave_stop(OneWireSlave* bus) { + UNUSED(bus); furi_hal_ibutton_stop(); furi_hal_ibutton_remove_interrupt(); } diff --git a/lib/one_wire/pulse_protocols/pulse_decoder.h b/lib/one_wire/pulse_protocols/pulse_decoder.h index 4e9f9d228b9..dbaef52b5e4 100644 --- a/lib/one_wire/pulse_protocols/pulse_decoder.h +++ b/lib/one_wire/pulse_protocols/pulse_decoder.h @@ -67,4 +67,4 @@ void pulse_decoder_get_data(PulseDecoder* decoder, int32_t index, uint8_t* data, #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/pulse_protocols/pulse_glue.h b/lib/one_wire/pulse_protocols/pulse_glue.h index aa58f239460..4954e2719b2 100644 --- a/lib/one_wire/pulse_protocols/pulse_glue.h +++ b/lib/one_wire/pulse_protocols/pulse_glue.h @@ -23,4 +23,4 @@ void pulse_glue_pop(PulseGlue* pulse_glue, uint32_t* length, uint32_t* period); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/one_wire/pulse_protocols/pulse_protocol.c b/lib/one_wire/pulse_protocols/pulse_protocol.c index ac01ea928de..76feba11358 100644 --- a/lib/one_wire/pulse_protocols/pulse_protocol.c +++ b/lib/one_wire/pulse_protocols/pulse_protocol.c @@ -64,4 +64,4 @@ void pulse_protocol_get_data(PulseProtocol* protocol, uint8_t* data, size_t leng if(protocol->get_data_cb != NULL) { protocol->get_data_cb(protocol->context, data, length); } -} \ No newline at end of file +} diff --git a/lib/one_wire/pulse_protocols/pulse_protocol.h b/lib/one_wire/pulse_protocols/pulse_protocol.h index 01bc14a1c55..bfce0e76d8b 100644 --- a/lib/one_wire/pulse_protocols/pulse_protocol.h +++ b/lib/one_wire/pulse_protocols/pulse_protocol.h @@ -119,4 +119,4 @@ void pulse_protocol_reset(PulseProtocol* protocol); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/qrcode/qrcode.c b/lib/qrcode/qrcode.c index cbbf4a4747b..fb5bd8a6e78 100644 --- a/lib/qrcode/qrcode.c +++ b/lib/qrcode/qrcode.c @@ -972,4 +972,4 @@ bool qrcode_getModule(QRCode* qrcode, uint8_t x, uint8_t y) { uint32_t offset = y * qrcode->size + x; return (qrcode->modules[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0; -} \ No newline at end of file +} diff --git a/lib/qrcode/qrcode.h b/lib/qrcode/qrcode.h index bc3ccb598e7..6d637ba04d6 100644 --- a/lib/qrcode/qrcode.h +++ b/lib/qrcode/qrcode.h @@ -96,4 +96,4 @@ bool qrcode_getModule(QRCode* qrcode, uint8_t x, uint8_t y); } #endif /* __cplusplus */ -#endif /* __QRCODE_H_ */ \ No newline at end of file +#endif /* __QRCODE_H_ */ diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index 467e315495f..8817b380392 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -76,6 +76,7 @@ const SubGhzProtocol subghz_protocol_came = { }; void* subghz_protocol_encoder_came_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderCame* instance = malloc(sizeof(SubGhzProtocolEncoderCame)); instance->base.protocol = &subghz_protocol_came; @@ -182,6 +183,7 @@ LevelDuration subghz_protocol_encoder_came_yield(void* context) { } void* subghz_protocol_decoder_came_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderCame* instance = malloc(sizeof(SubGhzProtocolDecoderCame)); instance->base.protocol = &subghz_protocol_came; instance->generic.protocol_name = instance->base.protocol->name; diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 67d5398fa04..51e7fe0b34e 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -136,7 +136,7 @@ void subghz_protocol_decoder_came_atomo_feed(void* context, bool level, uint32_t subghz_protocol_came_atomo_const.te_delta) { event = ManchesterEventLongLow; } else if( - duration >= (subghz_protocol_came_atomo_const.te_long * 2 + + duration >= ((uint32_t)subghz_protocol_came_atomo_const.te_long * 2 + subghz_protocol_came_atomo_const.te_delta)) { if(instance->decoder.decode_count_bit == subghz_protocol_came_atomo_const.min_count_bit_for_found) { diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index fe5f7877110..4ca1162322b 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -103,6 +103,7 @@ const SubGhzProtocol subghz_protocol_came_twee = { }; void* subghz_protocol_encoder_came_twee_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderCameTwee* instance = malloc(sizeof(SubGhzProtocolEncoderCameTwee)); instance->base.protocol = &subghz_protocol_came_twee; @@ -289,6 +290,7 @@ LevelDuration subghz_protocol_encoder_came_twee_yield(void* context) { } void* subghz_protocol_decoder_came_twee_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderCameTwee* instance = malloc(sizeof(SubGhzProtocolDecoderCameTwee)); instance->base.protocol = &subghz_protocol_came_twee; instance->generic.protocol_name = instance->base.protocol->name; @@ -351,7 +353,7 @@ void subghz_protocol_decoder_came_twee_feed(void* context, bool level, uint32_t subghz_protocol_came_twee_const.te_delta) { event = ManchesterEventLongLow; } else if( - duration >= (subghz_protocol_came_twee_const.te_long * 2 + + duration >= ((uint32_t)subghz_protocol_came_twee_const.te_long * 2 + subghz_protocol_came_twee_const.te_delta)) { if(instance->decoder.decode_count_bit >= subghz_protocol_came_twee_const.min_count_bit_for_found) { diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index d5006ae6675..d5761831c7b 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -69,6 +69,7 @@ const SubGhzProtocol subghz_protocol_faac_slh = { }; void* subghz_protocol_decoder_faac_slh_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderFaacSLH* instance = malloc(sizeof(SubGhzProtocolDecoderFaacSLH)); instance->base.protocol = &subghz_protocol_faac_slh; instance->generic.protocol_name = instance->base.protocol->name; @@ -111,7 +112,7 @@ void subghz_protocol_decoder_faac_slh_feed(void* context, bool level, uint32_t d break; case FaacSLHDecoderStepSaveDuration: if(level) { - if(duration >= (subghz_protocol_faac_slh_const.te_short * 3 + + if(duration >= ((uint32_t)subghz_protocol_faac_slh_const.te_short * 3 + subghz_protocol_faac_slh_const.te_delta)) { instance->decoder.parser_step = FaacSLHDecoderStepFoundPreambula; if(instance->decoder.decode_count_bit >= diff --git a/lib/subghz/protocols/firefly.c b/lib/subghz/protocols/firefly.c index 3a339e0a9a7..21047a30402 100644 --- a/lib/subghz/protocols/firefly.c +++ b/lib/subghz/protocols/firefly.c @@ -75,6 +75,7 @@ const SubGhzProtocol subghz_protocol_firefly = { }; void* subghz_protocol_encoder_firefly_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderFirefly* instance = malloc(sizeof(SubGhzProtocolEncoderFirefly)); instance->base.protocol = &subghz_protocol_firefly; @@ -193,6 +194,7 @@ LevelDuration subghz_protocol_encoder_firefly_yield(void* context) { } void* subghz_protocol_decoder_firefly_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderFirefly* instance = malloc(sizeof(SubGhzProtocolDecoderFirefly)); instance->base.protocol = &subghz_protocol_firefly; instance->generic.protocol_name = instance->base.protocol->name; diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index dd6548a2e54..5f124c376c0 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -69,6 +69,7 @@ const SubGhzProtocol subghz_protocol_gate_tx = { }; void* subghz_protocol_encoder_gate_tx_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderGateTx* instance = malloc(sizeof(SubGhzProtocolEncoderGateTx)); instance->base.protocol = &subghz_protocol_gate_tx; @@ -175,6 +176,7 @@ LevelDuration subghz_protocol_encoder_gate_tx_yield(void* context) { } void* subghz_protocol_decoder_gate_tx_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderGateTx* instance = malloc(sizeof(SubGhzProtocolDecoderGateTx)); instance->base.protocol = &subghz_protocol_gate_tx; instance->generic.protocol_name = instance->base.protocol->name; @@ -218,7 +220,7 @@ void subghz_protocol_decoder_gate_tx_feed(void* context, bool level, uint32_t du break; case GateTXDecoderStepSaveDuration: if(!level) { - if(duration >= (subghz_protocol_gate_tx_const.te_short * 10 + + if(duration >= ((uint32_t)subghz_protocol_gate_tx_const.te_short * 10 + subghz_protocol_gate_tx_const.te_delta)) { instance->decoder.parser_step = GateTXDecoderStepFoundStartBit; if(instance->decoder.decode_count_bit >= diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index 7a3fd23392e..20ff50fc0cd 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -72,6 +72,7 @@ const SubGhzProtocol subghz_protocol_hormann = { }; void* subghz_protocol_encoder_hormann_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderHormann* instance = malloc(sizeof(SubGhzProtocolEncoderHormann)); instance->base.protocol = &subghz_protocol_hormann; @@ -191,6 +192,7 @@ LevelDuration subghz_protocol_encoder_hormann_yield(void* context) { } void* subghz_protocol_decoder_hormann_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderHormann* instance = malloc(sizeof(SubGhzProtocolDecoderHormann)); instance->base.protocol = &subghz_protocol_hormann; instance->generic.protocol_name = instance->base.protocol->name; diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index d2962435ade..93693b68f71 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -68,6 +68,7 @@ const SubGhzProtocol subghz_protocol_ido = { }; void* subghz_protocol_decoder_ido_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderIDo* instance = malloc(sizeof(SubGhzProtocolDecoderIDo)); instance->base.protocol = &subghz_protocol_ido; instance->generic.protocol_name = instance->base.protocol->name; @@ -111,8 +112,8 @@ void subghz_protocol_decoder_ido_feed(void* context, bool level, uint32_t durati break; case IDoDecoderStepSaveDuration: if(level) { - if(duration >= - (subghz_protocol_ido_const.te_short * 5 + subghz_protocol_ido_const.te_delta)) { + if(duration >= ((uint32_t)subghz_protocol_ido_const.te_short * 5 + + subghz_protocol_ido_const.te_delta)) { instance->decoder.parser_step = IDoDecoderStepFoundPreambula; if(instance->decoder.decode_count_bit >= subghz_protocol_ido_const.min_count_bit_for_found) { diff --git a/lib/subghz/protocols/ido.h b/lib/subghz/protocols/ido.h index c53a1593794..266529e1fba 100644 --- a/lib/subghz/protocols/ido.h +++ b/lib/subghz/protocols/ido.h @@ -72,4 +72,4 @@ bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipp * @param context Pointer to a SubGhzProtocolDecoderIDo instance * @param output Resulting text */ -void subghz_protocol_decoder_ido_get_string(void* context, string_t output); \ No newline at end of file +void subghz_protocol_decoder_ido_get_string(void* context, string_t output); diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 9c6673e82a3..566ae576489 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -384,7 +384,7 @@ void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t dur break; case KeeloqDecoderStepCheckDuration: if(!level) { - if(duration >= (subghz_protocol_keeloq_const.te_short * 2 + + if(duration >= ((uint32_t)subghz_protocol_keeloq_const.te_short * 2 + subghz_protocol_keeloq_const.te_delta)) { // Found end TX instance->decoder.parser_step = KeeloqDecoderStepReset; diff --git a/lib/subghz/protocols/keeloq_common.c b/lib/subghz/protocols/keeloq_common.c index 9dfc0934845..7e864a325bd 100644 --- a/lib/subghz/protocols/keeloq_common.c +++ b/lib/subghz/protocols/keeloq_common.c @@ -81,4 +81,4 @@ inline uint64_t subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor) { data &= 0x0FFFFFFF; return (((uint64_t)data << 32) | data) ^ xor; -} \ No newline at end of file +} diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index f623a61d3e8..5a89934bd6d 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -70,6 +70,7 @@ const SubGhzProtocol subghz_protocol_kia = { }; void* subghz_protocol_decoder_kia_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderKIA* instance = malloc(sizeof(SubGhzProtocolDecoderKIA)); instance->base.protocol = &subghz_protocol_kia; instance->generic.protocol_name = instance->base.protocol->name; @@ -141,7 +142,7 @@ void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t durati case KIADecoderStepSaveDuration: if(level) { if(duration >= - (subghz_protocol_kia_const.te_long + subghz_protocol_kia_const.te_delta * 2)) { + (uint32_t)(subghz_protocol_kia_const.te_long + subghz_protocol_kia_const.te_delta * 2)) { //Found stop bit instance->decoder.parser_step = KIADecoderStepReset; if(instance->decoder.decode_count_bit >= diff --git a/lib/subghz/protocols/nero_radio.c b/lib/subghz/protocols/nero_radio.c index d25c377a51e..6797843fd69 100644 --- a/lib/subghz/protocols/nero_radio.c +++ b/lib/subghz/protocols/nero_radio.c @@ -71,6 +71,7 @@ const SubGhzProtocol subghz_protocol_nero_radio = { }; void* subghz_protocol_encoder_nero_radio_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderNeroRadio* instance = malloc(sizeof(SubGhzProtocolEncoderNeroRadio)); instance->base.protocol = &subghz_protocol_nero_radio; @@ -200,6 +201,7 @@ LevelDuration subghz_protocol_encoder_nero_radio_yield(void* context) { } void* subghz_protocol_decoder_nero_radio_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderNeroRadio* instance = malloc(sizeof(SubGhzProtocolDecoderNeroRadio)); instance->base.protocol = &subghz_protocol_nero_radio; instance->generic.protocol_name = instance->base.protocol->name; @@ -278,7 +280,7 @@ void subghz_protocol_decoder_nero_radio_feed(void* context, bool level, uint32_t break; case NeroRadioDecoderStepCheckDuration: if(!level) { - if(duration >= (subghz_protocol_nero_radio_const.te_short * 10 + + if(duration >= ((uint32_t)subghz_protocol_nero_radio_const.te_short * 10 + subghz_protocol_nero_radio_const.te_delta * 2)) { //Found stop bit if(DURATION_DIFF( diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c index 474b742ad5a..1ba0cf86032 100644 --- a/lib/subghz/protocols/nero_sketch.c +++ b/lib/subghz/protocols/nero_sketch.c @@ -70,6 +70,7 @@ const SubGhzProtocol subghz_protocol_nero_sketch = { }; void* subghz_protocol_encoder_nero_sketch_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderNeroSketch* instance = malloc(sizeof(SubGhzProtocolEncoderNeroSketch)); instance->base.protocol = &subghz_protocol_nero_sketch; @@ -194,6 +195,7 @@ LevelDuration subghz_protocol_encoder_nero_sketch_yield(void* context) { } void* subghz_protocol_decoder_nero_sketch_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderNeroSketch* instance = malloc(sizeof(SubGhzProtocolDecoderNeroSketch)); instance->base.protocol = &subghz_protocol_nero_sketch; instance->generic.protocol_name = instance->base.protocol->name; diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index 6f94e8fdfc5..d2844dcd623 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -69,6 +69,7 @@ const SubGhzProtocol subghz_protocol_nice_flo = { }; void* subghz_protocol_encoder_nice_flo_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderNiceFlo* instance = malloc(sizeof(SubGhzProtocolEncoderNiceFlo)); instance->base.protocol = &subghz_protocol_nice_flo; @@ -175,6 +176,7 @@ LevelDuration subghz_protocol_encoder_nice_flo_yield(void* context) { } void* subghz_protocol_decoder_nice_flo_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderNiceFlo* instance = malloc(sizeof(SubGhzProtocolDecoderNiceFlo)); instance->base.protocol = &subghz_protocol_nice_flo; instance->generic.protocol_name = instance->base.protocol->name; diff --git a/lib/subghz/protocols/nice_flo.h b/lib/subghz/protocols/nice_flo.h index ca5cfe3f65f..430b111df19 100644 --- a/lib/subghz/protocols/nice_flo.h +++ b/lib/subghz/protocols/nice_flo.h @@ -106,4 +106,4 @@ bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance * @param output Resulting text */ -void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output); \ No newline at end of file +void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output); diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index 42f035e6d93..7579a3cac09 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -80,6 +80,7 @@ const SubGhzProtocol subghz_protocol_princeton = { }; void* subghz_protocol_encoder_princeton_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderPrinceton* instance = malloc(sizeof(SubGhzProtocolEncoderPrinceton)); instance->base.protocol = &subghz_protocol_princeton; @@ -194,6 +195,7 @@ LevelDuration subghz_protocol_encoder_princeton_yield(void* context) { } void* subghz_protocol_decoder_princeton_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderPrinceton* instance = malloc(sizeof(SubGhzProtocolDecoderPrinceton)); instance->base.protocol = &subghz_protocol_princeton; instance->generic.protocol_name = instance->base.protocol->name; @@ -238,7 +240,7 @@ void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t break; case PrincetonDecoderStepCheckDuration: if(!level) { - if(duration >= (subghz_protocol_princeton_const.te_short * 10 + + if(duration >= ((uint32_t)subghz_protocol_princeton_const.te_short * 10 + subghz_protocol_princeton_const.te_delta)) { instance->decoder.parser_step = PrincetonDecoderStepSaveDuration; if(instance->decoder.decode_count_bit == diff --git a/lib/subghz/protocols/princeton_for_testing.c b/lib/subghz/protocols/princeton_for_testing.c index bdf5f4292d8..5c3f7151c5e 100644 --- a/lib/subghz/protocols/princeton_for_testing.c +++ b/lib/subghz/protocols/princeton_for_testing.c @@ -249,7 +249,7 @@ void subghz_decoder_princeton_for_testing_parse( break; case PrincetonDecoderStepCheckDuration: if(!level) { - if(duration >= (instance->te_short * 10 + instance->te_delta)) { + if(duration >= ((uint32_t)instance->te_short * 10 + instance->te_delta)) { instance->parser_step = PrincetonDecoderStepSaveDuration; if(instance->code_count_bit == instance->code_min_count_bit_for_found) { instance->te /= (instance->code_count_bit * 4 + 1); diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 111f45366b8..516aa633842 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -192,6 +192,7 @@ size_t subghz_protocol_raw_get_sample_write(SubGhzProtocolDecoderRAW* instance) } void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderRAW* instance = malloc(sizeof(SubGhzProtocolDecoderRAW)); instance->base.protocol = &subghz_protocol_raw; instance->upload_raw = NULL; @@ -243,6 +244,7 @@ void subghz_protocol_decoder_raw_get_string(void* context, string_t output) { } void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolEncoderRAW* instance = malloc(sizeof(SubGhzProtocolEncoderRAW)); instance->base.protocol = &subghz_protocol_raw; diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index c352b4ae686..a9a7c040cd7 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -76,6 +76,7 @@ const SubGhzProtocol subghz_protocol_scher_khan = { }; void* subghz_protocol_decoder_scher_khan_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderScherKhan* instance = malloc(sizeof(SubGhzProtocolDecoderScherKhan)); instance->base.protocol = &subghz_protocol_scher_khan; instance->generic.protocol_name = instance->base.protocol->name; @@ -150,7 +151,7 @@ void subghz_protocol_decoder_scher_khan_feed(void* context, bool level, uint32_t break; case ScherKhanDecoderStepSaveDuration: if(level) { - if(duration >= (subghz_protocol_scher_khan_const.te_long + + if(duration >= (uint32_t)(subghz_protocol_scher_khan_const.te_long + subghz_protocol_scher_khan_const.te_delta * 2)) { //Found stop bit instance->decoder.parser_step = ScherKhanDecoderStepReset; diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 1ad605b2f6f..ff43e2a4c16 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -89,6 +89,7 @@ const SubGhzProtocol subghz_protocol_secplus_v1 = { }; void* subghz_protocol_decoder_secplus_v1_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderSecPlus_v1* instance = malloc(sizeof(SubGhzProtocolDecoderSecPlus_v1)); instance->base.protocol = &subghz_protocol_secplus_v1; instance->generic.protocol_name = instance->base.protocol->name; @@ -321,7 +322,7 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu // pin = (fixed // 3**10) % (3**9) 3^10=59049 3^9=19683 pin = (fixed / 59049) % 19683; - if(0 <= pin && pin <= 9999) { + if(pin <= 9999) { string_cat_printf(output, " pin:%d", pin); } else if(10000 <= pin && pin <= 11029) { string_cat_printf(output, " pin:enter"); diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 4ad1ea9ef61..936eb0a60e6 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -81,6 +81,7 @@ const SubGhzProtocol subghz_protocol_secplus_v2 = { }; void* subghz_protocol_decoder_secplus_v2_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderSecPlus_v2* instance = malloc(sizeof(SubGhzProtocolDecoderSecPlus_v2)); instance->base.protocol = &subghz_protocol_secplus_v2; instance->generic.protocol_name = instance->base.protocol->name; @@ -154,7 +155,7 @@ void subghz_protocol_decoder_secplus_v2_feed(void* context, bool level, uint32_t subghz_protocol_secplus_v2_const.te_delta) { event = ManchesterEventLongLow; } else if( - duration >= (subghz_protocol_secplus_v2_const.te_long * 2 + + duration >= (uint32_t)(subghz_protocol_secplus_v2_const.te_long * 2 + subghz_protocol_secplus_v2_const.te_delta)) { if(instance->decoder.decode_count_bit >= subghz_protocol_secplus_v2_const.min_count_bit_for_found) { diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index 9f58d7340b0..764e81478a3 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -75,6 +75,7 @@ const SubGhzProtocol subghz_protocol_somfy_keytis = { }; void* subghz_protocol_decoder_somfy_keytis_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderSomfyKeytis* instance = malloc(sizeof(SubGhzProtocolDecoderSomfyKeytis)); instance->base.protocol = &subghz_protocol_somfy_keytis; instance->generic.protocol_name = instance->base.protocol->name; diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 4f1212bc990..63407427388 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -74,6 +74,7 @@ const SubGhzProtocol subghz_protocol_somfy_telis = { }; void* subghz_protocol_decoder_somfy_telis_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); SubGhzProtocolDecoderSomfyTelis* instance = malloc(sizeof(SubGhzProtocolDecoderSomfyTelis)); instance->base.protocol = &subghz_protocol_somfy_telis; instance->generic.protocol_name = instance->base.protocol->name; diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index 1acb6ba5416..d3903bc511d 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -303,7 +303,7 @@ bool subghz_keystore_save(SubGhzKeystore* instance, const char* file_name, uint8 } // HEX Encode encrypted line const char xx[] = "0123456789ABCDEF"; - for(size_t i = 0; i < len; i++) { + for(int i = 0; i < len; i++) { size_t cursor = len - i - 1; size_t hex_cursor = len * 2 - i * 2 - 1; encrypted_line[hex_cursor] = xx[encrypted_line[cursor] & 0xF]; @@ -601,4 +601,4 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* string_clear(str_temp); return result; -} \ No newline at end of file +} diff --git a/lib/toolbox/args.c b/lib/toolbox/args.c index 8d6295ddf57..287ca7efc92 100644 --- a/lib/toolbox/args.c +++ b/lib/toolbox/args.c @@ -92,4 +92,4 @@ bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count) { } return result; -} \ No newline at end of file +} diff --git a/lib/toolbox/args.h b/lib/toolbox/args.h index 4ae1e1db889..dc72bdafab8 100644 --- a/lib/toolbox/args.h +++ b/lib/toolbox/args.h @@ -78,4 +78,4 @@ bool args_char_to_hex(char hi_nibble, char low_nibble, uint8_t* byte); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/hex.c b/lib/toolbox/hex.c index 8b443e124bf..739eb30b6b2 100644 --- a/lib/toolbox/hex.c +++ b/lib/toolbox/hex.c @@ -25,4 +25,4 @@ bool hex_chars_to_uint8(char hi, char low, uint8_t* value) { } else { return false; } -} \ No newline at end of file +} diff --git a/lib/toolbox/hex.h b/lib/toolbox/hex.h index ac67549afb1..ca10f2bec4d 100644 --- a/lib/toolbox/hex.h +++ b/lib/toolbox/hex.h @@ -25,4 +25,4 @@ bool hex_chars_to_uint8(char hi, char low, uint8_t* value); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/level_duration.h b/lib/toolbox/level_duration.h index bef0b6eca24..9406cef3145 100644 --- a/lib/toolbox/level_duration.h +++ b/lib/toolbox/level_duration.h @@ -79,4 +79,4 @@ static inline uint32_t level_duration_get_duration(LevelDuration level_duration) return (level_duration >= 0) ? level_duration : -level_duration; } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/manchester_decoder.h b/lib/toolbox/manchester_decoder.h index 580d88e26b0..4fb6dbc6402 100644 --- a/lib/toolbox/manchester_decoder.h +++ b/lib/toolbox/manchester_decoder.h @@ -28,4 +28,4 @@ bool manchester_advance( #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/manchester_encoder.c b/lib/toolbox/manchester_encoder.c index c0fc4ca9429..c22e4a177cc 100644 --- a/lib/toolbox/manchester_encoder.c +++ b/lib/toolbox/manchester_encoder.c @@ -51,4 +51,4 @@ bool manchester_encoder_advance( ManchesterEncoderResult manchester_encoder_finish(ManchesterEncoderState* state) { state->step = 0; return (state->prev_bit << 1) + state->prev_bit; -} \ No newline at end of file +} diff --git a/lib/toolbox/manchester_encoder.h b/lib/toolbox/manchester_encoder.h index 639d9b818a7..57ea8fb455d 100644 --- a/lib/toolbox/manchester_encoder.h +++ b/lib/toolbox/manchester_encoder.h @@ -29,4 +29,4 @@ ManchesterEncoderResult manchester_encoder_finish(ManchesterEncoderState* state) #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/md5.c b/lib/toolbox/md5.c index b873ee0fa32..3cf7cf05c07 100644 --- a/lib/toolbox/md5.c +++ b/lib/toolbox/md5.c @@ -296,4 +296,4 @@ void md5(const unsigned char* input, size_t ilen, unsigned char output[16]) { md5_finish(&ctx, output); memset(&ctx, 0, sizeof(md5_context)); -} \ No newline at end of file +} diff --git a/lib/toolbox/md5.h b/lib/toolbox/md5.h index 7878881eb1e..fe53db8d3e5 100644 --- a/lib/toolbox/md5.h +++ b/lib/toolbox/md5.h @@ -80,4 +80,4 @@ void md5(const unsigned char* input, size_t ilen, unsigned char output[16]); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/random_name.c b/lib/toolbox/random_name.c index 34a53867f1a..b581bb9799f 100644 --- a/lib/toolbox/random_name.c +++ b/lib/toolbox/random_name.c @@ -33,8 +33,8 @@ void set_random_name(char* name, uint8_t max_name_size) { "opening", "crack", }; - uint8_t prefix_i = rand() % SIZEOF_ARRAY(prefix); - uint8_t suffix_i = rand() % SIZEOF_ARRAY(suffix); + uint8_t prefix_i = rand() % COUNT_OF(prefix); + uint8_t suffix_i = rand() % COUNT_OF(suffix); sniprintf(name, max_name_size, "%s_%s", prefix[prefix_i], suffix[suffix_i]); // Set first symbol to upper case diff --git a/lib/toolbox/stream/file_stream.c b/lib/toolbox/stream/file_stream.c index 340cb61a959..70db8af9d99 100644 --- a/lib/toolbox/stream/file_stream.c +++ b/lib/toolbox/stream/file_stream.c @@ -228,4 +228,4 @@ static bool file_stream_delete_and_insert( string_clear(scratch_name); return result; -} \ No newline at end of file +} diff --git a/lib/toolbox/stream/file_stream.h b/lib/toolbox/stream/file_stream.h index ec371a53c42..4531b3e7aeb 100644 --- a/lib/toolbox/stream/file_stream.h +++ b/lib/toolbox/stream/file_stream.h @@ -44,4 +44,4 @@ FS_Error file_stream_get_error(Stream* stream); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/stream/stream.c b/lib/toolbox/stream/stream.c index 4aee8acd0b5..982c498368b 100644 --- a/lib/toolbox/stream/stream.c +++ b/lib/toolbox/stream/stream.c @@ -217,7 +217,7 @@ bool stream_delete_and_insert_vaformat( string_init_vprintf(data, format, args); StreamWriteData write_data = { .data = (uint8_t*)string_get_cstr(data), .size = string_size(data)}; - bool result = stream_delete_and_insert(stream, 0, stream_write_struct, &write_data); + bool result = stream_delete_and_insert(stream, delete_size, stream_write_struct, &write_data); string_clear(data); return result; @@ -333,4 +333,4 @@ void stream_dump_data(Stream* stream) { printf("\r\n"); printf("DATA END\r\n"); stream_seek(stream, tell, StreamOffsetFromStart); -} \ No newline at end of file +} diff --git a/lib/toolbox/stream/stream.h b/lib/toolbox/stream/stream.h index 97ded8bda2c..c10e9f5e5ff 100644 --- a/lib/toolbox/stream/stream.h +++ b/lib/toolbox/stream/stream.h @@ -333,4 +333,4 @@ void stream_dump_data(Stream* stream); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/stream/stream_i.h b/lib/toolbox/stream/stream_i.h index a62e174c221..178d3feee39 100644 --- a/lib/toolbox/stream/stream_i.h +++ b/lib/toolbox/stream/stream_i.h @@ -7,7 +7,7 @@ extern "C" { #endif -#define STREAM_CACHE_SIZE 512 +#define STREAM_CACHE_SIZE 512u typedef struct StreamVTable StreamVTable; diff --git a/lib/toolbox/stream/string_stream.c b/lib/toolbox/stream/string_stream.c index 5fec06c3ee1..3244b7ba89e 100644 --- a/lib/toolbox/stream/string_stream.c +++ b/lib/toolbox/stream/string_stream.c @@ -176,4 +176,4 @@ static size_t string_stream_write_char(StringStream* stream, char c) { stream->index++; return 1; -} \ No newline at end of file +} diff --git a/lib/toolbox/stream/string_stream.h b/lib/toolbox/stream/string_stream.h index 1827258d9b5..6cccfa6ccf8 100644 --- a/lib/toolbox/stream/string_stream.h +++ b/lib/toolbox/stream/string_stream.h @@ -15,4 +15,4 @@ Stream* string_stream_alloc(); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/tar/tar_archive.c b/lib/toolbox/tar/tar_archive.c index 315497e1e6f..91d2c8127f5 100644 --- a/lib/toolbox/tar/tar_archive.c +++ b/lib/toolbox/tar/tar_archive.c @@ -345,4 +345,4 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch free(name); storage_file_free(directory); return success; -} \ No newline at end of file +} diff --git a/lib/toolbox/tar/tar_archive.h b/lib/toolbox/tar/tar_archive.h index a8976181fb3..d9b0f32158b 100644 --- a/lib/toolbox/tar/tar_archive.h +++ b/lib/toolbox/tar/tar_archive.h @@ -63,4 +63,4 @@ bool tar_archive_finalize(TarArchive* archive); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/version.c b/lib/toolbox/version.c index 902be876c22..40c48370b38 100644 --- a/lib/toolbox/version.c +++ b/lib/toolbox/version.c @@ -55,4 +55,4 @@ uint8_t version_get_target(const Version* v) { bool version_get_dirty_flag(const Version* v) { return v ? v->build_is_dirty : version.build_is_dirty; -} \ No newline at end of file +} diff --git a/lib/toolbox/version.h b/lib/toolbox/version.h index 7e82e45d4bd..652ff3feace 100644 --- a/lib/toolbox/version.h +++ b/lib/toolbox/version.h @@ -84,4 +84,4 @@ bool version_get_dirty_flag(const Version* v); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/u8g2/u8g2_glue.c b/lib/u8g2/u8g2_glue.c index cc186663f32..33d30f29283 100644 --- a/lib/u8g2/u8g2_glue.c +++ b/lib/u8g2/u8g2_glue.c @@ -3,6 +3,8 @@ #include uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { + UNUSED(u8x8); + UNUSED(arg_ptr); switch(msg) { case U8X8_MSG_GPIO_AND_DELAY_INIT: /* HAL initialization contains all what we need so we can skip this part. */ @@ -27,6 +29,7 @@ uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, vo } uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { + UNUSED(u8x8); switch(msg) { case U8X8_MSG_BYTE_SEND: furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_display, (uint8_t*)arg_ptr, arg_int, 10000); diff --git a/lib/u8g2/u8x8_display.c b/lib/u8g2/u8x8_display.c index 76a099b135f..83b0ca41114 100644 --- a/lib/u8g2/u8x8_display.c +++ b/lib/u8g2/u8x8_display.c @@ -147,4 +147,4 @@ void u8x8_ClearLine(u8x8_t* u8x8, uint8_t line) { u8x8->display_cb( u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void*)&tile); } -} \ No newline at end of file +} diff --git a/lib/u8g2/u8x8_gpio.c b/lib/u8g2/u8x8_gpio.c index bb1470d324e..1fcc0a393bc 100644 --- a/lib/u8g2/u8x8_gpio.c +++ b/lib/u8g2/u8x8_gpio.c @@ -44,4 +44,4 @@ void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly) { u8x8->gpio_and_delay_cb(u8x8, msg, dly, NULL); } -*/ \ No newline at end of file +*/ diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c index 3d05d0bafa1..555d7cfb6c9 100644 --- a/lib/update_util/update_manifest.c +++ b/lib/update_util/update_manifest.c @@ -179,4 +179,4 @@ bool update_manifest_init_mem( flipper_format_free(flipper_file); return update_manifest->valid; -} \ No newline at end of file +} diff --git a/lib/update_util/update_manifest.h b/lib/update_util/update_manifest.h index d03c71d2928..75871e1d3ac 100644 --- a/lib/update_util/update_manifest.h +++ b/lib/update_util/update_manifest.h @@ -59,4 +59,4 @@ bool update_manifest_has_obdata(UpdateManifest* update_manifest); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/update_util/update_operation.c b/lib/update_util/update_operation.c index beea98d2678..cf72dd0c82d 100644 --- a/lib/update_util/update_operation.c +++ b/lib/update_util/update_operation.c @@ -194,4 +194,4 @@ void update_operation_disarm() { void update_operation_persist_package_index(uint32_t index) { furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, index); -} \ No newline at end of file +} diff --git a/lib/update_util/update_operation.h b/lib/update_util/update_operation.h index 6b6ab7305e3..10f3c6b41c6 100644 --- a/lib/update_util/update_operation.h +++ b/lib/update_util/update_operation.h @@ -69,4 +69,4 @@ void update_operation_disarm(); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/make/base.mk b/make/base.mk index 696c4294c11..281419e9d18 100644 --- a/make/base.mk +++ b/make/base.mk @@ -8,4 +8,4 @@ OPENOCD_OPTS = CFLAGS = CPPFLAGS = LDFLAGS = -SVD_FILE = \ No newline at end of file +SVD_FILE = diff --git a/make/defaults.mk b/make/defaults.mk index 86e4f03d05a..ade34a6b0f7 100644 --- a/make/defaults.mk +++ b/make/defaults.mk @@ -1,2 +1,2 @@ TARGET ?= f7 -export TARGET \ No newline at end of file +export TARGET diff --git a/make/freertos-heap.mk b/make/freertos-heap.mk index e839e61c260..93992900830 100644 --- a/make/freertos-heap.mk +++ b/make/freertos-heap.mk @@ -1 +1 @@ -LDFLAGS += -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r -Wl,--wrap,_calloc_r -Wl,--wrap,_realloc_r \ No newline at end of file +LDFLAGS += -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r -Wl,--wrap,_calloc_r -Wl,--wrap,_realloc_r diff --git a/scripts/ReadMe.md b/scripts/ReadMe.md index b04ed0d1a0c..86b5b8afe1f 100644 --- a/scripts/ReadMe.md +++ b/scripts/ReadMe.md @@ -57,4 +57,4 @@ Run in the root folder of the repo: ```bash python scripts/storage.py -p send assets/resources /ext -``` \ No newline at end of file +``` From 37bd0d546a65740d8d19e588f9c54fa8651b1ef1 Mon Sep 17 00:00:00 2001 From: hedger Date: Fri, 6 May 2022 19:26:25 +0300 Subject: [PATCH 07/24] [FL-2517, FL-2518, FL-2523] Updater UI overhaul (#1196) * Updater: UI rework initial * Updater: further updates to UI, added a temporary parrot * Updater: additional checks on radio stack type before update * Second iteration of updater UI: additional handling of resource unpacking errors * updater: removed extra logging, renamed some stages * Updater: Changed "back" button icon on error screen * Archive: signed/unsigned fix * Updater: cancelling update also cancels LFS+resources processing; restored /ext/update/ folder magic to 0 * Updater: root dir fix Co-authored-by: nminaylov --- .../archive/helpers/archive_browser.c | 12 +- applications/power/power_service/power_api.c | 3 +- applications/updater/cli/updater_cli.c | 2 +- .../updater/scenes/updater_scene_main.c | 8 +- applications/updater/updater.c | 15 +- applications/updater/util/update_task.c | 173 ++++++++++++++---- applications/updater/util/update_task.h | 51 ++++-- .../updater/util/update_task_worker_backup.c | 45 ++--- .../updater/util/update_task_worker_flasher.c | 47 ++--- applications/updater/views/updater_main.c | 49 ++--- applications/updater/views/updater_main.h | 2 - assets/compiled/assets_icons.c | 4 + assets/compiled/assets_icons.h | 1 + assets/icons/Update/Updating_32x40.png | Bin 0 -> 3704 bytes firmware/targets/f7/Src/main.c | 3 +- firmware/targets/f7/Src/update.c | 3 +- lib/update_util/update_manifest.h | 1 - lib/update_util/update_operation.c | 25 ++- lib/update_util/update_operation.h | 8 +- 19 files changed, 274 insertions(+), 178 deletions(-) create mode 100644 assets/icons/Update/Updating_32x40.png diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c index faf10de98d2..cb3d3ca83e2 100644 --- a/applications/archive/helpers/archive_browser.c +++ b/applications/archive/helpers/archive_browser.c @@ -21,14 +21,14 @@ void archive_update_offset(ArchiveBrowserView* browser) { browser->view, (ArchiveBrowserViewModel * model) { uint16_t bounds = model->item_cnt > 3 ? 2 : model->item_cnt; - if((model->item_cnt > 3u) && ((uint32_t)model->item_idx >= (model->item_cnt - 1))) { + if((model->item_cnt > 3u) && (model->item_idx >= ((int32_t)model->item_cnt - 1))) { model->list_offset = model->item_idx - 3; } else if(model->list_offset < model->item_idx - bounds) { model->list_offset = - CLAMP((uint32_t)model->item_idx - 2, model->item_cnt - bounds, 0u); + CLAMP(model->item_idx - 2, (int32_t)model->item_cnt - bounds, 0); } else if(model->list_offset > model->item_idx - bounds) { model->list_offset = - CLAMP((uint32_t)model->item_idx - 1, model->item_cnt - bounds, 0u); + CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0); } return true; @@ -80,7 +80,7 @@ void archive_set_item_count(ArchiveBrowserView* browser, uint32_t count) { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { model->item_cnt = count; - model->item_idx = CLAMP((uint32_t)model->item_idx, model->item_cnt - 1, 0u); + model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0); return false; }); archive_update_offset(browser); @@ -97,7 +97,7 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) { model->item_idx - model->array_offset, model->item_idx - model->array_offset + 1); model->item_cnt--; - model->item_idx = CLAMP((uint32_t)model->item_idx, model->item_cnt - 1, 0u); + model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0); items_cnt = model->item_cnt; return false; }); @@ -160,7 +160,7 @@ bool archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { } else { offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 1; } - offset_new = CLAMP((uint32_t)offset_new, model->item_cnt - FILE_LIST_BUF_LEN, 0u); + offset_new = CLAMP(offset_new, (int32_t)model->item_cnt - FILE_LIST_BUF_LEN, 0); } return false; }); diff --git a/applications/power/power_service/power_api.c b/applications/power/power_service/power_api.c index b290cb831d8..865c21c80d3 100644 --- a/applications/power/power_service/power_api.c +++ b/applications/power/power_service/power_api.c @@ -2,6 +2,7 @@ #include #include +#include void power_off(Power* power) { furi_hal_power_off(); @@ -14,7 +15,7 @@ void power_off(Power* power) { void power_reboot(PowerBootMode mode) { if(mode == PowerBootModeNormal) { - furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + update_operation_disarm(); } else if(mode == PowerBootModeDfu) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeDfu); } else if(mode == PowerBootModeUpdateStart) { diff --git a/applications/updater/cli/updater_cli.c b/applications/updater/cli/updater_cli.c index 000ff56cdfb..dfc7fbcef86 100644 --- a/applications/updater/cli/updater_cli.c +++ b/applications/updater/cli/updater_cli.c @@ -134,4 +134,4 @@ void updater_on_system_start() { #else UNUSED(updater_start_app); #endif -} +} \ No newline at end of file diff --git a/applications/updater/scenes/updater_scene_main.c b/applications/updater/scenes/updater_scene_main.c index c5fc99ffb9b..5f7aeaca4b6 100644 --- a/applications/updater/scenes/updater_scene_main.c +++ b/applications/updater/scenes/updater_scene_main.c @@ -45,8 +45,8 @@ void updater_scene_main_on_enter(void* context) { view_dispatcher_switch_to_view(updater->view_dispatcher, UpdaterViewMain); } -static void updater_scene_restart_to_postupdate() { - furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate); +static void updater_scene_cancel_update() { + update_operation_disarm(); furi_hal_power_reset(); } @@ -57,7 +57,7 @@ bool updater_scene_main_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeTick) { if(!update_task_is_running(updater->update_task)) { if(updater->idle_ticks++ >= (UPDATE_DELAY_OPERATION_ERROR / UPDATER_APP_TICK)) { - updater_scene_restart_to_postupdate(); + updater_scene_cancel_update(); } } else { updater->idle_ticks = 0; @@ -74,7 +74,7 @@ bool updater_scene_main_on_event(void* context, SceneManagerEvent event) { case UpdaterCustomEventCancelUpdate: if(!update_task_is_running(updater->update_task)) { - updater_scene_restart_to_postupdate(); + updater_scene_cancel_update(); } consumed = true; break; diff --git a/applications/updater/updater.c b/applications/updater/updater.c index b58c8daa043..4c9fe41f9b0 100644 --- a/applications/updater/updater.c +++ b/applications/updater/updater.c @@ -26,15 +26,10 @@ static bool updater_back_event_callback(void* context) { return scene_manager_handle_back_event(updater->scene_manager); } -static void status_update_cb( - const char* message, - const uint8_t progress, - const uint8_t idx_stage, - const uint8_t total_stages, - bool failed, - void* context) { +static void + status_update_cb(const char* message, const uint8_t progress, bool failed, void* context) { UpdaterMainView* main_view = context; - updater_main_model_set_state(main_view, message, progress, idx_stage, total_stages, failed); + updater_main_model_set_state(main_view, message, progress, failed); } Updater* updater_alloc(const char* arg) { @@ -64,9 +59,7 @@ Updater* updater_alloc(const char* arg) { updater->view_dispatcher, updater_tick_event_callback, UPDATER_APP_TICK); view_dispatcher_attach_to_gui( - updater->view_dispatcher, - updater->gui, - arg ? ViewDispatcherTypeFullscreen : ViewDispatcherTypeWindow); + updater->view_dispatcher, updater->gui, ViewDispatcherTypeFullscreen); updater->main_view = updater_main_alloc(); view_dispatcher_add_view( diff --git a/applications/updater/util/update_task.c b/applications/updater/util/update_task.c index 6ff61700ae4..373f680a903 100644 --- a/applications/updater/util/update_task.c +++ b/applications/updater/util/update_task.c @@ -14,54 +14,139 @@ static const char* update_task_stage_descr[] = { [UpdateTaskStageReadManifest] = "Loading update manifest", [UpdateTaskStageValidateDFUImage] = "Checking DFU file", [UpdateTaskStageFlashWrite] = "Writing flash", - [UpdateTaskStageFlashValidate] = "Validating", - [UpdateTaskStageRadioImageValidate] = "Checking radio image", - [UpdateTaskStageRadioErase] = "Removing radio stack", - [UpdateTaskStageRadioWrite] = "Writing radio stack", - [UpdateTaskStageRadioInstall] = "Installing radio stack", - [UpdateTaskStageRadioBusy] = "Core2 is updating", + [UpdateTaskStageFlashValidate] = "Validating flash", + [UpdateTaskStageRadioImageValidate] = "Checking radio FW", + [UpdateTaskStageRadioErase] = "Uninstalling radio FW", + [UpdateTaskStageRadioWrite] = "Writing radio FW", + [UpdateTaskStageRadioInstall] = "Installing radio FW", + [UpdateTaskStageRadioBusy] = "Radio is updating", [UpdateTaskStageOBValidation] = "Validating opt. bytes", [UpdateTaskStageLfsBackup] = "Backing up LFS", [UpdateTaskStageLfsRestore] = "Restoring LFS", [UpdateTaskStageResourcesUpdate] = "Updating resources", - [UpdateTaskStageCompleted] = "Completed!", + [UpdateTaskStageCompleted] = "Restarting...", [UpdateTaskStageError] = "Error", - [UpdateTaskStageOBError] = "OB error, pls report", + [UpdateTaskStageOBError] = "OB Err, report", }; -static void update_task_set_status(UpdateTask* update_task, const char* status) { - if(!status) { - if(update_task->state.stage >= COUNT_OF(update_task_stage_descr)) { - status = "..."; - } else { - status = update_task_stage_descr[update_task->state.stage]; +typedef struct { + UpdateTaskStageGroup group; + uint8_t weight; +} UpdateTaskStageGroupMap; + +#define STAGE_DEF(GROUP, WEIGHT) \ + { .group = (GROUP), .weight = (WEIGHT), } + +static const UpdateTaskStageGroupMap update_task_stage_progress[] = { + [UpdateTaskStageProgress] = STAGE_DEF(UpdateTaskStageGroupMisc, 0), + + [UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5), + [UpdateTaskStageLfsBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 30), + + [UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 30), + [UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 50), + [UpdateTaskStageRadioWrite] = STAGE_DEF(UpdateTaskStageGroupRadio, 100), + [UpdateTaskStageRadioInstall] = STAGE_DEF(UpdateTaskStageGroupRadio, 5), + [UpdateTaskStageRadioBusy] = STAGE_DEF(UpdateTaskStageGroupRadio, 70), + + [UpdateTaskStageOBValidation] = STAGE_DEF(UpdateTaskStageGroupOptionBytes, 10), + + [UpdateTaskStageValidateDFUImage] = STAGE_DEF(UpdateTaskStageGroupFirmware, 100), + [UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 200), + [UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 50), + + [UpdateTaskStageLfsRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 30), + + [UpdateTaskStageResourcesUpdate] = STAGE_DEF(UpdateTaskStageGroupResources, 255), + + [UpdateTaskStageCompleted] = STAGE_DEF(UpdateTaskStageGroupMisc, 1), + [UpdateTaskStageError] = STAGE_DEF(UpdateTaskStageGroupMisc, 1), + [UpdateTaskStageOBError] = STAGE_DEF(UpdateTaskStageGroupMisc, 1), +}; + +static UpdateTaskStageGroup update_task_get_task_groups(UpdateTask* update_task) { + UpdateTaskStageGroup ret = UpdateTaskStageGroupPreUpdate | UpdateTaskStageGroupPostUpdate; + UpdateManifest* manifest = update_task->manifest; + if(!string_empty_p(manifest->radio_image)) { + ret |= UpdateTaskStageGroupRadio; + } + if(update_manifest_has_obdata(manifest)) { + ret |= UpdateTaskStageGroupOptionBytes; + } + if(!string_empty_p(manifest->firmware_dfu_image)) { + ret |= UpdateTaskStageGroupFirmware; + } + if(!string_empty_p(manifest->resource_bundle)) { + ret |= UpdateTaskStageGroupResources; + } + return ret; +} + +static void update_task_calc_completed_stages(UpdateTask* update_task) { + uint32_t completed_stages_points = 0; + for(UpdateTaskStage past_stage = UpdateTaskStageProgress; + past_stage < update_task->state.stage; + ++past_stage) { + const UpdateTaskStageGroupMap* grp_descr = &update_task_stage_progress[past_stage]; + if((grp_descr->group & update_task->state.groups) == 0) { + continue; } + completed_stages_points += grp_descr->weight; } - string_set_str(update_task->state.status, status); + update_task->state.completed_stages_points = completed_stages_points; } void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, uint8_t progress) { if(stage != UpdateTaskStageProgress) { - // do not override more specific error states - if((update_task->state.stage < UpdateTaskStageError) || (stage < UpdateTaskStageError)) { - update_task->state.stage = stage; + /* do not override more specific error states */ + if((stage >= UpdateTaskStageError) && (update_task->state.stage >= UpdateTaskStageError)) { + return; + } + /* Build error message with code "[stage_idx-stage_percent]" */ + if(stage >= UpdateTaskStageError) { + string_printf( + update_task->state.status, + "%s #[%d-%d]", + update_task_stage_descr[stage], + update_task->state.stage, + update_task->state.stage_progress); + } else { + string_set_str(update_task->state.status, update_task_stage_descr[stage]); + } + /* Store stage update */ + update_task->state.stage = stage; + /* If we are still alive, sum completed stages weights */ + if((stage > UpdateTaskStageProgress) && (stage < UpdateTaskStageCompleted)) { + update_task_calc_completed_stages(update_task); } - update_task->state.current_stage_idx++; - update_task_set_status(update_task, NULL); } - if(progress > 100) { - progress = 100; + /* Store stage progress for all non-error updates - to provide details on error state */ + if(!update_stage_is_error(stage)) { + update_task->state.stage_progress = progress; } - update_task->state.progress = progress; + /* Calculate "overall" progress, based on stage weights */ + uint32_t adapted_progress = 1; + if(update_task->state.total_progress_points != 0) { + if(stage < UpdateTaskStageCompleted) { + adapted_progress = MIN( + (update_task->state.completed_stages_points + + (update_task_stage_progress[update_task->state.stage].weight * progress / 100)) * + 100 / (update_task->state.total_progress_points), + 100u); + + } else { + adapted_progress = update_task->state.overall_progress; + } + } + update_task->state.overall_progress = adapted_progress; + if(update_task->status_change_cb) { (update_task->status_change_cb)( string_get_cstr(update_task->state.status), - progress, - update_task->state.current_stage_idx, - update_task->state.total_stages, - update_task->state.stage >= UpdateTaskStageError, + adapted_progress, + update_stage_is_error(update_task->state.stage), update_task->status_change_cb_state); } } @@ -106,8 +191,7 @@ static void update_task_worker_thread_cb(FuriThreadState state, void* context) { return; } - int32_t op_result = furi_thread_get_return_code(update_task->thread); - if(op_result == UPDATE_TASK_NOERR) { + if(furi_thread_get_return_code(update_task->thread) == UPDATE_TASK_NOERR) { osDelay(UPDATE_DELAY_OPERATION_OK); furi_hal_power_reset(); } @@ -117,7 +201,8 @@ UpdateTask* update_task_alloc() { UpdateTask* update_task = malloc(sizeof(UpdateTask)); update_task->state.stage = UpdateTaskStageProgress; - update_task->state.progress = 0; + update_task->state.stage_progress = 0; + update_task->state.overall_progress = 0; string_init(update_task->state.status); update_task->manifest = update_manifest_alloc(); @@ -163,6 +248,12 @@ void update_task_free(UpdateTask* update_task) { bool update_task_parse_manifest(UpdateTask* update_task) { furi_assert(update_task); + update_task->state.stage_progress = 0; + update_task->state.overall_progress = 0; + update_task->state.total_progress_points = 0; + update_task->state.completed_stages_points = 0; + update_task->state.groups = 0; + update_task_set_progress(update_task, UpdateTaskStageReadManifest, 0); bool result = false; string_t manifest_path; @@ -180,19 +271,31 @@ bool update_task_parse_manifest(UpdateTask* update_task) { UPDATE_MANIFEST_DEFAULT_NAME, manifest_path); update_task_set_progress(update_task, UpdateTaskStageProgress, 30); - if(!update_manifest_init(update_task->manifest, string_get_cstr(manifest_path))) { + + UpdateManifest* manifest = update_task->manifest; + if(!update_manifest_init(manifest, string_get_cstr(manifest_path))) { break; } + update_task->state.groups = update_task_get_task_groups(update_task); + for(size_t stage_counter = 0; stage_counter < COUNT_OF(update_task_stage_progress); + ++stage_counter) { + const UpdateTaskStageGroupMap* grp_descr = &update_task_stage_progress[stage_counter]; + if((grp_descr->group & update_task->state.groups) != 0) { + update_task->state.total_progress_points += grp_descr->weight; + } + } + update_task_set_progress(update_task, UpdateTaskStageProgress, 50); - if(!string_empty_p(update_task->manifest->firmware_dfu_image) && - !update_task_check_file_exists(update_task, update_task->manifest->firmware_dfu_image)) { + if((update_task->state.groups & UpdateTaskStageGroupFirmware) && + !update_task_check_file_exists(update_task, manifest->firmware_dfu_image)) { break; } update_task_set_progress(update_task, UpdateTaskStageProgress, 70); - if(!string_empty_p(update_task->manifest->radio_image) && - !update_task_check_file_exists(update_task, update_task->manifest->radio_image)) { + if((update_task->state.groups & UpdateTaskStageGroupRadio) && + (!update_task_check_file_exists(update_task, manifest->radio_image) || + (manifest->radio_version.version.type == 0))) { break; } diff --git a/applications/updater/util/update_task.h b/applications/updater/util/update_task.h index 3197c8c19e0..cfbbb8500db 100644 --- a/applications/updater/util/update_task.h +++ b/applications/updater/util/update_task.h @@ -10,46 +10,63 @@ extern "C" { #include #include -#define UPDATE_DELAY_OPERATION_OK 600 +#define UPDATE_DELAY_OPERATION_OK 300 #define UPDATE_DELAY_OPERATION_ERROR INT_MAX typedef enum { - UpdateTaskStageProgress, + UpdateTaskStageProgress = 0, + UpdateTaskStageReadManifest, - UpdateTaskStageValidateDFUImage, - UpdateTaskStageFlashWrite, - UpdateTaskStageFlashValidate, + UpdateTaskStageLfsBackup, + UpdateTaskStageRadioImageValidate, UpdateTaskStageRadioErase, UpdateTaskStageRadioWrite, UpdateTaskStageRadioInstall, UpdateTaskStageRadioBusy, + UpdateTaskStageOBValidation, - UpdateTaskStageLfsBackup, + + UpdateTaskStageValidateDFUImage, + UpdateTaskStageFlashWrite, + UpdateTaskStageFlashValidate, + UpdateTaskStageLfsRestore, UpdateTaskStageResourcesUpdate, + UpdateTaskStageCompleted, UpdateTaskStageError, - UpdateTaskStageOBError + UpdateTaskStageOBError, + UpdateTaskStageMAX } UpdateTaskStage; +inline bool update_stage_is_error(const UpdateTaskStage stage) { + return stage >= UpdateTaskStageError; +} + +typedef enum { + UpdateTaskStageGroupMisc = 0, + UpdateTaskStageGroupPreUpdate = 1 << 1, + UpdateTaskStageGroupFirmware = 1 << 2, + UpdateTaskStageGroupOptionBytes = 1 << 3, + UpdateTaskStageGroupRadio = 1 << 4, + UpdateTaskStageGroupPostUpdate = 1 << 5, + UpdateTaskStageGroupResources = 1 << 6, +} UpdateTaskStageGroup; + typedef struct { UpdateTaskStage stage; - uint8_t progress; - uint8_t current_stage_idx; - uint8_t total_stages; + uint8_t overall_progress, stage_progress; string_t status; + UpdateTaskStageGroup groups; + uint32_t total_progress_points; + uint32_t completed_stages_points; } UpdateTaskState; typedef struct UpdateTask UpdateTask; -typedef void (*updateProgressCb)( - const char* status, - const uint8_t stage_pct, - const uint8_t idx_stage, - const uint8_t total_stages, - bool failed, - void* state); +typedef void ( + *updateProgressCb)(const char* status, const uint8_t stage_pct, bool failed, void* state); UpdateTask* update_task_alloc(); diff --git a/applications/updater/util/update_task_worker_backup.c b/applications/updater/util/update_task_worker_backup.c index 38d71dfdd8c..485fdd48a75 100644 --- a/applications/updater/util/update_task_worker_backup.c +++ b/applications/updater/util/update_task_worker_backup.c @@ -27,7 +27,6 @@ static bool update_task_pre_update(UpdateTask* update_task) { path_concat( string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, backup_file_path); - update_task->state.total_stages = 1; update_task_set_progress(update_task, UpdateTaskStageLfsBackup, 0); /* to avoid bootloops */ furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); @@ -62,22 +61,18 @@ static bool update_task_post_update(UpdateTask* update_task) { string_t file_path; string_init(file_path); - /* status text is too long, too few stages to bother with a counter */ - update_task->state.total_stages = 0; - + TarArchive* archive = tar_archive_alloc(update_task->storage); do { CHECK_RESULT(update_task_parse_manifest(update_task)); path_concat( string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, file_path); - bool unpack_resources = !string_empty_p(update_task->manifest->resource_bundle); - update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0); - furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + update_operation_disarm(); CHECK_RESULT(lfs_backup_unpack(update_task->storage, string_get_cstr(file_path))); - if(unpack_resources) { + if(update_task->state.groups & UpdateTaskStageGroupResources) { TarUnpackProgress progress = { .update_task = update_task, .total_files = 0, @@ -90,20 +85,19 @@ static bool update_task_post_update(UpdateTask* update_task) { string_get_cstr(update_task->manifest->resource_bundle), file_path); - TarArchive* archive = tar_archive_alloc(update_task->storage); tar_archive_set_file_callback(archive, update_task_resource_unpack_cb, &progress); - success = tar_archive_open(archive, string_get_cstr(file_path), TAR_OPEN_MODE_READ); - if(success) { - progress.total_files = tar_archive_get_entries_count(archive); - if(progress.total_files > 0) { - tar_archive_unpack_to(archive, EXT_PATH); - } + CHECK_RESULT( + tar_archive_open(archive, string_get_cstr(file_path), TAR_OPEN_MODE_READ)); + + progress.total_files = tar_archive_get_entries_count(archive); + if(progress.total_files > 0) { + CHECK_RESULT(tar_archive_unpack_to(archive, EXT_PATH)); } - tar_archive_free(archive); } success = true; } while(false); + tar_archive_free(archive); string_clear(file_path); return success; } @@ -116,18 +110,17 @@ int32_t update_task_worker_backup_restore(void* context) { FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); if((boot_mode != FuriHalRtcBootModePreUpdate) && (boot_mode != FuriHalRtcBootModePostUpdate)) { /* no idea how we got here. Clear to normal boot */ - furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + update_operation_disarm(); return UPDATE_TASK_NOERR; } - update_task->state.current_stage_idx = 0; - if(!update_operation_get_current_package_path(update_task->storage, update_task->update_path)) { return UPDATE_TASK_FAILED; } - /* Waiting for BT service to 'start', so we don't race for boot mode */ + /* Waiting for BT service to 'start', so we don't race for boot mode flag */ furi_record_open("bt"); + furi_record_close("bt"); if(boot_mode == FuriHalRtcBootModePreUpdate) { success = update_task_pre_update(update_task); @@ -135,13 +128,11 @@ int32_t update_task_worker_backup_restore(void* context) { success = update_task_post_update(update_task); } - furi_record_close("bt"); - - if(success) { - update_task_set_progress(update_task, UpdateTaskStageCompleted, 100); - } else { - update_task_set_progress(update_task, UpdateTaskStageError, update_task->state.progress); + if(!success) { + update_task_set_progress(update_task, UpdateTaskStageError, 0); + return UPDATE_TASK_FAILED; } - return success ? UPDATE_TASK_NOERR : UPDATE_TASK_FAILED; + update_task_set_progress(update_task, UpdateTaskStageCompleted, 100); + return UPDATE_TASK_NOERR; } diff --git a/applications/updater/util/update_task_worker_flasher.c b/applications/updater/util/update_task_worker_flasher.c index 6b03439dd6e..1f22e2f7201 100644 --- a/applications/updater/util/update_task_worker_flasher.c +++ b/applications/updater/util/update_task_worker_flasher.c @@ -111,19 +111,13 @@ static bool update_task_write_stack_data(UpdateTask* update_task) { } bytes_read = storage_file_read(update_task->file, fw_block, n_bytes_to_read); - if(bytes_read == 0) { - break; - } + CHECK_RESULT(bytes_read != 0); int16_t i_page = furi_hal_flash_get_page_number(update_task->manifest->radio_address + element_offs); - if(i_page < 0) { - break; - } + CHECK_RESULT(i_page >= 0); - if(!furi_hal_flash_program_page(i_page, fw_block, bytes_read)) { - break; - } + CHECK_RESULT(furi_hal_flash_program_page(i_page, fw_block, bytes_read)); element_offs += bytes_read; update_task_set_progress( @@ -142,19 +136,19 @@ static void update_task_wait_for_restart(UpdateTask* update_task) { static bool update_task_write_stack(UpdateTask* update_task) { bool success = false; + UpdateManifest* manifest = update_task->manifest; do { FURI_LOG_W(TAG, "Writing stack"); update_task_set_progress(update_task, UpdateTaskStageRadioImageValidate, 0); - CHECK_RESULT(update_task_open_file(update_task, update_task->manifest->radio_image)); + CHECK_RESULT(update_task_open_file(update_task, manifest->radio_image)); CHECK_RESULT( crc32_calc_file(update_task->file, &update_task_file_progress, update_task) == - update_task->manifest->radio_crc); + manifest->radio_crc); CHECK_RESULT(update_task_write_stack_data(update_task)); update_task_set_progress(update_task, UpdateTaskStageRadioInstall, 0); CHECK_RESULT( - ble_glue_fus_stack_install(update_task->manifest->radio_address, 0) != - BleGlueCommandResultError); + ble_glue_fus_stack_install(manifest->radio_address, 0) != BleGlueCommandResultError); update_task_set_progress(update_task, UpdateTaskStageRadioInstall, 80); CHECK_RESULT(ble_glue_fus_wait_operation() == BleGlueCommandResultOK); update_task_set_progress(update_task, UpdateTaskStageRadioInstall, 100); @@ -280,7 +274,6 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { manifest->ob_write_mask.obs[idx].values.base) != 0; if(can_patch) { - /* patch & restart loop */ const uint32_t patched_value = /* take all non-writable bits from real value */ (device_ob_value & ~(manifest->ob_write_mask.obs[idx].values.base)) | @@ -297,8 +290,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { if(!is_fixed) { /* Things are so bad that fixing what we are allowed to still doesn't match - * reference value - */ + * reference value */ FURI_LOG_W( TAG, "OB #%d is FUBAR (fixed&masked %08X, not %08X)", @@ -317,11 +309,11 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { } } if(!match) { - update_task_set_progress(update_task, UpdateTaskStageOBError, 95); + update_task_set_progress(update_task, UpdateTaskStageOBError, 0); } if(ob_dirty) { - FURI_LOG_W(TAG, "OB were changed, applying"); + FURI_LOG_W(TAG, "OBs were changed, applying"); furi_hal_flash_ob_apply(); } return match; @@ -332,24 +324,18 @@ int32_t update_task_worker_flash_writer(void* context) { UpdateTask* update_task = context; bool success = false; - update_task->state.current_stage_idx = 0; - update_task->state.total_stages = 0; - do { CHECK_RESULT(update_task_parse_manifest(update_task)); - if(!string_empty_p(update_task->manifest->radio_image)) { + if(update_task->state.groups & UpdateTaskStageGroupRadio) { CHECK_RESULT(update_task_manage_radiostack(update_task)); } - bool check_ob = update_manifest_has_obdata(update_task->manifest); - if(check_ob) { - update_task->state.total_stages++; + if(update_task->state.groups & UpdateTaskStageGroupOptionBytes) { CHECK_RESULT(update_task_validate_optionbytes(update_task)); } - if(!string_empty_p(update_task->manifest->firmware_dfu_image)) { - update_task->state.total_stages += 4; + if(update_task->state.groups & UpdateTaskStageGroupFirmware) { CHECK_RESULT(update_task_write_dfu(update_task)); } @@ -359,5 +345,10 @@ int32_t update_task_worker_flash_writer(void* context) { success = true; } while(false); - return success ? UPDATE_TASK_NOERR : UPDATE_TASK_FAILED; + if(!success) { + update_task_set_progress(update_task, UpdateTaskStageError, 0); + return UPDATE_TASK_FAILED; + } + + return UPDATE_TASK_NOERR; } diff --git a/applications/updater/views/updater_main.c b/applications/updater/views/updater_main.c index 8d9b3e95314..72541b9abd6 100644 --- a/applications/updater/views/updater_main.c +++ b/applications/updater/views/updater_main.c @@ -15,12 +15,11 @@ struct UpdaterMainView { void* context; }; -static const uint8_t PROGRESS_RENDER_STEP = 3; /* percent, to limit rendering rate */ +static const uint8_t PROGRESS_RENDER_STEP = 1; /* percent, to limit rendering rate */ typedef struct { string_t status; uint8_t progress, rendered_progress; - uint8_t idx_stage, total_stages; bool failed; } UpdaterProgressModel; @@ -28,14 +27,10 @@ void updater_main_model_set_state( UpdaterMainView* main_view, const char* message, uint8_t progress, - uint8_t idx_stage, - uint8_t total_stages, bool failed) { with_view_model( main_view->view, (UpdaterProgressModel * model) { model->failed = failed; - model->idx_stage = idx_stage; - model->total_stages = total_stages; model->progress = progress; if(string_cmp_str(model->status, message)) { string_set(model->status, message); @@ -65,14 +60,10 @@ bool updater_main_input(InputEvent* event, void* context) { return true; } - if(event->type != InputTypeShort) { - return true; - } - - if(event->key == InputKeyOk) { + if((event->type == InputTypeShort) && (event->key == InputKeyOk)) { view_dispatcher_send_custom_event( main_view->view_dispatcher, UpdaterCustomEventRetryUpdate); - } else if(event->key == InputKeyBack) { + } else if((event->type == InputTypeLong) && (event->key == InputKeyBack)) { view_dispatcher_send_custom_event( main_view->view_dispatcher, UpdaterCustomEventCancelUpdate); } @@ -85,27 +76,25 @@ static void updater_main_draw_callback(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontPrimary); - uint16_t y_offset = model->failed ? 5 : 13; - string_t status_text; - if(!model->failed && (model->idx_stage != 0) && (model->idx_stage <= model->total_stages)) { - string_init_printf( - status_text, - "[%d/%d] %s", - model->idx_stage, - model->total_stages, - string_get_cstr(model->status)); - } else { - string_init_set(status_text, model->status); - } - canvas_draw_str_aligned( - canvas, 128 / 2, y_offset, AlignCenter, AlignTop, string_get_cstr(status_text)); - string_clear(status_text); if(model->failed) { + canvas_draw_str_aligned(canvas, 42, 16, AlignLeft, AlignTop, "Update Failed!"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned( + canvas, 42, 32, AlignLeft, AlignTop, string_get_cstr(model->status)); + + canvas_draw_icon(canvas, 7, 16, &I_Warning_30x23); + canvas_draw_str_aligned( + canvas, 18, 51, AlignLeft, AlignTop, "to retry, hold to abort"); + canvas_draw_icon(canvas, 7, 50, &I_Ok_btn_9x9); + canvas_draw_icon(canvas, 75, 51, &I_Pin_back_arrow_10x8); + } else { + canvas_draw_str_aligned(canvas, 55, 14, AlignLeft, AlignTop, "UPDATING"); canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned( - canvas, 128 / 2, 20, AlignCenter, AlignTop, "[OK] to retry, [Back] to abort"); + canvas, 64, 51, AlignCenter, AlignTop, string_get_cstr(model->status)); + canvas_draw_icon(canvas, 4, 5, &I_Updating_32x40); + elements_progress_bar(canvas, 42, 29, 80, (float)model->progress / 100); } - elements_progress_bar(canvas, 14, 35, 100, (float)model->progress / 100); } UpdaterMainView* updater_main_alloc() { @@ -116,7 +105,7 @@ UpdaterMainView* updater_main_alloc() { with_view_model( main_view->view, (UpdaterProgressModel * model) { - string_init_set(model->status, "Waiting for storage"); + string_init_set(model->status, "Waiting for SD card"); return true; }); diff --git a/applications/updater/views/updater_main.h b/applications/updater/views/updater_main.h index d787295696f..81a0e86c914 100644 --- a/applications/updater/views/updater_main.h +++ b/applications/updater/views/updater_main.h @@ -17,8 +17,6 @@ void updater_main_model_set_state( UpdaterMainView* main_view, const char* message, uint8_t progress, - uint8_t idx_stage, - uint8_t total_stages, bool failed); void updater_main_set_storage_pubsub(UpdaterMainView* main_view, FuriPubSubSubscription* sub); diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index 8b17d0780b2..709fab4573e 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -642,6 +642,9 @@ const uint8_t* const _I_Drive_112x35[] = {_I_Drive_112x35_0}; const uint8_t _I_Error_62x31_0[] = {0x01,0x00,0x9e,0x00,0x00,0x47,0xc2,0xfe,0x07,0x58,0x66,0x02,0x02,0x07,0x48,0x1c,0x02,0x0c,0x06,0x3c,0x00,0x08,0x61,0x00,0x73,0xa0,0x00,0x86,0x20,0x07,0x39,0x00,0x09,0x01,0x88,0x07,0x70,0xd1,0x09,0x0b,0xe0,0x07,0x38,0x1c,0x62,0x11,0x08,0x80,0x8c,0x8a,0x0f,0x1c,0x82,0x7d,0x20,0x58,0x0b,0xe4,0x02,0x1d,0x0e,0x82,0x6e,0xa0,0xb8,0x0c,0x1c,0x02,0x39,0x07,0x82,0x4e,0xa0,0xb7,0x08,0x04,0x07,0x71,0x03,0x82,0x7e,0xa0,0xb0,0xe8,0x04,0x0b,0xe1,0x01,0x81,0x01,0xc6,0x01,0xc0,0x81,0xf8,0x01,0x42,0x27,0x18,0x04,0xc0,0x1e,0x63,0x71,0x3d,0x0c,0x08,0x3e,0x20,0xa1,0x22,0x94,0x08,0x5e,0x21,0x51,0x0f,0x08,0xbc,0x47,0xe2,0x07,0x29,0x81,0x40,0x49,0xe2,0x07,0x28,0x61,0x80,0x4b,0xe2,0x07,0x28,0x19,0xe0,0xc0,0xe2,0x0d,0x18,0xc0,0x1d,0x00,0x02,0xa8,0x30,0x39,0x2e,0x10,0x0e,0x5e,0x00,0x3b,0x7e,0x00,0xec,0x46,0x10,0x3f,0x80,0xc8,}; const uint8_t* const _I_Error_62x31[] = {_I_Error_62x31_0}; +const uint8_t _I_Updating_32x40_0[] = {0x01,0x00,0x56,0x00,0xc0,0x7f,0xc0,0x03,0xc0,0x01,0x97,0x82,0x07,0x00,0xe0,0x5c,0x00,0x65,0x38,0x01,0x94,0x70,0x06,0x50,0xe0,0x19,0x41,0xc0,0x65,0xff,0x01,0xb4,0x0c,0x02,0x7e,0x08,0x38,0x0c,0x7c,0xd6,0x70,0x18,0xfb,0xfe,0xfc,0x0c,0x18,0xc8,0x78,0x20,0x33,0x81,0x8f,0x8a,0x07,0x3e,0xbe,0x70,0x38,0x71,0xff,0xc7,0x0f,0xc7,0x0f,0xf8,0x71,0xc0,0x76,0x13,0x30,0xd9,0x88,0xcc,0x5f,0x03,0xb2,0x21,0xa1,0x2c,0xc0,0x26,0x82,0x10,0x1f,0x80,0xd1,0x24,0x40,0x04,}; +const uint8_t* const _I_Updating_32x40[] = {_I_Updating_32x40_0}; + const uint8_t _I_DolphinExcited_64x63_0[] = {0x01,0x00,0x36,0x01,0x00,0x25,0x00,0x0f,0xd2,0x00,0x3b,0xe0,0x00,0xeb,0x10,0x0c,0x34,0x40,0x30,0xd0,0x88,0x80,0x1d,0xa1,0x00,0x42,0xfc,0x7f,0xc0,0x63,0x04,0x01,0x0e,0x02,0x0f,0x00,0x00,0x8c,0x08,0x0e,0x37,0x00,0x10,0xc6,0x20,0x10,0x10,0xd9,0x11,0x92,0x1c,0x1a,0x3e,0x00,0x04,0x42,0x02,0x1a,0x20,0xb0,0xce,0x00,0x64,0x07,0x20,0x59,0x16,0x50,0x36,0x45,0x94,0x84,0x78,0x20,0x60,0x75,0x8e,0x43,0x06,0x63,0x3c,0x33,0x94,0x0c,0xd2,0x5c,0x30,0x38,0xe4,0x08,0x43,0x10,0xc0,0x5e,0x06,0x22,0x53,0x1a,0x02,0x08,0x7f,0xd0,0x32,0xc1,0x50,0x21,0x14,0x0e,0x70,0x1c,0x46,0xe2,0x07,0x19,0x06,0x3c,0xdc,0x20,0x91,0xae,0x01,0xcc,0xbe,0x30,0x09,0xfc,0x12,0x41,0xff,0x83,0xcc,0x0a,0xa3,0x1f,0x03,0x99,0xe8,0x7c,0x10,0xf8,0x25,0xa0,0x5e,0x50,0x0f,0x84,0x1e,0x09,0x54,0x03,0x9f,0xf2,0x07,0x02,0xd5,0x11,0xca,0x01,0xfe,0x80,0xc0,0xaa,0x9f,0xf0,0x39,0x5f,0xd0,0x43,0xaa,0x83,0x41,0x92,0xc3,0x1f,0x03,0x8d,0x52,0x02,0x2e,0x25,0xc9,0x6a,0x99,0x46,0xa6,0x2a,0xa0,0x1c,0xaf,0xca,0x62,0x94,0x28,0xcb,0x7e,0x0f,0x15,0x71,0xf8,0x3c,0x22,0x71,0x03,0x8a,0x84,0x67,0x18,0x0f,0xac,0x1c,0x0e,0x38,0x08,0x0c,0x3e,0x01,0xae,0xbd,0x13,0x0c,0x0e,0x35,0x8e,0xa8,0x1c,0xb0,0x1f,0xf8,0x06,0x83,0xf4,0x27,0x38,0x07,0xff,0xff,0x8f,0x03,0xa0,0x4c,0x80,0xed,0x60,0x03,0xb4,0x60,0x0e,0xd0,0x60,0x3a,0x87,0x84,0x0e,0xb7,0xc2,0xfa,0x18,0x05,0x44,0x20,0x73,0xff,0xf7,0xce,0xe4,0x07,0x2d,0x52,0x2c,0x80,0xe7,0x54,0xea,0x81,0xd7,0x50,0x0f,0x7a,0xaa,0x3d,0x41,0xe2,0x07,0x5a,0x80,0x3c,0xa0,0x40,0x72,0xd0,0x6a,0x80,0xa2,0x07,0x3a,0x05,0x54,0x8e,0x20,0x73,0xc0,0x03,0xd8,0x60,0x30,0x40,0x3a,0xc0,0x00,0xee,0xea,0x10,0x3b,0x80,}; const uint8_t* const _I_DolphinExcited_64x63[] = {_I_DolphinExcited_64x63_0}; @@ -835,6 +838,7 @@ const Icon I_Connect_me_62x31 = {.width=62,.height=31,.frame_count=1,.frame_rate const Icon I_Connected_62x31 = {.width=62,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_Connected_62x31}; const Icon I_Drive_112x35 = {.width=112,.height=35,.frame_count=1,.frame_rate=0,.frames=_I_Drive_112x35}; const Icon I_Error_62x31 = {.width=62,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_Error_62x31}; +const Icon I_Updating_32x40 = {.width=32,.height=40,.frame_count=1,.frame_rate=0,.frames=_I_Updating_32x40}; const Icon I_DolphinExcited_64x63 = {.width=64,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinExcited_64x63}; const Icon I_DolphinMafia_115x62 = {.width=115,.height=62,.frame_count=1,.frame_rate=0,.frames=_I_DolphinMafia_115x62}; const Icon I_DolphinNice_96x59 = {.width=96,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinNice_96x59}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index be1023f6522..12ddb78e9a7 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -173,6 +173,7 @@ extern const Icon I_Connect_me_62x31; extern const Icon I_Connected_62x31; extern const Icon I_Drive_112x35; extern const Icon I_Error_62x31; +extern const Icon I_Updating_32x40; extern const Icon I_DolphinExcited_64x63; extern const Icon I_DolphinMafia_115x62; extern const Icon I_DolphinNice_96x59; diff --git a/assets/icons/Update/Updating_32x40.png b/assets/icons/Update/Updating_32x40.png new file mode 100644 index 0000000000000000000000000000000000000000..d8f7654b8d7fbac32c389ac50d29928636d80576 GIT binary patch literal 3704 zcmaJ@c{o&U8$Y%}S+a&?jCflxV-O}|8_TG%G`3MmV+;nfGzK%0Mx{-*Y*`ZuHMA*` zWh#YiQ6!WlOG0CbNtV9xzHfcsAMg8}>pJJTpZnau-~D^;`##roE;>8fNr)?p0{|dl zkFv(_R}lZ+DJsN&7V|`J1AsV^h(tQuBat8~jp9cPCIA4VH^(I$o6J)%8{iS7+^u?M z?xhDu17HodXrr`ezVsCUcUD@);zi5_ad$cSE!ily`qN$FsGJMKc{?lpEiYX-6zg`x z_^Vof(ZiDw-0A7%cgxk|+2bp1%yuc(78$LivHU>51QTNl?@>!|Le)3bumt5%gTf%` zvF2y~A};`7Mu^FXqTe-N5x7GE1OaN7?hcuTp`T}}oV7dvP!cc*mKon9kca^qbzK|f zfX1!BU6%*G;y?-j1T!P8z`!jDVCtK_nF!ERlH9Kd^yF_V5e4D|fQ+4XI|MDB0LR>- zG1`KhXFwj?0<0^{DHC9MK7!c^vT8(tuy|~ul*KWCm0_jb0)UJK0pxbsRv{2tC=c3M zH(26Ljj2Ql0G#I3*7O6N`f`=2ua(2+W(J4Vho1%Cv%)FvlJ*lD0cWRYX~?3+h0txA z0YG`F= z3o1Db^tuB914~}|ePVfs#9v1&#WIaoEVk!fcWyLQ-6pShJt{LzKbT zs73zUwZ4cM;CQA*Mk%M@%<6F*Ijjs5Ki({CrAOwCYpgZIoLY_F)iG>v?})birCIF7 zN@uV`1M@K^$y&WBby#NN6l_*4ZB;BeTmoR9bK*EY+W4?Jm=pC?KrmJk+ZhH}M9u45 zR^F5ZNc$VWm^=VTu3Jj5*dqY6rWbw!fa=d%j})gUqF;&vfOTH{mD8H!Vz~@jpaPm?-p4Fiz>38`(?#SiyHpebvm9-ia@S|8m_XI<{D%L1WUWJp3 z<@5qu~WHbgv?Ss!v}sZ z5o^oV`l`NNJy-MSACj`($*3KYO;<)7#nm+vVfLHsgHU}aokEvFvrcJZHd<>kk<|2Y zMD#w34N6a{NR&!+y0YB#e567S{^G(gS}cDDrZ7cjzahbVRQSdJ)Un&LsL1c>$0KdX?CRGuv&_U#E8lecm`R zK5^z-_-2W75@#AvK0B3ylujrWZLLs(WT0<~yh+b!bcMcysbu(HmAXoC!|q<(9Vwsm zN+uPa>Yf^vI)2O5EyT^di+O94>uoow+eh6`-n4al;QXmX?5)D>t`b$ZCnbB!+A!gm z1n2gH-UYSZtEYe9CGMY#vCTV&DsaVDyi|%)S9l2{%wny&Y3@Rk+Cf(xd=B4VnnH(( zEUSb;PM}?oA-DY4eo1~gW5-(sBwyYeoH2Qyy}wPpO``3Dj*yPI&b{uyQoquuQls98 z-r8QDY1*{H^kgqLl$v9aqn)z=C&784VpV&q4pzlf^@X;7F?)lbWKM`JyjqZ)_|Rdu zK>Aj&p!kK`&FxS#f*OeKO;ifjGse%fB;r2@T_sj_%$yx6-qIXUl~f;4&|zQjN2S)+ z^ZuU<8H#3pY|1ttw!ue2e~>B8hY0H{tS@{qQoE})B`DLcs-yf3y``m5yPw^|ZkmcW z>B0@E`>MN{JJWr^{TO zBAQc2mA_VXK76xKko6?1zw|xn?S~e`i<7sP9dxr)n!KJPxR&2$c-Z0NEuV6VvWlL~ zCyqmoh8^`hx?Ho}=|Q$uZa0+F*jImeu%`LMF}N9m@S|-)$n2$=;I)Wr=WB1)f(H<_ z8d2R*8BrToa+ml0XkJbDUN^*?QcGP>_(CaE9=WjfNs|B2P9z zHk-*?Z5EU8RHG$RIEr&BOL+Z$f9=c;`B$Pj@`qG@KwGrX+q<{KpKBK#kdC65C)vJ@tr-pF#x3gERHBM>1X0==ieH{`|*^ zV-s!7x#6ashMtL$#xYlA((jv(o&i}oL$*4N7LgrPW#`Uj#W>m2=Evn9yjM}V-}K5@ zj(h5&@rQjUkv{^?IoXE3)E9HY>|rJ;U3siA@8E9T{gK`N{`h+xla%a~>;jAgF|B;h zJ7~qu3Maokdy*wam}8_@D#_mN% z&|CchzqKz*8kZXoxZ_Ap2-Noi^(mwh|*7%z`Y^>yP0rgt57Kebyi)tgOa z7ngm%Yg;)s?BVF$6}iA9_4a<;U-4>s5;a*kNoMmr>+bBY3AF5beQrjgRAn}9RK=UL z|0Df+MBqYvYkBLdRv|;2;q>8_N9?}2>w60pBXUl8HM_5t-ma*9uhrXK_aXemyyO{G z`F$U`DO1%C_b@zyYHUs}kUPJg{*a*Tqf%8j7WJXhF5KxwZo-KhCpIqHa3=%ll;Hk5 zb#?c}NSM8G+fi`pXcmjon>C#o{*ZcTx8yU+(Wie5+>AW&$@%m3w&(rNTL&^uRV;{3 zqL_O+;dP;GodQxG;(87D^W}mZ)uXC*wG}_3xO$)Pp$&!!9=UlrI}x)>Bd3!;75NtB z<~W)o-e&YOdFYjlAg_a7HU7x%#yQsh+*67xDRw@0E#>E%^Fy6> zEp}ZRwiIcjPu63R7mzHP}vMfZzj+h0Yw|71>v+#VlT9bP`rj$P@Q*|ZefURTB} znWu4Ym)wCjXf&u*w=og3H&;sA`c85yxm5!VHEJ0R!(gDlFEBqL&DRf( zv9|p?9e;-a2hizMI0OosILMWj$Jim8-8tbX3a3qa@qf=qH9Y@9!?5z=CK8Y@o=nFU6t7mIzwAU7CfHct4vq4&! z7(uNJt@ZVdjPZ_A&3&gu8mQ zxPR%x??X2uVS|n%n|+_oQJEQMYrno1H;z&SzO?}5Ffm|KW8-kW6zluz0S#!%9LrHI zeHh><%iM|XTSVVbVfn%ilw04a5h&P)zOGg5%?VwV&U2X4TgpG$nSUiq<=kO%Q+fYl foyeCwjur=a)Gr7(;O%(J7X;YbI9iuk9XtIWpmT_g literal 0 HcmV?d00001 diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c index 629c154ed6f..2c28265f764 100644 --- a/firmware/targets/f7/Src/main.c +++ b/firmware/targets/f7/Src/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #define TAG "Main" @@ -47,7 +48,7 @@ int main() { flipper_boot_update_exec(); // if things go nice, we shouldn't reach this point. // But if we do, abandon to avoid bootloops - furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + update_operation_disarm(); furi_hal_power_reset(); } else { furi_hal_light_sequence("rgb G"); diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c index 4b3ee3ad5e6..f4a434b11bd 100644 --- a/firmware/targets/f7/Src/update.c +++ b/firmware/targets/f7/Src/update.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -101,7 +102,7 @@ static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* m static bool flipper_update_get_work_directory(string_t out_dir) { const uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); - if(update_index == 0) { + if(update_index == UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC) { string_set(out_dir, UPDATE_DIR_DEFAULT_REL_PATH); return true; } diff --git a/lib/update_util/update_manifest.h b/lib/update_util/update_manifest.h index 75871e1d3ac..2893be5a01f 100644 --- a/lib/update_util/update_manifest.h +++ b/lib/update_util/update_manifest.h @@ -12,7 +12,6 @@ extern "C" { /* Paths don't include /ext -- because at startup SD card is mounted as root */ #define UPDATE_DIR_DEFAULT_REL_PATH "/update" #define UPDATE_MANIFEST_DEFAULT_NAME "update.fuf" -#define UPDATE_MAINFEST_DEFAULT_PATH UPDATE_DIR_DEFAULT_REL_PATH "/" UPDATE_MANIFEST_DEFAULT_NAME typedef union { uint8_t raw[6]; diff --git a/lib/update_util/update_operation.c b/lib/update_util/update_operation.c index cf72dd0c82d..c9a7cd18752 100644 --- a/lib/update_util/update_operation.c +++ b/lib/update_util/update_operation.c @@ -9,10 +9,10 @@ #include #include -static const char* UPDATE_ROOT_DIR = "/ext" UPDATE_DIR_DEFAULT_REL_PATH; -static const char* UPDATE_PREFIX = "/ext" UPDATE_DIR_DEFAULT_REL_PATH "/"; -static const char* UPDATE_SUFFIX = "/" UPDATE_MANIFEST_DEFAULT_NAME; -static const uint32_t MAX_DIR_NAME_LEN = 250; +#define UPDATE_ROOT_DIR "/ext" UPDATE_DIR_DEFAULT_REL_PATH +#define UPDATE_PREFIX "/ext" UPDATE_DIR_DEFAULT_REL_PATH "/" +#define UPDATE_SUFFIX "/" UPDATE_MANIFEST_DEFAULT_NAME +#define MAX_DIR_NAME_LEN 250 static const char* update_prepare_result_descr[] = { [UpdatePrepareResultOK] = "OK", @@ -59,7 +59,7 @@ int32_t update_operation_get_package_index(Storage* storage, const char* update_ furi_assert(update_package_dir); if(strlen(update_package_dir) == 0) { - return 0; + return UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC; } bool found = false; @@ -90,9 +90,9 @@ int32_t update_operation_get_package_index(Storage* storage, const char* update_ } bool update_operation_get_current_package_path(Storage* storage, string_t out_path) { - uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); + const uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); string_set_str(out_path, UPDATE_ROOT_DIR); - if(update_index == 0) { + if(update_index == UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC) { return true; } @@ -184,14 +184,19 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { } bool update_operation_is_armed() { - return furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModePreUpdate; + FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); + return (boot_mode >= FuriHalRtcBootModePreUpdate) && + (boot_mode <= FuriHalRtcBootModePostUpdate) && + (furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex) > 0); } void update_operation_disarm() { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); - furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, 0); + furi_hal_rtc_set_register( + FuriHalRtcRegisterUpdateFolderFSIndex, INT_MAX); } -void update_operation_persist_package_index(uint32_t index) { +void update_operation_persist_package_index(int32_t index) { + furi_check(index >= 0); furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, index); } diff --git a/lib/update_util/update_operation.h b/lib/update_util/update_operation.h index 10f3c6b41c6..c11f2754ae5 100644 --- a/lib/update_util/update_operation.h +++ b/lib/update_util/update_operation.h @@ -8,6 +8,8 @@ extern "C" { #endif +#define UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC 0 + /* * Checks if supplied full manifest path is valid * @param full_path Full path to manifest file. Must be named UPDATE_MANIFEST_DEFAULT_NAME @@ -39,7 +41,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path); * Gets update package index to pass in RTC registers * @param storage Storage API * @param update_package_dir Package directory name - * @return int32_t <0 - error, >= 0 - update index value + * @return int32_t <=0 - error, >0 - update index value */ int32_t update_operation_get_package_index(Storage* storage, const char* update_package_dir); @@ -55,10 +57,10 @@ bool update_operation_get_current_package_path(Storage* storage, string_t out_pa * Stores given update index in RTC registers * @param index Value to store */ -void update_operation_persist_package_index(uint32_t index); +void update_operation_persist_package_index(int32_t index); /* - * Sets up update operation to be performed on reset + * Checks if an update operation step is pending after reset */ bool update_operation_is_armed(); From 5171a6ad145a4042cc86e9f953594174b0dfc637 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Fri, 6 May 2022 19:48:39 +0300 Subject: [PATCH 08/24] [FL-2514] Port iButton application to C (#1198) * Initial C iButton app setup * Add more scenes * Add even more scenes * Add even more scenes again * More scenes... * Add key info scene * Add delete success scene * Use scene state to store internal data * Add parameter parsing * Add emulate scene * Add write scene * Add write success scene * Add Read scene * Add read success scene * Add exit confirm scene * Add retry confirm scene * Add CRC error scene * Add not key scene * Add read key menu scene * Rename some scenes * Refactor conditionals * Remove unneeded custom events * Remove the old iButton app * Correct formatting * Remove rogue comments and function prototypes * iButton: cleanup merge artifacts and fix warnings Co-authored-by: Aleksandr Kutuzov --- applications/ibutton/ibutton.c | 349 ++++++++++++++++++ applications/ibutton/ibutton.cpp | 10 - applications/ibutton/ibutton.h | 3 + applications/ibutton/ibutton_app.cpp | 342 ----------------- applications/ibutton/ibutton_app.h | 144 -------- applications/ibutton/ibutton_custom_event.h | 12 + applications/ibutton/ibutton_event.h | 36 -- applications/ibutton/ibutton_i.h | 86 +++++ applications/ibutton/ibutton_view_manager.cpp | 140 ------- applications/ibutton/ibutton_view_manager.h | 51 --- .../ibutton/scene/ibutton_scene_add_type.cpp | 66 ---- .../ibutton/scene/ibutton_scene_add_type.h | 12 - .../ibutton/scene/ibutton_scene_add_value.cpp | 53 --- .../ibutton/scene/ibutton_scene_add_value.h | 13 - .../scene/ibutton_scene_delete_confirm.cpp | 86 ----- .../scene/ibutton_scene_delete_confirm.h | 9 - .../scene/ibutton_scene_delete_success.cpp | 47 --- .../scene/ibutton_scene_delete_success.h | 9 - .../ibutton/scene/ibutton_scene_emulate.h | 9 - .../scene/ibutton_scene_exit_confirm.cpp | 51 --- .../scene/ibutton_scene_exit_confirm.h | 9 - .../ibutton/scene/ibutton_scene_generic.h | 14 - .../ibutton/scene/ibutton_scene_info.cpp | 58 --- .../ibutton/scene/ibutton_scene_info.h | 9 - .../ibutton/scene/ibutton_scene_read.cpp | 72 ---- .../ibutton/scene/ibutton_scene_read.h | 9 - .../scene/ibutton_scene_read_crc_error.cpp | 74 ---- .../scene/ibutton_scene_read_crc_error.h | 9 - .../scene/ibutton_scene_read_key_menu.cpp | 65 ---- .../scene/ibutton_scene_read_key_menu.h | 12 - .../ibutton_scene_read_not_key_error.cpp | 74 ---- .../scene/ibutton_scene_read_not_key_error.h | 9 - .../scene/ibutton_scene_read_success.cpp | 86 ----- .../scene/ibutton_scene_read_success.h | 9 - .../scene/ibutton_scene_retry_confirm.cpp | 51 --- .../scene/ibutton_scene_retry_confirm.h | 9 - .../ibutton/scene/ibutton_scene_save_name.cpp | 70 ---- .../ibutton/scene/ibutton_scene_save_name.h | 9 - .../scene/ibutton_scene_save_success.cpp | 52 --- .../scene/ibutton_scene_save_success.h | 9 - .../scene/ibutton_scene_saved_key_menu.cpp | 73 ---- .../scene/ibutton_scene_saved_key_menu.h | 12 - .../scene/ibutton_scene_select_key.cpp | 18 - .../ibutton/scene/ibutton_scene_select_key.h | 9 - .../ibutton/scene/ibutton_scene_start.cpp | 60 --- .../ibutton/scene/ibutton_scene_start.h | 12 - .../ibutton/scene/ibutton_scene_write.cpp | 111 ------ .../ibutton/scene/ibutton_scene_write.h | 12 - .../scene/ibutton_scene_write_success.cpp | 52 --- .../scene/ibutton_scene_write_success.h | 9 - applications/ibutton/scenes/ibutton_scene.c | 30 ++ applications/ibutton/scenes/ibutton_scene.h | 29 ++ .../ibutton/scenes/ibutton_scene_add_type.c | 58 +++ .../ibutton/scenes/ibutton_scene_add_value.c | 57 +++ .../ibutton/scenes/ibutton_scene_config.h | 20 + .../scenes/ibutton_scene_delete_confirm.c | 91 +++++ .../scenes/ibutton_scene_delete_success.c | 48 +++ .../ibutton_scene_emulate.c} | 66 ++-- .../scenes/ibutton_scene_exit_confirm.c | 51 +++ .../ibutton/scenes/ibutton_scene_info.c | 61 +++ .../ibutton/scenes/ibutton_scene_read.c | 72 ++++ .../scenes/ibutton_scene_read_crc_error.c | 71 ++++ .../scenes/ibutton_scene_read_key_menu.c | 61 +++ .../scenes/ibutton_scene_read_not_key_error.c | 72 ++++ .../scenes/ibutton_scene_read_success.c | 87 +++++ .../scenes/ibutton_scene_retry_confirm.c | 51 +++ .../ibutton/scenes/ibutton_scene_save_name.c | 68 ++++ .../scenes/ibutton_scene_save_success.c | 52 +++ .../scenes/ibutton_scene_saved_key_menu.c | 75 ++++ .../ibutton/scenes/ibutton_scene_select_key.c | 22 ++ .../ibutton/scenes/ibutton_scene_start.c | 51 +++ .../ibutton/scenes/ibutton_scene_write.c | 121 ++++++ .../scenes/ibutton_scene_write_success.c | 52 +++ 73 files changed, 1785 insertions(+), 2186 deletions(-) create mode 100644 applications/ibutton/ibutton.c delete mode 100644 applications/ibutton/ibutton.cpp create mode 100644 applications/ibutton/ibutton.h delete mode 100644 applications/ibutton/ibutton_app.cpp delete mode 100644 applications/ibutton/ibutton_app.h create mode 100644 applications/ibutton/ibutton_custom_event.h delete mode 100644 applications/ibutton/ibutton_event.h create mode 100644 applications/ibutton/ibutton_i.h delete mode 100755 applications/ibutton/ibutton_view_manager.cpp delete mode 100644 applications/ibutton/ibutton_view_manager.h delete mode 100644 applications/ibutton/scene/ibutton_scene_add_type.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_add_type.h delete mode 100755 applications/ibutton/scene/ibutton_scene_add_value.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_add_value.h delete mode 100755 applications/ibutton/scene/ibutton_scene_delete_confirm.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_delete_confirm.h delete mode 100644 applications/ibutton/scene/ibutton_scene_delete_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_delete_success.h delete mode 100644 applications/ibutton/scene/ibutton_scene_emulate.h delete mode 100644 applications/ibutton/scene/ibutton_scene_exit_confirm.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_exit_confirm.h delete mode 100644 applications/ibutton/scene/ibutton_scene_generic.h delete mode 100755 applications/ibutton/scene/ibutton_scene_info.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_info.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_crc_error.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_crc_error.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_key_menu.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_key_menu.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_not_key_error.h delete mode 100644 applications/ibutton/scene/ibutton_scene_read_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_read_success.h delete mode 100644 applications/ibutton/scene/ibutton_scene_retry_confirm.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_retry_confirm.h delete mode 100644 applications/ibutton/scene/ibutton_scene_save_name.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_save_name.h delete mode 100644 applications/ibutton/scene/ibutton_scene_save_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_save_success.h delete mode 100644 applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_saved_key_menu.h delete mode 100644 applications/ibutton/scene/ibutton_scene_select_key.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_select_key.h delete mode 100644 applications/ibutton/scene/ibutton_scene_start.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_start.h delete mode 100644 applications/ibutton/scene/ibutton_scene_write.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_write.h delete mode 100644 applications/ibutton/scene/ibutton_scene_write_success.cpp delete mode 100644 applications/ibutton/scene/ibutton_scene_write_success.h create mode 100644 applications/ibutton/scenes/ibutton_scene.c create mode 100644 applications/ibutton/scenes/ibutton_scene.h create mode 100644 applications/ibutton/scenes/ibutton_scene_add_type.c create mode 100644 applications/ibutton/scenes/ibutton_scene_add_value.c create mode 100644 applications/ibutton/scenes/ibutton_scene_config.h create mode 100644 applications/ibutton/scenes/ibutton_scene_delete_confirm.c create mode 100644 applications/ibutton/scenes/ibutton_scene_delete_success.c rename applications/ibutton/{scene/ibutton_scene_emulate.cpp => scenes/ibutton_scene_emulate.c} (50%) create mode 100644 applications/ibutton/scenes/ibutton_scene_exit_confirm.c create mode 100644 applications/ibutton/scenes/ibutton_scene_info.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_crc_error.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_key_menu.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_not_key_error.c create mode 100644 applications/ibutton/scenes/ibutton_scene_read_success.c create mode 100644 applications/ibutton/scenes/ibutton_scene_retry_confirm.c create mode 100644 applications/ibutton/scenes/ibutton_scene_save_name.c create mode 100644 applications/ibutton/scenes/ibutton_scene_save_success.c create mode 100644 applications/ibutton/scenes/ibutton_scene_saved_key_menu.c create mode 100644 applications/ibutton/scenes/ibutton_scene_select_key.c create mode 100644 applications/ibutton/scenes/ibutton_scene_start.c create mode 100644 applications/ibutton/scenes/ibutton_scene_write.c create mode 100644 applications/ibutton/scenes/ibutton_scene_write_success.c diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c new file mode 100644 index 00000000000..a38f077f3f0 --- /dev/null +++ b/applications/ibutton/ibutton.c @@ -0,0 +1,349 @@ +#include "ibutton.h" +#include "ibutton_i.h" +#include "ibutton/scenes/ibutton_scene.h" + +#include +#include + +static const NotificationSequence* ibutton_notification_sequences[] = { + &sequence_error, + &sequence_success, + &sequence_blink_cyan_10, + &sequence_blink_magenta_10, + &sequence_blink_yellow_10, + &sequence_set_red_255, + &sequence_reset_red, + &sequence_set_green_255, + &sequence_reset_green, +}; + +static void ibutton_make_app_folder(iButton* ibutton) { + if(!storage_simply_mkdir(ibutton->storage, IBUTTON_APP_FOLDER)) { + dialog_message_show_storage_error(ibutton->dialogs, "Cannot create\napp folder"); + } +} + +static bool ibutton_load_key_data(iButton* ibutton, string_t key_path) { + FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); + bool result = false; + string_t data; + string_init(data); + + do { + if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break; + + // header + uint32_t version; + if(!flipper_format_read_header(file, data, &version)) break; + if(string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break; + if(version != 1) break; + + // key type + iButtonKeyType type; + if(!flipper_format_read_string(file, "Key type", data)) break; + if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break; + + // key data + uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0}; + if(!flipper_format_read_hex(file, "Data", key_data, ibutton_key_get_size_by_type(type))) + break; + + ibutton_key_set_type(ibutton->key, type); + ibutton_key_set_data(ibutton->key, key_data, IBUTTON_KEY_DATA_SIZE); + + result = true; + } while(false); + + flipper_format_free(file); + string_clear(data); + + if(!result) { + dialog_message_show_storage_error(ibutton->dialogs, "Cannot load\nkey file"); + } + + return result; +} + +bool ibutton_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + iButton* ibutton = context; + return scene_manager_handle_custom_event(ibutton->scene_manager, event); +} + +bool ibutton_back_event_callback(void* context) { + furi_assert(context); + iButton* ibutton = context; + return scene_manager_handle_back_event(ibutton->scene_manager); +} + +void ibutton_tick_event_callback(void* context) { + furi_assert(context); + iButton* ibutton = context; + scene_manager_handle_tick_event(ibutton->scene_manager); +} + +iButton* ibutton_alloc() { + iButton* ibutton = malloc(sizeof(iButton)); + + ibutton->scene_manager = scene_manager_alloc(&ibutton_scene_handlers, ibutton); + + ibutton->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(ibutton->view_dispatcher); + view_dispatcher_set_event_callback_context(ibutton->view_dispatcher, ibutton); + view_dispatcher_set_custom_event_callback( + ibutton->view_dispatcher, ibutton_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + ibutton->view_dispatcher, ibutton_back_event_callback); + view_dispatcher_set_tick_event_callback( + ibutton->view_dispatcher, ibutton_tick_event_callback, 100); + + ibutton->gui = furi_record_open("gui"); + view_dispatcher_attach_to_gui( + ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen); + + ibutton->storage = furi_record_open("storage"); + ibutton->dialogs = furi_record_open("dialogs"); + ibutton->notifications = furi_record_open("notification"); + + ibutton->key = ibutton_key_alloc(); + ibutton->key_worker = ibutton_worker_alloc(); + ibutton_worker_start_thread(ibutton->key_worker); + + ibutton->submenu = submenu_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewSubmenu, submenu_get_view(ibutton->submenu)); + + ibutton->byte_input = byte_input_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewByteInput, byte_input_get_view(ibutton->byte_input)); + + ibutton->text_input = text_input_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewTextInput, text_input_get_view(ibutton->text_input)); + + ibutton->popup = popup_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewPopup, popup_get_view(ibutton->popup)); + + ibutton->widget = widget_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewWidget, widget_get_view(ibutton->widget)); + + ibutton->dialog_ex = dialog_ex_alloc(); + view_dispatcher_add_view( + ibutton->view_dispatcher, iButtonViewDialogEx, dialog_ex_get_view(ibutton->dialog_ex)); + + return ibutton; +} + +void ibutton_free(iButton* ibutton) { + furi_assert(ibutton); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewDialogEx); + dialog_ex_free(ibutton->dialog_ex); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewWidget); + widget_free(ibutton->widget); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewPopup); + popup_free(ibutton->popup); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewTextInput); + text_input_free(ibutton->text_input); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewByteInput); + byte_input_free(ibutton->byte_input); + + view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewSubmenu); + submenu_free(ibutton->submenu); + + view_dispatcher_free(ibutton->view_dispatcher); + scene_manager_free(ibutton->scene_manager); + + furi_record_close("storage"); + ibutton->storage = NULL; + + furi_record_close("notification"); + ibutton->notifications = NULL; + + furi_record_close("dialogs"); + ibutton->dialogs = NULL; + + furi_record_close("gui"); + ibutton->gui = NULL; + + ibutton_worker_stop_thread(ibutton->key_worker); + ibutton_worker_free(ibutton->key_worker); + ibutton_key_free(ibutton->key); + + free(ibutton); +} + +bool ibutton_file_select(iButton* ibutton) { + bool success = dialog_file_select_show( + ibutton->dialogs, + IBUTTON_APP_FOLDER, + IBUTTON_APP_EXTENSION, + ibutton->file_name, + IBUTTON_FILE_NAME_SIZE, + ibutton_key_get_name_p(ibutton->key)); + + if(success) { + string_t key_str; + string_init_printf( + key_str, "%s/%s%s", IBUTTON_APP_FOLDER, ibutton->file_name, IBUTTON_APP_EXTENSION); + success = ibutton_load_key_data(ibutton, key_str); + + if(success) { + ibutton_key_set_name(ibutton->key, ibutton->file_name); + } + + string_clear(key_str); + } + + return success; +} + +bool ibutton_load_key(iButton* ibutton, const char* key_name) { + string_t key_path; + string_init_set_str(key_path, key_name); + + const bool success = ibutton_load_key_data(ibutton, key_path); + + if(success) { + path_extract_filename_no_ext(key_name, key_path); + ibutton_key_set_name(ibutton->key, string_get_cstr(key_path)); + } + + string_clear(key_path); + return success; +} + +bool ibutton_save_key(iButton* ibutton, const char* key_name) { + // Create ibutton directory if necessary + ibutton_make_app_folder(ibutton); + + FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); + iButtonKey* key = ibutton->key; + + string_t key_file_name; + bool result = false; + string_init(key_file_name); + + do { + // First remove key if it was saved (we rename the key) + if(!ibutton_delete_key(ibutton)) break; + + // Save the key + ibutton_key_set_name(key, key_name); + + // Set full file name, for new key + string_printf( + key_file_name, + "%s/%s%s", + IBUTTON_APP_FOLDER, + ibutton_key_get_name_p(key), + IBUTTON_APP_EXTENSION); + + // Open file for write + if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break; + + // Write header + if(!flipper_format_write_header_cstr(file, IBUTTON_APP_FILE_TYPE, 1)) break; + + // Write key type + if(!flipper_format_write_comment_cstr(file, "Key type can be Cyfral, Dallas or Metakom")) + break; + const char* key_type = ibutton_key_get_string_by_type(ibutton_key_get_type(key)); + if(!flipper_format_write_string_cstr(file, "Key type", key_type)) break; + + // Write data + if(!flipper_format_write_comment_cstr( + file, "Data size for Cyfral is 2, for Metakom is 4, for Dallas is 8")) + break; + + if(!flipper_format_write_hex( + file, "Data", ibutton_key_get_data_p(key), ibutton_key_get_data_size(key))) + break; + result = true; + + } while(false); + + flipper_format_free(file); + + string_clear(key_file_name); + + if(!result) { + dialog_message_show_storage_error(ibutton->dialogs, "Cannot save\nkey file"); + } + + return result; +} + +bool ibutton_delete_key(iButton* ibutton) { + string_t file_name; + bool result = false; + + string_init_printf( + file_name, + "%s/%s%s", + IBUTTON_APP_FOLDER, + ibutton_key_get_name_p(ibutton->key), + IBUTTON_APP_EXTENSION); + result = storage_simply_remove(ibutton->storage, string_get_cstr(file_name)); + string_clear(file_name); + + return result; +} + +void ibutton_text_store_set(iButton* ibutton, const char* text, ...) { + va_list args; + va_start(args, text); + + vsnprintf(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE, text, args); + + va_end(args); +} + +void ibutton_text_store_clear(iButton* ibutton) { + memset(ibutton->text_store, 0, IBUTTON_TEXT_STORE_SIZE); +} + +void ibutton_switch_to_previous_scene_one_of( + iButton* ibutton, + const uint32_t* scene_ids, + size_t scene_ids_size) { + furi_assert(scene_ids_size); + SceneManager* scene_manager = ibutton->scene_manager; + + for(size_t i = 0; i < scene_ids_size; ++i) { + const uint32_t scene_id = scene_ids[i]; + if(scene_manager_has_previous_scene(scene_manager, scene_id)) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, scene_id); + return; + } + } +} + +void ibutton_notification_message(iButton* ibutton, uint32_t message) { + furi_assert(message < sizeof(ibutton_notification_sequences) / sizeof(NotificationSequence*)); + notification_message(ibutton->notifications, ibutton_notification_sequences[message]); +} + +int32_t ibutton_app(void* p) { + iButton* ibutton = ibutton_alloc(); + + ibutton_make_app_folder(ibutton); + + if(p && ibutton_load_key(ibutton, (const char*)p)) { + // TODO: Display an error if the key from p could not be loaded + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); + } else { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart); + } + + view_dispatcher_run(ibutton->view_dispatcher); + + ibutton_free(ibutton); + return 0; +} diff --git a/applications/ibutton/ibutton.cpp b/applications/ibutton/ibutton.cpp deleted file mode 100644 index aae0d31738c..00000000000 --- a/applications/ibutton/ibutton.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "ibutton_app.h" - -// app enter function -extern "C" int32_t ibutton_app(void* p) { - iButtonApp* app = new iButtonApp(); - app->run(p); - delete app; - - return 255; -} diff --git a/applications/ibutton/ibutton.h b/applications/ibutton/ibutton.h new file mode 100644 index 00000000000..56d6e3b6b3e --- /dev/null +++ b/applications/ibutton/ibutton.h @@ -0,0 +1,3 @@ +#pragma once + +typedef struct iButton iButton; diff --git a/applications/ibutton/ibutton_app.cpp b/applications/ibutton/ibutton_app.cpp deleted file mode 100644 index 43eb3692498..00000000000 --- a/applications/ibutton/ibutton_app.cpp +++ /dev/null @@ -1,342 +0,0 @@ -#include "ibutton_app.h" -#include -#include -#include -#include -#include - -const char* iButtonApp::app_folder = "/any/ibutton"; -const char* iButtonApp::app_extension = ".ibtn"; -const char* iButtonApp::app_filetype = "Flipper iButton key"; - -void iButtonApp::run(void* args) { - iButtonEvent event; - bool consumed; - bool exit = false; - - make_app_folder(); - - if(args && load_key((const char*)args)) { - current_scene = Scene::SceneEmulate; - } - - scenes[current_scene]->on_enter(this); - - while(!exit) { - view.receive_event(&event); - - consumed = scenes[current_scene]->on_event(this, &event); - - if(!consumed) { - if(event.type == iButtonEvent::Type::EventTypeBack) { - exit = switch_to_previous_scene(); - } - } - }; - - scenes[current_scene]->on_exit(this); -} - -iButtonApp::iButtonApp() - : notification{"notification"} - , storage{"storage"} - , dialogs{"dialogs"} { - key = ibutton_key_alloc(); - key_worker = ibutton_worker_alloc(); - ibutton_worker_start_thread(key_worker); -} - -iButtonApp::~iButtonApp() { - for(std::map::iterator it = scenes.begin(); it != scenes.end(); ++it) { - delete it->second; - } - scenes.clear(); - - ibutton_worker_stop_thread(key_worker); - ibutton_worker_free(key_worker); - ibutton_key_free(key); -} - -iButtonAppViewManager* iButtonApp::get_view_manager() { - return &view; -} - -void iButtonApp::switch_to_next_scene(Scene next_scene) { - previous_scenes_list.push_front(current_scene); - - if(next_scene != Scene::SceneExit) { - scenes[current_scene]->on_exit(this); - current_scene = next_scene; - scenes[current_scene]->on_enter(this); - } -} - -void iButtonApp::search_and_switch_to_previous_scene(std::initializer_list scenes_list) { - Scene previous_scene = Scene::SceneStart; - bool scene_found = false; - - while(!scene_found) { - previous_scene = get_previous_scene(); - for(Scene element : scenes_list) { - if(previous_scene == element || previous_scene == Scene::SceneStart) { - scene_found = true; - break; - } - } - } - - scenes[current_scene]->on_exit(this); - current_scene = previous_scene; - scenes[current_scene]->on_enter(this); -} - -bool iButtonApp::switch_to_previous_scene(uint8_t count) { - Scene previous_scene = Scene::SceneStart; - - for(uint8_t i = 0; i < count; i++) { - previous_scene = get_previous_scene(); - if(previous_scene == Scene::SceneExit) break; - } - - if(previous_scene == Scene::SceneExit) { - return true; - } else { - scenes[current_scene]->on_exit(this); - current_scene = previous_scene; - scenes[current_scene]->on_enter(this); - return false; - } -} - -iButtonApp::Scene iButtonApp::get_previous_scene() { - Scene scene = previous_scenes_list.front(); - previous_scenes_list.pop_front(); - return scene; -} - -iButtonWorker* iButtonApp::get_key_worker() { - return key_worker; -} - -iButtonKey* iButtonApp::get_key() { - return key; -} - -char* iButtonApp::get_file_name() { - return file_name; -} - -uint8_t iButtonApp::get_file_name_size() { - return file_name_size; -} - -void iButtonApp::notify_read() { - notification_message(notification, &sequence_blink_cyan_10); -} - -void iButtonApp::notify_emulate() { - notification_message(notification, &sequence_blink_magenta_10); -} - -void iButtonApp::notify_yellow_blink() { - notification_message(notification, &sequence_blink_yellow_10); -} - -void iButtonApp::notify_error() { - notification_message(notification, &sequence_error); -} - -void iButtonApp::notify_success() { - notification_message(notification, &sequence_success); -} - -void iButtonApp::notify_green_on() { - notification_message_block(notification, &sequence_set_green_255); -} - -void iButtonApp::notify_green_off() { - notification_message(notification, &sequence_reset_green); -} - -void iButtonApp::notify_red_on() { - notification_message_block(notification, &sequence_set_red_255); -} - -void iButtonApp::notify_red_off() { - notification_message(notification, &sequence_reset_red); -} - -void iButtonApp::set_text_store(const char* text...) { - va_list args; - va_start(args, text); - - vsnprintf(text_store, text_store_size, text, args); - - va_end(args); -} - -char* iButtonApp::get_text_store() { - return text_store; -} - -uint8_t iButtonApp::get_text_store_size() { - return text_store_size; -} - -// file managment -bool iButtonApp::save_key(const char* key_name) { - // Create ibutton directory if necessary - make_app_folder(); - - FlipperFormat* file = flipper_format_file_alloc(storage); - string_t key_file_name; - bool result = false; - string_init(key_file_name); - - do { - // First remove key if it was saved (we rename the key) - if(!delete_key()) break; - - // Save the key - ibutton_key_set_name(key, key_name); - - // Set full file name, for new key - string_printf( - key_file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension); - - // Open file for write - if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break; - - // Write header - if(!flipper_format_write_header_cstr(file, iButtonApp::app_filetype, 1)) break; - - // Write key type - if(!flipper_format_write_comment_cstr(file, "Key type can be Cyfral, Dallas or Metakom")) - break; - const char* key_type = ibutton_key_get_string_by_type(ibutton_key_get_type(key)); - if(!flipper_format_write_string_cstr(file, "Key type", key_type)) break; - - // Write data - if(!flipper_format_write_comment_cstr( - file, "Data size for Cyfral is 2, for Metakom is 4, for Dallas is 8")) - break; - - if(!flipper_format_write_hex( - file, "Data", ibutton_key_get_data_p(key), ibutton_key_get_data_size(key))) - break; - result = true; - - } while(false); - - flipper_format_free(file); - - string_clear(key_file_name); - - if(!result) { - dialog_message_show_storage_error(dialogs, "Cannot save\nkey file"); - } - - return result; -} - -bool iButtonApp::load_key_data(string_t key_path) { - FlipperFormat* file = flipper_format_file_alloc(storage); - bool result = false; - string_t data; - string_init(data); - - do { - if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break; - - // header - uint32_t version; - if(!flipper_format_read_header(file, data, &version)) break; - if(string_cmp_str(data, iButtonApp::app_filetype) != 0) break; - if(version != 1) break; - - // key type - iButtonKeyType type; - if(!flipper_format_read_string(file, "Key type", data)) break; - if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break; - - // key data - uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0}; - if(!flipper_format_read_hex(file, "Data", key_data, ibutton_key_get_size_by_type(type))) - break; - - ibutton_key_set_type(key, type); - ibutton_key_set_data(key, key_data, IBUTTON_KEY_DATA_SIZE); - - result = true; - } while(false); - - flipper_format_free(file); - string_clear(data); - - if(!result) { - dialog_message_show_storage_error(dialogs, "Cannot load\nkey file"); - } - - return result; -} - -bool iButtonApp::load_key(const char* key_name) { - bool result = false; - string_t key_path; - - string_init_set_str(key_path, key_name); - - result = load_key_data(key_path); - if(result) { - path_extract_filename_no_ext(key_name, key_path); - ibutton_key_set_name(key, string_get_cstr(key_path)); - } - string_clear(key_path); - return result; -} - -bool iButtonApp::load_key() { - bool result = false; - - // Input events and views are managed by file_select - bool res = dialog_file_select_show( - dialogs, - app_folder, - app_extension, - get_file_name(), - get_file_name_size(), - ibutton_key_get_name_p(key)); - - if(res) { - string_t key_str; - - // Get key file path - string_init_printf(key_str, "%s/%s%s", app_folder, get_file_name(), app_extension); - - result = load_key_data(key_str); - if(result) { - ibutton_key_set_name(key, get_file_name()); - } - string_clear(key_str); - } - - return result; -} - -bool iButtonApp::delete_key() { - string_t file_name; - bool result = false; - - string_init_printf( - file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension); - result = storage_simply_remove(storage, string_get_cstr(file_name)); - string_clear(file_name); - - return result; -} - -void iButtonApp::make_app_folder() { - if(!storage_simply_mkdir(storage, app_folder)) { - dialog_message_show_storage_error(dialogs, "Cannot create\napp folder"); - } -} diff --git a/applications/ibutton/ibutton_app.h b/applications/ibutton/ibutton_app.h deleted file mode 100644 index 08af38573a8..00000000000 --- a/applications/ibutton/ibutton_app.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once -#include -#include - -#include "ibutton_view_manager.h" -#include "scene/ibutton_scene_generic.h" -#include "scene/ibutton_scene_start.h" -#include "scene/ibutton_scene_read.h" -#include "scene/ibutton_scene_read_crc_error.h" -#include "scene/ibutton_scene_read_not_key_error.h" -#include "scene/ibutton_scene_read_success.h" -#include "scene/ibutton_scene_retry_confirm.h" -#include "scene/ibutton_scene_exit_confirm.h" -#include "scene/ibutton_scene_read_key_menu.h" -#include "scene/ibutton_scene_write.h" -#include "scene/ibutton_scene_write_success.h" -#include "scene/ibutton_scene_saved_key_menu.h" -#include "scene/ibutton_scene_delete_confirm.h" -#include "scene/ibutton_scene_delete_success.h" -#include "scene/ibutton_scene_emulate.h" -#include "scene/ibutton_scene_save_name.h" -#include "scene/ibutton_scene_save_success.h" -#include "scene/ibutton_scene_info.h" -#include "scene/ibutton_scene_select_key.h" -#include "scene/ibutton_scene_add_type.h" -#include "scene/ibutton_scene_add_value.h" -#include -#include -#include -#include -#include - -class iButtonApp { -public: - void run(void* args); - - iButtonApp(); - ~iButtonApp(); - - enum class Scene : uint8_t { - SceneExit, - SceneStart, - SceneRead, - SceneReadNotKeyError, - SceneReadCRCError, - SceneReadSuccess, - SceneRetryConfirm, - SceneExitConfirm, - SceneReadKeyMenu, - SceneWrite, - SceneWriteSuccess, - SceneEmulate, - SceneSavedKeyMenu, - SceneDeleteConfirm, - SceneDeleteSuccess, - SceneSaveName, - SceneSaveSuccess, - SceneInfo, - SceneSelectKey, - SceneAddType, - SceneAddValue, - }; - - static const char* app_folder; - static const char* app_extension; - static const char* app_filetype; - - iButtonAppViewManager* get_view_manager(); - void switch_to_next_scene(Scene index); - void search_and_switch_to_previous_scene(std::initializer_list scenes_list); - bool switch_to_previous_scene(uint8_t count = 1); - Scene get_previous_scene(); - - const GpioPin* get_ibutton_pin(); - iButtonWorker* get_key_worker(); - iButtonKey* get_key(); - - void notify_read(); - void notify_yellow_blink(); - void notify_emulate(); - - void notify_error(); - void notify_success(); - void notify_green_on(); - void notify_green_off(); - void notify_red_on(); - void notify_red_off(); - - void set_text_store(const char* text...); - char* get_text_store(); - uint8_t get_text_store_size(); - - char* get_file_name(); - uint8_t get_file_name_size(); - - bool save_key(const char* key_name); - bool load_key(); - bool load_key(const char* key_name); - bool delete_key(); - -private: - std::list previous_scenes_list = {Scene::SceneExit}; - Scene current_scene = Scene::SceneStart; - iButtonAppViewManager view; - - std::map scenes = { - {Scene::SceneStart, new iButtonSceneStart()}, - {Scene::SceneRead, new iButtonSceneRead()}, - {Scene::SceneReadCRCError, new iButtonSceneReadCRCError()}, - {Scene::SceneReadNotKeyError, new iButtonSceneReadNotKeyError()}, - {Scene::SceneReadSuccess, new iButtonSceneReadSuccess()}, - {Scene::SceneRetryConfirm, new iButtonSceneRetryConfirm()}, - {Scene::SceneExitConfirm, new iButtonSceneExitConfirm()}, - {Scene::SceneReadKeyMenu, new iButtonSceneReadKeyMenu()}, - {Scene::SceneWrite, new iButtonSceneWrite()}, - {Scene::SceneWriteSuccess, new iButtonSceneWriteSuccess()}, - {Scene::SceneEmulate, new iButtonSceneEmulate()}, - {Scene::SceneSavedKeyMenu, new iButtonSceneSavedKeyMenu()}, - {Scene::SceneDeleteConfirm, new iButtonSceneDeleteConfirm()}, - {Scene::SceneDeleteSuccess, new iButtonSceneDeleteSuccess()}, - {Scene::SceneSaveName, new iButtonSceneSaveName()}, - {Scene::SceneSaveSuccess, new iButtonSceneSaveSuccess()}, - {Scene::SceneInfo, new iButtonSceneInfo()}, - {Scene::SceneSelectKey, new iButtonSceneSelectKey()}, - {Scene::SceneAddType, new iButtonSceneAddType()}, - {Scene::SceneAddValue, new iButtonSceneAddValue()}, - }; - - iButtonWorker* key_worker; - iButtonKey* key; - - RecordController notification; - RecordController storage; - RecordController dialogs; - - static const uint8_t file_name_size = 100; - char file_name[file_name_size]; - - static const uint8_t text_store_size = 128; - char text_store[text_store_size + 1]; - - bool load_key_data(string_t key_path); - void make_app_folder(); -}; diff --git a/applications/ibutton/ibutton_custom_event.h b/applications/ibutton/ibutton_custom_event.h new file mode 100644 index 00000000000..2be42d66daf --- /dev/null +++ b/applications/ibutton/ibutton_custom_event.h @@ -0,0 +1,12 @@ +#pragma once + +enum iButtonCustomEvent { + // Reserve first 100 events for button types and indexes, starting from 0 + iButtonCustomEventReserved = 100, + + iButtonCustomEventBack, + iButtonCustomEventTextEditResult, + iButtonCustomEventByteEditResult, + iButtonCustomEventWorkerEmulated, + iButtonCustomEventWorkerRead, +}; diff --git a/applications/ibutton/ibutton_event.h b/applications/ibutton/ibutton_event.h deleted file mode 100644 index 8b1775c1b4d..00000000000 --- a/applications/ibutton/ibutton_event.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include -#include -#include -#include - -class iButtonApp; - -class iButtonEvent { -public: - // events enum - enum class Type : uint8_t { - EventTypeTick, - EventTypeBack, - EventTypeMenuSelected, - EventTypeDialogResult, - EventTypeTextEditResult, - EventTypeByteEditResult, - EventTypeWidgetButtonResult, - EventTypeWorkerEmulated, - EventTypeWorkerRead, - EventTypeWorkerWrite, - }; - - // payload - union { - uint32_t dummy; - uint32_t menu_index; - DialogExResult dialog_result; - GuiButtonType widget_button_result; - iButtonWorkerWriteResult worker_write_result; - } payload; - - // event type - Type type; -}; diff --git a/applications/ibutton/ibutton_i.h b/applications/ibutton/ibutton_i.h new file mode 100644 index 00000000000..36857fd6479 --- /dev/null +++ b/applications/ibutton/ibutton_i.h @@ -0,0 +1,86 @@ +#pragma once + +#include "ibutton.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ibutton_custom_event.h" +#include "scenes/ibutton_scene.h" + +#define IBUTTON_FILE_NAME_SIZE 100 +#define IBUTTON_TEXT_STORE_SIZE 128 + +#define IBUTTON_APP_FOLDER "/any/ibutton" +#define IBUTTON_APP_EXTENSION ".ibtn" +#define IBUTTON_APP_FILE_TYPE "Flipper iButton key" + +struct iButton { + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + + Gui* gui; + Storage* storage; + DialogsApp* dialogs; + NotificationApp* notifications; + + iButtonWorker* key_worker; + iButtonKey* key; + + char file_name[IBUTTON_FILE_NAME_SIZE]; + char text_store[IBUTTON_TEXT_STORE_SIZE + 1]; + + Submenu* submenu; + ByteInput* byte_input; + TextInput* text_input; + Popup* popup; + Widget* widget; + DialogEx* dialog_ex; +}; + +typedef enum { + iButtonViewSubmenu, + iButtonViewByteInput, + iButtonViewTextInput, + iButtonViewPopup, + iButtonViewWidget, + iButtonViewDialogEx, +} iButtonView; + +typedef enum { + iButtonNotificationMessageError, + iButtonNotificationMessageSuccess, + iButtonNotificationMessageRead, + iButtonNotificationMessageEmulate, + iButtonNotificationMessageYellowBlink, + iButtonNotificationMessageRedOn, + iButtonNotificationMessageRedOff, + iButtonNotificationMessageGreenOn, + iButtonNotificationMessageGreenOff, +} iButtonNotificationMessage; + +bool ibutton_file_select(iButton* ibutton); +bool ibutton_load_key(iButton* ibutton, const char* key_name); +bool ibutton_save_key(iButton* ibutton, const char* key_name); +bool ibutton_delete_key(iButton* ibutton); +void ibutton_text_store_set(iButton* ibutton, const char* text, ...); +void ibutton_text_store_clear(iButton* ibutton); +void ibutton_switch_to_previous_scene_one_of( + iButton* ibutton, + const uint32_t* scene_ids, + size_t scene_ids_size); +void ibutton_notification_message(iButton* ibutton, uint32_t message); diff --git a/applications/ibutton/ibutton_view_manager.cpp b/applications/ibutton/ibutton_view_manager.cpp deleted file mode 100755 index 5a2c94f1e0b..00000000000 --- a/applications/ibutton/ibutton_view_manager.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "ibutton_view_manager.h" -#include "ibutton_event.h" -#include - -iButtonAppViewManager::iButtonAppViewManager() { - event_queue = osMessageQueueNew(10, sizeof(iButtonEvent), NULL); - - view_dispatcher = view_dispatcher_alloc(); - auto callback = cbc::obtain_connector(this, &iButtonAppViewManager::previous_view_callback); - - dialog_ex = dialog_ex_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewDialogEx), - dialog_ex_get_view(dialog_ex)); - - submenu = submenu_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewSubmenu), - submenu_get_view(submenu)); - - text_input = text_input_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewTextInput), - text_input_get_view(text_input)); - - byte_input = byte_input_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewByteInput), - byte_input_get_view(byte_input)); - - popup = popup_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewPopup), - popup_get_view(popup)); - - widget = widget_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewWidget), - widget_get_view(widget)); - - gui = static_cast(furi_record_open("gui")); - view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); - - //TODO think about that method, seems unsafe and over-engineered - view_set_previous_callback(dialog_ex_get_view(dialog_ex), callback); - view_set_previous_callback(submenu_get_view(submenu), callback); - view_set_previous_callback(text_input_get_view(text_input), callback); - view_set_previous_callback(byte_input_get_view(byte_input), callback); - view_set_previous_callback(popup_get_view(popup), callback); - view_set_previous_callback(widget_get_view(widget), callback); -} - -iButtonAppViewManager::~iButtonAppViewManager() { - // remove views - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewDialogEx)); - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewSubmenu)); - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewTextInput)); - view_dispatcher_remove_view( - view_dispatcher, static_cast(iButtonAppViewManager::Type::iButtonAppViewPopup)); - view_dispatcher_remove_view( - view_dispatcher, - static_cast(iButtonAppViewManager::Type::iButtonAppViewByteInput)); - view_dispatcher_remove_view( - view_dispatcher, static_cast(iButtonAppViewManager::Type::iButtonAppViewWidget)); - - // free view modules - popup_free(popup); - text_input_free(text_input); - byte_input_free(byte_input); - submenu_free(submenu); - dialog_ex_free(dialog_ex); - widget_free(widget); - - // free dispatcher - view_dispatcher_free(view_dispatcher); - - // free event queue - osMessageQueueDelete(event_queue); -} - -void iButtonAppViewManager::switch_to(Type type) { - view_dispatcher_switch_to_view(view_dispatcher, static_cast(type)); -} - -Submenu* iButtonAppViewManager::get_submenu() { - return submenu; -} - -Popup* iButtonAppViewManager::get_popup() { - return popup; -} - -DialogEx* iButtonAppViewManager::get_dialog_ex() { - return dialog_ex; -} - -TextInput* iButtonAppViewManager::get_text_input() { - return text_input; -} - -ByteInput* iButtonAppViewManager::get_byte_input() { - return byte_input; -} - -Widget* iButtonAppViewManager::get_widget() { - return widget; -} - -void iButtonAppViewManager::receive_event(iButtonEvent* event) { - if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { - event->type = iButtonEvent::Type::EventTypeTick; - } -} - -void iButtonAppViewManager::send_event(iButtonEvent* event) { - osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); - furi_check(result == osOK); -} - -uint32_t iButtonAppViewManager::previous_view_callback(void*) { - if(event_queue != NULL) { - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - send_event(&event); - } - - return VIEW_IGNORE; -} diff --git a/applications/ibutton/ibutton_view_manager.h b/applications/ibutton/ibutton_view_manager.h deleted file mode 100644 index 336ba6e2fa2..00000000000 --- a/applications/ibutton/ibutton_view_manager.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include "ibutton_event.h" - -class iButtonAppViewManager { -public: - enum class Type : uint8_t { - iButtonAppViewTextInput, - iButtonAppViewByteInput, - iButtonAppViewSubmenu, - iButtonAppViewDialogEx, - iButtonAppViewPopup, - iButtonAppViewWidget, - }; - - osMessageQueueId_t event_queue; - - iButtonAppViewManager(); - ~iButtonAppViewManager(); - - void switch_to(Type type); - - Submenu* get_submenu(); - Popup* get_popup(); - DialogEx* get_dialog_ex(); - TextInput* get_text_input(); - ByteInput* get_byte_input(); - Widget* get_widget(); - - void receive_event(iButtonEvent* event); - void send_event(iButtonEvent* event); - -private: - ViewDispatcher* view_dispatcher; - DialogEx* dialog_ex; - Submenu* submenu; - TextInput* text_input; - ByteInput* byte_input; - Popup* popup; - Widget* widget; - Gui* gui; - - uint32_t previous_view_callback(void* context); -}; diff --git a/applications/ibutton/scene/ibutton_scene_add_type.cpp b/applications/ibutton/scene/ibutton_scene_add_type.cpp deleted file mode 100644 index c9537768b21..00000000000 --- a/applications/ibutton/scene/ibutton_scene_add_type.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "ibutton_scene_add_type.h" -#include "../ibutton_app.h" -#include - -typedef enum { - SubmenuIndexCyfral, - SubmenuIndexDallas, - SubmenuIndexMetakom, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneAddType::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Cyfral", SubmenuIndexCyfral, submenu_callback, app); - submenu_add_item(submenu, "Dallas", SubmenuIndexDallas, submenu_callback, app); - submenu_add_item(submenu, "Metakom", SubmenuIndexMetakom, submenu_callback, app); - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneAddType::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - iButtonKey* key = app->get_key(); - - switch(event->payload.menu_index) { - case SubmenuIndexCyfral: - ibutton_key_set_type(key, iButtonKeyCyfral); - break; - case SubmenuIndexDallas: - ibutton_key_set_type(key, iButtonKeyDS1990); - break; - case SubmenuIndexMetakom: - ibutton_key_set_type(key, iButtonKeyMetakom); - break; - } - ibutton_key_set_name(key, ""); - ibutton_key_clear_data(key); - app->switch_to_next_scene(iButtonApp::Scene::SceneAddValue); - consumed = true; - } - - return consumed; -} - -void iButtonSceneAddType::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_add_type.h b/applications/ibutton/scene/ibutton_scene_add_type.h deleted file mode 100644 index 6a3d07e591f..00000000000 --- a/applications/ibutton/scene/ibutton_scene_add_type.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneAddType : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_add_value.cpp b/applications/ibutton/scene/ibutton_scene_add_value.cpp deleted file mode 100755 index d0108ae5764..00000000000 --- a/applications/ibutton/scene/ibutton_scene_add_value.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "ibutton_scene_add_value.h" -#include "../ibutton_app.h" -#include - -static void byte_input_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeByteEditResult; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneAddValue::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - ByteInput* byte_input = view_manager->get_byte_input(); - iButtonKey* key = app->get_key(); - - memcpy(this->new_key_data, ibutton_key_get_data_p(key), ibutton_key_get_data_size(key)); - - byte_input_set_result_callback( - byte_input, - byte_input_callback, - NULL, - app, - this->new_key_data, - ibutton_key_get_data_size(key)); - - byte_input_set_header_text(byte_input, "Enter the key"); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewByteInput); -} - -bool iButtonSceneAddValue::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeByteEditResult) { - ibutton_key_set_data(app->get_key(), this->new_key_data, IBUTTON_KEY_DATA_SIZE); - DOLPHIN_DEED(DolphinDeedIbuttonAdd); - app->switch_to_next_scene(iButtonApp::Scene::SceneSaveName); - consumed = true; - } - - return consumed; -} - -void iButtonSceneAddValue::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - ByteInput* byte_input = view_manager->get_byte_input(); - - byte_input_set_result_callback(byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(byte_input, {0}); -} diff --git a/applications/ibutton/scene/ibutton_scene_add_value.h b/applications/ibutton/scene/ibutton_scene_add_value.h deleted file mode 100644 index 7a734160397..00000000000 --- a/applications/ibutton/scene/ibutton_scene_add_value.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" -#include - -class iButtonSceneAddValue : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint8_t new_key_data[IBUTTON_KEY_DATA_SIZE] = {}; -}; diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp b/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp deleted file mode 100755 index 8e782e33014..00000000000 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "ibutton_scene_delete_confirm.h" -#include "../ibutton_app.h" - -static void widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - app->get_view_manager()->send_event(&event); - } -} - -void iButtonSceneDeleteConfirm::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - iButtonKey* key = app->get_key(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - - app->set_text_store("\e#Delete %s?\e#", ibutton_key_get_name_p(key)); - widget_add_text_box_element( - widget, 0, 0, 128, 27, AlignCenter, AlignCenter, app->get_text_store(), false); - widget_add_button_element(widget, GuiButtonTypeLeft, "Cancel", widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Delete", widget_callback, app); - - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "%02X %02X %02X %02X %02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); - break; - case iButtonKeyCyfral: - app->set_text_store("%02X %02X", key_data[0], key_data[1]); - widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); - break; - case iButtonKeyMetakom: - app->set_text_store( - "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom"); - break; - } - widget_add_string_element( - widget, 64, 33, AlignCenter, AlignBottom, FontSecondary, app->get_text_store()); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneDeleteConfirm::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { - if(event->payload.widget_button_result == GuiButtonTypeRight) { - if(app->delete_key()) { - app->switch_to_next_scene(iButtonApp::Scene::SceneDeleteSuccess); - } - } else { - app->switch_to_previous_scene(); - } - - consumed = true; - } - - return consumed; -} - -void iButtonSceneDeleteConfirm::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - app->set_text_store(""); - - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.h b/applications/ibutton/scene/ibutton_scene_delete_confirm.h deleted file mode 100644 index cacbb7fe5e6..00000000000 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneDeleteConfirm : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.cpp b/applications/ibutton/scene/ibutton_scene_delete_success.cpp deleted file mode 100644 index ba1381610fc..00000000000 --- a/applications/ibutton/scene/ibutton_scene_delete_success.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "ibutton_scene_delete_success.h" -#include "../ibutton_app.h" - -static void popup_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneDeleteSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); - - popup_set_callback(popup, popup_callback); - popup_set_context(popup, app); - popup_set_timeout(popup, 1500); - popup_enable_timeout(popup); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); -} - -bool iButtonSceneDeleteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneSelectKey}); - consumed = true; - } - - return consumed; -} - -void iButtonSceneDeleteSuccess::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - - popup_disable_timeout(popup); - popup_set_context(popup, NULL); - popup_set_callback(popup, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.h b/applications/ibutton/scene/ibutton_scene_delete_success.h deleted file mode 100644 index 1fbe5230aed..00000000000 --- a/applications/ibutton/scene/ibutton_scene_delete_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneDeleteSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_emulate.h b/applications/ibutton/scene/ibutton_scene_emulate.h deleted file mode 100644 index 61107b94bb0..00000000000 --- a/applications/ibutton/scene/ibutton_scene_emulate.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneEmulate : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp b/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp deleted file mode 100644 index 2c9fe94cb3f..00000000000 --- a/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "ibutton_scene_exit_confirm.h" -#include "../ibutton_app.h" - -static void widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - app->get_view_manager()->send_event(&event); - } -} - -void iButtonSceneExitConfirm::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Stay", widget_callback, app); - widget_add_string_element( - widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu"); - widget_add_string_element( - widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneExitConfirm::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { - if(event->payload.widget_button_result == GuiButtonTypeLeft) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); - } else if(event->payload.widget_button_result == GuiButtonTypeRight) { - app->switch_to_previous_scene(); - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - consumed = true; - } - - return consumed; -} - -void iButtonSceneExitConfirm::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_exit_confirm.h b/applications/ibutton/scene/ibutton_scene_exit_confirm.h deleted file mode 100644 index f621a59a5ee..00000000000 --- a/applications/ibutton/scene/ibutton_scene_exit_confirm.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneExitConfirm : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_generic.h b/applications/ibutton/scene/ibutton_scene_generic.h deleted file mode 100644 index 0e2444b58ec..00000000000 --- a/applications/ibutton/scene/ibutton_scene_generic.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "../ibutton_event.h" - -class iButtonApp; - -class iButtonScene { -public: - virtual void on_enter(iButtonApp* app) = 0; - virtual bool on_event(iButtonApp* app, iButtonEvent* event) = 0; - virtual void on_exit(iButtonApp* app) = 0; - virtual ~iButtonScene(){}; - -private: -}; diff --git a/applications/ibutton/scene/ibutton_scene_info.cpp b/applications/ibutton/scene/ibutton_scene_info.cpp deleted file mode 100755 index dd779789293..00000000000 --- a/applications/ibutton/scene/ibutton_scene_info.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "ibutton_scene_info.h" -#include "../ibutton_app.h" - -void iButtonSceneInfo::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - iButtonKey* key = app->get_key(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - - app->set_text_store("%s", ibutton_key_get_name_p(key)); - widget_add_text_box_element( - widget, 0, 0, 128, 28, AlignCenter, AlignCenter, app->get_text_store(), false); - - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "%02X %02X %02X %02X %02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Dallas"); - break; - case iButtonKeyMetakom: - app->set_text_store( - "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Metakom"); - break; - case iButtonKeyCyfral: - app->set_text_store("%02X %02X", key_data[0], key_data[1]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); - break; - } - widget_add_string_element( - widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, app->get_text_store()); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneInfo::on_event(iButtonApp*, iButtonEvent*) { - return false; -} - -void iButtonSceneInfo::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - app->set_text_store(""); - - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_info.h b/applications/ibutton/scene/ibutton_scene_info.h deleted file mode 100644 index bbfb0c607c0..00000000000 --- a/applications/ibutton/scene/ibutton_scene_info.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneInfo : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read.cpp b/applications/ibutton/scene/ibutton_scene_read.cpp deleted file mode 100644 index 1cfdbfe320f..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "ibutton_scene_read.h" -#include "../ibutton_app.h" -#include - -static void read_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event = { - .payload = {.dummy = 0}, - .type = iButtonEvent::Type::EventTypeWorkerRead, - }; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneRead::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - iButtonKey* key = app->get_key(); - iButtonWorker* worker = app->get_key_worker(); - DOLPHIN_DEED(DolphinDeedIbuttonRead); - - popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom); - popup_set_text(popup, "waiting\nfor key ...", 95, 30, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - ibutton_key_set_name(key, ""); - - ibutton_worker_read_set_callback(worker, read_callback, app); - ibutton_worker_read_start(worker, key); -} - -bool iButtonSceneRead::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWorkerRead) { - consumed = true; - - iButtonKey* key = app->get_key(); - bool success = false; - if(ibutton_key_get_type(key) == iButtonKeyDS1990) { - if(!ibutton_key_dallas_crc_is_valid(key)) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadCRCError); - } else if(!ibutton_key_dallas_is_1990_key(key)) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadNotKeyError); - } else { - success = true; - } - } else { - success = true; - } - if(success) { - app->notify_success(); - app->notify_green_on(); - DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess); - app->switch_to_next_scene(iButtonApp::Scene::SceneReadSuccess); - } - } else if(event->type == iButtonEvent::Type::EventTypeTick) { - consumed = true; - app->notify_read(); - } - - return consumed; -} - -void iButtonSceneRead::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - ibutton_worker_stop(app->get_key_worker()); - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_read.h b/applications/ibutton/scene/ibutton_scene_read.h deleted file mode 100644 index 5654777847d..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneRead : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp deleted file mode 100644 index d9d3ffd5cc4..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "ibutton_scene_read_crc_error.h" -#include "../ibutton_app.h" -#include - -static void dialog_ex_callback(DialogExResult result, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadCRCError::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - const uint8_t* key_data = ibutton_key_get_data_p(app->get_key()); - - app->set_text_store( - "%02X %02X %02X %02X %02X %02X %02X %02X\nExpected CRC: %X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7], - maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); - - dialog_ex_set_header(dialog_ex, "CRC ERROR", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, app->get_text_store(), 64, 19, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, "Retry"); - dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); - dialog_ex_set_context(dialog_ex, app); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); - app->notify_error(); - app->notify_red_on(); -} - -bool iButtonSceneReadCRCError::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeDialogResult) { - if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); - } else { - app->switch_to_previous_scene(); - } - - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadCRCError::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - - app->set_text_store(""); - - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); - - app->notify_red_off(); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.h b/applications/ibutton/scene/ibutton_scene_read_crc_error.h deleted file mode 100644 index db72d068a32..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadCRCError : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp b/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp deleted file mode 100644 index 215eb76f65d..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "ibutton_scene_read_key_menu.h" -#include "../ibutton_app.h" - -typedef enum { - SubmenuIndexSave, - SubmenuIndexEmulate, - SubmenuIndexWrite, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadKeyMenu::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Save", SubmenuIndexSave, submenu_callback, app); - submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, submenu_callback, app); - if(ibutton_key_get_type(app->get_key()) == iButtonKeyDS1990) { - submenu_add_item(submenu, "Write", SubmenuIndexWrite, submenu_callback, app); - } - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneReadKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - switch(event->payload.menu_index) { - case SubmenuIndexWrite: - app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); - break; - case SubmenuIndexEmulate: - app->switch_to_next_scene(iButtonApp::Scene::SceneEmulate); - break; - case SubmenuIndexSave: - app->switch_to_next_scene(iButtonApp::Scene::SceneSaveName); - break; - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - app->switch_to_previous_scene(); - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadKeyMenu::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_key_menu.h b/applications/ibutton/scene/ibutton_scene_read_key_menu.h deleted file mode 100644 index d68a4d1db38..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_key_menu.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadKeyMenu : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp deleted file mode 100644 index 58ea853c181..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "ibutton_scene_read_not_key_error.h" -#include "../ibutton_app.h" -#include - -static void dialog_ex_callback(DialogExResult result, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadNotKeyError::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - const uint8_t* key_data = ibutton_key_get_data_p(app->get_key()); - - app->set_text_store( - "THIS IS NOT A KEY\n%02X %02X %02X %02X %02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7], - maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); - - dialog_ex_set_header(dialog_ex, "ERROR:", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, app->get_text_store(), 64, 19, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, "Retry"); - dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); - dialog_ex_set_context(dialog_ex, app); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); - app->notify_error(); - app->notify_red_on(); -} - -bool iButtonSceneReadNotKeyError::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeDialogResult) { - if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); - } else { - app->switch_to_previous_scene(); - } - - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadNotKeyError::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - - app->set_text_store(""); - - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); - - app->notify_red_off(); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h b/applications/ibutton/scene/ibutton_scene_read_not_key_error.h deleted file mode 100644 index 30d20033eaa..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadNotKeyError : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_read_success.cpp b/applications/ibutton/scene/ibutton_scene_read_success.cpp deleted file mode 100644 index c4523904d32..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_success.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "ibutton_scene_read_success.h" -#include "../ibutton_app.h" -#include - -static void dialog_ex_callback(DialogExResult result, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - iButtonKey* key = app->get_key(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "Dallas\n%02X %02X %02X %02X\n%02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - break; - case iButtonKeyCyfral: - app->set_text_store("Cyfral\n%02X %02X", key_data[0], key_data[1]); - break; - case iButtonKeyMetakom: - app->set_text_store( - "Metakom\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - break; - } - - dialog_ex_set_text(dialog_ex, app->get_text_store(), 95, 30, AlignCenter, AlignCenter); - dialog_ex_set_left_button_text(dialog_ex, "Retry"); - dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63); - dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); - dialog_ex_set_context(dialog_ex, app); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); -} - -bool iButtonSceneReadSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeDialogResult) { - if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); - } else { - app->switch_to_next_scene(iButtonApp::Scene::SceneRetryConfirm); - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - app->switch_to_next_scene(iButtonApp::Scene::SceneExitConfirm); - consumed = true; - } - - return consumed; -} - -void iButtonSceneReadSuccess::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - DialogEx* dialog_ex = view_manager->get_dialog_ex(); - - app->set_text_store(""); - - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_right_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); - dialog_ex_set_icon(dialog_ex, 0, 0, NULL); - - app->notify_green_off(); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_success.h b/applications/ibutton/scene/ibutton_scene_read_success.h deleted file mode 100644 index bf9003c2328..00000000000 --- a/applications/ibutton/scene/ibutton_scene_read_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneReadSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp b/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp deleted file mode 100644 index aa3483b3d39..00000000000 --- a/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "ibutton_scene_retry_confirm.h" -#include "../ibutton_app.h" - -static void widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - app->get_view_manager()->send_event(&event); - } -} - -void iButtonSceneRetryConfirm::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - - widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Stay", widget_callback, app); - widget_add_string_element( - widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?"); - widget_add_string_element( - widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); -} - -bool iButtonSceneRetryConfirm::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { - if(event->payload.widget_button_result == GuiButtonTypeLeft) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneRead}); - } else if(event->payload.widget_button_result == GuiButtonTypeRight) { - app->switch_to_previous_scene(); - } - consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeBack) { - consumed = true; - } - - return consumed; -} - -void iButtonSceneRetryConfirm::on_exit(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Widget* widget = view_manager->get_widget(); - widget_reset(widget); -} diff --git a/applications/ibutton/scene/ibutton_scene_retry_confirm.h b/applications/ibutton/scene/ibutton_scene_retry_confirm.h deleted file mode 100644 index 0fa71ad1110..00000000000 --- a/applications/ibutton/scene/ibutton_scene_retry_confirm.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneRetryConfirm : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_save_name.cpp b/applications/ibutton/scene/ibutton_scene_save_name.cpp deleted file mode 100644 index 71eee148bdd..00000000000 --- a/applications/ibutton/scene/ibutton_scene_save_name.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "ibutton_scene_save_name.h" -#include "../ibutton_app.h" -#include - -static void text_input_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeTextEditResult; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneSaveName::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - TextInput* text_input = view_manager->get_text_input(); - - const char* key_name = ibutton_key_get_name_p(app->get_key()); - bool key_name_empty = !strcmp(key_name, ""); - - if(key_name_empty) { - set_random_name(app->get_text_store(), app->get_text_store_size()); - } else { - app->set_text_store("%s", key_name); - } - - text_input_set_header_text(text_input, "Name the key"); - text_input_set_result_callback( - text_input, - text_input_callback, - app, - app->get_text_store(), - IBUTTON_KEY_NAME_SIZE, - key_name_empty); - - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(app->app_folder, app->app_extension, key_name); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewTextInput); -} - -bool iButtonSceneSaveName::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeTextEditResult) { - if(app->save_key(app->get_text_store())) { - app->switch_to_next_scene(iButtonApp::Scene::SceneSaveSuccess); - } else { - app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadKeyMenu, - iButtonApp::Scene::SceneSavedKeyMenu, - iButtonApp::Scene::SceneAddType}); - } - consumed = true; - } - - return consumed; -} - -void iButtonSceneSaveName::on_exit(iButtonApp* app) { - TextInput* text_input = app->get_view_manager()->get_text_input(); - - void* validator_context = text_input_get_validator_callback_context(text_input); - text_input_set_validator(text_input, NULL, NULL); - validator_is_file_free((ValidatorIsFile*)validator_context); - - text_input_reset(text_input); -} diff --git a/applications/ibutton/scene/ibutton_scene_save_name.h b/applications/ibutton/scene/ibutton_scene_save_name.h deleted file mode 100644 index 2d7f102e14a..00000000000 --- a/applications/ibutton/scene/ibutton_scene_save_name.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSaveName : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_save_success.cpp b/applications/ibutton/scene/ibutton_scene_save_success.cpp deleted file mode 100644 index 92c0e695685..00000000000 --- a/applications/ibutton/scene/ibutton_scene_save_success.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "ibutton_scene_save_success.h" -#include "../ibutton_app.h" -#include - -static void popup_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneSaveSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - DOLPHIN_DEED(DolphinDeedIbuttonSave); - - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); - - popup_set_callback(popup, popup_callback); - popup_set_context(popup, app); - popup_set_timeout(popup, 1500); - popup_enable_timeout(popup); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); -} - -bool iButtonSceneSaveSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadKeyMenu, - iButtonApp::Scene::SceneSavedKeyMenu, - iButtonApp::Scene::SceneAddType}); - consumed = true; - } - - return consumed; -} - -void iButtonSceneSaveSuccess::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - - popup_disable_timeout(popup); - popup_set_context(popup, NULL); - popup_set_callback(popup, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_save_success.h b/applications/ibutton/scene/ibutton_scene_save_success.h deleted file mode 100644 index 14c7412dc9b..00000000000 --- a/applications/ibutton/scene/ibutton_scene_save_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSaveSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp b/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp deleted file mode 100644 index d9d042d9cd9..00000000000 --- a/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "ibutton_scene_saved_key_menu.h" -#include "../ibutton_app.h" -#include - -typedef enum { - SubmenuIndexEmulate, - SubmenuIndexWrite, - SubmenuIndexEdit, - SubmenuIndexDelete, - SubmenuIndexInfo, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneSavedKeyMenu::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, submenu_callback, app); - if(ibutton_key_get_type(app->get_key()) == iButtonKeyDS1990) { - submenu_add_item(submenu, "Write", SubmenuIndexWrite, submenu_callback, app); - } - submenu_add_item(submenu, "Edit", SubmenuIndexEdit, submenu_callback, app); - submenu_add_item(submenu, "Delete", SubmenuIndexDelete, submenu_callback, app); - submenu_add_item(submenu, "Info", SubmenuIndexInfo, submenu_callback, app); - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneSavedKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - switch(event->payload.menu_index) { - case SubmenuIndexWrite: - app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); - break; - case SubmenuIndexEmulate: - app->switch_to_next_scene(iButtonApp::Scene::SceneEmulate); - break; - case SubmenuIndexEdit: - app->switch_to_next_scene(iButtonApp::Scene::SceneAddValue); - break; - case SubmenuIndexDelete: - app->switch_to_next_scene(iButtonApp::Scene::SceneDeleteConfirm); - break; - case SubmenuIndexInfo: - app->switch_to_next_scene(iButtonApp::Scene::SceneInfo); - break; - } - consumed = true; - } - - return consumed; -} - -void iButtonSceneSavedKeyMenu::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h b/applications/ibutton/scene/ibutton_scene_saved_key_menu.h deleted file mode 100644 index 08809779d11..00000000000 --- a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSavedKeyMenu : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_select_key.cpp b/applications/ibutton/scene/ibutton_scene_select_key.cpp deleted file mode 100644 index 6a1246a49f2..00000000000 --- a/applications/ibutton/scene/ibutton_scene_select_key.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "ibutton_scene_select_key.h" -#include "../ibutton_app.h" - -void iButtonSceneSelectKey::on_enter(iButtonApp* app) { - // Process file_select return - if(app->load_key()) { - app->switch_to_next_scene(iButtonApp::Scene::SceneSavedKeyMenu); - } else { - app->switch_to_previous_scene(); - } -} - -bool iButtonSceneSelectKey::on_event(iButtonApp*, iButtonEvent*) { - return false; -} - -void iButtonSceneSelectKey::on_exit(iButtonApp*) { -} diff --git a/applications/ibutton/scene/ibutton_scene_select_key.h b/applications/ibutton/scene/ibutton_scene_select_key.h deleted file mode 100644 index d6819909973..00000000000 --- a/applications/ibutton/scene/ibutton_scene_select_key.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneSelectKey : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scene/ibutton_scene_start.cpp b/applications/ibutton/scene/ibutton_scene_start.cpp deleted file mode 100644 index f746545958f..00000000000 --- a/applications/ibutton/scene/ibutton_scene_start.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "ibutton_scene_start.h" -#include "../ibutton_app.h" - -typedef enum { - SubmenuIndexRead, - SubmenuIndexSaved, - SubmenuIndexAdd, -} SubmenuIndex; - -static void submenu_callback(void* context, uint32_t index) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneStart::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_add_item(submenu, "Read", SubmenuIndexRead, submenu_callback, app); - submenu_add_item(submenu, "Saved", SubmenuIndexSaved, submenu_callback, app); - submenu_add_item(submenu, "Add Manually", SubmenuIndexAdd, submenu_callback, app); - submenu_set_selected_item(submenu, submenu_item_selected); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneStart::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - submenu_item_selected = event->payload.menu_index; - switch(event->payload.menu_index) { - case SubmenuIndexRead: - app->switch_to_next_scene(iButtonApp::Scene::SceneRead); - break; - case SubmenuIndexSaved: - app->switch_to_next_scene(iButtonApp::Scene::SceneSelectKey); - break; - case SubmenuIndexAdd: - app->switch_to_next_scene(iButtonApp::Scene::SceneAddType); - break; - } - consumed = true; - } - - return consumed; -} - -void iButtonSceneStart::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_reset(submenu); -} diff --git a/applications/ibutton/scene/ibutton_scene_start.h b/applications/ibutton/scene/ibutton_scene_start.h deleted file mode 100644 index 28ef28d3513..00000000000 --- a/applications/ibutton/scene/ibutton_scene_start.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneStart : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - uint32_t submenu_item_selected = 0; -}; diff --git a/applications/ibutton/scene/ibutton_scene_write.cpp b/applications/ibutton/scene/ibutton_scene_write.cpp deleted file mode 100644 index d4f84e11c9c..00000000000 --- a/applications/ibutton/scene/ibutton_scene_write.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "ibutton_scene_write.h" -#include "../ibutton_app.h" - -static void ibutton_worker_write_cb(void* context, iButtonWorkerWriteResult result) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeWorkerWrite; - event.payload.worker_write_result = result; - - app->get_view_manager()->send_event(&event); -} - -void iButtonSceneWrite::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - iButtonKey* key = app->get_key(); - iButtonWorker* worker = app->get_key_worker(); - const uint8_t* key_data = ibutton_key_get_data_p(key); - const char* key_name = ibutton_key_get_name_p(key); - uint8_t line_count = 2; - - // check that stored key has name - if(strcmp(key_name, "") != 0) { - app->set_text_store("writing\n%s", key_name); - line_count = 2; - } else { - // if not, show key data - switch(ibutton_key_get_type(key)) { - case iButtonKeyDS1990: - app->set_text_store( - "writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - line_count = 3; - break; - case iButtonKeyCyfral: - app->set_text_store("writing\n%02X %02X", key_data[0], key_data[1]); - line_count = 2; - break; - case iButtonKeyMetakom: - app->set_text_store( - "writing\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); - line_count = 2; - break; - } - } - - switch(line_count) { - case 3: - popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 22, AlignCenter, AlignTop); - break; - - default: - popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 28, AlignCenter, AlignTop); - break; - } - - popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - - blink_yellow = false; - ibutton_worker_write_set_callback(worker, ibutton_worker_write_cb, app); - ibutton_worker_write_start(worker, key); -} - -bool iButtonSceneWrite::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWorkerWrite) { - consumed = true; - - switch(event->payload.worker_write_result) { - case iButtonWorkerWriteOK: - case iButtonWorkerWriteSameKey: - app->switch_to_next_scene(iButtonApp::Scene::SceneWriteSuccess); - break; - case iButtonWorkerWriteNoDetect: - blink_yellow = false; - break; - case iButtonWorkerWriteCannotWrite: - blink_yellow = true; - break; - } - } else if(event->type == iButtonEvent::Type::EventTypeTick) { - if(blink_yellow) { - app->notify_yellow_blink(); - } else { - app->notify_emulate(); - } - } - - return consumed; -} - -void iButtonSceneWrite::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - ibutton_worker_stop(app->get_key_worker()); - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_write.h b/applications/ibutton/scene/ibutton_scene_write.h deleted file mode 100644 index 8b52473af54..00000000000 --- a/applications/ibutton/scene/ibutton_scene_write.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneWrite : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - bool blink_yellow; -}; diff --git a/applications/ibutton/scene/ibutton_scene_write_success.cpp b/applications/ibutton/scene/ibutton_scene_write_success.cpp deleted file mode 100644 index 3f27c672417..00000000000 --- a/applications/ibutton/scene/ibutton_scene_write_success.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "ibutton_scene_write_success.h" -#include "../ibutton_app.h" - -static void popup_callback(void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); - app->notify_green_off(); -} - -void iButtonSceneWriteSuccess::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - - popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52); - popup_set_text(popup, "Successfully written!", 40, 12, AlignLeft, AlignBottom); - - popup_set_callback(popup, popup_callback); - popup_set_context(popup, app); - popup_set_timeout(popup, 1500); - popup_enable_timeout(popup); - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - - app->notify_success(); - app->notify_green_on(); -} - -bool iButtonSceneWriteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadKeyMenu, iButtonApp::Scene::SceneStart}); - consumed = true; - } - - return consumed; -} - -void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - - popup_disable_timeout(popup); - popup_set_context(popup, NULL); - popup_set_callback(popup, NULL); -} diff --git a/applications/ibutton/scene/ibutton_scene_write_success.h b/applications/ibutton/scene/ibutton_scene_write_success.h deleted file mode 100644 index 99680c7dd2c..00000000000 --- a/applications/ibutton/scene/ibutton_scene_write_success.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "ibutton_scene_generic.h" - -class iButtonSceneWriteSuccess : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; -}; diff --git a/applications/ibutton/scenes/ibutton_scene.c b/applications/ibutton/scenes/ibutton_scene.c new file mode 100644 index 00000000000..c36a0eb5d4d --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene.c @@ -0,0 +1,30 @@ +#include "ibutton_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const ibutton_on_enter_handlers[])(void*) = { +#include "ibutton_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const ibutton_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "ibutton_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const ibutton_on_exit_handlers[])(void* context) = { +#include "ibutton_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers ibutton_scene_handlers = { + .on_enter_handlers = ibutton_on_enter_handlers, + .on_event_handlers = ibutton_on_event_handlers, + .on_exit_handlers = ibutton_on_exit_handlers, + .scene_num = iButtonSceneNum, +}; diff --git a/applications/ibutton/scenes/ibutton_scene.h b/applications/ibutton/scenes/ibutton_scene.h new file mode 100644 index 00000000000..60d2353ed6b --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) iButtonScene##id, +typedef enum { +#include "ibutton_scene_config.h" + iButtonSceneNum, +} iButtonScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers ibutton_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "ibutton_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "ibutton_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "ibutton_scene_config.h" +#undef ADD_SCENE diff --git a/applications/ibutton/scenes/ibutton_scene_add_type.c b/applications/ibutton/scenes/ibutton_scene_add_type.c new file mode 100644 index 00000000000..db129295a3e --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_add_type.c @@ -0,0 +1,58 @@ +#include "../ibutton_i.h" + +enum SubmenuIndex { + SubmenuIndexCyfral, + SubmenuIndexDallas, + SubmenuIndexMetakom, +}; + +void ibutton_scene_add_type_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_add_type_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, "Cyfral", SubmenuIndexCyfral, ibutton_scene_add_type_submenu_callback, ibutton); + submenu_add_item( + submenu, "Dallas", SubmenuIndexDallas, ibutton_scene_add_type_submenu_callback, ibutton); + submenu_add_item( + submenu, "Metakom", SubmenuIndexMetakom, ibutton_scene_add_type_submenu_callback, ibutton); + + submenu_set_selected_item(submenu, SubmenuIndexCyfral); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + iButtonKey* key = ibutton->key; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexCyfral) { + ibutton_key_set_type(key, iButtonKeyCyfral); + } else if(event.event == SubmenuIndexDallas) { + ibutton_key_set_type(key, iButtonKeyDS1990); + } else if(event.event == SubmenuIndexMetakom) { + ibutton_key_set_type(key, iButtonKeyMetakom); + } else { + furi_crash("Unknown key type"); + } + + ibutton_key_set_name(key, ""); + ibutton_key_clear_data(key); + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue); + } + + return consumed; +} + +void ibutton_scene_add_type_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_add_value.c b/applications/ibutton/scenes/ibutton_scene_add_value.c new file mode 100644 index 00000000000..b3ec11a502a --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_add_value.c @@ -0,0 +1,57 @@ +#include "../ibutton_i.h" + +#include + +void ibutton_scene_add_type_byte_input_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventByteEditResult); +} + +void ibutton_scene_add_value_on_enter(void* context) { + iButton* ibutton = context; + iButtonKey* key = ibutton->key; + uint8_t* new_key_data = malloc(IBUTTON_KEY_DATA_SIZE); + + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneAddValue, (uint32_t)new_key_data); + memcpy(new_key_data, ibutton_key_get_data_p(key), ibutton_key_get_data_size(key)); + + byte_input_set_result_callback( + ibutton->byte_input, + ibutton_scene_add_type_byte_input_callback, + NULL, + ibutton, + new_key_data, + ibutton_key_get_data_size(key)); + + byte_input_set_header_text(ibutton->byte_input, "Enter the key"); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewByteInput); +} + +bool ibutton_scene_add_value_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + uint8_t* new_key_data = + (uint8_t*)scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneAddValue); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventByteEditResult) { + ibutton_key_set_data(ibutton->key, new_key_data, IBUTTON_KEY_DATA_SIZE); + DOLPHIN_DEED(DolphinDeedIbuttonAdd); + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); + } + } + + return consumed; +} + +void ibutton_scene_add_value_on_exit(void* context) { + iButton* ibutton = context; + uint8_t* new_key_data = + (uint8_t*)scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneAddValue); + + byte_input_set_result_callback(ibutton->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(ibutton->byte_input, NULL); + free(new_key_data); +} diff --git a/applications/ibutton/scenes/ibutton_scene_config.h b/applications/ibutton/scenes/ibutton_scene_config.h new file mode 100644 index 00000000000..d30b43beb4c --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_config.h @@ -0,0 +1,20 @@ +ADD_SCENE(ibutton, start, Start) +ADD_SCENE(ibutton, emulate, Emulate) +ADD_SCENE(ibutton, write, Write) +ADD_SCENE(ibutton, write_success, WriteSuccess) +ADD_SCENE(ibutton, info, Info) +ADD_SCENE(ibutton, read, Read) +ADD_SCENE(ibutton, read_key_menu, ReadKeyMenu) +ADD_SCENE(ibutton, read_success, ReadSuccess) +ADD_SCENE(ibutton, read_crc_error, ReadCRCError) +ADD_SCENE(ibutton, read_not_key_error, ReadNotKeyError) +ADD_SCENE(ibutton, select_key, SelectKey) +ADD_SCENE(ibutton, add_type, AddType) +ADD_SCENE(ibutton, add_value, AddValue) +ADD_SCENE(ibutton, saved_key_menu, SavedKeyMenu) +ADD_SCENE(ibutton, save_name, SaveName) +ADD_SCENE(ibutton, save_success, SaveSuccess) +ADD_SCENE(ibutton, delete_confirm, DeleteConfirm) +ADD_SCENE(ibutton, delete_success, DeleteSuccess) +ADD_SCENE(ibutton, retry_confirm, RetryConfirm) +ADD_SCENE(ibutton, exit_confirm, ExitConfirm) diff --git a/applications/ibutton/scenes/ibutton_scene_delete_confirm.c b/applications/ibutton/scenes/ibutton_scene_delete_confirm.c new file mode 100644 index 00000000000..73ea97cc636 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_delete_confirm.c @@ -0,0 +1,91 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_delete_confirm_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + iButton* ibutton = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); + } +} + +void ibutton_scene_delete_confirm_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", ibutton_key_get_name_p(key)); + widget_add_text_box_element( + widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, false); + widget_add_button_element( + widget, GuiButtonTypeLeft, "Cancel", ibutton_scene_delete_confirm_widget_callback, ibutton); + widget_add_button_element( + widget, + GuiButtonTypeRight, + "Delete", + ibutton_scene_delete_confirm_widget_callback, + ibutton); + + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "%02X %02X %02X %02X %02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + widget_add_string_element( + widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); + break; + + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); + widget_add_string_element( + widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); + break; + + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); + widget_add_string_element( + widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom"); + break; + } + widget_add_string_element( + widget, 64, 33, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeRight) { + if(ibutton_delete_key(ibutton)) { + scene_manager_next_scene(scene_manager, iButtonSceneDeleteSuccess); + } + //TODO: What if the key could not be deleted? + } else if(event.event == GuiButtonTypeLeft) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_delete_confirm_on_exit(void* context) { + iButton* ibutton = context; + ibutton_text_store_clear(ibutton); + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_delete_success.c b/applications/ibutton/scenes/ibutton_scene_delete_success.c new file mode 100644 index 00000000000..8b7d9dfc02f --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_delete_success.c @@ -0,0 +1,48 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_delete_success_popup_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventBack); +} + +void ibutton_scene_delete_success_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); + popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); + + popup_set_callback(popup, ibutton_scene_delete_success_popup_callback); + popup_set_context(popup, ibutton); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); +} + +bool ibutton_scene_delete_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventBack) { + scene_manager_search_and_switch_to_previous_scene( + ibutton->scene_manager, iButtonSceneSelectKey); + } + } + + return consumed; +} + +void ibutton_scene_delete_success_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + + popup_disable_timeout(popup); + popup_set_context(popup, NULL); + popup_set_callback(popup, NULL); +} diff --git a/applications/ibutton/scene/ibutton_scene_emulate.cpp b/applications/ibutton/scenes/ibutton_scene_emulate.c similarity index 50% rename from applications/ibutton/scene/ibutton_scene_emulate.cpp rename to applications/ibutton/scenes/ibutton_scene_emulate.c index c00535f8c87..8ffe73b66a7 100644 --- a/applications/ibutton/scene/ibutton_scene_emulate.cpp +++ b/applications/ibutton/scenes/ibutton_scene_emulate.c @@ -1,37 +1,35 @@ -#include "ibutton_scene_emulate.h" -#include "../ibutton_app.h" +#include "../ibutton_i.h" #include -static void emulate_callback(void* context, bool emulated) { - furi_assert(context); +static void ibutton_scene_emulate_callback(void* context, bool emulated) { + iButton* ibutton = context; if(emulated) { - iButtonApp* app = static_cast(context); - iButtonEvent event = { - .payload = {.worker_write_result = iButtonWorkerWriteOK}, - .type = iButtonEvent::Type::EventTypeWorkerEmulated, - }; - app->get_view_manager()->send_event(&event); + view_dispatcher_send_custom_event( + ibutton->view_dispatcher, iButtonCustomEventWorkerEmulated); } } -void iButtonSceneEmulate::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Popup* popup = view_manager->get_popup(); - iButtonKey* key = app->get_key(); +void ibutton_scene_emulate_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); const char* key_name = ibutton_key_get_name_p(key); + uint8_t line_count = 2; DOLPHIN_DEED(DolphinDeedIbuttonEmulate); // check that stored key has name if(strcmp(key_name, "") != 0) { - app->set_text_store("emulating\n%s", key_name); + ibutton_text_store_set(ibutton, "emulating\n%s", key_name); line_count = 2; } else { // if not, show key data switch(ibutton_key_get_type(key)) { case iButtonKeyDS1990: - app->set_text_store( + ibutton_text_store_set( + ibutton, "emulating\n%02X %02X %02X %02X\n%02X %02X %02X %02X", key_data[0], key_data[1], @@ -44,11 +42,12 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) { line_count = 3; break; case iButtonKeyCyfral: - app->set_text_store("emulating\n%02X %02X", key_data[0], key_data[1]); + ibutton_text_store_set(ibutton, "emulating\n%02X %02X", key_data[0], key_data[1]); line_count = 2; break; case iButtonKeyMetakom: - app->set_text_store( + ibutton_text_store_set( + ibutton, "emulating\n%02X %02X %02X %02X", key_data[0], key_data[1], @@ -62,40 +61,45 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) { switch(line_count) { case 3: popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 22, AlignCenter, AlignTop); + popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop); break; default: popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); - popup_set_text(popup, app->get_text_store(), 82, 28, AlignCenter, AlignTop); + popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop); break; } popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - ibutton_worker_emulate_set_callback(app->get_key_worker(), emulate_callback, app); - ibutton_worker_emulate_start(app->get_key_worker(), key); + ibutton_worker_emulate_set_callback( + ibutton->key_worker, ibutton_scene_emulate_callback, ibutton); + ibutton_worker_emulate_start(ibutton->key_worker, key); } -bool iButtonSceneEmulate::on_event(iButtonApp* app, iButtonEvent* event) { +bool ibutton_scene_emulate_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; bool consumed = false; - if(event->type == iButtonEvent::Type::EventTypeWorkerEmulated) { - app->notify_yellow_blink(); + if(event.type == SceneManagerEventTypeTick) { consumed = true; - } else if(event->type == iButtonEvent::Type::EventTypeTick) { - app->notify_emulate(); + ibutton_notification_message(ibutton, iButtonNotificationMessageEmulate); + } else if(event.type == SceneManagerEventTypeCustom) { consumed = true; + if(event.event == iButtonCustomEventWorkerEmulated) { + ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink); + } } return consumed; } -void iButtonSceneEmulate::on_exit(iButtonApp* app) { - Popup* popup = app->get_view_manager()->get_popup(); - ibutton_worker_stop(app->get_key_worker()); +void ibutton_scene_emulate_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + ibutton_worker_stop(ibutton->key_worker); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); diff --git a/applications/ibutton/scenes/ibutton_scene_exit_confirm.c b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c new file mode 100644 index 00000000000..abd171f6ac8 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c @@ -0,0 +1,51 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_exit_confirm_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + iButton* ibutton = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); + } +} + +void ibutton_scene_exit_confirm_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + + widget_add_button_element( + widget, GuiButtonTypeLeft, "Exit", ibutton_scene_exit_confirm_widget_callback, ibutton); + widget_add_button_element( + widget, GuiButtonTypeRight, "Stay", ibutton_scene_exit_confirm_widget_callback, ibutton); + widget_add_string_element( + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu"); + widget_add_string_element( + widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; // Ignore Back button presses + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeLeft) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, iButtonSceneStart); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_exit_confirm_on_exit(void* context) { + iButton* ibutton = context; + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_info.c b/applications/ibutton/scenes/ibutton_scene_info.c new file mode 100644 index 00000000000..5b0af1d8f62 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_info.c @@ -0,0 +1,61 @@ +#include "../ibutton_i.h" + +void ibutton_scene_info_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + iButtonKey* key = ibutton->key; + + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set(ibutton, "%s", ibutton_key_get_name_p(key)); + widget_add_text_box_element( + widget, 0, 0, 128, 28, AlignCenter, AlignCenter, ibutton->text_store, false); + + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "%02X %02X %02X %02X %02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + widget_add_string_element( + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Dallas"); + break; + + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); + widget_add_string_element( + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Metakom"); + break; + + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); + widget_add_string_element( + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); + break; + } + + widget_add_string_element( + widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, ibutton->text_store); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_info_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void ibutton_scene_info_on_exit(void* context) { + iButton* ibutton = context; + ibutton_text_store_clear(ibutton); + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read.c b/applications/ibutton/scenes/ibutton_scene_read.c new file mode 100644 index 00000000000..a25f27e6063 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read.c @@ -0,0 +1,72 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_read_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventWorkerRead); +} + +void ibutton_scene_read_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + iButtonKey* key = ibutton->key; + iButtonWorker* worker = ibutton->key_worker; + DOLPHIN_DEED(DolphinDeedIbuttonRead); + + popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom); + popup_set_text(popup, "waiting\nfor key ...", 95, 30, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + ibutton_key_set_name(key, ""); + + ibutton_worker_read_set_callback(worker, ibutton_scene_read_callback, ibutton); + ibutton_worker_read_start(worker, key); +} + +bool ibutton_scene_read_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeTick) { + consumed = true; + ibutton_notification_message(ibutton, iButtonNotificationMessageRead); + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventWorkerRead) { + bool success = false; + iButtonKey* key = ibutton->key; + + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + if(!ibutton_key_dallas_crc_is_valid(key)) { + scene_manager_next_scene(scene_manager, iButtonSceneReadCRCError); + } else if(!ibutton_key_dallas_is_1990_key(key)) { + scene_manager_next_scene(scene_manager, iButtonSceneReadNotKeyError); + } else { + success = true; + } + } else { + success = true; + } + + if(success) { + ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess); + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn); + DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess); + scene_manager_next_scene(scene_manager, iButtonSceneReadSuccess); + } + } + } + + return consumed; +} + +void ibutton_scene_read_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + ibutton_worker_stop(ibutton->key_worker); + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_crc_error.c b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c new file mode 100644 index 00000000000..4df96d641ca --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c @@ -0,0 +1,71 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_read_crc_error_dialog_ex_callback(DialogExResult result, void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_read_crc_error_on_enter(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set( + ibutton, + "%02X %02X %02X %02X %02X %02X %02X %02X\nExpected CRC: %X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7], + maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); + + dialog_ex_set_header(dialog_ex, "CRC ERROR", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, ibutton->text_store, 64, 19, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "More"); + dialog_ex_set_result_callback(dialog_ex, ibutton_scene_read_crc_error_dialog_ex_callback); + dialog_ex_set_context(dialog_ex, ibutton); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewDialogEx); + + ibutton_notification_message(ibutton, iButtonNotificationMessageError); + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOn); +} + +bool ibutton_scene_read_crc_error_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == DialogExResultRight) { + scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); + } else if(event.event == DialogExResultLeft) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_read_crc_error_on_exit(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + + ibutton_text_store_clear(ibutton); + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOff); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_key_menu.c b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c new file mode 100644 index 00000000000..7d479a463f1 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c @@ -0,0 +1,61 @@ +#include "../ibutton_i.h" + +typedef enum { + SubmenuIndexSave, + SubmenuIndexEmulate, + SubmenuIndexWrite, +} SubmenuIndex; + +void ibutton_scene_read_key_menu_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_read_key_menu_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, "Save", SubmenuIndexSave, ibutton_scene_read_key_menu_submenu_callback, ibutton); + submenu_add_item( + submenu, + "Emulate", + SubmenuIndexEmulate, + ibutton_scene_read_key_menu_submenu_callback, + ibutton); + if(ibutton_key_get_type(ibutton->key) == iButtonKeyDS1990) { + submenu_add_item( + submenu, + "Write", + SubmenuIndexWrite, + ibutton_scene_read_key_menu_submenu_callback, + ibutton); + } + + submenu_set_selected_item(submenu, SubmenuIndexSave); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_read_key_menu_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexSave) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); + } else if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); + } else if(event.event == SubmenuIndexWrite) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite); + } + } + + return consumed; +} + +void ibutton_scene_read_key_menu_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c new file mode 100644 index 00000000000..76f14daed68 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c @@ -0,0 +1,72 @@ +#include "../ibutton_i.h" +#include + +static void + ibutton_scene_read_not_key_error_dialog_ex_callback(DialogExResult result, void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_read_not_key_error_on_enter(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + ibutton_text_store_set( + ibutton, + "THIS IS NOT A KEY\n%02X %02X %02X %02X %02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7], + maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); + + dialog_ex_set_header(dialog_ex, "CRC ERROR", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, ibutton->text_store, 64, 19, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "More"); + dialog_ex_set_result_callback(dialog_ex, ibutton_scene_read_not_key_error_dialog_ex_callback); + dialog_ex_set_context(dialog_ex, ibutton); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewDialogEx); + + ibutton_notification_message(ibutton, iButtonNotificationMessageError); + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOn); +} + +bool ibutton_scene_read_not_key_error_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == DialogExResultRight) { + scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); + } else if(event.event == DialogExResultLeft) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_read_not_key_error_on_exit(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + + ibutton_text_store_clear(ibutton); + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + ibutton_notification_message(ibutton, iButtonNotificationMessageRedOff); +} diff --git a/applications/ibutton/scenes/ibutton_scene_read_success.c b/applications/ibutton/scenes/ibutton_scene_read_success.c new file mode 100644 index 00000000000..c3a13478746 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_read_success.c @@ -0,0 +1,87 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_read_success_dialog_ex_callback(DialogExResult result, void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_read_success_on_enter(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + iButtonKey* key = ibutton->key; + const uint8_t* key_data = ibutton_key_get_data_p(key); + + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "Dallas\n%02X %02X %02X %02X\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + break; + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "Cyfral\n%02X %02X", key_data[0], key_data[1]); + break; + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, + "Metakom\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3]); + break; + } + + dialog_ex_set_text(dialog_ex, ibutton->text_store, 95, 30, AlignCenter, AlignCenter); + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "More"); + dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63); + dialog_ex_set_result_callback(dialog_ex, ibutton_scene_read_success_dialog_ex_callback); + dialog_ex_set_context(dialog_ex, ibutton); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewDialogEx); +} + +bool ibutton_scene_read_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + scene_manager_next_scene(scene_manager, iButtonSceneExitConfirm); + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == DialogExResultRight) { + scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); + } else if(event.event == DialogExResultLeft) { + scene_manager_next_scene(scene_manager, iButtonSceneRetryConfirm); + } + } + + return consumed; +} + +void ibutton_scene_read_success_on_exit(void* context) { + iButton* ibutton = context; + DialogEx* dialog_ex = ibutton->dialog_ex; + + ibutton_text_store_clear(ibutton); + + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOff); +} diff --git a/applications/ibutton/scenes/ibutton_scene_retry_confirm.c b/applications/ibutton/scenes/ibutton_scene_retry_confirm.c new file mode 100644 index 00000000000..d2778ac15ea --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_retry_confirm.c @@ -0,0 +1,51 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_retry_confirm_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + iButton* ibutton = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); + } +} + +void ibutton_scene_retry_confirm_on_enter(void* context) { + iButton* ibutton = context; + Widget* widget = ibutton->widget; + + widget_add_button_element( + widget, GuiButtonTypeLeft, "Exit", ibutton_scene_retry_confirm_widget_callback, ibutton); + widget_add_button_element( + widget, GuiButtonTypeRight, "Stay", ibutton_scene_retry_confirm_widget_callback, ibutton); + widget_add_string_element( + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?"); + widget_add_string_element( + widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); +} + +bool ibutton_scene_retry_confirm_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; // Ignore Back button presses + } else if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeLeft) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, iButtonSceneRead); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void ibutton_scene_retry_confirm_on_exit(void* context) { + iButton* ibutton = context; + widget_reset(ibutton->widget); +} diff --git a/applications/ibutton/scenes/ibutton_scene_save_name.c b/applications/ibutton/scenes/ibutton_scene_save_name.c new file mode 100644 index 00000000000..b1baf6afc73 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_save_name.c @@ -0,0 +1,68 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_save_name_text_input_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventTextEditResult); +} + +void ibutton_scene_save_name_on_enter(void* context) { + iButton* ibutton = context; + TextInput* text_input = ibutton->text_input; + + const char* key_name = ibutton_key_get_name_p(ibutton->key); + const bool key_name_is_empty = !strcmp(key_name, ""); + + if(key_name_is_empty) { + set_random_name(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE); + } else { + ibutton_text_store_set(ibutton, "%s", key_name); + } + + text_input_set_header_text(text_input, "Name the key"); + text_input_set_result_callback( + text_input, + ibutton_scene_save_name_text_input_callback, + ibutton, + ibutton->text_store, + IBUTTON_KEY_NAME_SIZE, + key_name_is_empty); + + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(IBUTTON_APP_FOLDER, IBUTTON_APP_EXTENSION, key_name); + text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput); +} + +bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventTextEditResult) { + if(ibutton_save_key(ibutton, ibutton->text_store)) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveSuccess); + } else { + const uint32_t possible_scenes[] = { + iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType}; + ibutton_switch_to_previous_scene_one_of( + ibutton, possible_scenes, sizeof(possible_scenes) / sizeof(uint32_t)); + } + } + } + + return consumed; +} + +void ibutton_scene_save_name_on_exit(void* context) { + iButton* ibutton = context; + TextInput* text_input = ibutton->text_input; + + void* validator_context = text_input_get_validator_callback_context(text_input); + text_input_set_validator(text_input, NULL, NULL); + validator_is_file_free((ValidatorIsFile*)validator_context); + + text_input_reset(text_input); +} diff --git a/applications/ibutton/scenes/ibutton_scene_save_success.c b/applications/ibutton/scenes/ibutton_scene_save_success.c new file mode 100644 index 00000000000..dffda6a0fd2 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_save_success.c @@ -0,0 +1,52 @@ +#include "../ibutton_i.h" +#include + +static void ibutton_scene_save_success_popup_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventBack); +} + +void ibutton_scene_save_success_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + DOLPHIN_DEED(DolphinDeedIbuttonSave); + + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); + popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); + + popup_set_callback(popup, ibutton_scene_save_success_popup_callback); + popup_set_context(popup, ibutton); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); +} + +bool ibutton_scene_save_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventBack) { + const uint32_t possible_scenes[] = { + iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType}; + ibutton_switch_to_previous_scene_one_of( + ibutton, possible_scenes, sizeof(possible_scenes) / sizeof(uint32_t)); + } + } + + return consumed; +} + +void ibutton_scene_save_success_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + + popup_disable_timeout(popup); + popup_set_context(popup, NULL); + popup_set_callback(popup, NULL); +} diff --git a/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c new file mode 100644 index 00000000000..3652977211b --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c @@ -0,0 +1,75 @@ +#include "../ibutton_i.h" + +enum SubmenuIndex { + SubmenuIndexEmulate, + SubmenuIndexWrite, + SubmenuIndexEdit, + SubmenuIndexDelete, + SubmenuIndexInfo, +}; + +void ibutton_scene_saved_key_menu_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_saved_key_menu_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, + "Emulate", + SubmenuIndexEmulate, + ibutton_scene_saved_key_menu_submenu_callback, + ibutton); + if(ibutton_key_get_type(ibutton->key) == iButtonKeyDS1990) { + submenu_add_item( + submenu, + "Write", + SubmenuIndexWrite, + ibutton_scene_saved_key_menu_submenu_callback, + ibutton); + } + submenu_add_item( + submenu, "Edit", SubmenuIndexEdit, ibutton_scene_saved_key_menu_submenu_callback, ibutton); + submenu_add_item( + submenu, + "Delete", + SubmenuIndexDelete, + ibutton_scene_saved_key_menu_submenu_callback, + ibutton); + submenu_add_item( + submenu, "Info", SubmenuIndexInfo, ibutton_scene_saved_key_menu_submenu_callback, ibutton); + + submenu_set_selected_item(submenu, SubmenuIndexEmulate); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); + } else if(event.event == SubmenuIndexWrite) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite); + } else if(event.event == SubmenuIndexEdit) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue); + } else if(event.event == SubmenuIndexDelete) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneDeleteConfirm); + } else if(event.event == SubmenuIndexInfo) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneInfo); + } + } + + return consumed; +} + +void ibutton_scene_saved_key_menu_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_select_key.c b/applications/ibutton/scenes/ibutton_scene_select_key.c new file mode 100644 index 00000000000..32169a9c08d --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_select_key.c @@ -0,0 +1,22 @@ +#include "../ibutton_i.h" + +void ibutton_scene_select_key_on_enter(void* context) { + iButton* ibutton = context; + + if(!ibutton_file_select(ibutton)) { + scene_manager_search_and_switch_to_previous_scene( + ibutton->scene_manager, iButtonSceneStart); + } else { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSavedKeyMenu); + } +} + +bool ibutton_scene_select_key_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void ibutton_scene_select_key_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/ibutton/scenes/ibutton_scene_start.c b/applications/ibutton/scenes/ibutton_scene_start.c new file mode 100644 index 00000000000..a3141f5ad9f --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_start.c @@ -0,0 +1,51 @@ +#include "../ibutton_i.h" + +enum SubmenuIndex { + SubmenuIndexRead, + SubmenuIndexSaved, + SubmenuIndexAdd, +}; + +void ibutton_scene_start_submenu_callback(void* context, uint32_t index) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, index); +} + +void ibutton_scene_start_on_enter(void* context) { + iButton* ibutton = context; + Submenu* submenu = ibutton->submenu; + + submenu_add_item( + submenu, "Read", SubmenuIndexRead, ibutton_scene_start_submenu_callback, ibutton); + submenu_add_item( + submenu, "Saved", SubmenuIndexSaved, ibutton_scene_start_submenu_callback, ibutton); + submenu_add_item( + submenu, "Add Manually", SubmenuIndexAdd, ibutton_scene_start_submenu_callback, ibutton); + + submenu_set_selected_item(submenu, SubmenuIndexRead); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); +} + +bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == SubmenuIndexRead) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); + } else if(event.event == SubmenuIndexSaved) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey); + } else if(event.event == SubmenuIndexAdd) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddType); + } + } + + return consumed; +} + +void ibutton_scene_start_on_exit(void* context) { + iButton* ibutton = context; + submenu_reset(ibutton->submenu); +} diff --git a/applications/ibutton/scenes/ibutton_scene_write.c b/applications/ibutton/scenes/ibutton_scene_write.c new file mode 100644 index 00000000000..35e45d83bd6 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_write.c @@ -0,0 +1,121 @@ +#include "../ibutton_i.h" + +typedef enum { + iButtonSceneWriteStateDefault, + iButtonSceneWriteStateBlinkYellow, +} iButtonSceneWriteState; + +static void ibutton_scene_write_callback(void* context, iButtonWorkerWriteResult result) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, result); +} + +void ibutton_scene_write_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + iButtonKey* key = ibutton->key; + iButtonWorker* worker = ibutton->key_worker; + + const uint8_t* key_data = ibutton_key_get_data_p(key); + const char* key_name = ibutton_key_get_name_p(key); + + uint8_t line_count = 2; + + // check that stored key has name + if(strcmp(key_name, "") != 0) { + ibutton_text_store_set(ibutton, "writing\n%s", key_name); + line_count = 2; + } else { + // if not, show key data + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + ibutton_text_store_set( + ibutton, + "writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3], + key_data[4], + key_data[5], + key_data[6], + key_data[7]); + line_count = 3; + break; + case iButtonKeyCyfral: + ibutton_text_store_set(ibutton, "writing\n%02X %02X", key_data[0], key_data[1]); + line_count = 2; + break; + case iButtonKeyMetakom: + ibutton_text_store_set( + ibutton, + "writing\n%02X %02X %02X %02X", + key_data[0], + key_data[1], + key_data[2], + key_data[3]); + line_count = 2; + break; + } + } + + switch(line_count) { + case 3: + popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); + popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop); + break; + + default: + popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); + popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop); + break; + } + + popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); + + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneWrite, iButtonSceneWriteStateDefault); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + + ibutton_worker_write_set_callback(worker, ibutton_scene_write_callback, ibutton); + ibutton_worker_write_start(worker, key); +} + +bool ibutton_scene_write_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + SceneManager* scene_manager = ibutton->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if((event.event == iButtonWorkerWriteOK) || (event.event == iButtonWorkerWriteSameKey)) { + scene_manager_next_scene(scene_manager, iButtonSceneWriteSuccess); + } else if(event.event == iButtonWorkerWriteNoDetect) { + scene_manager_set_scene_state( + scene_manager, iButtonSceneWrite, iButtonSceneWriteStateDefault); + } else if(event.event == iButtonWorkerWriteCannotWrite) { + scene_manager_set_scene_state( + scene_manager, iButtonSceneWrite, iButtonSceneWriteStateBlinkYellow); + } + + } else if(event.type == SceneManagerEventTypeTick) { + consumed = true; + if(scene_manager_get_scene_state(scene_manager, iButtonSceneWrite) == + iButtonSceneWriteStateBlinkYellow) { + ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink); + } else { + ibutton_notification_message(ibutton, iButtonNotificationMessageEmulate); + } + } + + return consumed; +} + +void ibutton_scene_write_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + ibutton_worker_stop(ibutton->key_worker); + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); +} diff --git a/applications/ibutton/scenes/ibutton_scene_write_success.c b/applications/ibutton/scenes/ibutton_scene_write_success.c new file mode 100644 index 00000000000..6abafbb3723 --- /dev/null +++ b/applications/ibutton/scenes/ibutton_scene_write_success.c @@ -0,0 +1,52 @@ +#include "../ibutton_i.h" + +static void ibutton_scene_write_success_popup_callback(void* context) { + iButton* ibutton = context; + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventBack); + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOff); +} + +void ibutton_scene_write_success_on_enter(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52); + popup_set_text(popup, "Successfully written!", 40, 12, AlignLeft, AlignBottom); + + popup_set_callback(popup, ibutton_scene_write_success_popup_callback); + popup_set_context(popup, ibutton); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess); + ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn); +} + +bool ibutton_scene_write_success_on_event(void* context, SceneManagerEvent event) { + iButton* ibutton = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == iButtonCustomEventBack) { + const uint32_t possible_scenes[] = {iButtonSceneReadKeyMenu, iButtonSceneStart}; + ibutton_switch_to_previous_scene_one_of( + ibutton, possible_scenes, sizeof(possible_scenes) / sizeof(uint32_t)); + } + } + + return consumed; +} + +void ibutton_scene_write_success_on_exit(void* context) { + iButton* ibutton = context; + Popup* popup = ibutton->popup; + + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + + popup_disable_timeout(popup); + popup_set_context(popup, NULL); + popup_set_callback(popup, NULL); +} From 51efe8b805d813b62e41e4a5bf309fdfa6e407c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Fri, 6 May 2022 20:35:52 +0300 Subject: [PATCH 09/24] [FL-2500] Change shadows direction and refactor status bar drawing code (#1200) * GUI: cleanup status bar drawing code and change shadows positions * Archive: drop shadows where they should be --- .../archive/views/archive_browser_view.c | 24 +-- applications/gui/gui.c | 145 ++++++++++-------- applications/power/power_service/power.c | 11 +- 3 files changed, 103 insertions(+), 77 deletions(-) diff --git a/applications/archive/views/archive_browser_view.c b/applications/archive/views/archive_browser_view.c index dc6962f21e0..fc578b36523 100644 --- a/applications/archive/views/archive_browser_view.c +++ b/applications/archive/views/archive_browser_view.c @@ -161,21 +161,21 @@ static void archive_render_status_bar(Canvas* canvas, ArchiveBrowserViewModel* m canvas_draw_box(canvas, 107, 0, 20, 13); canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, 1, 0, 50, 12); - canvas_draw_line(canvas, 0, 1, 0, 11); - canvas_draw_line(canvas, 1, 12, 49, 12); - canvas_draw_str_aligned(canvas, 26, 9, AlignCenter, AlignBottom, tab_name); + canvas_draw_rframe(canvas, 0, 0, 51, 13, 1); // frame + canvas_draw_line(canvas, 49, 1, 49, 11); // shadow right + canvas_draw_line(canvas, 1, 11, 49, 11); // shadow bottom + canvas_draw_str_aligned(canvas, 25, 9, AlignCenter, AlignBottom, tab_name); - canvas_draw_frame(canvas, 108, 0, 20, 12); - canvas_draw_line(canvas, 107, 1, 107, 11); - canvas_draw_line(canvas, 108, 12, 126, 12); + canvas_draw_rframe(canvas, 107, 0, 21, 13, 1); + canvas_draw_line(canvas, 126, 1, 126, 11); + canvas_draw_line(canvas, 108, 11, 126, 11); if(model->move_fav) { - canvas_draw_icon(canvas, 111, 4, &I_ButtonUp_7x4); - canvas_draw_icon(canvas, 118, 4, &I_ButtonDown_7x4); + canvas_draw_icon(canvas, 110, 4, &I_ButtonUp_7x4); + canvas_draw_icon(canvas, 117, 4, &I_ButtonDown_7x4); } else { - canvas_draw_icon(canvas, 112, 2, &I_ButtonLeft_4x7); - canvas_draw_icon(canvas, 120, 2, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 111, 2, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 119, 2, &I_ButtonRight_4x7); } canvas_set_color(canvas, ColorWhite); @@ -347,7 +347,7 @@ ArchiveBrowserView* browser_alloc() { browser->view = view_alloc(); view_allocate_model(browser->view, ViewModelTypeLocking, sizeof(ArchiveBrowserViewModel)); view_set_context(browser->view, browser); - view_set_draw_callback(browser->view, (ViewDrawCallback)archive_view_render); + view_set_draw_callback(browser->view, archive_view_render); view_set_input_callback(browser->view, archive_view_input); string_init(browser->path); diff --git a/applications/gui/gui.c b/applications/gui/gui.c index 4fc0935ea8f..77ee4487ea8 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -47,10 +47,9 @@ bool gui_redraw_fs(Gui* gui) { static void gui_redraw_status_bar(Gui* gui, bool need_attention) { ViewPortArray_it_t it; - uint8_t x; - uint8_t x_used = 0; + uint8_t left_used = 0; + uint8_t right_used = 0; uint8_t width; - ViewPort* view_port; canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal); canvas_frame_set( gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT); @@ -69,100 +68,126 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { canvas_set_bitmap_mode(gui->canvas, 0); // Right side - x = GUI_DISPLAY_WIDTH; + uint8_t x = GUI_DISPLAY_WIDTH - 1; ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]); - while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) { - // Render view_port; - view_port = *ViewPortArray_ref(it); + while(!ViewPortArray_end_p(it) && right_used < GUI_STATUS_BAR_WIDTH) { + ViewPort* view_port = *ViewPortArray_ref(it); if(view_port_is_enabled(view_port)) { width = view_port_get_width(view_port); if(!width) width = 8; - x_used += width; + // Recalculate next position + right_used += (width + 2); x -= (width + 2); + // Prepare work area background canvas_frame_set( - gui->canvas, x - 3, GUI_STATUS_BAR_Y, width + 5, GUI_STATUS_BAR_HEIGHT); - + gui->canvas, + x - 1, + GUI_STATUS_BAR_Y + 1, + width + 2, + GUI_STATUS_BAR_WORKAREA_HEIGHT + 2); canvas_set_color(gui->canvas, ColorWhite); - canvas_draw_box(gui->canvas, 2, 1, width + 2, 10); + canvas_draw_box( + gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas)); canvas_set_color(gui->canvas, ColorBlack); - - canvas_draw_rframe( - gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1); - canvas_draw_line(gui->canvas, 1, 1, 1, canvas_height(gui->canvas) - 2); - canvas_draw_line( - gui->canvas, - 2, - canvas_height(gui->canvas) - 2, - canvas_width(gui->canvas) - 2, - canvas_height(gui->canvas) - 2); - + // ViewPort draw canvas_frame_set( - gui->canvas, x, GUI_STATUS_BAR_Y + 1, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); - + gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); view_port_draw(view_port, gui->canvas); } ViewPortArray_next(it); } + // Draw frame around icons on the right + if(right_used) { + canvas_frame_set( + gui->canvas, + GUI_DISPLAY_WIDTH - 3 - right_used, + GUI_STATUS_BAR_Y, + right_used + 3, + GUI_STATUS_BAR_HEIGHT); + canvas_set_color(gui->canvas, ColorBlack); + canvas_draw_rframe( + gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1); + canvas_draw_line( + gui->canvas, + canvas_width(gui->canvas) - 2, + 1, + canvas_width(gui->canvas) - 2, + canvas_height(gui->canvas) - 2); + canvas_draw_line( + gui->canvas, + 1, + canvas_height(gui->canvas) - 2, + canvas_width(gui->canvas) - 2, + canvas_height(gui->canvas) - 2); + } + // Left side - x = 0; + x = 2; ViewPortArray_it(it, gui->layers[GuiLayerStatusBarLeft]); - while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) { - // Render view_port; - view_port = *ViewPortArray_ref(it); + while(!ViewPortArray_end_p(it) && (right_used + left_used) < GUI_STATUS_BAR_WIDTH) { + ViewPort* view_port = *ViewPortArray_ref(it); if(view_port_is_enabled(view_port)) { width = view_port_get_width(view_port); if(!width) width = 8; - x_used += width; - + // Prepare work area background canvas_frame_set( - gui->canvas, 0, GUI_STATUS_BAR_Y, x + width + 5, GUI_STATUS_BAR_HEIGHT); - canvas_draw_rframe( - gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1); - canvas_draw_line(gui->canvas, 1, 1, 1, canvas_height(gui->canvas) - 2); - canvas_draw_line( gui->canvas, - 2, - canvas_height(gui->canvas) - 2, - canvas_width(gui->canvas) - 2, - canvas_height(gui->canvas) - 2); - - canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width + 5, GUI_STATUS_BAR_HEIGHT); - + x - 1, + GUI_STATUS_BAR_Y + 1, + width + 2, + GUI_STATUS_BAR_WORKAREA_HEIGHT + 2); canvas_set_color(gui->canvas, ColorWhite); - canvas_draw_box(gui->canvas, 2, 1, width + 2, 10); + canvas_draw_box( + gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas)); canvas_set_color(gui->canvas, ColorBlack); - + // ViewPort draw canvas_frame_set( - gui->canvas, x + 3, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); + gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); view_port_draw(view_port, gui->canvas); - + // Recalculate next position + left_used += (width + 2); x += (width + 2); } ViewPortArray_next(it); } - + // Extra notification if(need_attention) { width = icon_get_width(&I_Attention_5x8); - canvas_frame_set(gui->canvas, 0, GUI_STATUS_BAR_Y, x + width + 5, GUI_STATUS_BAR_HEIGHT); + // Prepare work area background + canvas_frame_set( + gui->canvas, + x - 1, + GUI_STATUS_BAR_Y + 1, + width + 2, + GUI_STATUS_BAR_WORKAREA_HEIGHT + 2); + canvas_set_color(gui->canvas, ColorWhite); + canvas_draw_box(gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas)); + canvas_set_color(gui->canvas, ColorBlack); + // Draw Icon + canvas_frame_set( + gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); + canvas_draw_icon(gui->canvas, 0, 0, &I_Attention_5x8); + // Recalculate next position + left_used += (width + 2); + x += (width + 2); + } + // Draw frame around icons on the left + if(left_used) { + canvas_frame_set(gui->canvas, 0, 0, left_used + 3, GUI_STATUS_BAR_HEIGHT); canvas_draw_rframe( gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1); - canvas_draw_line(gui->canvas, 1, 1, 1, canvas_height(gui->canvas) - 2); canvas_draw_line( gui->canvas, - 2, + canvas_width(gui->canvas) - 2, + 1, + canvas_width(gui->canvas) - 2, + canvas_height(gui->canvas) - 2); + canvas_draw_line( + gui->canvas, + 1, canvas_height(gui->canvas) - 2, canvas_width(gui->canvas) - 2, canvas_height(gui->canvas) - 2); - - canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width + 5, GUI_STATUS_BAR_HEIGHT); - - canvas_set_color(gui->canvas, ColorWhite); - canvas_draw_box(gui->canvas, 2, 1, width + 2, 10); - canvas_set_color(gui->canvas, ColorBlack); - - canvas_frame_set( - gui->canvas, x + 3, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); - canvas_draw_icon(gui->canvas, 0, 0, &I_Attention_5x8); } } diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index 5f7eeb84713..ac1856e752c 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -11,20 +11,21 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { furi_assert(context); Power* power = context; - canvas_draw_icon(canvas, 0, 1, &I_Battery_26x8); + canvas_draw_icon(canvas, 0, 0, &I_Battery_26x8); if(power->info.gauge_is_ok) { - canvas_draw_box(canvas, 2, 3, (power->info.charge + 4) / 5, 4); + canvas_draw_box(canvas, 2, 2, (power->info.charge + 4) / 5, 4); if(power->state == PowerStateCharging) { canvas_set_bitmap_mode(canvas, 1); canvas_set_color(canvas, ColorWhite); - canvas_draw_icon(canvas, 8, 0, &I_Charging_lightning_mask_9x10); + // TODO: replace -1 magic for uint8_t with re-framing + canvas_draw_icon(canvas, 8, -1, &I_Charging_lightning_mask_9x10); canvas_set_color(canvas, ColorBlack); - canvas_draw_icon(canvas, 8, 0, &I_Charging_lightning_9x10); + canvas_draw_icon(canvas, 8, -1, &I_Charging_lightning_9x10); canvas_set_bitmap_mode(canvas, 0); } } else { - canvas_draw_box(canvas, 8, 4, 8, 2); + canvas_draw_box(canvas, 8, 3, 8, 2); } } From 23cff2a7d2a2e1483cea10f7d6ace84222e2ed72 Mon Sep 17 00:00:00 2001 From: hedger Date: Sun, 8 May 2022 19:33:47 +0300 Subject: [PATCH 10/24] [FL-2526] SubGhz: fixed receiver list scrolling #1207 --- applications/subghz/views/receiver.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/applications/subghz/views/receiver.c b/applications/subghz/views/receiver.c index fc66e4fdd89..7b19cbcf243 100644 --- a/applications/subghz/views/receiver.c +++ b/applications/subghz/views/receiver.c @@ -68,14 +68,13 @@ static void subghz_view_receiver_update_offset(SubGhzViewReceiver* subghz_receiv size_t history_item = model->history_item; uint16_t bounds = history_item > 3 ? 2 : history_item; - if(history_item > 3 && model->idx >= history_item - 1) { + if(history_item > 3 && model->idx >= (int16_t)(history_item - 1)) { model->list_offset = model->idx - 3; } else if(model->list_offset < model->idx - bounds) { - model->list_offset = CLAMP( - (uint16_t)(model->list_offset + 1), (uint16_t)(history_item - bounds), 0); - } else if(model->list_offset > model->idx - bounds) { model->list_offset = - CLAMP((uint16_t)(model->idx - 1), (uint16_t)(history_item - bounds), 0); + CLAMP(model->list_offset + 1, (int16_t)(history_item - bounds), 0); + } else if(model->list_offset > model->idx - bounds) { + model->list_offset = CLAMP(model->idx - 1, (int16_t)(history_item - bounds), 0); } return true; }); From f04d0eea9683d45cea6b8761f4598fcbf07e023d Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Sun, 8 May 2022 21:50:20 +0400 Subject: [PATCH 11/24] SubGhz: add protocol MegaCode (#1204) * SubGhz: add protocol MegaCode * SubGhz: check for guard time injection at the end of buffer * SubGhz: rollback samples counting in trasmitter * SubGhz: fix subghz_file_encoder_worker incorrect pulse sequence * Input: tune debounce interval * SubGhz: fix spelling in subghz_file_encoder_worker_add_level_duration Co-authored-by: Aleksandr Kutuzov --- .../subghz/scenes/subghz_scene_read_raw.c | 3 +- .../subghz/scenes/subghz_scene_set_type.c | 4 +- .../targets/f7/furi_hal/furi_hal_resources.h | 2 +- .../targets/f7/furi_hal/furi_hal_subghz.c | 3 + lib/subghz/protocols/megacode.c | 413 ++++++++++++++++++ lib/subghz/protocols/megacode.h | 109 +++++ lib/subghz/protocols/registry.c | 2 +- lib/subghz/protocols/registry.h | 1 + lib/subghz/subghz_file_encoder_worker.c | 23 +- lib/subghz/transmitter.c | 11 +- lib/subghz/transmitter.h | 10 +- 11 files changed, 556 insertions(+), 25 deletions(-) create mode 100644 lib/subghz/protocols/megacode.c create mode 100644 lib/subghz/protocols/megacode.h diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index 88d0686ba17..767f09248ff 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -202,7 +202,8 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { DOLPHIN_DEED(DolphinDeedSubGhzSend); // set callback end tx subghz_protocol_raw_file_encoder_worker_set_callback_end( - (SubGhzProtocolEncoderRAW*)subghz->txrx->transmitter->protocol_instance, + (SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance( + subghz->txrx->transmitter), subghz_scene_read_raw_callback_end_tx, subghz); subghz->state_notifications = SubGhzNotificationStateTx; diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index 964b85b2fed..9dad8cd9a76 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -268,7 +268,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); if(subghz->txrx->transmitter) { subghz_protocol_keeloq_create_data( - subghz->txrx->transmitter->protocol_instance, + subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), subghz->txrx->fff_data, key & 0x0FFFFFFF, 0x2, @@ -292,7 +292,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); if(subghz->txrx->transmitter) { subghz_protocol_keeloq_create_data( - subghz->txrx->transmitter->protocol_instance, + subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), subghz->txrx->fff_data, key & 0x0FFFFFFF, 0x2, diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index 69485307b1a..f12edcb30d4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -10,7 +10,7 @@ extern "C" { #endif /* Input Related Constants */ -#define INPUT_DEBOUNCE_TICKS 20 +#define INPUT_DEBOUNCE_TICKS 30 /* Input Keys */ typedef enum { diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 956342ffdbe..c5b5043b4f0 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -799,6 +799,9 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { } else { furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; } + // This code must be invoked only once: when encoder starts with low level. + // Otherwise whole thing will crash. + furi_check(samples > 0); } uint32_t duration = level_duration_get_duration(ld); diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c new file mode 100644 index 00000000000..48a6908e9ea --- /dev/null +++ b/lib/subghz/protocols/megacode.c @@ -0,0 +1,413 @@ +#include "megacode.h" + +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +/* + * Help + * https://wiki.cuvoodoo.info/doku.php?id=megacode + * https://wiki.cuvoodoo.info/lib/exe/fetch.php?media=megacode:megacode_1.pdf + * https://fccid.io/EF4ACP00872/Test-Report/Megacode-2-112615.pdf + * https://github.com/aaronsp777/megadecoder + * https://github.com/rjmendez/Linear_keyfob + * https://github.com/j07rdi/Linear_MegaCode_Garage_Remote + * + */ + +#define TAG "SubGhzProtocolMegaCode" + +static const SubGhzBlockConst subghz_protocol_megacode_const = { + .te_short = 1000, + .te_long = 1000, + .te_delta = 200, + .min_count_bit_for_found = 24, +}; + +struct SubGhzProtocolDecoderMegaCode { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + uint8_t last_bit; +}; + +struct SubGhzProtocolEncoderMegaCode { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + MegaCodeDecoderStepReset = 0, + MegaCodeDecoderStepFoundStartBit, + MegaCodeDecoderStepSaveDuration, + MegaCodeDecoderStepCheckDuration, +} MegaCodeDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_megacode_decoder = { + .alloc = subghz_protocol_decoder_megacode_alloc, + .free = subghz_protocol_decoder_megacode_free, + + .feed = subghz_protocol_decoder_megacode_feed, + .reset = subghz_protocol_decoder_megacode_reset, + + .get_hash_data = subghz_protocol_decoder_megacode_get_hash_data, + .serialize = subghz_protocol_decoder_megacode_serialize, + .deserialize = subghz_protocol_decoder_megacode_deserialize, + .get_string = subghz_protocol_decoder_megacode_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_megacode_encoder = { + .alloc = subghz_protocol_encoder_megacode_alloc, + .free = subghz_protocol_encoder_megacode_free, + + .deserialize = subghz_protocol_encoder_megacode_deserialize, + .stop = subghz_protocol_encoder_megacode_stop, + .yield = subghz_protocol_encoder_megacode_yield, +}; + +const SubGhzProtocol subghz_protocol_megacode = { + .name = SUBGHZ_PROTOCOL_MEGACODE_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_megacode_decoder, + .encoder = &subghz_protocol_megacode_encoder, +}; + +void* subghz_protocol_encoder_megacode_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderMegaCode* instance = malloc(sizeof(SubGhzProtocolEncoderMegaCode)); + + instance->base.protocol = &subghz_protocol_megacode; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 52; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_runing = false; + return instance; +} + +void subghz_protocol_encoder_megacode_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderMegaCode* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderMegaCode instance + * @return true On success + */ +static bool subghz_protocol_encoder_megacode_get_upload(SubGhzProtocolEncoderMegaCode* instance) { + furi_assert(instance); + uint8_t last_bit = 0; + size_t size_upload = (instance->generic.data_count_bit * 2); + if(size_upload > instance->encoder.size_upload) { + FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); + return false; + } else { + instance->encoder.size_upload = size_upload; + } + + /* + * Due to the nature of the protocol + * + * 00000 1 + * _____|-| = 1 becomes + * + * 00 1 000 + * __|-|___ = 0 becomes + * + * it's easier for us to generate an upload backwards + */ + + size_t index = size_upload - 1; + + // Send end level + instance->encoder.upload[index--] = + level_duration_make(true, (uint32_t)subghz_protocol_megacode_const.te_short); + if(bit_read(instance->generic.data, 0)) { + last_bit = 1; + } else { + last_bit = 0; + } + + //Send key data + for(uint8_t i = 1; i < instance->generic.data_count_bit; i++) { + if(bit_read(instance->generic.data, i)) { + //if bit 1 + instance->encoder.upload[index--] = level_duration_make( + false, + last_bit ? (uint32_t)subghz_protocol_megacode_const.te_short * 5 : + (uint32_t)subghz_protocol_megacode_const.te_short * 2); + last_bit = 1; + } else { + //if bit 0 + instance->encoder.upload[index--] = level_duration_make( + false, + last_bit ? (uint32_t)subghz_protocol_megacode_const.te_short * 8 : + (uint32_t)subghz_protocol_megacode_const.te_short * 5); + last_bit = 0; + } + instance->encoder.upload[index--] = + level_duration_make(true, (uint32_t)subghz_protocol_megacode_const.te_short); + } + + //Send PT_GUARD + if(bit_read(instance->generic.data, 0)) { + //if end bit 1 + instance->encoder.upload[index] = + level_duration_make(false, (uint32_t)subghz_protocol_megacode_const.te_short * 11); + } else { + //if end bit 1 + instance->encoder.upload[index] = + level_duration_make(false, (uint32_t)subghz_protocol_megacode_const.te_short * 14); + } + + return true; +} + +bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderMegaCode* instance = context; + bool res = false; + do { + if(!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_megacode_get_upload(instance); + instance->encoder.is_runing = true; + + res = true; + } while(false); + + return res; +} + +void subghz_protocol_encoder_megacode_stop(void* context) { + SubGhzProtocolEncoderMegaCode* instance = context; + instance->encoder.is_runing = false; +} + +LevelDuration subghz_protocol_encoder_megacode_yield(void* context) { + SubGhzProtocolEncoderMegaCode* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) { + instance->encoder.is_runing = 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_megacode_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderMegaCode* instance = malloc(sizeof(SubGhzProtocolDecoderMegaCode)); + instance->base.protocol = &subghz_protocol_megacode; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_megacode_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMegaCode* instance = context; + free(instance); +} + +void subghz_protocol_decoder_megacode_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMegaCode* instance = context; + instance->decoder.parser_step = MegaCodeDecoderStepReset; +} + +void subghz_protocol_decoder_megacode_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderMegaCode* instance = context; + switch(instance->decoder.parser_step) { + case MegaCodeDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short * 13) < + subghz_protocol_megacode_const.te_delta * 15)) { //10..16ms + //Found header MegaCode + instance->decoder.parser_step = MegaCodeDecoderStepFoundStartBit; + } + break; + case MegaCodeDecoderStepFoundStartBit: + if(level && (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short) < + subghz_protocol_megacode_const.te_delta)) { + //Found start bit MegaCode + instance->decoder.parser_step = MegaCodeDecoderStepSaveDuration; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->last_bit = 1; + + } else { + instance->decoder.parser_step = MegaCodeDecoderStepReset; + } + break; + case MegaCodeDecoderStepSaveDuration: + if(!level) { //save interval + if(duration >= (subghz_protocol_megacode_const.te_short * 10)) { + instance->decoder.parser_step = MegaCodeDecoderStepReset; + if(instance->decoder.decode_count_bit >= + subghz_protocol_megacode_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); + } + break; + } + + if(!instance->last_bit) { + instance->decoder.te_last = duration - subghz_protocol_megacode_const.te_short * 3; + } else { + instance->decoder.te_last = duration; + } + instance->decoder.parser_step = MegaCodeDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = MegaCodeDecoderStepReset; + } + break; + case MegaCodeDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_megacode_const.te_short * 5) < + subghz_protocol_megacode_const.te_delta * 5) && + (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short) < + subghz_protocol_megacode_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->last_bit = 1; + instance->decoder.parser_step = MegaCodeDecoderStepSaveDuration; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_megacode_const.te_short * 2) < + subghz_protocol_megacode_const.te_delta * 2) && + (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short) < + subghz_protocol_megacode_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->last_bit = 0; + instance->decoder.parser_step = MegaCodeDecoderStepSaveDuration; + } else + instance->decoder.parser_step = MegaCodeDecoderStepReset; + } else { + instance->decoder.parser_step = MegaCodeDecoderStepReset; + } + break; + } +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_megacode_check_remote_controller(SubGhzBlockGeneric* instance) { + /* + * Short: 1000 µs + * Long: 1000 µs + * Gap: 11000 .. 14000 µs + * A Linear Megacode transmission consists of 24 bit frames starting with + * the most significant bit and ending with the least. Each of the 24 bit + * frames is 6 milliseconds wide and always contains a single 1 millisecond + * pulse. A frame with more than 1 pulse or a frame with no pulse is invalid + * and a receiver should reset and begin watching for another start bit. + * Start bit is always 1. + * + * + * Example (I created with my own remote): + * Remote “A” has the code “17316”, a Facility Code of “3”, and a single button. + * Start bit (S) = 1 + * Facility Code 3 (F) = 0011 + * Remote Code (Key) 17316 = 43A4 = 0100001110100100 + * Button (Btn) 1 = 001 + * S F Key Btn + * Result = 1|0011|0100001110100100|001 + * + * 00000 1 + * _____|-| = 1 becomes + * + * 00 1 000 + * __|-|___ = 0 becomes + * + * The device needs to transmit with a 9000 µs gap between retransmissions: + * 000001 001000 001000 000001 000001 001000 000001 001000 001000 001000 001000 000001 + * 000001 000001 001000 000001 001000 001000 000001 001000 001000 001000 001000 000001 + * wait 9000 µs + * 000001 001000 001000 000001 000001 001000 000001 001000 001000 001000 001000 000001 + * 000001 000001 001000 000001 001000 001000 000001 001000 001000 001000 001000 000001 + * + */ + if((instance->data >> 23) == 1) { + instance->serial = (instance->data >> 3) & 0xFFFF; + instance->btn = instance->data & 0b111; + instance->cnt = (instance->data >> 19) & 0b1111; + } else { + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + } +} + +uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMegaCode* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +bool subghz_protocol_decoder_megacode_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset) { + furi_assert(context); + SubGhzProtocolDecoderMegaCode* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); +} + +bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderMegaCode* instance = context; + return subghz_block_generic_deserialize(&instance->generic, flipper_format); +} + +void subghz_protocol_decoder_megacode_get_string(void* context, string_t output) { + furi_assert(context); + SubGhzProtocolDecoderMegaCode* instance = context; + subghz_protocol_megacode_check_remote_controller(&instance->generic); + + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:%06lX\r\n" + "Sn:%04lX Btn:%X\r\n" + "Facility:%X\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)instance->generic.data, + instance->generic.serial, + instance->generic.btn, + instance->generic.cnt); +} diff --git a/lib/subghz/protocols/megacode.h b/lib/subghz/protocols/megacode.h new file mode 100644 index 00000000000..1a3cfd5d3f8 --- /dev/null +++ b/lib/subghz/protocols/megacode.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_MEGACODE_NAME "MegaCode" + +typedef struct SubGhzProtocolDecoderMegaCode SubGhzProtocolDecoderMegaCode; +typedef struct SubGhzProtocolEncoderMegaCode SubGhzProtocolEncoderMegaCode; + +extern const SubGhzProtocolDecoder subghz_protocol_megacode_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_megacode_encoder; +extern const SubGhzProtocol subghz_protocol_megacode; + +/** + * Allocate SubGhzProtocolEncoderMegaCode. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderMegaCode* pointer to a SubGhzProtocolEncoderMegaCode instance + */ +void* subghz_protocol_encoder_megacode_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderMegaCode. + * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance + */ +void subghz_protocol_encoder_megacode_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance + */ +void subghz_protocol_encoder_megacode_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_megacode_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderMegaCode. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderMegaCode* pointer to a SubGhzProtocolDecoderMegaCode instance + */ +void* subghz_protocol_decoder_megacode_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderMegaCode. + * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance + */ +void subghz_protocol_decoder_megacode_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderMegaCode. + * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance + */ +void subghz_protocol_decoder_megacode_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_megacode_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderMegaCode. + * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param frequency The frequency at which the signal was received, Hz + * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @return true On success + */ +bool subghz_protocol_decoder_megacode_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset); + +/** + * Deserialize data SubGhzProtocolDecoderMegaCode. + * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance + * @param output Resulting text + */ +void subghz_protocol_decoder_megacode_get_string(void* context, string_t output); diff --git a/lib/subghz/protocols/registry.c b/lib/subghz/protocols/registry.c index a88603b64ac..0741da93931 100644 --- a/lib/subghz/protocols/registry.c +++ b/lib/subghz/protocols/registry.c @@ -8,7 +8,7 @@ const SubGhzProtocol* subghz_protocol_registry[] = { &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis, &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_gate_tx, &subghz_protocol_raw, &subghz_protocol_firefly, &subghz_protocol_secplus_v2, - &subghz_protocol_secplus_v1, + &subghz_protocol_secplus_v1, &subghz_protocol_megacode, }; diff --git a/lib/subghz/protocols/registry.h b/lib/subghz/protocols/registry.h index 8d904fe1f59..abd5697dac7 100644 --- a/lib/subghz/protocols/registry.h +++ b/lib/subghz/protocols/registry.h @@ -24,6 +24,7 @@ #include "firefly.h" #include "secplus_v2.h" #include "secplus_v1.h" +#include "megacode.h" /** * Registration by name SubGhzProtocol. diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 91538e1f2ea..abc679bcee8 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -19,7 +19,6 @@ struct SubGhzFileEncoderWorker { volatile bool worker_running; volatile bool worker_stoping; bool level; - int32_t duration; string_t str_data; string_t file_path; @@ -37,25 +36,21 @@ void subghz_file_encoder_worker_callback_end( instance->context_end = context_end; } -void subghz_file_encoder_worker_add_livel_duration( +void subghz_file_encoder_worker_add_level_duration( SubGhzFileEncoderWorker* instance, int32_t duration) { bool res = true; if(duration < 0 && !instance->level) { - instance->duration += duration; res = false; } else if(duration > 0 && instance->level) { - instance->duration += duration; res = false; - } else if(duration == 0) { - instance->duration = 0; } if(res) { instance->level = !instance->level; - instance->duration += duration; - xStreamBufferSend(instance->stream, &instance->duration, sizeof(int32_t), 10); - instance->duration = 0; + xStreamBufferSend(instance->stream, &duration, sizeof(int32_t), 100); + } else { + FURI_LOG_E(TAG, "Invalid level in the stream"); } } @@ -80,7 +75,7 @@ bool subghz_file_encoder_worker_data_parse( ind_start))) { //check that there is still an element in the line and that it has not gone beyond the line str1 = strchr(str1, ' '); str1 += 1; //if found, shift the pointer by next element per line - subghz_file_encoder_worker_add_livel_duration(instance, atoi(str1)); + subghz_file_encoder_worker_add_level_duration(instance, atoi(str1)); } res = true; } @@ -152,14 +147,14 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { string_get_cstr(instance->str_data), strlen(string_get_cstr(instance->str_data)))) { //to stop DMA correctly - subghz_file_encoder_worker_add_livel_duration(instance, LEVEL_DURATION_RESET); - subghz_file_encoder_worker_add_livel_duration(instance, LEVEL_DURATION_RESET); + subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); + subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); break; } } else { - subghz_file_encoder_worker_add_livel_duration(instance, LEVEL_DURATION_RESET); - subghz_file_encoder_worker_add_livel_duration(instance, LEVEL_DURATION_RESET); + subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); + subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); break; } } diff --git a/lib/subghz/transmitter.c b/lib/subghz/transmitter.c index c74c38ea053..0dc2bacde41 100644 --- a/lib/subghz/transmitter.c +++ b/lib/subghz/transmitter.c @@ -3,6 +3,11 @@ #include "protocols/base.h" #include "protocols/registry.h" +struct SubGhzTransmitter { + const SubGhzProtocol* protocol; + SubGhzProtocolEncoderBase* protocol_instance; +}; + SubGhzTransmitter* subghz_transmitter_alloc_init(SubGhzEnvironment* environment, const char* protocol_name) { SubGhzTransmitter* instance = NULL; @@ -23,6 +28,11 @@ void subghz_transmitter_free(SubGhzTransmitter* instance) { free(instance); } +SubGhzProtocolEncoderBase* subghz_transmitter_get_protocol_instance(SubGhzTransmitter* instance) { + furi_assert(instance); + return instance->protocol_instance; +} + bool subghz_transmitter_stop(SubGhzTransmitter* instance) { furi_assert(instance); bool ret = false; @@ -46,6 +56,5 @@ bool subghz_transmitter_deserialize(SubGhzTransmitter* instance, FlipperFormat* LevelDuration subghz_transmitter_yield(void* context) { SubGhzTransmitter* instance = context; - return instance->protocol->encoder->yield(instance->protocol_instance); } diff --git a/lib/subghz/transmitter.h b/lib/subghz/transmitter.h index 205a3eee562..53f10b07565 100644 --- a/lib/subghz/transmitter.h +++ b/lib/subghz/transmitter.h @@ -6,11 +6,6 @@ typedef struct SubGhzTransmitter SubGhzTransmitter; -struct SubGhzTransmitter { - const SubGhzProtocol* protocol; - SubGhzProtocolEncoderBase* protocol_instance; -}; - /** * Allocate and init SubGhzTransmitter. * @param environment Pointer to a SubGhzEnvironment instance @@ -25,6 +20,11 @@ SubGhzTransmitter* */ void subghz_transmitter_free(SubGhzTransmitter* instance); +/** Get protocol instance. + * @param instance Pointer to a SubGhzTransmitter instance + */ +SubGhzProtocolEncoderBase* subghz_transmitter_get_protocol_instance(SubGhzTransmitter* instance); + /** * Forced transmission stop. * @param instance Pointer to a SubGhzTransmitter instance From fac4391af72711ec28104a192426548e440a3000 Mon Sep 17 00:00:00 2001 From: SG Date: Wed, 11 May 2022 00:05:36 +1000 Subject: [PATCH 12/24] [FL-2499] Folders rename fix (#1190) * Toolbox: dir_walk concept (like os.walk) * Storage CLI: tree command * Storage: fix folders copying, stage 1 * UnitTest: proper delays in subghz tests * Toolbox: dir_walk, recursive and filter options * dir_walk: unit tests * Merge: Fix unused param * SubGhz: cleaned up data parsing routine * SubGhz unit test: cleaned up logs, yield data load * SubGhz unit test: naming Co-authored-by: Aleksandr Kutuzov --- applications/storage/storage.h | 4 +- applications/storage/storage_cli.c | 45 +++ applications/storage/storage_external_api.c | 62 +++- .../unit_tests/storage/dirwalk_test.c | 272 ++++++++++++++++++ .../unit_tests/storage/storage_test.c | 145 ++++++++++ applications/unit_tests/subghz/subghz_test.c | 102 +++---- applications/unit_tests/test_index.c | 2 + lib/subghz/subghz_file_encoder_worker.c | 33 +-- lib/toolbox/dir_walk.c | 152 ++++++++++ lib/toolbox/dir_walk.h | 79 +++++ 10 files changed, 822 insertions(+), 74 deletions(-) create mode 100644 applications/unit_tests/storage/dirwalk_test.c create mode 100644 lib/toolbox/dir_walk.c create mode 100644 lib/toolbox/dir_walk.h diff --git a/applications/storage/storage.h b/applications/storage/storage.h index eecd1beb4c3..1e6ced23b84 100644 --- a/applications/storage/storage.h +++ b/applications/storage/storage.h @@ -282,7 +282,7 @@ FS_Error storage_int_restore(Storage* api, const char* dstname); /***************** Simplified Functions ******************/ /** - * Removes a file/directory from the repository, the directory must be empty and the file/directory must not be open + * Removes a file/directory, the directory must be empty and the file/directory must not be open * @param storage pointer to the api * @param path * @return true on success or if file/dir is not exist @@ -290,7 +290,7 @@ FS_Error storage_int_restore(Storage* api, const char* dstname); bool storage_simply_remove(Storage* storage, const char* path); /** - * Removes a file/directory from the repository, the directory can be not empty + * Recursively removes a file/directory, the directory can be not empty * @param storage pointer to the api * @param path * @return true on success or if file/dir is not exist diff --git a/applications/storage/storage_cli.c b/applications/storage/storage_cli.c index 70da21d216c..b35e37a892e 100644 --- a/applications/storage/storage_cli.c +++ b/applications/storage/storage_cli.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ static void storage_cli_print_usage() { printf("\tinfo\t - get FS info\r\n"); printf("\tformat\t - format filesystem\r\n"); printf("\tlist\t - list files and dirs\r\n"); + printf("\ttree\t - list files and dirs, recursive\r\n"); printf("\tremove\t - delete the file or directory\r\n"); printf("\tread\t - read text from file and print file size and content to cli\r\n"); printf( @@ -138,6 +140,44 @@ static void storage_cli_list(Cli* cli, string_t path) { } } +static void storage_cli_tree(Cli* cli, string_t path) { + if(string_cmp_str(path, "/") == 0) { + string_set(path, "/int"); + storage_cli_tree(cli, path); + string_set(path, "/ext"); + storage_cli_tree(cli, path); + } else { + Storage* api = furi_record_open("storage"); + DirWalk* dir_walk = dir_walk_alloc(api); + string_t name; + string_init(name); + + if(dir_walk_open(dir_walk, string_get_cstr(path))) { + FileInfo fileinfo; + bool read_done = false; + + while(dir_walk_read(dir_walk, name, &fileinfo) == DirWalkOK) { + read_done = true; + if(fileinfo.flags & FSF_DIRECTORY) { + printf("\t[D] %s\r\n", string_get_cstr(name)); + } else { + printf("\t[F] %s %lub\r\n", string_get_cstr(name), (uint32_t)(fileinfo.size)); + } + } + + if(!read_done) { + printf("\tEmpty\r\n"); + } + } else { + storage_cli_print_error(dir_walk_get_error(dir_walk)); + } + + string_clear(name); + dir_walk_free(dir_walk); + furi_record_close("storage"); + } +} + static void storage_cli_read(Cli* cli, string_t path) { UNUSED(cli); Storage* api = furi_record_open("storage"); @@ -474,6 +514,11 @@ void storage_cli(Cli* cli, string_t args, void* context) { break; } + if(string_cmp_str(cmd, "tree") == 0) { + storage_cli_tree(cli, path); + break; + } + if(string_cmp_str(cmd, "read") == 0) { storage_cli_read(cli, path); break; diff --git a/applications/storage/storage_external_api.c b/applications/storage/storage_external_api.c index 1335c7080f8..7f600af23a4 100644 --- a/applications/storage/storage_external_api.c +++ b/applications/storage/storage_external_api.c @@ -4,6 +4,7 @@ #include "storage_i.h" #include "storage_message.h" #include +#include #define MAX_NAME_LENGTH 256 @@ -332,12 +333,69 @@ FS_Error storage_common_remove(Storage* storage, const char* path) { FS_Error storage_common_rename(Storage* storage, const char* old_path, const char* new_path) { FS_Error error = storage_common_copy(storage, old_path, new_path); if(error == FSE_OK) { - error = storage_common_remove(storage, old_path); + if(storage_simply_remove_recursive(storage, old_path)) { + error = FSE_OK; + } else { + error = FSE_INTERNAL; + } } return error; } +static FS_Error + storage_copy_recursive(Storage* storage, const char* old_path, const char* new_path) { + FS_Error error = storage_common_mkdir(storage, new_path); + DirWalk* dir_walk = dir_walk_alloc(storage); + string_t path; + string_t tmp_new_path; + string_t tmp_old_path; + FileInfo fileinfo; + string_init(path); + string_init(tmp_new_path); + string_init(tmp_old_path); + + do { + if(error != FSE_OK) break; + + if(!dir_walk_open(dir_walk, old_path)) { + error = dir_walk_get_error(dir_walk); + break; + } + + while(1) { + DirWalkResult res = dir_walk_read(dir_walk, path, &fileinfo); + + if(res == DirWalkError) { + error = dir_walk_get_error(dir_walk); + break; + } else if(res == DirWalkLast) { + break; + } else { + string_set(tmp_old_path, path); + string_right(path, strlen(old_path)); + string_printf(tmp_new_path, "%s%s", new_path, string_get_cstr(path)); + + if(fileinfo.flags & FSF_DIRECTORY) { + error = storage_common_mkdir(storage, string_get_cstr(tmp_new_path)); + } else { + error = storage_common_copy( + storage, string_get_cstr(tmp_old_path), string_get_cstr(tmp_new_path)); + } + + if(error != FSE_OK) break; + } + } + + } while(false); + + string_clear(tmp_new_path); + string_clear(tmp_old_path); + string_clear(path); + dir_walk_free(dir_walk); + return error; +} + FS_Error storage_common_copy(Storage* storage, const char* old_path, const char* new_path) { FS_Error error; @@ -346,7 +404,7 @@ FS_Error storage_common_copy(Storage* storage, const char* old_path, const char* if(error == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { - error = storage_common_mkdir(storage, new_path); + error = storage_copy_recursive(storage, old_path, new_path); } else { Stream* stream_from = file_stream_alloc(storage); Stream* stream_to = file_stream_alloc(storage); diff --git a/applications/unit_tests/storage/dirwalk_test.c b/applications/unit_tests/storage/dirwalk_test.c new file mode 100644 index 00000000000..25e12259657 --- /dev/null +++ b/applications/unit_tests/storage/dirwalk_test.c @@ -0,0 +1,272 @@ +#include "../minunit.h" +#include +#include +#include + +static const char* const storage_test_dirwalk_paths[] = { + "1", + "11", + "111", + "1/2", + "1/22", + "1/222", + "11/2", + "111/2", + "111/22", + "111/22/33", +}; + +static const char* const storage_test_dirwalk_files[] = { + "file1.test", + "file2.test", + "file3.ext_test", + "1/file1.test", + "111/22/33/file1.test", + "111/22/33/file2.test", + "111/22/33/file3.ext_test", + "111/22/33/file4.ext_test", +}; + +typedef struct { + const char* const path; + bool is_dir; +} StorageTestPathDesc; + +const StorageTestPathDesc storage_test_dirwalk_full[] = { + {.path = "1", .is_dir = true}, + {.path = "11", .is_dir = true}, + {.path = "111", .is_dir = true}, + {.path = "1/2", .is_dir = true}, + {.path = "1/22", .is_dir = true}, + {.path = "1/222", .is_dir = true}, + {.path = "11/2", .is_dir = true}, + {.path = "111/2", .is_dir = true}, + {.path = "111/22", .is_dir = true}, + {.path = "111/22/33", .is_dir = true}, + {.path = "file1.test", .is_dir = false}, + {.path = "file2.test", .is_dir = false}, + {.path = "file3.ext_test", .is_dir = false}, + {.path = "1/file1.test", .is_dir = false}, + {.path = "111/22/33/file1.test", .is_dir = false}, + {.path = "111/22/33/file2.test", .is_dir = false}, + {.path = "111/22/33/file3.ext_test", .is_dir = false}, + {.path = "111/22/33/file4.ext_test", .is_dir = false}, +}; + +const StorageTestPathDesc storage_test_dirwalk_no_recursive[] = { + {.path = "1", .is_dir = true}, + {.path = "11", .is_dir = true}, + {.path = "111", .is_dir = true}, + {.path = "file1.test", .is_dir = false}, + {.path = "file2.test", .is_dir = false}, + {.path = "file3.ext_test", .is_dir = false}, +}; + +const StorageTestPathDesc storage_test_dirwalk_filter[] = { + {.path = "file1.test", .is_dir = false}, + {.path = "file2.test", .is_dir = false}, + {.path = "1/file1.test", .is_dir = false}, + {.path = "111/22/33/file1.test", .is_dir = false}, + {.path = "111/22/33/file2.test", .is_dir = false}, +}; + +typedef struct { + bool is_dir; + bool visited; +} StorageTestPath; + +DICT_DEF2(StorageTestPathDict, string_t, STRING_OPLIST, StorageTestPath, M_POD_OPLIST) + +static StorageTestPathDict_t* + storage_test_paths_alloc(const StorageTestPathDesc paths[], size_t paths_count) { + StorageTestPathDict_t* data = malloc(sizeof(StorageTestPathDict_t)); + StorageTestPathDict_init(*data); + + for(size_t i = 0; i < paths_count; i++) { + string_t key; + string_init_set(key, paths[i].path); + StorageTestPath value = { + .is_dir = paths[i].is_dir, + .visited = false, + }; + + StorageTestPathDict_set_at(*data, key, value); + string_clear(key); + } + + return data; +} + +static void storage_test_paths_free(StorageTestPathDict_t* data) { + StorageTestPathDict_clear(*data); + free(data); +} + +static bool storage_test_paths_mark(StorageTestPathDict_t* data, string_t path, bool is_dir) { + bool found = false; + + StorageTestPath* record = StorageTestPathDict_get(*data, path); + if(record) { + if(is_dir == record->is_dir) { + if(record->visited == false) { + record->visited = true; + found = true; + } + } + } + + return found; +} + +static bool storage_test_paths_check(StorageTestPathDict_t* data) { + bool error = false; + + StorageTestPathDict_it_t it; + for(StorageTestPathDict_it(it, *data); !StorageTestPathDict_end_p(it); + StorageTestPathDict_next(it)) { + const StorageTestPathDict_itref_t* itref = StorageTestPathDict_cref(it); + + if(itref->value.visited == false) { + error = true; + break; + } + } + + return error; +} + +static bool write_file_13DA(Storage* storage, const char* path) { + File* file = storage_file_alloc(storage); + bool result = false; + if(storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + result = storage_file_write(file, "13DA", 4) == 4; + } + storage_file_close(file); + storage_file_free(file); + + return result; +} + +static void storage_dirs_create(Storage* storage, const char* base) { + string_t path; + string_init(path); + + storage_common_mkdir(storage, base); + + for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_paths); i++) { + string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]); + storage_common_mkdir(storage, string_get_cstr(path)); + } + + for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_files); i++) { + string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]); + write_file_13DA(storage, string_get_cstr(path)); + } + + string_clear(path); +} + +MU_TEST_1(test_dirwalk_full, Storage* storage) { + string_t path; + string_init(path); + FileInfo fileinfo; + + StorageTestPathDict_t* paths = + storage_test_paths_alloc(storage_test_dirwalk_full, COUNT_OF(storage_test_dirwalk_full)); + + DirWalk* dir_walk = dir_walk_alloc(storage); + mu_check(dir_walk_open(dir_walk, "/ext/dirwalk")); + + while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { + string_right(path, strlen("/ext/dirwalk/")); + mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); + } + + dir_walk_free(dir_walk); + string_clear(path); + + mu_check(storage_test_paths_check(paths) == false); + + storage_test_paths_free(paths); +} + +MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) { + string_t path; + string_init(path); + FileInfo fileinfo; + + StorageTestPathDict_t* paths = storage_test_paths_alloc( + storage_test_dirwalk_no_recursive, COUNT_OF(storage_test_dirwalk_no_recursive)); + + DirWalk* dir_walk = dir_walk_alloc(storage); + dir_walk_set_recursive(dir_walk, false); + mu_check(dir_walk_open(dir_walk, "/ext/dirwalk")); + + while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { + string_right(path, strlen("/ext/dirwalk/")); + mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); + } + + dir_walk_free(dir_walk); + string_clear(path); + + mu_check(storage_test_paths_check(paths) == false); + + storage_test_paths_free(paths); +} + +static bool test_dirwalk_filter_no_folder_ext(const char* name, FileInfo* fileinfo, void* ctx) { + UNUSED(ctx); + + // only files + if(!(fileinfo->flags & FSF_DIRECTORY)) { + // with ".test" in name + if(strstr(name, ".test") != NULL) { + return true; + } + } + + return false; +} + +MU_TEST_1(test_dirwalk_filter, Storage* storage) { + string_t path; + string_init(path); + FileInfo fileinfo; + + StorageTestPathDict_t* paths = storage_test_paths_alloc( + storage_test_dirwalk_filter, COUNT_OF(storage_test_dirwalk_filter)); + + DirWalk* dir_walk = dir_walk_alloc(storage); + dir_walk_set_filter_cb(dir_walk, test_dirwalk_filter_no_folder_ext, NULL); + mu_check(dir_walk_open(dir_walk, "/ext/dirwalk")); + + while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { + string_right(path, strlen("/ext/dirwalk/")); + mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); + } + + dir_walk_free(dir_walk); + string_clear(path); + + mu_check(storage_test_paths_check(paths) == false); + + storage_test_paths_free(paths); +} + +MU_TEST_SUITE(test_dirwalk_suite) { + Storage* storage = furi_record_open("storage"); + storage_dirs_create(storage, "/ext/dirwalk"); + + MU_RUN_TEST_1(test_dirwalk_full, storage); + MU_RUN_TEST_1(test_dirwalk_no_recursive, storage); + MU_RUN_TEST_1(test_dirwalk_filter, storage); + + storage_simply_remove_recursive(storage, "/ext/dirwalk"); + furi_record_close("storage"); +} + +int run_minunit_test_dirwalk() { + MU_RUN_SUITE(test_dirwalk_suite); + return MU_EXIT_CODE; +} \ No newline at end of file diff --git a/applications/unit_tests/storage/storage_test.c b/applications/unit_tests/storage/storage_test.c index adc5f330d30..9f237bd0f61 100644 --- a/applications/unit_tests/storage/storage_test.c +++ b/applications/unit_tests/storage/storage_test.c @@ -164,8 +164,153 @@ MU_TEST_SUITE(storage_dir) { MU_RUN_TEST(storage_dir_open_lock); } +static const char* const storage_copy_test_paths[] = { + "1", + "11", + "111", + "1/2", + "1/22", + "1/222", + "11/1", + "111/2", + "111/22", + "111/22/33", +}; + +static const char* const storage_copy_test_files[] = { + "file.test", + "1/file.test", + "111/22/33/file.test", +}; + +static bool write_file_13DA(Storage* storage, const char* path) { + File* file = storage_file_alloc(storage); + bool result = false; + if(storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + result = storage_file_write(file, "13DA", 4) == 4; + } + storage_file_close(file); + storage_file_free(file); + + return result; +} + +static bool check_file_13DA(Storage* storage, const char* path) { + File* file = storage_file_alloc(storage); + bool result = false; + if(storage_file_open(file, path, FSAM_READ, FSOM_OPEN_EXISTING)) { + char data[10] = {0}; + result = storage_file_read(file, data, 4) == 4; + if(result) { + result = memcmp(data, "13DA", 4) == 0; + } + } + storage_file_close(file); + storage_file_free(file); + + return result; +} + +static void storage_dir_create(Storage* storage, const char* base) { + string_t path; + string_init(path); + + storage_common_mkdir(storage, base); + + for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) { + string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); + storage_common_mkdir(storage, string_get_cstr(path)); + } + + for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) { + string_printf(path, "%s/%s", base, storage_copy_test_files[i]); + write_file_13DA(storage, string_get_cstr(path)); + } + + string_clear(path); +} + +static void storage_dir_remove(Storage* storage, const char* base) { + storage_simply_remove_recursive(storage, base); +} + +static bool storage_dir_rename_check(Storage* storage, const char* base) { + bool result = false; + string_t path; + string_init(path); + + result = (storage_common_stat(storage, base, NULL) == FSE_OK); + + if(result) { + for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) { + string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); + result = (storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK); + if(!result) { + break; + } + } + } + + if(result) { + for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) { + string_printf(path, "%s/%s", base, storage_copy_test_files[i]); + result = check_file_13DA(storage, string_get_cstr(path)); + if(!result) { + break; + } + } + } + + string_clear(path); + return result; +} + +MU_TEST(storage_file_rename) { + Storage* storage = furi_record_open("storage"); + File* file = storage_file_alloc(storage); + + mu_check(write_file_13DA(storage, "/ext/file.old")); + mu_check(check_file_13DA(storage, "/ext/file.old")); + mu_assert_int_eq(FSE_OK, storage_common_rename(storage, "/ext/file.old", "/ext/file.new")); + mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, "/ext/file.old", NULL)); + mu_assert_int_eq(FSE_OK, storage_common_stat(storage, "/ext/file.new", NULL)); + mu_check(check_file_13DA(storage, "/ext/file.new")); + mu_assert_int_eq(FSE_OK, storage_common_remove(storage, "/ext/file.new")); + + storage_file_free(file); + furi_record_close("storage"); +} + +MU_TEST(storage_dir_rename) { + Storage* storage = furi_record_open("storage"); + + storage_dir_create(storage, "/ext/dir.old"); + + mu_check(storage_dir_rename_check(storage, "/ext/dir.old")); + + mu_assert_int_eq(FSE_OK, storage_common_rename(storage, "/ext/dir.old", "/ext/dir.new")); + mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, "/ext/dir.old", NULL)); + mu_check(storage_dir_rename_check(storage, "/ext/dir.new")); + + storage_dir_remove(storage, "/ext/dir.new"); + mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, "/ext/dir.new", NULL)); + + furi_record_close("storage"); +} + +MU_TEST_SUITE(storage_rename) { + MU_RUN_TEST(storage_file_rename); + MU_RUN_TEST(storage_dir_rename); + + Storage* storage = furi_record_open("storage"); + storage_dir_remove(storage, "/ext/dir.old"); + storage_dir_remove(storage, "/ext/dir.new"); + furi_record_close("storage"); +} + int run_minunit_test_storage() { MU_RUN_SUITE(storage_file); MU_RUN_SUITE(storage_dir); + MU_RUN_SUITE(storage_rename); return MU_EXIT_CODE; } diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index e0fb8b6b8fb..191ca745ce7 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -32,7 +32,7 @@ static void subghz_test_rx_callback( string_init(text); subghz_protocol_decoder_base_get_string(decoder_base, text); subghz_receiver_reset(receiver_handler); - FURI_LOG_I(TAG, "\r\n%s", string_get_cstr(text)); + FURI_LOG_T(TAG, "\r\n%s", string_get_cstr(text)); string_clear(text); subghz_test_decoder_count++; } @@ -54,7 +54,7 @@ static void subghz_test_deinit(void) { subghz_environment_free(environment_handler); } -static bool subghz_decode_test(const char* path, const char* name_decoder) { +static bool subghz_decoder_test(const char* path, const char* name_decoder) { subghz_test_decoder_count = 0; uint32_t test_start = furi_hal_get_tick(); @@ -64,18 +64,18 @@ static bool subghz_decode_test(const char* path, const char* name_decoder) { if(decoder) { file_worker_encoder_handler = subghz_file_encoder_worker_alloc(); if(subghz_file_encoder_worker_start(file_worker_encoder_handler, path)) { - //the worker needs a file in order to open and read part of the file + // the worker needs a file in order to open and read part of the file osDelay(100); LevelDuration level_duration; while(furi_hal_get_tick() - test_start < TEST_TIMEOUT) { - furi_hal_delay_us( - 500); //you need to have time to read from the file from the SD card level_duration = subghz_file_encoder_worker_get_level_duration(file_worker_encoder_handler); if(!level_duration_is_reset(level_duration)) { bool level = level_duration_get_level(level_duration); uint32_t duration = level_duration_get_duration(level_duration); + // Yield, to load data inside the worker + osThreadYield(); decoder->protocol->decoder->feed(decoder, level, duration); } else { break; @@ -88,7 +88,7 @@ static bool subghz_decode_test(const char* path, const char* name_decoder) { } subghz_file_encoder_worker_free(file_worker_encoder_handler); } - FURI_LOG_I(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); + FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); if(furi_hal_get_tick() - test_start > TEST_TIMEOUT) { printf("\033[0;31mTest decoder %s ERROR TimeOut\033[0m\r\n", name_decoder); return false; @@ -97,24 +97,25 @@ static bool subghz_decode_test(const char* path, const char* name_decoder) { } } -static bool subghz_decode_ramdom_test(const char* path) { +static bool subghz_decode_random_test(const char* path) { subghz_test_decoder_count = 0; subghz_receiver_reset(receiver_handler); uint32_t test_start = furi_hal_get_tick(); file_worker_encoder_handler = subghz_file_encoder_worker_alloc(); if(subghz_file_encoder_worker_start(file_worker_encoder_handler, path)) { - //the worker needs a file in order to open and read part of the file + // the worker needs a file in order to open and read part of the file osDelay(100); LevelDuration level_duration; while(furi_hal_get_tick() - test_start < TEST_TIMEOUT * 10) { - furi_hal_delay_us(500); //you need to have time to read from the file from the SD card level_duration = subghz_file_encoder_worker_get_level_duration(file_worker_encoder_handler); if(!level_duration_is_reset(level_duration)) { bool level = level_duration_get_level(level_duration); uint32_t duration = level_duration_get_duration(level_duration); + // Yield, to load data inside the worker + osThreadYield(); subghz_receiver_decode(receiver_handler, level, duration); } else { break; @@ -126,7 +127,7 @@ static bool subghz_decode_ramdom_test(const char* path) { } subghz_file_encoder_worker_free(file_worker_encoder_handler); } - FURI_LOG_I(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); + FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); if(furi_hal_get_tick() - test_start > TEST_TIMEOUT * 10) { printf("\033[0;31mRandom test ERROR TimeOut\033[0m\r\n"); return false; @@ -137,7 +138,7 @@ static bool subghz_decode_ramdom_test(const char* path) { } } -static bool subghz_ecode_test(const char* path) { +static bool subghz_encoder_test(const char* path) { subghz_test_decoder_count = 0; uint32_t test_start = furi_hal_get_tick(); string_t temp_str; @@ -189,7 +190,7 @@ static bool subghz_ecode_test(const char* path) { subghz_transmitter_free(transmitter); } flipper_format_free(fff_data_file); - FURI_LOG_I(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); + FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); if(furi_hal_get_tick() - test_start > TEST_TIMEOUT) { printf("\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", string_get_cstr(temp_str)); subghz_test_decoder_count = 0; @@ -207,167 +208,166 @@ MU_TEST(subghz_keystore_test) { MU_TEST(subghz_decoder_came_atomo_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/came_atomo_raw.sub", SUBGHZ_PROTOCOL_CAME_ATOMO_NAME), "Test decoder " SUBGHZ_PROTOCOL_CAME_ATOMO_NAME " error\r\n"); } MU_TEST(subghz_decoder_came_test) { mu_assert( - subghz_decode_test("/ext/unit_tests/subghz/came_raw.sub", SUBGHZ_PROTOCOL_CAME_NAME), + subghz_decoder_test("/ext/unit_tests/subghz/came_raw.sub", SUBGHZ_PROTOCOL_CAME_NAME), "Test decoder " SUBGHZ_PROTOCOL_CAME_NAME " error\r\n"); } MU_TEST(subghz_decoder_came_twee_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/came_twee_raw.sub", SUBGHZ_PROTOCOL_CAME_TWEE_NAME), "Test decoder " SUBGHZ_PROTOCOL_CAME_TWEE_NAME " error\r\n"); } MU_TEST(subghz_decoder_faac_slh_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/faac_slh_raw.sub", SUBGHZ_PROTOCOL_FAAC_SLH_NAME), "Test decoder " SUBGHZ_PROTOCOL_FAAC_SLH_NAME " error\r\n"); } MU_TEST(subghz_decoder_gate_tx_test) { mu_assert( - subghz_decode_test("/ext/unit_tests/subghz/gate_tx_raw.sub", SUBGHZ_PROTOCOL_GATE_TX_NAME), + subghz_decoder_test("/ext/unit_tests/subghz/gate_tx_raw.sub", SUBGHZ_PROTOCOL_GATE_TX_NAME), "Test decoder " SUBGHZ_PROTOCOL_GATE_TX_NAME " error\r\n"); } MU_TEST(subghz_decoder_hormann_hsm_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/hormann_hsm_raw.sub", SUBGHZ_PROTOCOL_HORMANN_HSM_NAME), "Test decoder " SUBGHZ_PROTOCOL_HORMANN_HSM_NAME " error\r\n"); } MU_TEST(subghz_decoder_ido_test) { mu_assert( - subghz_decode_test("/ext/unit_tests/subghz/ido_117_111_raw.sub", SUBGHZ_PROTOCOL_IDO_NAME), + subghz_decoder_test("/ext/unit_tests/subghz/ido_117_111_raw.sub", SUBGHZ_PROTOCOL_IDO_NAME), "Test decoder " SUBGHZ_PROTOCOL_IDO_NAME " error\r\n"); } MU_TEST(subghz_decoder_keelog_test) { mu_assert( - subghz_decode_test("/ext/unit_tests/subghz/doorhan_raw.sub", SUBGHZ_PROTOCOL_KEELOQ_NAME), + subghz_decoder_test("/ext/unit_tests/subghz/doorhan_raw.sub", SUBGHZ_PROTOCOL_KEELOQ_NAME), "Test decoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); } MU_TEST(subghz_decoder_kia_seed_test) { mu_assert( - subghz_decode_test("/ext/unit_tests/subghz/kia_seed_raw.sub", SUBGHZ_PROTOCOL_KIA_NAME), + subghz_decoder_test("/ext/unit_tests/subghz/kia_seed_raw.sub", SUBGHZ_PROTOCOL_KIA_NAME), "Test decoder " SUBGHZ_PROTOCOL_KIA_NAME " error\r\n"); } MU_TEST(subghz_decoder_nero_radio_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/nero_radio_raw.sub", SUBGHZ_PROTOCOL_NERO_RADIO_NAME), "Test decoder " SUBGHZ_PROTOCOL_NERO_RADIO_NAME " error\r\n"); } MU_TEST(subghz_decoder_nero_sketch_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/nero_sketch_raw.sub", SUBGHZ_PROTOCOL_NERO_SKETCH_NAME), "Test decoder " SUBGHZ_PROTOCOL_NERO_SKETCH_NAME " error\r\n"); } MU_TEST(subghz_decoder_nice_flo_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/nice_flo_raw.sub", SUBGHZ_PROTOCOL_NICE_FLO_NAME), "Test decoder " SUBGHZ_PROTOCOL_NICE_FLO_NAME " error\r\n"); } MU_TEST(subghz_decoder_nice_flor_s_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/nice_flor_s_raw.sub", SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME), "Test decoder " SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME " error\r\n"); } MU_TEST(subghz_decoder_princeton_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/Princeton_raw.sub", SUBGHZ_PROTOCOL_PRINCETON_NAME), "Test decoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n"); } MU_TEST(subghz_decoder_scher_khan_magic_code_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/scher_khan_magic_code.sub", SUBGHZ_PROTOCOL_SCHER_KHAN_NAME), "Test decoder " SUBGHZ_PROTOCOL_SCHER_KHAN_NAME " error\r\n"); } MU_TEST(subghz_decoder_somfy_keytis_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/Somfy_keytis_raw.sub", SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME), "Test decoder " SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME " error\r\n"); } MU_TEST(subghz_decoder_somfy_telis_test) { mu_assert( - subghz_decode_test( + subghz_decoder_test( "/ext/unit_tests/subghz/somfy_telis_raw.sub", SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME), "Test decoder " SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME " error\r\n"); } MU_TEST(subghz_decoder_star_line_test) { mu_assert( - subghz_decode_test("/ext/unit_tests/subghz/cenmax_raw.sub", SUBGHZ_PROTOCOL_STAR_LINE_NAME), + subghz_decoder_test( + "/ext/unit_tests/subghz/cenmax_raw.sub", SUBGHZ_PROTOCOL_STAR_LINE_NAME), "Test decoder " SUBGHZ_PROTOCOL_STAR_LINE_NAME " error\r\n"); } -MU_TEST(subghz_ecoder_princeton_test) { +MU_TEST(subghz_encoder_princeton_test) { mu_assert( - subghz_ecode_test("/ext/unit_tests/subghz/princeton.sub"), + subghz_encoder_test("/ext/unit_tests/subghz/princeton.sub"), "Test encoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n"); } -MU_TEST(subghz_ecoder_came_test) { +MU_TEST(subghz_encoder_came_test) { mu_assert( - subghz_ecode_test("/ext/unit_tests/subghz/came.sub"), + subghz_encoder_test("/ext/unit_tests/subghz/came.sub"), "Test encoder " SUBGHZ_PROTOCOL_CAME_NAME " error\r\n"); } -MU_TEST(subghz_ecoder_came_twee_test) { +MU_TEST(subghz_encoder_came_twee_test) { mu_assert( - subghz_ecode_test("/ext/unit_tests/subghz/came_twee.sub"), + subghz_encoder_test("/ext/unit_tests/subghz/came_twee.sub"), "Test encoder " SUBGHZ_PROTOCOL_CAME_TWEE_NAME " error\r\n"); } -MU_TEST(subghz_ecoder_gate_tx_test) { +MU_TEST(subghz_encoder_gate_tx_test) { mu_assert( - subghz_ecode_test("/ext/unit_tests/subghz/gate_tx.sub"), + subghz_encoder_test("/ext/unit_tests/subghz/gate_tx.sub"), "Test encoder " SUBGHZ_PROTOCOL_GATE_TX_NAME " error\r\n"); } -MU_TEST(subghz_ecoder_nice_flo_test) { +MU_TEST(subghz_encoder_nice_flo_test) { mu_assert( - subghz_ecode_test("/ext/unit_tests/subghz/nice_flo.sub"), + subghz_encoder_test("/ext/unit_tests/subghz/nice_flo.sub"), "Test encoder " SUBGHZ_PROTOCOL_NICE_FLO_NAME " error\r\n"); } -MU_TEST(subghz_ecoder_keelog_test) { +MU_TEST(subghz_encoder_keelog_test) { mu_assert( - subghz_ecode_test("/ext/unit_tests/subghz/doorhan.sub"), + subghz_encoder_test("/ext/unit_tests/subghz/doorhan.sub"), "Test encoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); } MU_TEST(subghz_random_test) { - mu_assert(subghz_decode_ramdom_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); + mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } MU_TEST_SUITE(subghz) { - //MU_SUITE_CONFIGURE(&subghz_test_init, &subghz_test_deinit); - subghz_test_init(); MU_RUN_TEST(subghz_keystore_test); @@ -390,12 +390,12 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_somfy_telis_test); MU_RUN_TEST(subghz_decoder_star_line_test); - MU_RUN_TEST(subghz_ecoder_princeton_test); - MU_RUN_TEST(subghz_ecoder_came_test); - MU_RUN_TEST(subghz_ecoder_came_twee_test); - MU_RUN_TEST(subghz_ecoder_gate_tx_test); - MU_RUN_TEST(subghz_ecoder_nice_flo_test); - MU_RUN_TEST(subghz_ecoder_keelog_test); + MU_RUN_TEST(subghz_encoder_princeton_test); + MU_RUN_TEST(subghz_encoder_came_test); + MU_RUN_TEST(subghz_encoder_came_twee_test); + MU_RUN_TEST(subghz_encoder_gate_tx_test); + MU_RUN_TEST(subghz_encoder_nice_flo_test); + MU_RUN_TEST(subghz_encoder_keelog_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); diff --git a/applications/unit_tests/test_index.c b/applications/unit_tests/test_index.c index eda0fe4a05a..4045c8e2abb 100644 --- a/applications/unit_tests/test_index.c +++ b/applications/unit_tests/test_index.c @@ -18,6 +18,7 @@ int run_minunit_test_flipper_format_string(); int run_minunit_test_stream(); int run_minunit_test_storage(); int run_minunit_test_subghz(); +int run_minunit_test_dirwalk(); void minunit_print_progress(void) { static char progress[] = {'\\', '|', '/', '-'}; @@ -60,6 +61,7 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { test_result |= run_minunit(); test_result |= run_minunit_test_storage(); test_result |= run_minunit_test_stream(); + test_result |= run_minunit_test_dirwalk(); test_result |= run_minunit_test_flipper_format(); test_result |= run_minunit_test_flipper_format_string(); test_result |= run_minunit_test_infrared_decoder_encoder(); diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index abc679bcee8..83cf90b720e 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -54,27 +54,24 @@ void subghz_file_encoder_worker_add_level_duration( } } -bool subghz_file_encoder_worker_data_parse( - SubGhzFileEncoderWorker* instance, - const char* strStart, - size_t len) { +bool subghz_file_encoder_worker_data_parse(SubGhzFileEncoderWorker* instance, const char* strStart) { char* str1; - size_t ind_start = (size_t)strStart; //store the start address of the beginning of the line bool res = false; + // Line sample: "RAW_Data: -1, 2, -2..." + + // Look for a key in the line + str1 = strstr(strStart, "RAW_Data: "); - str1 = strstr( - strStart, "RAW_Data: "); //looking for the beginning of the desired title in the line if(str1 != NULL) { - str1 = strchr( - str1, - ' '); //if found, shift the pointer by 1 element per line "RAW_Data: -1, 2, -2..." - while( - strchr(str1, ' ') != NULL && - ((size_t)str1 < - (len + - ind_start))) { //check that there is still an element in the line and that it has not gone beyond the line + // Skip key + str1 = strchr(str1, ' '); + + // Check that there is still an element in the line + while(strchr(str1, ' ') != NULL) { str1 = strchr(str1, ' '); - str1 += 1; //if found, shift the pointer by next element per line + + // Skip space + str1 += 1; subghz_file_encoder_worker_add_level_duration(instance, atoi(str1)); } res = true; @@ -143,9 +140,7 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { if(stream_read_line(stream, instance->str_data)) { string_strim(instance->str_data); if(!subghz_file_encoder_worker_data_parse( - instance, - string_get_cstr(instance->str_data), - strlen(string_get_cstr(instance->str_data)))) { + instance, string_get_cstr(instance->str_data))) { //to stop DMA correctly subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); diff --git a/lib/toolbox/dir_walk.c b/lib/toolbox/dir_walk.c new file mode 100644 index 00000000000..2efbc0f1a85 --- /dev/null +++ b/lib/toolbox/dir_walk.c @@ -0,0 +1,152 @@ +#include "dir_walk.h" +#include + +LIST_DEF(DirIndexList, uint32_t); + +struct DirWalk { + File* file; + string_t path; + DirIndexList_t index_list; + uint32_t current_index; + bool recursive; + DirWalkFilterCb filter_cb; + void* filter_context; +}; + +DirWalk* dir_walk_alloc(Storage* storage) { + DirWalk* dir_walk = malloc(sizeof(DirWalk)); + string_init(dir_walk->path); + dir_walk->file = storage_file_alloc(storage); + DirIndexList_init(dir_walk->index_list); + dir_walk->recursive = true; + dir_walk->filter_cb = NULL; + return dir_walk; +} + +void dir_walk_free(DirWalk* dir_walk) { + storage_file_free(dir_walk->file); + string_clear(dir_walk->path); + DirIndexList_clear(dir_walk->index_list); + free(dir_walk); +} + +void dir_walk_set_recursive(DirWalk* dir_walk, bool recursive) { + dir_walk->recursive = recursive; +} + +void dir_walk_set_filter_cb(DirWalk* dir_walk, DirWalkFilterCb cb, void* context) { + dir_walk->filter_cb = cb; + dir_walk->filter_context = context; +} + +bool dir_walk_open(DirWalk* dir_walk, const char* path) { + string_set(dir_walk->path, path); + dir_walk->current_index = 0; + return storage_dir_open(dir_walk->file, path); +} + +static bool dir_walk_filter(DirWalk* dir_walk, const char* name, FileInfo* fileinfo) { + if(dir_walk->filter_cb) { + return dir_walk->filter_cb(name, fileinfo, dir_walk->filter_context); + } else { + return true; + } +} + +static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo) { + DirWalkResult result = DirWalkError; + char* name = malloc(256); + FileInfo info; + bool end = false; + + while(!end) { + storage_dir_read(dir_walk->file, &info, name, 255); + + if(storage_file_get_error(dir_walk->file) == FSE_OK) { + result = DirWalkOK; + dir_walk->current_index++; + + if(dir_walk_filter(dir_walk, name, &info)) { + if(return_path != NULL) { + string_printf(return_path, "%s/%s", string_get_cstr(dir_walk->path), name); + } + + if(fileinfo != NULL) { + memcpy(fileinfo, &info, sizeof(FileInfo)); + } + + end = true; + } + + if((info.flags & FSF_DIRECTORY) && dir_walk->recursive) { + // step into + DirIndexList_push_back(dir_walk->index_list, dir_walk->current_index); + dir_walk->current_index = 0; + storage_dir_close(dir_walk->file); + + string_cat_printf(dir_walk->path, "/%s", name); + storage_dir_open(dir_walk->file, string_get_cstr(dir_walk->path)); + } + } else if(storage_file_get_error(dir_walk->file) == FSE_NOT_EXIST) { + if(DirIndexList_size(dir_walk->index_list) == 0) { + // last + result = DirWalkLast; + end = true; + } else { + // step out + uint32_t index; + DirIndexList_pop_back(&index, dir_walk->index_list); + dir_walk->current_index = 0; + + storage_dir_close(dir_walk->file); + + size_t last_char = string_search_rchar(dir_walk->path, '/'); + if(last_char != STRING_FAILURE) { + string_left(dir_walk->path, last_char); + } + + storage_dir_open(dir_walk->file, string_get_cstr(dir_walk->path)); + + // rewind + while(true) { + if(index == dir_walk->current_index) { + result = DirWalkOK; + break; + } + + if(!storage_dir_read(dir_walk->file, &info, name, 255)) { + result = DirWalkError; + end = true; + break; + } + + dir_walk->current_index++; + } + } + } else { + result = DirWalkError; + end = true; + } + } + + free(name); + return result; +} + +FS_Error dir_walk_get_error(DirWalk* dir_walk) { + return storage_file_get_error(dir_walk->file); +} + +DirWalkResult dir_walk_read(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo) { + return dir_walk_iter(dir_walk, return_path, fileinfo); +} + +void dir_walk_close(DirWalk* dir_walk) { + if(storage_file_is_open(dir_walk->file)) { + storage_dir_close(dir_walk->file); + } + + DirIndexList_reset(dir_walk->index_list); + string_reset(dir_walk->path); + dir_walk->current_index = 0; +} diff --git a/lib/toolbox/dir_walk.h b/lib/toolbox/dir_walk.h new file mode 100644 index 00000000000..fc65104200d --- /dev/null +++ b/lib/toolbox/dir_walk.h @@ -0,0 +1,79 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DirWalk DirWalk; + +typedef enum { + DirWalkOK, /**< OK */ + DirWalkError, /**< Error */ + DirWalkLast, /**< Last element */ +} DirWalkResult; + +typedef bool (*DirWalkFilterCb)(const char* name, FileInfo* fileinfo, void* ctx); + +/** + * Allocate DirWalk + * @param storage + * @return DirWalk* + */ +DirWalk* dir_walk_alloc(Storage* storage); + +/** + * Free DirWalk + * @param dir_walk + */ +void dir_walk_free(DirWalk* dir_walk); + +/** + * Set recursive mode (true by default) + * @param dir_walk + * @param recursive + */ +void dir_walk_set_recursive(DirWalk* dir_walk, bool recursive); + +/** + * Set filter callback (Should return true if the data is valid) + * @param dir_walk + * @param cb + * @param context + */ +void dir_walk_set_filter_cb(DirWalk* dir_walk, DirWalkFilterCb cb, void* context); + +/** + * Open directory + * @param dir_walk + * @param path + * @return true + * @return false + */ +bool dir_walk_open(DirWalk* dir_walk, const char* path); + +/** + * Get error id + * @param dir_walk + * @return FS_Error + */ +FS_Error dir_walk_get_error(DirWalk* dir_walk); + +/** + * Read next element from directory + * @param dir_walk + * @param return_path + * @param fileinfo + * @return DirWalkResult + */ +DirWalkResult dir_walk_read(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo); + +/** + * Close directory + * @param dir_walk + */ +void dir_walk_close(DirWalk* dir_walk); + +#ifdef __cplusplus +} +#endif \ No newline at end of file From 94d7a714bc7185a05f69a690bbd8cd68815b0ac2 Mon Sep 17 00:00:00 2001 From: Francois Marier Date: Tue, 10 May 2022 07:10:03 -0700 Subject: [PATCH 13/24] Fix typo in nfc_device ("depricated") #1212 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/nfc/nfc_device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index 14fdb67b7c2..9970cbfed12 100644 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -764,7 +764,7 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path) { uint32_t data_cnt = 0; string_t temp_str; string_init(temp_str); - bool depricated_version = false; + bool deprecated_version = false; do { // Check existance of shadow file @@ -783,7 +783,7 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path) { uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; if(string_cmp_str(temp_str, nfc_file_header) || (version != nfc_file_version)) { - depricated_version = true; + deprecated_version = true; break; } // Read Nfc device type @@ -810,8 +810,8 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path) { } while(false); if(!parsed) { - if(depricated_version) { - dialog_message_show_storage_error(dev->dialogs, "File format depricated"); + if(deprecated_version) { + dialog_message_show_storage_error(dev->dialogs, "File format deprecated"); } else { dialog_message_show_storage_error(dev->dialogs, "Can not parse\nfile"); } From 20686561501876a589c5b27a279885f33619bfb7 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Tue, 10 May 2022 18:44:07 +0400 Subject: [PATCH 14/24] SubGhz: add unit_test firefly, megacode, security+ 1.0, security+ 2.0 (#1209) * SubGhz: add unit_test firefly, megacode, security+ 1.0, security+ 2.0 * SubGhz: add urit_test file * SubGhz: fix syntax Co-authored-by: Aleksandr Kutuzov --- applications/unit_tests/subghz/subghz_test.c | 47 ++++++++++++++++++- assets/unit_tests/subghz/firefly_raw.sub | 11 +++++ assets/unit_tests/subghz/firely.sub | 7 +++ assets/unit_tests/subghz/megacode.sub | 7 +++ assets/unit_tests/subghz/megacode_raw.sub | 8 ++++ .../subghz/security_pls_1_0_raw.sub | 35 ++++++++++++++ .../subghz/security_pls_2_0_raw.sub | 32 +++++++++++++ assets/unit_tests/subghz/test_random_raw.sub | 23 +++++++++ 8 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 assets/unit_tests/subghz/firefly_raw.sub create mode 100644 assets/unit_tests/subghz/firely.sub create mode 100644 assets/unit_tests/subghz/megacode.sub create mode 100644 assets/unit_tests/subghz/megacode_raw.sub create mode 100644 assets/unit_tests/subghz/security_pls_1_0_raw.sub create mode 100644 assets/unit_tests/subghz/security_pls_2_0_raw.sub diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index 191ca745ce7..51699a81e94 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -13,7 +13,7 @@ #define CAME_ATOMO_DIR_NAME "/ext/subghz/assets/came_atomo" #define NICE_FLOR_S_DIR_NAME "/ext/subghz/assets/nice_flor_s" #define TEST_RANDOM_DIR_NAME "/ext/unit_tests/subghz/test_random_raw.sub" -#define TEST_RANDOM_COUNT_PARSE 59 +#define TEST_RANDOM_COUNT_PARSE 109 #define TEST_TIMEOUT 10000 static SubGhzEnvironment* environment_handler; @@ -327,6 +327,33 @@ MU_TEST(subghz_decoder_star_line_test) { "Test decoder " SUBGHZ_PROTOCOL_STAR_LINE_NAME " error\r\n"); } +MU_TEST(subghz_decoder_firefly_test) { + mu_assert( + subghz_decoder_test("/ext/unit_tests/subghz/firefly_raw.sub", SUBGHZ_PROTOCOL_FIREFLY_NAME), + "Test decoder " SUBGHZ_PROTOCOL_FIREFLY_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_megacode_test) { + mu_assert( + subghz_decoder_test( + "/ext/unit_tests/subghz/megacode_raw.sub", SUBGHZ_PROTOCOL_MEGACODE_NAME), + "Test decoder " SUBGHZ_PROTOCOL_MEGACODE_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_secplus_v1_test) { + mu_assert( + subghz_decoder_test( + "/ext/unit_tests/subghz/security_pls_1_0_raw.sub", SUBGHZ_PROTOCOL_SECPLUS_V1_NAME), + "Test decoder " SUBGHZ_PROTOCOL_SECPLUS_V1_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_secplus_v2_test) { + mu_assert( + subghz_decoder_test( + "/ext/unit_tests/subghz/security_pls_2_0_raw.sub", SUBGHZ_PROTOCOL_SECPLUS_V2_NAME), + "Test decoder " SUBGHZ_PROTOCOL_SECPLUS_V2_NAME " error\r\n"); +} + MU_TEST(subghz_encoder_princeton_test) { mu_assert( subghz_encoder_test("/ext/unit_tests/subghz/princeton.sub"), @@ -363,6 +390,18 @@ MU_TEST(subghz_encoder_keelog_test) { "Test encoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); } +MU_TEST(subghz_encoder_firefly_test) { + mu_assert( + subghz_encoder_test("/ext/unit_tests/subghz/firely.sub"), + "Test encoder " SUBGHZ_PROTOCOL_FIREFLY_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_megacode_test) { + mu_assert( + subghz_encoder_test("/ext/unit_tests/subghz/megacode.sub"), + "Test encoder " SUBGHZ_PROTOCOL_MEGACODE_NAME " error\r\n"); +} + MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } @@ -389,6 +428,10 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_somfy_keytis_test); MU_RUN_TEST(subghz_decoder_somfy_telis_test); MU_RUN_TEST(subghz_decoder_star_line_test); + MU_RUN_TEST(subghz_decoder_firefly_test); + MU_RUN_TEST(subghz_decoder_megacode_test); + MU_RUN_TEST(subghz_decoder_secplus_v1_test); + MU_RUN_TEST(subghz_decoder_secplus_v2_test); MU_RUN_TEST(subghz_encoder_princeton_test); MU_RUN_TEST(subghz_encoder_came_test); @@ -396,6 +439,8 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_gate_tx_test); MU_RUN_TEST(subghz_encoder_nice_flo_test); MU_RUN_TEST(subghz_encoder_keelog_test); + MU_RUN_TEST(subghz_encoder_firefly_test); + MU_RUN_TEST(subghz_encoder_megacode_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); diff --git a/assets/unit_tests/subghz/firefly_raw.sub b/assets/unit_tests/subghz/firefly_raw.sub new file mode 100644 index 00000000000..c143fa028a9 --- /dev/null +++ b/assets/unit_tests/subghz/firefly_raw.sub @@ -0,0 +1,11 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 300000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 361 -4326 2555 -28090 65 -302 65 -1890 131 -2062 2547 -95068 2565 -48020 67 -47036 2551 -30016 2561 -47778 67 -14884 2481 -95118 2537 -95132 2549 -48496 65 -21526 2571 -16342 97 -4142 65 -1938 2543 -95008 2551 -44030 1579 -548 1469 -588 433 -1568 469 -1540 479 -1550 1489 -538 473 -1574 1467 -538 1493 -566 443 -22130 693 -3742 321 -1702 341 -1690 1353 -628 391 -1666 1401 -584 1445 -596 391 -22192 1487 -554 1471 -550 447 -1584 453 -1568 445 -1578 1469 -550 459 -1598 1465 -540 1461 -576 445 -22164 1479 -546 1501 -544 453 -1568 447 -1580 445 -1584 1451 -560 443 -1594 1473 -548 1479 -556 441 -22160 1475 -548 1487 -554 449 -1578 451 -1586 451 -1572 1469 -552 449 -1578 1473 -558 1469 -552 449 -22142 1507 -546 1479 -548 457 -1574 447 -1580 447 -1584 1475 -554 441 -1592 1465 -546 1473 -546 483 -22132 1157 -1082 67 -166 65 -198 65 -1150 257 -1706 339 -1666 365 -1642 1409 -610 407 -1626 1417 -620 1435 -580 409 -22184 1495 -572 1463 -552 447 -1584 453 -1574 447 -1580 1473 -548 459 -1568 1501 -520 1501 -552 463 -22124 535 -7674 339 -1680 1345 -678 361 -1664 1395 -618 1411 -646 373 -22194 1511 -526 1477 -550 483 -1542 479 -1562 471 -1566 1483 -546 445 -1574 1471 -534 1497 -548 483 -169938 2539 -89172 167 -5768 2551 -93014 967 -252 1571 -5844 2503 -87590 65 -5948 2523 -64008 1605 -520 1473 -554 449 -1584 449 -1576 447 -1546 1505 -546 451 -1574 1469 -546 1475 -548 459 -22160 1525 -506 1501 -516 479 -1550 469 -1570 469 -1570 1471 -538 471 -1568 1489 -516 1501 -554 443 -22152 1507 -522 1511 -518 481 -1580 451 -1542 483 -1548 1505 -546 451 -1570 1471 -552 1473 -548 455 -22180 1505 -522 1501 -544 451 -1560 475 -1548 481 -1556 1477 -552 475 -1546 1505 -516 1517 -516 473 -22148 1515 -518 1499 -546 485 -1570 443 -1580 447 -1582 1475 -526 483 -1548 1507 -546 1479 -558 449 -22138 1495 -586 1437 -616 403 -1594 429 -1608 417 -1606 1465 -556 433 -1606 1465 -536 1499 -544 445 -22170 1401 -792 1245 -770 271 -1716 325 -1680 359 -1664 1397 -620 393 -1644 1407 -614 1433 -586 429 -22202 1477 -572 1469 -548 449 -1576 457 -1578 479 -1544 1473 -590 429 -1570 1491 -540 1509 -554 429 -22196 1481 -556 1467 -580 439 -1592 431 -1608 415 -1608 1441 -586 463 -1568 1467 -552 1489 -534 473 -22166 1485 -574 1469 -580 453 -1572 443 -1578 447 -1578 1477 -554 447 -1580 1479 -550 1481 -550 475 -22160 1525 -542 1467 -540 483 -1574 447 -1582 451 -1578 1481 -558 447 -1560 1493 -550 1505 -544 449 -22182 1435 -646 1391 -664 369 -1642 385 -1652 395 -1600 1463 -584 417 -1606 1467 -576 1443 -586 429 -148588 275 -106 847 -128 877 -100 281 -97826 2541 -92318 2505 -12474 2563 -73674 2555 -41600 2543 -76554 1601 -516 1471 -554 +RAW_Data: 487 -1556 453 -1570 441 -1590 1467 -556 469 -1538 1501 -522 1501 -552 463 -22124 1513 -514 1509 -548 445 -1582 461 -1568 443 -1574 1467 -536 465 -1574 1499 -516 1503 -556 441 -22150 1537 -484 1495 -544 479 -1558 459 -1574 447 -1580 1471 -548 459 -1576 1471 -554 1471 -550 459 -22160 1517 -516 1503 -546 447 -1574 473 -1546 481 -1576 1479 -520 467 -1572 1497 -550 1469 -556 441 -22156 1533 -528 1495 -530 469 -1568 445 -1566 485 -1548 1505 -544 451 -1572 1471 -554 1503 -516 495 -22160 1511 -520 1477 -546 483 -1542 485 -1546 481 -1542 1509 -526 455 -1578 1507 -544 1481 -524 485 -22146 1543 -510 1481 -552 475 -1546 473 -1568 481 -1540 1503 -522 473 -1556 1507 -558 1491 -518 479 -22164 1523 -520 1503 -544 453 -1566 479 -1550 469 -1572 1493 -546 447 -1576 1477 -552 1509 -544 451 -22178 639 -596 65 -926 63 -1954 237 -1680 355 -1670 383 -1636 1423 -596 439 -1578 1471 -574 1465 -576 445 -22182 1439 -676 1335 -702 339 -1648 387 -1648 409 -1608 1429 -618 419 -1612 1447 -578 1439 -614 425 -22186 1497 -530 1505 -556 471 -1540 479 -1582 431 -1570 1497 -546 481 -1536 1497 -554 1501 -556 463 -22178 1503 -566 1433 -586 433 -1604 445 -1576 441 -1580 1503 -548 453 -1572 1473 -578 1467 -558 469 -149080 311 -1034 895 -1084 939 -1006 337 -78790 97 -6890 2535 -28048 2511 -64482 2573 -88138 65 -6956 2515 -95140 2509 -61986 1589 -522 1475 -548 449 -1576 475 -1548 481 -1546 1475 -564 443 -1564 1477 -580 1477 -554 449 -22166 1503 -532 1481 -544 447 -1576 449 -1572 473 -1548 1473 -580 451 -1568 1463 -552 1477 -552 461 -22164 1521 -528 1493 -548 443 -1580 461 -1540 475 -1574 1473 -554 471 -1568 1489 -516 1497 -538 471 -22154 1385 -786 1245 -796 261 -1702 341 -1650 391 -1644 1411 -608 409 -1620 1415 -624 1409 -614 413 -22178 1533 -498 1519 -546 445 -1576 449 -1578 457 -1568 1503 -546 451 -1570 1467 -554 1503 -552 463 -22162 1401 -774 1257 -754 297 -1678 353 -1650 383 -1666 1397 -618 385 -1642 1437 -612 1433 -586 427 -22194 1483 -552 1477 -546 485 -1544 453 -1576 481 -1576 1479 -560 449 -1548 1507 -546 1479 -558 447 -22170 1413 -786 1245 -776 295 -1664 337 -1680 387 -1652 1385 -638 407 -1614 1441 -582 1451 -606 409 -22204 1503 -528 1507 -550 465 -1534 481 -1584 429 -1572 1497 -548 447 -1580 1481 -550 1503 -546 455 -22166 1519 -552 1469 -580 419 -1612 419 -1596 447 -1582 1479 -554 447 -1582 1479 -550 1519 -518 479 -134730 169 -172 559 -194 579 -676 257 -87040 99 -7384 2269 -488 313 -37888 65 -12084 2515 -33298 2247 -474 309 -42656 63 -51970 2233 -456 309 -94658 2233 -430 325 -90692 357 -186 2417 -518 1517 -514 475 -1550 467 -1570 471 -1538 1499 -556 443 -1564 1483 -552 1501 -524 +RAW_Data: 481 -22144 1433 -668 1373 -666 337 -1680 355 -1634 383 -1634 1431 -622 399 -1606 1443 -582 1443 -586 431 -22166 1521 -512 1497 -548 447 -1580 459 -1568 447 -1574 1473 -554 465 -1572 1497 -516 1507 -554 453 -22148 1503 -540 1489 -546 479 -1542 449 -1578 457 -1576 1475 -546 483 -1540 1507 -552 1473 -548 453 -22154 1539 -516 1469 -586 431 -1574 447 -1576 479 -1558 1485 -554 439 -1580 1501 -550 1457 -552 473 -22154 1521 -550 1485 -540 447 -1578 457 -1578 447 -1572 1471 -556 485 -1540 1483 -552 1501 -556 443 -22186 1437 -662 1345 -704 339 -1688 361 -1646 375 -1640 1399 -616 421 -1612 1441 -614 1435 -586 429 -22200 1513 -520 1503 -544 453 -1572 447 -1580 483 -1550 1475 -552 475 -1548 1501 -554 1491 -540 475 -22184 1499 -530 1485 -548 457 -1570 477 -1578 443 -1576 1501 -546 449 -1562 1499 -538 1493 -572 443 -22166 1471 -612 1429 -624 401 -1608 417 -1620 431 -1600 1461 -582 419 -1610 1441 -582 1473 -548 459 -205658 1761 -436 863 -68558 2597 -23434 1775 -438 519 -94592 1803 -422 829 -86706 1727 -434 527 -66 319 -94536 1753 -444 865 -238 1489 -652 1385 -656 357 -1668 365 -1628 403 -1612 1439 -614 403 -1626 1425 -588 1443 -584 409 -22168 1531 -528 1491 -530 469 -1568 443 -1564 483 -1538 1505 -546 455 -1570 1469 -556 1503 -518 491 -22128 1455 -660 1359 -686 355 -1632 385 -1632 411 -1640 1411 -596 423 -1606 1437 -580 1443 -596 423 -22188 1495 -550 1467 -534 473 -1566 481 -1540 483 -1572 1477 -552 449 -1582 1477 -558 1471 -552 449 -22174 543 -3692 235 -1680 357 -1668 353 -1698 1375 -636 371 -1644 1409 -610 1437 -578 449 -22180 1499 -542 1491 -542 479 -1540 481 -1566 449 -1562 1499 -554 465 -1568 1463 -554 1493 -536 473 -22168 1405 -774 1257 -788 267 -1676 355 -1672 369 -1660 1387 -624 417 -1606 1427 -624 1425 -586 415 -22208 1507 -552 1489 -548 443 -1562 483 -1550 481 -1546 1505 -558 447 -1586 1473 -548 1481 -554 479 -22166 1383 -786 1245 -776 295 -1664 373 -1646 387 -1644 1403 -642 411 -1624 1417 -594 1445 -612 409 -22210 1515 -516 1503 -554 453 -1564 457 -1572 447 -1580 1501 -554 465 -1570 1467 -554 1493 -570 443 -195814 1353 -442 1267 -37900 99 -53710 411 -142 2207 -8336 2487 -46990 1301 -452 1317 -86162 65 -8376 1289 -444 1327 -94552 1311 -488 1251 -1726 1531 -544 1467 -580 417 -1578 457 -1578 443 -1576 1475 -566 441 -1568 1503 -512 1509 -526 455 -22168 1473 -582 1469 -538 483 -1538 459 -1574 447 -1580 1471 -582 429 -1572 1469 -552 1473 -548 461 -22170 1437 -640 1401 -620 393 -1636 385 -1634 409 -1604 1457 -588 415 -1608 1431 -590 1459 -554 449 -22188 1483 -556 1487 -542 445 -1578 459 -1576 443 -1574 1473 -556 469 -1570 1459 -550 1503 -554 443 -22160 1469 -590 +RAW_Data: 1469 -582 409 -1620 429 -1608 415 -1602 1455 -568 441 -1578 1475 -552 1479 -560 467 -22166 1483 -572 1463 -546 451 -1580 453 -1580 481 -1542 1475 -588 451 -1570 1453 -550 1503 -540 469 -22158 1505 -554 1475 -554 487 -1556 453 -1562 477 -1546 1495 -546 479 -1544 1511 -554 1477 -532 471 -22180 1471 -602 1437 -602 407 -1610 421 -1614 421 -1606 1433 -582 457 -1578 1475 -550 1469 -586 465 -22164 1515 -546 1469 -546 483 -1572 447 -1558 471 -1580 1471 -578 451 -1568 1495 -542 1497 -530 471 -22194 1433 -644 1393 -662 371 -1640 385 -1642 413 -1628 1431 -584 431 -1602 1469 -540 1501 -576 443 -22180 1479 -592 1439 -608 407 -1620 427 -1610 415 -1606 1465 -570 441 -1612 1441 -586 1451 -576 445 -22196 1533 -522 1489 -540 477 -1574 481 -1544 455 -1568 1505 -546 459 -1572 1501 -556 1497 -530 471 -210202 685 -540 475 -138 839 -138 239 -9950 2501 -71112 761 -462 511 -66 1297 -85614 97 -8850 745 -466 1821 -94546 827 -468 481 -140 815 -164 237 -32934 1583 -540 1477 -554 441 -1582 447 -1580 453 -1568 1465 -554 479 -1556 1487 -558 1477 -550 453 -22174 1503 -516 1483 -584 429 -1572 449 -1576 447 -1588 1475 -558 449 -1580 1473 -546 1485 -556 449 -22168 1469 -586 1443 -614 401 -1624 401 -1608 415 -1608 1463 -570 441 -1574 1471 -586 1449 -572 445 -22164 1401 -772 1255 -756 301 -1674 353 -1708 329 -1662 1397 -650 387 -1632 1405 -614 1433 -584 431 -22200 1489 -566 1463 -582 419 -1580 457 -1596 447 -1576 1473 -554 443 -1580 1469 -582 1451 -550 479 -22174 1387 -786 1251 -792 257 -1704 331 -1690 337 -1706 1377 -632 395 -1632 1433 -586 1451 -584 413 -22198 1541 -512 1485 -554 481 -1574 445 -1560 461 -1568 1495 -556 469 -1568 1495 -518 1503 -554 469 -22160 1541 -516 1501 -556 443 -1564 495 -1536 479 -1550 1517 -544 445 -1576 1507 -556 1485 -542 445 -22202 1501 -530 1503 -554 465 -1574 445 -1582 461 -1574 1469 -546 479 -1568 1471 -556 1513 -550 463 -22170 1473 -614 1419 -602 439 -1614 417 -1610 415 -1590 1465 -588 429 -1606 1469 -586 1455 -570 441 -22200 1407 -760 1277 -772 267 -1692 363 -1678 355 -1668 1393 -660 369 -1642 1441 -584 1449 -574 445 -22206 1533 -528 1497 -530 471 -1572 449 -1576 455 -1578 1507 -544 455 -1572 1503 -556 1467 -560 469 -22188 1439 -678 1347 -672 375 -1648 393 -1646 387 -1636 1431 -588 431 -1610 1439 -618 1437 -596 437 -143610 67 -510 99 -66 223 -272 173 -70 273 -204 235 -64 483 -26542 2521 -65448 297 -348 2417 -76720 65 -8388 65 -9450 203 -332 587 -72 885 -92 899 -27534 67 -39500 221 -406 521 -72 885 -98 919 -29920 1581 -534 1491 -548 445 -1580 461 -1544 477 -1574 1465 -556 473 -1568 1455 -554 1501 -524 483 -22136 1529 -498 +RAW_Data: 1493 -576 441 -1568 469 -1574 447 -1576 1465 -548 481 -1544 1503 -542 1473 -554 449 -22176 1499 -530 1505 -554 463 -1540 479 -1546 479 -1558 1483 -556 449 -1580 1473 -548 1483 -552 447 -22198 1511 -508 1507 -554 441 -1580 453 -1586 453 -1576 1473 -548 451 -1586 1475 -554 1499 -554 445 -22180 1503 -526 1481 -550 481 -1544 485 -1574 449 -1566 1479 -548 461 -1572 1503 -540 1499 -530 471 -22192 1499 -530 1475 -584 433 -1572 475 -1586 429 -1570 1495 -548 449 -1578 1473 -552 1505 -546 455 -22202 1499 -544 1469 -562 471 -1570 447 -1580 457 -1568 1505 -544 451 -1574 1471 -554 1503 -554 465 -22160 1533 -530 1485 -548 459 -1600 443 -1576 441 -1580 1505 -544 455 -1568 1497 -556 1495 -530 473 -22200 1499 -544 1491 -544 479 -1572 451 -1572 447 -1578 1479 -550 493 -1564 1465 -590 1451 -576 445 -22198 1531 -532 1483 -548 479 -1542 483 -1576 449 -1562 1501 -554 465 -1574 1469 -556 1491 -572 445 -22196 1533 -528 1495 -532 473 -1574 449 -1580 457 -1576 1505 -546 453 -1572 1503 -556 1465 -558 471 -22200 1499 -530 1517 -552 463 -1568 445 -1580 457 -1578 1471 -578 451 -1574 1473 -554 1503 -556 469 -22188 1501 -554 1473 -544 479 -1592 461 -1568 447 -1576 1493 -552 453 -1584 1475 -554 1503 -554 471 -141048 233 -68 741 -68 133 -100 467 -49002 2539 -43448 2529 -91062 2557 -95072 2545 -89712 641 -300 1759 -3612 463 -9880 1221 -712 327 -1694 1367 -616 1445 -582 409 -22192 1505 -522 1497 -554 447 -1584 455 -1570 449 -1578 1473 -548 459 -1572 1475 -576 1465 -554 469 -22142 1507 -526 1509 -548 455 -1574 447 -1578 447 -1580 1479 -554 441 -1580 1467 -584 1457 -554 445 -22200 1513 -510 1509 -526 473 -1562 481 -1554 455 -1574 1473 -544 479 -1556 1481 -550 1497 -554 453 -22156 1529 -524 1497 -552 453 -1588 451 -1574 449 -1582 1475 -546 455 -1572 1505 -520 1503 -554 465 -22156 1537 -516 1485 -548 459 -1570 481 -1550 467 -1570 1495 -548 447 -1576 1493 -552 1481 -548 459 -22194 1513 -524 1481 -578 453 -1574 451 -1564 485 -1558 1477 -556 449 -1580 1471 -582 1491 -516 479 -22170 1535 -530 1499 -548 449 -1580 457 -1574 445 -1576 1511 -554 431 -1572 1497 -548 1507 -556 429 -22194 1523 -546 1473 -568 429 -1598 443 -1606 451 -1574 1471 -546 485 -1562 1481 -554 1503 -540 471 -22190 1387 -788 1277 -776 263 -1696 335 -1680 385 -1652 1385 -638 407 -1614 1445 -594 1445 -612 411 -22212 1541 -518 1499 -554 445 -1562 461 -1568 475 -1560 1495 -554 481 -1556 1487 -552 1507 -556 443 -22214 1521 -514 1507 -552 451 -1570 461 -1606 447 -1578 1483 -556 467 -1572 1471 -552 1491 -574 445 -22232 1507 -528 1481 -562 473 -1574 447 -1580 457 -1578 1505 -546 459 -1574 1471 -588 1461 -562 473 -22200 1431 -694 +RAW_Data: 1341 -740 305 -1690 361 -1644 387 -1670 1391 -626 403 -1644 1441 -598 1443 -608 411 -22244 1515 -518 1501 -552 439 -1598 469 -1572 447 -1576 1495 -554 453 -1586 1475 -552 1501 -554 467 -182986 65 -11040 2545 -94994 2537 -94978 2557 -10004 2527 -82554 2547 -84234 65 -10744 2497 -32446 1555 -544 1479 -558 421 -1608 447 -1582 451 -1542 1509 -552 449 -1548 1507 -528 1479 -550 481 -22134 1537 -518 1483 -548 457 -1566 477 -1574 441 -1572 1465 -552 481 -1576 1445 -586 1453 -552 477 -22154 1519 -522 1503 -546 449 -1570 441 -1578 485 -1558 1481 -558 449 -1550 1505 -544 1479 -558 449 -22154 1515 -542 1479 -556 447 -1594 459 -1544 475 -1570 1467 -558 469 -1566 1491 -548 1465 -558 487 -22132 1403 -776 1249 -800 271 -1678 357 -1648 393 -1634 1399 -650 389 -1610 1441 -610 1437 -584 429 -22204 1499 -528 1505 -552 463 -1574 447 -1578 443 -1558 1485 -552 479 -1548 1491 -574 1467 -546 483 -22168 1453 -632 1431 -614 389 -1614 419 -1634 411 -1584 1453 -616 391 -1636 1431 -582 1479 -554 443 -22204 887 -198 67 -950 65 -194 63 -200 65 -498 65 -910 261 -1696 339 -1646 387 -1650 1417 -640 377 -1614 1441 -612 1439 -618 401 -22186 1539 -516 1505 -556 437 -1596 463 -1572 447 -1582 1477 -546 481 -1540 1505 -552 1499 -554 453 -22184 1529 -500 1497 -586 431 -1570 471 -1576 447 -1576 1477 -552 481 -1580 1479 -558 1473 -554 481 -168716 2521 -95042 2539 -94986 2535 -25722 2535 -26624 2505 -18626 99 -76268 2541 -94974 2559 -17198 65 -6348 67 -42186 2539 -17892 131 -93800 99 -394 65 -7158 1331 -448 \ No newline at end of file diff --git a/assets/unit_tests/subghz/firely.sub b/assets/unit_tests/subghz/firely.sub new file mode 100644 index 00000000000..a38c21df09d --- /dev/null +++ b/assets/unit_tests/subghz/firely.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 300000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Firefly +Bit: 10 +Key: 00 00 00 00 00 00 01 E4 diff --git a/assets/unit_tests/subghz/megacode.sub b/assets/unit_tests/subghz/megacode.sub new file mode 100644 index 00000000000..e968fd9bd1d --- /dev/null +++ b/assets/unit_tests/subghz/megacode.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 318000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: MegaCode +Bit: 24 +Key: 00 00 00 00 00 8A E2 D2 diff --git a/assets/unit_tests/subghz/megacode_raw.sub b/assets/unit_tests/subghz/megacode_raw.sub new file mode 100644 index 00000000000..c2235d8c52f --- /dev/null +++ b/assets/unit_tests/subghz/megacode_raw.sub @@ -0,0 +1,8 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 318000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: -754 361 -17246 131 -8734 65 -71908 65 -27774 65 -1230 65 -13826 99 -800 65 -634 67 -796 99 -47716 65 -18338 67 -18176 131 -7986 65 -1084 131 -2090 65 -48694 163 -40926 65 -4538 65 -10224 65 -9874 20955 -1970 1023 -4928 1007 -4946 1011 -7910 981 -1992 1021 -7898 1013 -1962 1007 -7896 1019 -4930 995 -4962 987 -1974 1029 -4924 1019 -4920 1025 -7896 1005 -1964 1027 -7894 1007 -4932 1033 -1948 1009 -7916 1009 -1982 1001 -4942 1011 -7880 1011 -2000 1003 -13820 1011 -1990 985 -4944 1021 -4932 995 -7916 1025 -1944 1025 -7892 1015 -1970 1025 -7892 1001 -4934 1031 -4926 1015 -1970 989 -4938 1007 -4954 1019 -7874 1013 -2000 985 -7896 1011 -4950 1001 -1968 1023 -7900 999 -1968 1007 -4968 973 -7936 985 -1970 1009 -13856 1013 -1968 981 -4962 1009 -4926 1005 -7924 1003 -1968 1013 -7892 1003 -1992 985 -7904 1011 -4936 1023 -4948 997 -1960 1015 -4950 987 -4970 993 -7896 1005 -1970 1009 -7928 1005 -4914 1023 -1984 1001 -7894 1011 -1970 999 -4962 1003 -7890 1007 -1992 1013 -13810 1011 -1994 987 -4938 1005 -4964 999 -7904 1013 -1974 987 -7910 1021 -1964 1015 -7894 1021 -4912 1019 -4948 1007 -1970 1017 -4916 1021 -4946 985 -7914 1003 -1972 1009 -7898 1041 -4912 1013 -1994 985 -7892 1027 -1964 1013 -4938 1003 -7904 1023 -1966 1017 -13824 1025 -1968 983 -4950 1007 -4944 999 -7900 1029 -1964 1015 -7914 981 -2000 981 -7932 979 -4936 1021 -4926 1013 -1998 979 -4946 1035 -4908 1031 -7896 999 -1964 1025 -7902 1021 -4914 1023 -1966 1015 -7908 1007 -1970 1003 -4952 981 -7910 1001 -1974 1003 -13832 1015 -1976 999 -4958 1019 -4938 985 -7900 1025 -1966 1011 -7914 1015 -1964 1009 -7906 1017 -4908 1027 -4916 1011 -2000 981 -4954 1007 -4926 1017 -7920 1011 -1958 1009 -7906 1019 -4912 1025 -1980 1009 -7900 1013 -1948 1027 -4916 1011 -7918 1005 -1976 1003 -13846 1013 -1970 1005 -4914 1041 -4916 1007 -7918 987 -2000 987 -7902 1013 -1970 1015 -7894 1007 -4936 1019 -4944 1009 -1970 1013 -4918 1019 -4954 977 -7914 1019 -1964 1007 -7906 1003 -4956 983 -1982 1027 -7896 1005 -1962 1027 -4930 1007 -7906 999 -1972 1009 -13850 1009 -1952 1027 -4944 983 -4954 1023 -7894 1007 -1952 1031 -7882 1035 -1970 1011 -7894 1007 -4936 1025 -4920 1023 -1968 1011 -4928 1009 -4920 1015 -7902 1015 -1966 1021 -7894 1011 -4948 997 -1970 1009 -7902 1027 -1978 1011 -4930 999 -7918 1007 -1966 1013 -13824 1015 -1966 1027 -4918 1027 -4912 1021 -7888 1009 -1998 989 -7918 1019 -1960 989 -7930 983 -4946 1025 -4920 1013 -1970 1015 -4950 1009 -4926 1005 -7892 1037 -1942 1011 -7926 1005 -4918 1007 -1996 985 -7928 1011 -1964 993 -4946 1025 -7880 1003 -1972 1009 -13854 1011 -1948 1019 -4956 983 -4946 1025 -7898 1003 -1966 1025 -7900 1019 -1964 1011 -7890 1021 -4912 1017 -4930 1013 -1968 1015 -4952 1009 -4932 1007 -7920 1009 -1972 979 -7924 1009 -4944 1003 -1970 1015 -7894 1017 +RAW_Data: -1968 997 -4952 1011 -7896 1013 -1954 1005 -13860 985 -2000 979 -4952 1005 -4946 993 -7930 979 -1990 1009 -7908 1017 -1968 1011 -7900 985 -4946 1027 -4920 1009 -1964 1015 -4942 1009 -263646 67 -9708 99 -68890 97 -48712 65 -62028 65 -4652 65 -108870 99 -71758 99 -3200 97 -47548 65 -7036 65 -104448 97 -38184 99 -6502 97 -17756 65 -10136 20983 -1968 999 -4950 1005 -4940 1001 -7898 1025 -1966 1011 -7876 1017 -1966 1023 -7918 981 -4936 1027 -4946 975 -2006 979 -4946 1017 -4954 977 -7930 983 -1980 1003 -7920 989 -4952 1007 -1970 1013 -7896 1007 -1970 1015 -4954 987 -7900 1007 -1970 1007 -13860 993 -1972 1007 -4956 1013 -4926 1005 -7908 995 -1972 1029 -7914 987 -1986 1009 -7906 981 -4956 1009 -4930 1005 -1966 1039 -4938 1007 -4916 1009 -7918 1019 -1968 989 -7892 1017 -4934 1027 -1956 1039 -7898 985 -1974 1007 -4960 981 -7930 985 -1996 989 -13824 1045 -1946 1025 -4928 1009 -4942 997 -7926 1011 -1968 1003 -7894 1023 -1962 993 -7902 1017 -4948 999 -4948 1007 -1968 1015 -4918 1045 -4926 999 -7888 1039 -1972 1013 -7888 1005 -4948 1001 -1970 1011 -7886 1013 -1974 1023 -4942 1005 -7890 1033 -1952 1021 -13806 1047 -1964 1001 -4936 1009 -4950 1001 -7882 1031 -1962 1007 -7906 1021 -1966 1011 -7908 985 -4946 1027 -4918 1011 -1968 1017 -4948 1009 -4932 1015 -7882 1009 -1964 1013 -7900 1017 -4950 1001 -1970 1013 -7916 1013 -1944 1031 -4916 1029 -7888 1007 -1976 1005 -13848 1013 -1968 995 -4952 1003 -4946 991 -7920 1019 -1968 983 -7904 1015 -1966 1019 -7894 1011 -4942 1027 -4924 1011 -1966 1015 -4944 1005 -4926 1007 -7914 1007 -1972 1013 -7884 1013 -4940 1027 -1968 1007 -7906 1001 -1980 999 -4944 1013 -7880 1009 -2000 1003 -13830 997 -1974 1009 -4930 1029 -4938 1013 -7880 1011 -1998 1001 -7908 997 -1966 1025 -7902 1013 -4938 983 -4962 979 -1998 1011 -4932 1005 -4924 1011 -7922 1009 -1970 1015 -7890 1011 -4946 1003 -1970 1013 -7892 1013 -1964 1027 -4928 1021 -7886 1007 -1980 1001 -13846 1013 -1968 999 -4948 1009 -4938 993 -7926 1011 -1964 991 -7926 1011 -1962 993 -7898 1041 -4906 1009 -4960 999 -1964 1023 -4932 1007 -4928 1013 -7898 1015 -1968 1013 -7894 1017 -4948 997 -1968 1031 -7892 1027 -1970 1005 -4914 1039 -7884 1023 -1964 1011 -13838 1013 -1948 1023 -4924 1015 -4942 1025 -7872 1029 -1964 1007 -7898 1025 -1960 1025 -7898 1021 -4912 1023 -4920 1011 -1970 1013 -4954 1011 -4926 1003 -7910 1011 -1968 1013 -7890 1009 -4938 1023 -1982 1007 -7902 1013 -1940 1023 -4926 1011 -7922 1007 -1980 997 -13816 1045 -1964 1001 -4948 1005 -4938 993 -7904 1005 -1966 1035 -7888 1027 -1964 1011 -7906 1015 -4916 1027 -4920 1011 -1968 1019 -4944 1009 -4928 1001 -7924 1009 -1972 979 -7914 1013 -4948 1001 -1970 1013 -7892 1015 -1966 1027 -4928 1021 -7872 1035 -1968 1011 -13832 1011 -1980 983 -4956 987 -4948 1025 -7892 1005 -1966 1007 -7914 1021 -1962 1007 +RAW_Data: -7912 985 -4942 1023 -4926 1007 -1992 981 -4944 1035 -4920 1007 -7904 1025 -1962 991 -7934 981 -4948 995 -2004 1007 -7880 1007 -1992 983 -4946 1027 -7890 1007 -1982 999 -13830 1011 -1968 1025 -4926 1013 -4942 997 -7898 1027 -1960 1023 -7910 983 -2000 979 -7906 1015 -4940 1025 -4920 1011 -1968 1013 -225644 65 -2082 65 -155560 133 -5172 65 -1102 131 -48576 99 -24714 67 -6858 65 -1314 67 -38246 65 -64888 65 -4564 67 -59374 99 -20160 99 -17606 65 -42096 97 -11950 131 -29302 65 -19034 99 -32020 97 -366 65 -4430 131 -14620 99 -17318 65 -5556 diff --git a/assets/unit_tests/subghz/security_pls_1_0_raw.sub b/assets/unit_tests/subghz/security_pls_1_0_raw.sub new file mode 100644 index 00000000000..5542663d67a --- /dev/null +++ b/assets/unit_tests/subghz/security_pls_1_0_raw.sub @@ -0,0 +1,35 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 390000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 297 -1592 167 -1594 231 -366 65 -598 65 -600 197 -98 199 -1098 99 -98 65 -862 133 -628 165 -597 361 -6828 65 -1668 231 -632 65 -792 163 -1284 163 -5554 199 -1588 165 -5300 97 -992 65 -432 197 -2566 99 -2340 63 -5932 65 -1462 65 -1062 131 -2454 65 -1446 133 -1682 65 -1260 65 -368 131 -1482 65 -134 131 -1512 197 -1710 131 -824 99 -66 133 -464 131 -866 65 -698 65 -200 65 -894 99 -1692 233 -1130 97 -2160 265 -1392 99 -132 131 -166 65 -1318 327 -1548 163 -6980 165 -994 65 -698 131 -1580 129 -132 63 -758 97 -466 99 -1590 395 -1024 97 -600 99 -732 63 -228 129 -98 165 -292 99 -696 231 -232 197 -166 133 -132 131 -430 165 -664 199 -1596 197 -530 65 -1054 63 -3474 165 -4504 65 -2980 99 -268 133 -2356 131 -798 99 -132 99 -796 97 -1692 97 -3804 199 -166 67 -66 97 -132 99 -5058 129 -1512 163 -1290 65 -298 199 -398 65 -1034 65 -1332 167 -3448 65 -1750 65 -1186 131 -462 65 -920 65 -166 97 -362 131 -1704 131 -1748 65 -2124 65 -1064 133 -1694 197 -5148 99 -566 131 -1696 99 -598 65 -698 231 -692 267 -2490 99 -1618 165 -1760 197 -2152 165 -1226 195 -100 99 -66 131 -100 99 -400 65 -456 131 -198 165 -368 261 -826 365 -858 99 -132 163 -460 229 -264 65 -664 165 -234 231 -98 165 -100 99 -1986 99 -2526 65 -832 167 -1762 231 -728 67 -530 133 -2082 97 -960 67 -498 199 -1658 133 -1488 99 -2652 99 -1258 165 -5284 99 -1660 65 -1790 65 -432 65 -3804 197 -2170 131 -196 129 -66 97 -832 99 -2466 97 -1622 99 -1624 163 -394 163 -1018 133 -1856 99 -430 67 -826 197 -3156 65 -166 97 -558 65 -1690 131 -1498 99 -66 65 -2716 161 -658 99 -1054 65 -230 65 -2074 97 -2042 65 -3074 263 -1698 165 -492 65 -400 131 -196 131 -368 165 -134 203 -168 201 -134 165 -398 301 -628 99 -1032 99 -830 65 -66 65 -432 229 -230 161 -394 197 -228 197 -330 327 -66 197 -822 231 -392 131 -892 393 -1456 131 -64 163 -1418 65 -166 165 -1428 133 -1526 163 -954 65 -888 99 -1956 133 -1194 131 -3514 65 -1728 97 -662 67 -1590 167 -2714 65 -930 65 -166 65 -728 131 -2752 65 -434 133 -1828 99 -3704 129 -1912 133 -1544 227 -494 133 -202 97 -466 65 -200 131 -1580 263 -1708 65 -626 65 -626 199 -166 133 -3446 99 -3420 99 -398 131 -1164 131 -7018 131 -3468 63 -1658 199 -956 101 -598 99 -1790 97 -1192 65 -362 133 -630 65 -100 429 -794 65 -696 231 -1130 65 -268 395 -730 131 -466 431 -66 233 -168 197 -998 97 -264 65 -796 163 -236 +RAW_Data: 265 -100 133 -1464 99 -464 67 -592 229 -362 131 -262 163 -134 325 -164 163 -130 97 -164 65 -724 97 -132 97 -958 131 -594 131 -264 161 -98 229 -100 97 -890 131 -364 99 -198 97 -262 131 -234 2497 -134 65 -68 165 -400 563 -400 433 -496 99 -100 131 -266 99 -100 65 -200 231 -894 65 -166 463 -200 201 -1228 131 -266 65 -496 99 -300 97 -202 165 -896 365 -132 163 -1698 165 -132 99 -168 67 -166 67 -796 165 -400 131 -200 165 -796 165 -98 2161 -66 65 -166 293 -228 887 -66 395 -656 297 -100 97 -530 97 -66 97 -594 65 -428 97 -332 65 -400 131 -164 261 -66 299 -334 65 -596 97 -166 99 -1184 161 -460 131 -132 229 -398 299 -664 165 -722 165 -166 263 -300 99 -232 199 -266 267 -660 97 -758 133 -530 65 -632 99 -264 329 -1028 67 -166 2451 -562 427 -464 163 -198 229 -264 229 -790 295 -164 297 -132 263 -726 267 -66 99 -364 197 -564 99 -1162 67 -960 97 -198 163 -630 133 -66 163 -132 195 -1288 197 -430 197 -1546 65 -890 97 -394 231 -924 2173 -100 65 -594 165 -100 99 -528 99 -166 99 -298 497 -66 65 -100 131 -198 265 -362 131 -198 293 -294 129 -1150 263 -262 65 -100 131 -494 231 -166 231 -468 99 -66 165 -1262 197 -298 65 -298 397 -432 297 -498 361 -200 65 -466 131 -166 101 -496 231 -364 233 -64 197 -196 65 -426 265 -198 99 -1218 97 -200 67 -232 131 -200 167 -200 99 -66 165 -928 67 -1722 99 -764 65 -892 99 -232 133 -300 133 -1080 621 -1526 487 -1504 507 -506 1517 -1524 519 -1508 509 -1512 447 -546 1503 -1038 1035 -1482 547 -976 1007 -1208 823 -490 1503 -532 1481 -1048 989 -1534 499 -524 1507 -514 1499 -1014 1007 -524 1503 -1530 473 -60198 1533 -1516 481 -1040 985 -1044 981 -1554 479 -1530 479 -1044 1007 -1502 511 -1538 483 -516 1503 -1542 473 -1016 1033 -1510 483 -1542 505 -1002 1003 -508 1521 -1010 1015 -1512 507 -526 1515 -518 1505 -1016 1007 -59156 529 -1528 463 -1580 447 -542 1507 -1544 469 -1554 481 -1512 499 -518 1507 -1016 1007 -1512 511 -1012 1021 -1010 1007 -518 1529 -472 1555 -982 1023 -1502 505 -508 1537 -488 1545 -1012 1003 -480 1531 -1516 507 -60180 493 -12296 821 -1698 299 -1686 387 -590 1465 -1570 459 -1046 979 -1546 475 -1534 489 -1044 1009 -482 1529 -1032 973 -1538 513 -480 1537 -492 1523 -1012 1017 -59154 497 -11798 301 -704 1325 -1148 913 -1612 417 -1102 897 -1118 945 -586 1437 -568 1465 -1058 977 -1534 477 -550 1495 -502 1515 -1006 1037 -494 1527 -1510 489 -60174 531 -16794 355 -640 1399 -1608 449 -1050 989 -1540 461 -1546 477 -1068 973 -518 +RAW_Data: 1503 -1024 1009 -1536 473 -552 1503 -498 1517 -1010 1017 -59162 513 -9838 227 -1670 371 -604 1425 -1116 949 -1554 477 -1030 981 -1042 973 -550 1477 -532 1511 -1010 1003 -1544 511 -496 1515 -516 1509 -1018 1007 -488 1539 -1504 503 -60216 1525 -1530 485 -1018 999 -1012 1019 -1538 475 -1546 477 -1012 1025 -1506 517 -1530 505 -510 1507 -1512 513 -1010 999 -1516 507 -1520 513 -1012 1015 -506 1527 -1014 991 -1542 483 -524 1517 -482 1529 -1008 1005 -137640 165 -1660 165 -1362 231 -3114 67 -2286 131 -1652 197 -1448 195 -1648 97 -3534 163 -988 65 -556 65 -132 133 -2594 199 -2054 65 -1918 65 -1458 163 -690 65 -1134 131 -1194 67 -1158 131 -1656 199 -198 99 -298 199 -2676 67 -2122 231 -1762 263 -1560 131 -1228 99 -198 197 -830 99 -166 97 -6274 99 -1058 163 -1676 97 -1788 65 -5742 99 -3890 131 -2682 195 -166 65 -1394 265 -432 99 -368 99 -100 67 -198 163 -564 133 -992 131 -266 133 -962 233 -200 131 -196 231 -560 131 -66 65 -764 131 -1058 133 -564 99 -1792 133 -2820 65 -3480 165 -9536 99 -66 97 -626 97 -1828 199 -1860 99 -66 197 -1060 99 -1746 65 -1690 99 -198 99 -1660 165 -1764 65 -1558 199 -1456 99 -164 65 -1318 395 -5966 131 -928 165 -1026 99 -534 65 -434 99 -100 97 -100 97 -3272 65 -2168 131 -2904 231 -1564 67 -958 263 -3780 65 -166 99 -3506 99 -1594 165 -1492 197 -164 63 -1382 197 -1162 65 -364 133 -822 65 -498 495 -230 165 -366 65 -464 231 -666 231 -198 65 -332 163 -566 65 -164 67 -332 231 -232 265 -198 97 -1254 361 -200 65 -2056 129 -430 131 -100 65 -1588 263 -198 97 -2992 97 -528 297 -134 97 -368 427 -66 67 -132 65 -132 367 -330 65 -266 229 -66 65 -66 65 -198 231 -66 133 -528 363 -162 161 -230 525 -230 65 -230 461 -132 327 -330 295 -130 197 -230 165 -270 265 -464 65 -698 265 -264 229 -400 99 -3476 97 -1490 199 -134 99 -2970 165 -1618 167 -1598 65 -1162 99 -234 167 -1162 135 -464 65 -664 165 -1126 197 -362 97 -1222 65 -3496 65 -7024 131 -1592 131 -530 97 -6464 231 -998 263 -428 65 -698 131 -198 131 -1414 63 -1346 165 -1060 65 -1664 167 -566 263 -666 165 -566 331 -100 131 -1522 167 -368 199 -896 229 -232 99 -968 99 -168 231 -66 197 -68 131 -168 133 -400 131 -268 233 -596 233 -132 97 -494 131 -1710 197 -1616 67 -592 99 -1226 267 -268 65 -266 133 -1986 165 -332 99 -366 131 -2700 97 -1398 65 -130 269 -198 65 -1664 131 -3180 165 -992 65 -866 99 -166 163 -2782 65 -2354 265 -5176 65 -66 163 -1290 67 -164 99 -2584 67 -3084 +RAW_Data: 195 -364 65 -164 229 -958 63 -166 193 -130 65 -556 99 -332 199 -430 197 -996 297 -1426 235 -1160 2053 -166 1063 -100 501 -132 535 -198 67 -66 165 -98 165 -460 365 -366 97 -432 329 -264 133 -100 165 -328 197 -360 1087 -264 97 -166 63 -166 233 -98 195 -294 97 -264 163 -266 197 -100 359 -66 65 -1958 165 -694 99 -166 99 -596 299 -466 97 -66 99 -696 231 -1492 297 -1554 165 -1680 165 -368 99 -166 99 -168 65 -794 197 -194 2581 -98 1151 -592 99 -426 197 -328 295 -164 65 -232 163 -530 165 -264 129 -98 229 -294 493 -426 99 -66 163 -164 261 -264 129 -166 229 -68 65 -558 131 -132 65 -132 197 -1550 361 -98 67 -132 99 -132 131 -786 99 -198 301 -366 165 -530 99 -234 2159 -264 1691 -166 367 -132 231 -100 197 -166 97 -366 163 -68 131 -366 165 -268 133 -430 233 -100 133 -132 199 -932 561 -1416 231 -794 199 -1296 165 -564 165 -666 99 -490 97 -760 163 -1582 295 -464 267 -330 2561 -134 931 -66 65 -132 99 -264 63 -132 99 -198 97 -364 129 -460 65 -230 263 -164 163 -100 365 -100 131 -398 97 -530 65 -266 299 -1028 133 -100 97 -166 65 -296 65 -166 133 -498 331 -962 99 -98 199 -1328 165 -200 65 -234 99 -400 231 -632 65 -232 199 -530 65 -866 429 -958 197 -368 165 -668 65 -984 163 -100 129 -1088 259 -752 97 -522 131 -892 65 -298 67 -364 199 -132 65 -788 97 -396 363 -1052 99 -228 131 -98 99 -1526 463 -330 131 -898 263 -332 97 -996 163 -494 99 -2950 65 -798 131 -2490 165 -1424 65 -1694 65 -1822 65 -1756 67 -3820 65 -2536 97 -2410 65 -1030 131 -404 263 -732 165 -1566 197 -1554 199 -400 65 -100 99 -566 165 -3584 65 -764 101 -2630 65 -2896 163 -364 67 -100 65 -1228 263 -232 63 -884 65 -4092 133 -1622 325 -166 99 -2352 65 -500 65 -1324 99 -366 65 -1592 297 -5134 131 -1130 65 -1962 99 -66 99 -1454 67 -1130 99 -134 199 -134 165 -1222 229 -166 131 -464 197 -196 263 -234 99 -534 65 -132 131 -166 133 -134 199 -1590 231 -66 131 -1160 131 -300 65 -698 199 -462 133 -3446 99 -2876 65 -596 65 -1716 133 -2886 97 -134 199 -1628 131 -1790 67 -2556 615 -1510 453 -1584 443 -1566 485 -1014 977 -1054 1003 -516 1501 -1010 1007 -520 1495 -1034 1005 -1530 481 -514 1541 -492 1523 -1012 1001 -1508 521 -1016 999 -512 1527 -1506 509 -488 1521 -1040 989 -1538 473 -60194 1519 -1540 511 -1010 1001 -1020 1009 -1516 515 -1010 1001 -518 1507 -524 1503 -1534 493 -1510 501 -1022 1011 -516 1507 -522 1507 -1512 509 -1506 519 -516 +RAW_Data: 1499 -1542 485 -492 1535 -1508 491 -1046 1005 -1008 1001 -59158 547 -1508 515 -1510 505 -1510 523 -976 1033 -1000 1031 -472 1527 -1008 1039 -482 1541 -1010 1017 -1512 485 -514 1533 -482 1527 -1000 1019 -1534 479 -1044 1011 -488 1505 -1522 511 -512 1529 -984 1013 -1522 509 -60190 1543 -1522 477 -1038 999 -1002 1029 -1504 523 -1012 1009 -482 1541 -486 1543 -1510 481 -1544 505 -1008 997 -516 1507 -520 1513 -1508 517 -1510 519 -490 1521 -1540 485 -514 1503 -1540 487 -1016 1019 -1008 1003 -59184 521 -1536 511 -1506 489 -1548 475 -1026 1011 -1014 1019 -488 1513 -1014 1043 -484 1513 -1012 1023 -1506 519 -492 1525 -520 1507 -1008 1005 -1542 479 -1012 1023 -514 1507 -1508 521 -516 1523 -1008 1009 -1516 511 -60208 1513 -1524 477 -1042 1013 -984 1011 -1516 509 -1008 1015 -522 1505 -526 1509 -1504 503 -1526 513 -1008 1015 -512 1497 -522 1513 -1504 527 -1514 481 -516 1527 -1528 509 -494 1511 -1540 493 -1018 1005 -1014 1003 -59166 553 -1502 511 -1504 487 -1546 511 -992 1011 -1010 1015 -520 1517 -1016 1007 -480 1527 -1016 1009 -1512 509 -510 1529 -490 1525 -1018 999 -1542 481 -1014 1035 -488 1541 -1506 481 -520 1509 -1018 1035 -1510 481 -60216 1525 -1508 521 -1024 1005 -1008 1017 -1504 487 -1018 1009 -526 1517 -516 1509 -1532 475 -1518 511 -1008 1031 -506 1495 -520 1507 -1540 483 -1544 477 -514 1531 -1506 487 -520 1513 -1516 509 -1006 1037 -1016 1011 -139572 133 -1724 99 -1590 165 -1660 65 -168 67 -1000 529 -598 65 -296 131 -130 197 -566 99 -732 99 -832 65 -4560 131 -1156 161 -982 261 -788 65 -720 65 -1286 65 -100 131 -368 131 -298 65 -500 65 -2674 65 -758 197 -168 131 -294 63 -1744 163 -5304 131 -3408 199 -2122 65 -2626 131 -832 67 -166 65 -4384 163 -1608 65 -66 97 -262 65 -1418 65 -390 65 -230 65 -66 165 -1666 133 -1690 165 -1744 65 -2206 131 -392 165 -398 95 -594 97 -864 197 -632 99 -66 101 -364 331 -494 65 -1024 197 -762 165 -200 133 -298 229 -524 97 -560 97 -98 297 -522 65 -166 165 -360 195 -1514 229 -896 99 -562 261 -1552 195 -1422 263 -98 167 -396 99 -4540 165 -266 67 -398 97 -1660 263 -230 131 -1092 99 -134 65 -464 231 -98 99 -1458 97 -5494 99 -3342 65 -432 99 -2910 131 -1492 99 -3612 65 -1684 197 -1608 195 -996 65 -132 99 -1728 165 -1196 65 -862 131 -626 231 -796 65 -732 165 -1462 197 -2710 65 -790 97 -3198 165 -1778 65 -4158 165 -100 229 -5170 133 -2622 65 -3872 97 -754 165 -1260 365 -100 133 -98 133 -98 199 -562 131 -262 165 -1216 197 -230 131 -1612 165 -528 163 -228 63 -264 97 -328 99 -728 299 -758 163 -164 327 -228 65 -164 +RAW_Data: 197 -130 65 -264 163 -462 231 -100 65 -296 163 -196 97 -262 163 -728 299 -462 299 -1492 165 -200 99 -232 65 -1054 2385 -100 395 -132 99 -664 99 -132 365 -596 99 -794 329 -564 133 -298 165 -166 235 -366 229 -132 163 -590 197 -66 197 -1252 293 -262 129 -592 259 -232 163 -526 65 -230 165 -368 101 -1160 99 -826 97 -396 65 -198 3377 -66 791 -100 133 -168 99 -166 199 -100 465 -230 67 -400 197 -396 295 -1310 791 -1228 229 -560 65 -264 129 -326 199 -332 99 -264 65 -426 293 -132 197 -1316 99 -754 131 -822 197 -66 97 -460 65 -756 295 -166 3453 -198 65 -800 97 -100 199 -462 99 -198 67 -66 135 -298 299 -302 65 -300 99 -598 531 -466 233 -234 395 -200 133 -962 99 -100 199 -928 99 -628 97 -100 97 -730 99 -696 233 -528 67 -98 67 -694 365 -198 67 -896 295 -1484 97 -626 2563 -66 525 -100 561 -166 163 -232 265 -396 67 -234 99 -166 495 -166 97 -134 231 -132 133 -436 263 -298 97 -264 129 -230 65 -164 131 -164 393 -98 99 -294 65 -426 261 -264 131 -362 97 -196 65 -462 131 -1906 97 -260 65 -394 129 -660 133 -132 165 -264 231 -730 99 -560 197 -790 65 -896 65 -200 99 -764 261 -404 165 -164 165 -100 97 -164 395 -98 97 -164 99 -98 131 -132 163 -562 229 -532 99 -198 65 -332 99 -200 301 -330 165 -200 99 -928 2555 -362 731 -464 165 -492 165 -134 131 -732 131 -494 99 -164 99 -362 97 -166 97 -362 97 -134 97 -134 131 -166 99 -166 133 -468 329 -296 133 -1198 65 -2178 229 -3362 131 -1792 65 -7008 99 -164 65 -1448 65 -590 65 -134 67 -498 131 -1228 131 -532 131 -132 67 -364 65 -2128 165 -2358 99 -1526 265 -1154 65 -2240 97 -558 65 -2306 605 -1000 999 -1008 1035 -1510 513 -482 1531 -1496 543 -496 1507 -510 1529 -1514 511 -990 1007 -1002 1047 -984 1015 -492 1537 -512 1499 -1020 1011 -490 1539 -1000 1033 -988 1039 -476 1549 -474 1533 -1018 1001 -60188 1493 -1592 449 -1046 949 -1598 439 -564 1455 -552 1475 -548 1505 -1020 975 -544 1497 -1530 511 -1500 513 -1008 1003 -1540 507 -1512 501 -1022 1011 -1014 985 -1532 513 -500 1509 -1534 505 -522 1479 -528 1507 -59194 517 -1006 1017 -1006 1003 -1508 537 -482 1535 -1508 509 -512 1497 -520 1505 -1520 513 -1006 1033 -988 1039 -1006 1015 -480 1533 -490 1525 -1006 1035 -486 1539 -1014 987 -1018 1033 -484 1541 -484 1517 -1016 999 -60216 1481 -1620 387 -1118 923 -1602 431 -556 1481 -556 1447 -578 1467 -1048 977 -520 1505 -1542 499 -1516 481 -1048 989 -1544 493 -1516 515 -1010 1017 -986 1033 -1508 507 -514 +RAW_Data: 1495 -1514 509 -528 1509 -516 1503 -59178 493 -1064 983 -1050 983 -1534 479 -540 1487 -1544 481 -520 1501 -518 1511 -1544 487 -1012 1019 -1010 1013 -1016 1003 -514 1519 -478 1531 -1016 1001 -514 1533 -1012 1003 -1000 1035 -486 1517 -524 1513 -1012 1019 -60160 1525 -1580 443 -1070 929 -1580 451 -556 1505 -548 1467 -520 1511 -1020 999 -514 1527 -1502 505 -1512 511 -1012 1021 -1508 517 -1518 513 -1006 1017 -1006 1001 -1512 511 -514 1527 -1500 507 -524 1517 -486 1535 -59184 527 -1018 993 -1016 1013 -1516 511 -508 1495 -1538 491 -520 1511 -522 1507 -1534 473 -1016 1011 -1024 1007 -1008 1001 -518 1515 -524 1507 -1008 1001 -520 1501 -1026 1009 -1008 1031 -508 1495 -518 1507 -1046 975 -60196 1551 -1516 483 -1050 989 -1532 497 -522 1511 -484 1511 -518 1509 -1044 1007 -484 1517 -1544 495 -1508 509 -1010 1017 -1514 503 -1516 515 -1012 1017 -1018 1005 -1512 515 -482 1529 -1514 503 -524 1505 -512 1499 -135388 65 -928 99 -3478 197 -164 131 -558 65 -1120 131 -2416 265 -1562 99 -4088 133 -1460 165 -202 65 -1428 97 -1518 199 -332 133 -2388 197 -1590 67 -2016 133 -1624 97 -1094 65 -1692 99 -3458 163 -570 131 -4418 229 -296 97 -198 97 -164 297 -132 461 -164 163 -1284 299 -332 131 -1064 133 -796 67 -232 67 -264 201 -432 133 -330 133 -198 99 -166 99 -768 65 -462 133 -98 99 -100 397 -1228 133 -532 65 -5202 163 -2542 99 -766 263 -1686 65 -298 67 -1230 65 -266 197 -262 163 -1296 229 -1742 65 -1054 65 -2286 133 -366 165 -2936 229 -1158 167 -198 67 -3148 263 -3174 165 -1720 133 -1766 131 -5204 163 -1814 67 -1664 65 -4348 97 -364 131 -1532 267 -3838 163 -1348 65 -3364 231 -3336 65 -100 97 -466 65 -730 67 -3524 129 -296 163 -1118 97 -66 231 -786 131 -262 97 -428 429 -528 195 -68 165 -964 99 -366 295 -460 99 -930 197 -300 99 -598 63 -600 131 -430 131 -66 131 -762 363 -1554 99 -168 135 -1452 65 -466 165 -692 99 -296 131 -592 97 -726 131 -134 97 -3000 99 -1608 131 -492 65 -854 193 -1058 99 -498 99 -1694 65 -996 199 -530 97 -1582 165 -1718 131 -3418 131 -1592 267 -1622 99 -530 99 -466 197 -5108 131 -100 67 -1656 95 -1318 65 -3530 133 -1196 65 -1886 131 -490 165 -2222 197 -1694 97 -2076 65 -1022 65 -758 163 -98 97 -164 97 -198 63 -688 97 -1086 65 -1614 65 -1822 67 -1028 133 -398 99 -430 131 -2932 165 -1122 99 -334 297 -2028 65 -1392 97 -622 131 -296 99 -100 165 -100 199 -100 99 -300 497 -100 197 -302 265 -102 99 -1428 165 -168 297 -234 65 -798 131 -68 197 -466 165 -230 67 -132 99 -166 167 -598 231 -264 +RAW_Data: 265 -136 233 -764 165 -100 297 -232 67 -166 2513 -66 1745 -232 165 -436 99 -366 131 -466 99 -468 199 -466 131 -102 527 -764 99 -98 199 -166 133 -266 133 -166 99 -68 197 -434 65 -268 231 -132 131 -200 65 -330 65 -200 131 -232 165 -134 65 -1160 97 -134 99 -200 99 -1200 429 -920 97 -590 2475 -132 1095 -132 133 -66 233 -430 167 -168 429 -166 427 -164 423 -66 99 -230 229 -262 325 -164 65 -330 129 -132 231 -300 329 -332 133 -462 197 -564 99 -996 67 -264 233 -764 99 -98 299 -1462 363 -824 133 -132 99 -298 99 -100 197 -68 65 -132 4251 -132 67 -234 133 -166 199 -100 131 -200 131 -198 67 -330 199 -364 197 -298 99 -66 199 -268 197 -298 397 -430 131 -528 99 -266 231 -328 595 -402 65 -500 129 -298 229 -64 99 -1290 231 -822 229 -328 131 -1116 263 -228 361 -862 99 -66 133 -796 65 -698 3715 -166 463 -564 97 -198 97 -132 97 -230 295 -98 229 -330 393 -164 131 -230 297 -526 229 -98 97 -66 363 -722 295 -64 163 -400 167 -762 363 -66 165 -234 133 -864 97 -798 65 -332 431 -498 65 -928 197 -68 133 -266 165 -594 65 -200 99 -464 265 -230 2321 -196 1857 -98 297 -132 431 -266 431 -462 131 -100 397 -330 65 -364 65 -432 229 -166 297 -66 295 -954 163 -626 163 -526 495 -466 201 -660 327 -666 131 -998 197 -166 67 -468 97 -564 99 -1460 163 -926 299 -926 99 -598 133 -498 67 -232 199 -828 131 -1328 327 -166 99 -598 231 -402 65 -132 65 -566 97 -264 167 -1560 67 -1330 67 -858 65 -1366 131 -2754 99 -1786 131 -5130 195 -164 67 -134 131 -1984 65 -1286 97 -294 99 -228 65 -1062 65 -3418 131 -68 131 -1096 563 -1016 975 -1042 983 -1046 1005 -1516 485 -518 1531 -518 1507 -1514 515 -1014 989 -1516 523 -1016 1007 -1506 505 -1002 1011 -1520 511 -1012 1017 -1000 1005 -1532 513 -510 1499 -518 1497 -1018 1035 -1510 481 -60186 1543 -1514 513 -1014 987 -1518 527 -486 1537 -1008 999 -1018 1009 -1520 513 -1506 519 -1018 991 -516 1503 -520 1515 -1512 527 -1512 481 -1016 1019 -1008 1021 -1506 521 -992 1037 -510 1491 -1010 1017 -1512 507 -59178 481 -1116 879 -1138 897 -1118 915 -1614 409 -608 1423 -586 1441 -1580 441 -1070 957 -1580 455 -1044 1007 -1528 479 -1040 1003 -1518 481 -1034 1017 -1008 1015 -1520 481 -506 1521 -514 1507 -1016 1007 -1518 511 -60172 459 -4210 815 -1730 299 -658 1411 -1108 941 -1074 945 -1562 483 -1542 493 -1012 1005 -526 1507 -512 1497 -1520 513 -1524 511 -1004 1001 -1014 1029 -1494 515 -1002 1043 -478 1529 -1018 1001 -1538 495 -59140 529 -7690 365 -624 +RAW_Data: 1381 -658 1397 -1602 423 -1114 911 -1582 441 -1070 955 -1572 481 -1036 971 -1566 479 -1034 981 -1012 1015 -1514 505 -530 1513 -516 1511 -1018 1007 -1514 481 -60210 459 -7710 1381 -1140 903 -1126 915 -1602 415 -1588 443 -1060 983 -550 1475 -550 1469 -1558 479 -1540 493 -1018 1005 -1018 1009 -1506 503 -1006 1037 -484 1535 -1010 1017 -1518 497 -59168 525 -1008 997 -1046 1009 -1016 989 -1510 527 -486 1539 -480 1527 -1532 515 -1006 1011 -1506 519 -990 1019 -1534 479 -1042 1015 -1512 477 -1026 1009 -1010 1015 -1512 507 -526 1513 -484 1543 -1018 1003 -1510 509 -60172 1509 -1612 389 -1104 939 -1596 419 -582 1471 -1074 961 -1040 991 -1542 453 -1548 481 -1038 1017 -514 1505 -492 1543 -1502 515 -1506 515 -1002 1033 -986 1035 -1514 481 -1016 1027 -518 1503 -1014 1011 -1514 521 -133944 165 -1586 97 -294 63 -5014 99 -492 231 -1222 65 -396 131 -3086 99 -1920 65 -266 129 -1918 65 -922 195 -1908 65 -2080 97 -1894 99 -1558 165 -1424 165 -5468 99 -1694 65 -1756 65 -1812 99 -490 65 -1710 229 -98 99 -132 131 -992 99 -168 131 -68 65 -2322 199 -1888 133 -132 199 -800 97 -662 201 -666 97 -134 65 -132 65 -134 133 -166 199 -396 65 -558 231 -330 99 -692 199 -264 133 -332 99 -268 65 -366 231 -732 163 -264 327 -132 129 -132 99 -724 367 -234 133 -130 363 -598 331 -166 199 -1068 299 -466 99 -2822 65 -66 131 -1562 65 -1684 131 -556 99 -198 199 -1254 99 -1032 65 -1296 65 -100 133 -1330 65 -1058 65 -1096 65 -632 65 -1856 65 -134 163 -890 65 -1646 65 -664 65 -528 65 -392 99 -1624 165 -496 99 -1428 129 -2826 65 -466 65 -864 65 -4422 131 -1926 99 -1466 131 -6930 99 -894 131 -1754 97 -1640 65 -66 97 -396 99 -130 65 -1086 99 -756 65 -198 65 -2188 261 -1594 131 -1722 65 -130 97 -6642 97 -134 131 -2376 67 -1590 65 -66 65 -998 165 -930 165 -264 65 -132 65 -296 97 -558 65 -66 99 -1086 363 -230 131 -1194 165 -1490 231 -166 133 -636 229 -428 363 -826 261 -130 97 -132 97 -164 131 -66 131 -2902 359 -1518 165 -598 133 -990 161 -396 301 -5214 261 -2776 65 -2326 99 -1698 65 -1618 99 -1358 65 -3480 231 -1558 131 -4656 97 -1554 65 -166 199 -200 201 -926 99 -664 133 -1656 229 -98 99 -1030 99 -1656 131 -1294 67 -396 131 -3038 165 -332 427 -230 361 -266 1027 -166 329 -166 265 -100 67 -230 799 -166 135 -200 631 -298 99 -168 297 -464 497 -264 429 -66 597 -164 197 -200 67 -232 97 -300 595 -132 165 -234 163 -100 65 -432 65 -4370 65 -722 131 -1688 131 -398 65 -1162 199 -2120 263 -1098 133 -758 +RAW_Data: 99 -296 97 -300 231 -200 133 -364 163 -532 199 -536 265 -762 399 -66 131 -332 99 -466 97 -132 431 -198 131 -100 131 -234 465 -164 231 -564 131 -398 131 -334 301 -132 99 -132 131 -498 65 -462 99 -1094 65 -66 99 -266 99 -800 65 -432 65 -562 65 -792 65 -166 99 -1230 131 -1248 65 -770 197 -1260 1985 -134 747 -66 655 -198 99 -530 299 -198 65 -166 299 -134 131 -200 531 -328 131 -624 165 -98 97 -230 97 -560 97 -560 131 -1654 131 -200 65 -166 99 -666 297 -796 67 -132 297 -664 199 -100 65 -532 131 -168 65 -466 165 -728 131 -624 2073 -166 233 -168 863 -166 131 -464 463 -100 131 -266 165 -196 399 -330 563 -632 65 -232 97 -66 131 -166 129 -98 131 -1386 99 -462 131 -1254 131 -1548 231 -824 65 -198 265 -996 99 -1062 231 -862 329 -264 261 -658 2367 -66 631 -98 859 -230 231 -558 129 -396 129 -66 297 -98 201 -134 131 -166 231 -162 295 -432 263 -66 331 -1384 65 -198 197 -98 131 -228 65 -132 65 -692 261 -560 97 -262 163 -232 99 -132 99 -134 65 -200 133 -132 99 -798 231 -1624 131 -498 67 -630 99 -300 165 -1126 293 -694 65 -98 65 -100 2267 -98 393 -494 197 -426 131 -166 67 -198 199 -266 429 -166 65 -300 131 -66 65 -232 133 -102 365 -134 97 -332 67 -232 331 -66 363 -366 97 -796 65 -166 165 -1260 263 -164 99 -266 527 -758 65 -428 197 -564 65 -366 429 -166 267 -830 133 -598 333 -666 65 -134 197 -398 97 -132 65 -168 133 -502 65 -364 131 -98 65 -630 197 -166 129 -822 65 -230 295 -64 65 -164 65 -790 97 -230 129 -364 163 -330 131 -132 65 -230 67 -166 97 -66 165 -632 231 -264 97 -294 99 -856 229 -694 261 -1546 97 -2076 65 -462 133 -5548 199 -732 99 -4170 133 -1232 99 -164 165 -1656 65 -766 167 -2258 163 -1610 197 -2020 99 -2518 131 -1020 65 -364 97 -200 97 -1664 163 -526 65 -1096 165 -1684 65 -986 99 -4860 131 -966 131 -1622 65 -1658 65 -1266 97 -266 165 -200 99 -964 99 -330 65 -3440 131 -166 99 -68 65 -1164 65 -132 99 -200 67 -792 163 -496 99 -860 427 -492 195 -230 99 -466 163 -1364 295 -132 165 -364 67 -1026 231 -370 65 -566 65 -530 363 -196 97 -164 97 -594 63 -164 165 -228 163 -66 233 -862 97 -692 65 -1744 163 -1416 67 -132 99 -1718 65 -556 131 -496 99 -1328 99 -132 167 -466 131 -4690 165 -1654 65 -1114 263 -1620 65 -1796 97 -1426 99 -1922 99 -7098 97 -466 131 -1578 131 -2384 165 -298 133 -766 131 -330 295 -2348 +RAW_Data: 131 -534 99 -798 2211 -134 297 -66 361 -66 197 -198 97 -398 199 -100 163 -100 65 -464 133 -134 233 -68 229 -696 199 -200 265 -330 65 -1218 163 -166 97 -426 229 -698 165 -100 99 -134 165 -372 65 -1426 65 -266 99 -794 65 -832 199 -464 165 -698 99 -266 165 -794 99 -298 133 -734 165 -266 99 -864 131 -232 1893 -166 1465 -1484 263 -560 99 -230 65 -462 197 -66 97 -890 165 -130 97 -132 163 -232 97 -132 161 -162 263 -262 99 -362 65 -432 65 -830 97 -234 99 -628 199 -66 99 -166 101 -268 265 -594 131 -1030 97 -1156 595 -800 167 -1920 65 -464 165 -264 131 -66 167 -134 233 -632 329 -100 97 -166 199 -466 199 -98 267 -200 97 -266 199 -300 65 -496 563 -100 101 -166 165 -730 233 -166 131 -590 97 -232 131 -164 359 -428 3159 -792 65 -624 197 -98 229 -132 393 -398 199 -200 133 -366 99 -132 67 -528 265 -730 197 -166 65 -200 397 -1358 131 -1712 363 -1462 299 -132 67 -1792 65 -794 99 -368 131 -134 165 -134 67 -266 265 -430 2315 -98 1473 -100 129 -66 229 -198 261 -166 97 -426 97 -100 229 -496 197 -162 163 -392 231 -166 229 -660 131 -366 297 -166 299 -232 97 -332 301 -866 133 -596 267 -364 99 -502 99 -1988 131 -134 65 -66 165 -366 231 -266 165 -690 99 -234 65 -498 67 -166 133 -762 2459 -166 1019 -264 99 -200 265 -562 65 -328 295 -330 197 -360 131 -98 227 -232 65 -426 259 -166 99 -496 131 -500 399 -992 67 -432 133 -66 99 -1394 231 -1524 133 -430 65 -886 65 -1716 131 -2818 63 -430 229 -296 97 -1706 131 -164 65 -1478 131 -458 99 -1568 165 -756 197 -890 99 -1088 359 -660 97 -98 229 -166 65 -500 99 -266 65 -566 65 -432 365 -200 99 -798 99 -296 327 -1218 165 -132 99 -466 165 -168 133 -632 363 -1482 163 -802 131 -862 133 -1332 65 -100 431 -830 97 -596 165 -3422 99 -896 65 -766 97 -3766 65 -132 65 -1152 163 -1810 99 -230 97 -654 229 -458 165 -200 67 -166 297 -134 99 -4840 133 -762 67 -764 231 -1248 97 -1780 97 -3332 65 -100 261 -1186 99 -3360 99 -364 97 -1738 163 -294 97 -4918 129 -1550 295 -1028 199 -1264 99 -1560 99 -2156 167 -1556 231 -1852 167 -998 67 -1116 65 -562 167 -334 133 -266 165 -394 99 -166 97 -3082 99 -232 301 -5148 131 -502 67 -732 197 -434 199 -200 99 -432 65 -232 199 -464 133 -1060 97 -1582 97 -98 97 -924 129 -462 229 -560 65 -132 97 -166 161 -164 97 -166 229 -360 97 -132 63 -198 131 -162 525 -1714 67 -732 99 -958 +RAW_Data: 65 -1166 165 -200 199 -166 133 -100 65 -1294 99 -166 265 -992 297 -728 65 -332 431 -166 261 -132 65 -132 65 -98 363 -230 163 -430 165 -230 129 -660 129 -66 131 -398 2453 -132 1329 -166 1187 -232 1657 -166 499 -68 99 -132 233 -894 99 -232 99 -134 363 -628 67 -998 131 -234 99 -266 197 -398 97 -200 167 -334 197 -430 429 -168 263 -1160 99 -364 131 -264 97 -1318 131 -790 99 -432 131 -132 199 -100 131 -930 133 -1424 99 -398 165 -1486 299 -166 165 -334 2325 -66 795 -102 397 -100 533 -100 429 -98 131 -464 65 -532 329 -366 165 -332 99 -432 295 -132 99 -662 67 -332 331 -1226 131 -102 199 -562 469 -430 97 -232 63 -328 65 -1914 133 -466 131 -832 163 -1660 331 -464 199 -828 131 -696 65 -132 2139 -66 2051 -66 263 -790 99 -566 429 -428 99 -330 297 -698 65 -200 197 -68 461 -1292 131 -168 165 -634 131 -234 133 -594 163 -360 165 -700 99 -964 133 -1026 65 -532 197 -1520 263 -688 65 -888 295 -658 65 -824 67 -598 97 -426 65 -130 161 -132 63 -658 99 -64 165 -522 199 -298 65 -428 197 -560 65 -200 165 -100 167 -594 229 -100 297 -268 65 -100 459 -200 97 -334 2997 -200 597 -498 97 -626 97 -134 363 -166 333 -266 65 -664 331 -300 299 -568 529 -662 263 -626 67 -594 99 -266 165 -230 361 -462 67 -66 131 -694 397 -1490 167 -132 165 -768 165 -130 165 -466 99 -298 99 -952 163 -428 97 -296 97 -360 99 -196 65 -658 65 -4052 229 -6240 165 -228 65 -426 99 -994 99 -398 363 -1512 161 -2042 65 -592 131 -2866 65 -500 167 -5246 97 -462 67 -1156 99 -2428 99 -960 65 -132 99 -164 65 -166 329 -2484 263 -232 67 -1368 99 -996 267 -498 67 -4612 131 -4866 65 -100 363 -464 231 -264 231 -262 297 -1594 99 -1596 65 -136 133 -1662 67 -1694 429 -1290 197 -198 293 -858 99 -1976 165 -66 97 -460 131 -460 97 -328 163 -1624 397 -300 67 -166 97 -430 299 -300 299 -1792 65 -4438 131 -622 67 -500 131 -1064 65 -400 65 -426 261 -1644 131 -3468 165 -1684 99 -866 101 -66 231 -464 65 -498 133 -492 97 -1712 99 -98 197 -66 265 -1586 199 -1334 99 -1948 97 -200 99 -266 65 -666 131 -132 99 -264 195 -3066 99 -3512 99 -1746 65 -598 97 -6068 167 -600 99 -1262 65 -166 65 -134 65 -132 131 -1520 99 -1254 97 -1828 197 -1294 129 -66 65 -1248 97 -754 165 -6542 231 -662 197 -560 359 -98 97 -130 99 -3080 63 -952 129 -296 65 -230 63 -428 99 -1788 133 -100 65 -462 199 -66 165 -1094 99 -66 +RAW_Data: 167 -3190 265 -1128 195 -298 525 -166 65 -594 597 -664 131 -498 165 -232 65 -296 129 -296 65 -494 297 -498 297 -596 201 -332 2027 -132 593 -68 891 -66 893 -98 365 -396 97 -398 99 -300 199 -366 163 -598 99 -100 131 -234 65 -132 331 -532 165 -166 231 -1660 133 -532 265 -100 131 -100 131 -298 199 -396 199 -334 197 -166 67 -334 131 -1662 165 -298 97 -534 65 -628 65 -534 65 -266 97 -826 133 -696 65 -294 233 -198 165 -134 2081 -66 929 -198 167 -300 99 -232 297 -234 199 -662 67 -166 99 -66 233 -132 433 -232 265 -300 297 -132 65 -132 97 -496 199 -360 465 -132 65 -132 297 -460 293 -64 161 -262 97 -492 199 -200 233 -132 97 -396 99 -858 199 -864 65 -66 99 -532 131 -1608 297 -1550 163 -432 229 -66 163 -394 1953 -134 1491 -100 991 -66 165 -232 265 -130 299 -432 167 -724 363 -134 167 -200 231 -66 199 -98 395 -66 165 -266 99 -332 197 -268 265 -466 265 -166 493 -362 65 -132 99 -360 199 -200 133 -758 99 -330 165 -298 163 -428 199 -368 165 -334 131 -500 163 -986 97 -394 329 -196 97 -558 195 -230 97 -532 2373 -232 165 -232 795 -132 267 -168 363 -166 297 -298 131 -134 65 -466 131 -464 65 -232 67 -266 229 -364 231 -232 297 -464 65 -198 133 -398 529 -134 65 -364 163 -732 233 -298 299 -134 231 -66 129 -264 397 -132 131 -200 329 -430 131 -132 265 -1292 65 -362 131 -264 97 -1020 165 -398 131 -364 65 -300 265 -924 195 -396 331 -166 167 -132 433 -198 99 -464 297 -266 165 -396 131 -1226 165 -694 65 -230 197 -896 65 -594 2969 -164 461 -298 133 -330 133 -234 65 -134 131 -66 65 -68 97 -66 99 -132 231 -694 363 -298 267 -268 231 -368 131 -300 99 -134 65 -166 461 -396 263 -66 165 -298 131 -66 229 -1644 163 -1610 229 -658 97 -132 129 -162 97 -428 65 -66 129 -1912 65 -1194 233 -2218 133 -360 65 -132 229 -3428 65 -262 65 -3208 133 -1224 99 -296 65 -2212 65 -496 65 -200 199 -498 65 -1144 65 -1764 165 -1726 65 -434 65 -898 165 -2354 67 -134 99 -464 99 -792 263 -954 1161 -100 295 -296 131 -132 457 -462 363 -200 725 -298 131 -134 231 -68 531 -166 667 -298 99 -66 595 -794 165 -202 199 -68 99 -298 165 -68 231 -202 201 -200 97 -1360 197 -266 165 -334 99 -234 165 -200 165 -100 131 -664 65 -566 397 -100 165 -132 199 -132 165 -988 197 -394 99 -164 65 -294 99 -262 63 -1288 233 -132 199 -168 265 -64 99 -728 133 -1192 65 -334 165 -132 199 -200 +RAW_Data: 131 -400 65 -398 165 -866 131 -264 393 -1680 231 -1494 299 -894 265 -364 65 -132 131 -960 99 -296 165 -824 65 -1716 99 -664 97 -134 165 -1526 165 -634 131 -166 135 -466 231 -696 2331 -100 329 -100 961 -198 65 -164 199 -98 331 -132 65 -298 731 -66 163 -332 265 -894 65 -132 265 -300 97 -334 229 -100 65 -1026 233 -366 329 -922 99 -266 329 -428 97 -462 361 -758 163 -1886 65 -498 229 -558 65 -600 267 -68 65 -1592 133 -202 2299 -332 393 -132 329 -326 231 -232 97 -590 231 -136 201 -1226 265 -530 199 -134 65 -232 297 -398 65 -564 65 -1458 65 -500 99 -302 99 -1120 65 -66 131 -98 197 -66 133 -66 65 -730 99 -200 197 -730 165 -664 297 -1462 165 -664 133 -168 65 -168 133 -368 197 -466 1957 -66 1525 -266 131 -366 65 -394 65 -98 163 -296 99 -130 265 -696 65 -398 131 -1128 197 -134 67 -894 97 -296 231 -166 401 -98 131 -928 265 -398 131 -798 131 -298 165 -830 65 -230 231 -168 97 -1252 131 -590 65 -460 229 -692 97 -332 65 -366 265 -732 2297 -66 197 -66 131 -166 231 -100 99 -298 365 -168 361 -130 129 -66 161 -198 97 -626 593 -66 99 -98 99 -556 297 -132 65 -134 65 -526 295 -196 197 -68 163 -264 327 -130 855 -66 393 -132 131 -100 65 -98 227 -164 197 -758 131 -268 99 -430 65 -1686 131 -1652 197 -788 63 -726 165 -100 131 -264 197 -1026 197 -1250 131 -1650 65 -1980 97 -132 63 -1424 97 -198 99 -100 65 -1090 65 -398 99 -1686 99 -754 63 -1714 97 -1842 65 -2988 65 -4980 165 -1624 65 -232 67 -1464 65 -3048 65 -166 97 -1986 65 -1062 99 -862 131 -2732 99 -2360 97 -1620 65 -1326 65 -330 197 -3238 67 -266 131 -2968 67 -132 135 -1688 131 -1718 97 -1648 65 -166 65 -1292 65 -1908 99 -424 131 -1222 197 -798 99 -700 97 -1758 165 -1562 99 -396 165 -166 99 -98 65 -366 65 -762 131 -332 233 -498 133 -98 163 -562 65 -68 131 -858 65 -896 65 -366 233 -532 197 -168 65 -68 65 -630 195 -724 231 -296 361 -164 261 -2862 233 -232 99 -3186 67 -232 163 -496 165 -1620 97 -1622 131 -7022 267 -268 165 -466 63 -528 295 -200 197 -332 65 -1656 131 -5478 65 -1296 99 -130 161 -694 67 -1694 131 -734 99 -2590 99 -1056 65 -432 327 -66 165 -164 65 -1120 229 -1656 165 -1128 131 -1232 99 -1560 65 -568 131 -360 231 -1598 99 -3250 67 -1818 65 -1216 263 -3328 65 -1508 133 -2600 65 -528 65 -2418 65 -460 97 -100 97 -164 65 -1560 133 -1822 163 -296 165 -1090 165 -168 133 -1264 +RAW_Data: 229 -1458 165 -66 133 -1626 197 -132 65 -394 65 -724 229 -132 65 -200 263 -296 97 -264 131 -130 229 -132 161 -1230 431 -132 99 -234 233 -362 99 -698 67 -334 65 -366 299 -398 99 -328 131 -396 165 -1458 99 -926 2239 -66 763 -68 1727 -266 65 -364 65 -464 365 -366 97 -664 165 -200 265 -234 261 -264 395 -362 329 -690 261 -164 495 -232 131 -326 165 -264 99 -198 397 -928 299 -268 299 -166 99 -298 167 -436 65 -266 67 -498 231 -896 367 -428 97 -332 133 -628 165 -1394 231 -926 131 -232 3127 -132 921 -428 263 -66 97 -230 97 -1022 329 -430 97 -166 65 -198 63 -100 65 -66 97 -66 361 -132 67 -232 131 -268 99 -366 99 -98 331 -364 99 -428 97 -66 491 -164 99 -164 65 -428 131 -260 429 -1380 263 -1564 65 -300 65 -498 99 -364 167 -200 231 -264 67 -264 365 -266 231 -262 65 -724 65 -130 2213 -130 361 -166 2065 -166 165 -100 133 -264 299 -332 99 -98 229 -198 65 -328 131 -100 263 -628 131 -330 231 -98 65 -132 129 -264 65 -130 163 -692 131 -66 99 -532 133 -234 99 -232 367 -298 401 -702 165 -498 399 -166 65 -132 131 -400 165 -1232 165 -1296 65 -232 165 -300 97 -396 2033 -198 463 -230 67 -68 563 -262 295 -330 197 -1190 197 -66 167 -66 263 -430 263 -100 163 -198 167 -102 165 -100 99 -234 67 -66 267 -396 197 -296 131 -1190 331 -200 67 -234 231 -530 263 -1610 263 -264 329 -196 129 -98 131 -132 227 -132 425 -526 129 -694 299 -856 63 -132 165 -166 165 -436 297 -1430 65 -66 99 -198 167 -266 65 -864 267 -996 65 -500 265 -1456 297 -726 163 -66 579 -1508 523 -1504 509 -1006 1033 -486 1513 -1514 507 -510 1537 -982 1011 -528 1509 -512 1495 -1034 999 -1016 999 -516 1539 -1014 989 -1510 527 -486 1537 -1508 517 -1512 485 -1546 483 -524 1519 -484 1529 -60168 1539 -1506 507 -1006 1015 -1016 1007 -1512 509 -1006 1033 -506 1495 -1544 497 -1014 1007 -1008 1001 -1544 477 -1024 1011 -1538 485 -1512 525 -1010 1005 -482 1529 -1018 1005 -1020 1009 -1532 475 -540 1507 -512 1491 -59188 513 -1506 515 -1512 519 -1020 985 -506 1519 -1538 491 -504 1533 -998 1013 -516 1505 -522 1505 -1018 1005 -1002 1035 -494 1525 -1014 995 -1546 483 -524 1513 -1504 515 -1502 509 -1512 509 -514 1527 -514 1501 -60186 1539 -1506 509 -1008 1003 -1016 1009 -1520 515 -1014 989 -518 1509 -1544 485 -1016 999 -1016 1003 -1544 483 -1016 1017 -1506 515 -1534 475 -1036 987 -520 1507 -1012 1035 -1006 1017 -1502 503 -526 1503 -508 1533 -59160 523 -1508 507 -1502 537 -984 1013 -528 1505 -1504 503 -520 1537 -994 +RAW_Data: 1007 -508 1533 -474 1527 -1008 1037 -1012 1003 -510 1503 -1018 1009 -1518 513 -514 1495 -1546 477 -1520 509 -1528 505 -492 1527 -520 1505 -60188 1543 -1514 483 -1044 1001 -1000 1009 -1520 513 -1012 1019 -508 1505 -1516 515 -1008 999 -1016 1007 -1516 513 -1010 1017 -1514 503 -1520 513 -1008 1001 -530 1495 -1012 1021 -1010 1001 -1530 503 -518 1507 -516 1507 -59162 517 -1554 479 -1540 493 -1034 981 -538 1483 -1534 505 -506 1497 -1038 1007 -488 1537 -484 1539 -1020 1007 -1016 1009 -484 1539 -1000 1005 -1532 511 -480 1535 -1514 513 -1504 515 -1508 519 -494 1529 -486 1535 -60182 1515 -1556 479 -1044 983 -1016 1005 -1512 507 -1036 1001 -488 1529 -1536 495 -1020 1009 -1010 1017 -1510 487 -1014 1039 -1510 505 -1510 521 -980 1039 -484 1539 -986 1039 -1016 1007 -1504 503 -520 1507 -516 1507 -131494 295 -198 195 -98 99 -362 97 -196 165 -130 233 -1528 197 -1756 165 -1024 129 -326 97 -1794 131 -1562 65 -1692 99 -100 99 -532 99 -1728 231 -5256 65 -7488 133 -164 133 -100 97 -266 327 -166 99 -1294 131 -628 97 -502 163 -1122 131 -856 65 -1480 63 -3748 131 -1356 65 -1152 99 -2316 131 -2640 65 -798 131 -2520 99 -66 133 -5954 129 -1680 131 -3458 131 -1086 65 -532 67 -632 165 -3482 65 -1024 163 -2800 65 -362 197 -1880 97 -494 99 -100 65 -1120 131 -3212 299 -266 99 -698 329 -1328 165 -66 133 -534 131 -794 227 -990 65 -164 133 -130 131 -198 65 -196 63 -66 165 -196 131 -98 329 -298 99 -230 65 -164 425 -100 523 -266 65 -1686 65 -1182 163 -3614 131 -3386 133 -6578 65 -432 231 -1682 131 -1680 99 -588 99 -2222 97 -364 131 -5214 131 -698 133 -394 327 -296 295 -396 199 -1256 131 -1190 99 -234 65 -3596 163 -2036 163 -660 133 -430 199 -800 67 -2854 165 -3516 99 -1660 131 -1596 99 -1726 133 -2326 65 -168 65 -530 165 -166 67 -1384 229 -494 165 -1248 99 -1224 65 -1624 99 -468 233 -4386 165 -1264 133 -762 65 -296 229 -1678 165 -1518 163 -1580 65 -132 65 -530 261 -166 161 -428 199 -134 99 -730 99 -558 99 -266 65 -1164 499 -468 131 -462 229 -362 131 -1480 327 -230 65 -732 65 -928 395 -298 65 -568 99 -232 99 -200 99 -1098 65 -3106 97 -266 99 -2356 67 -494 65 -1816 163 -390 165 -1032 67 -2308 165 -134 99 -1284 97 -1550 99 -494 97 -1326 97 -3530 65 -3702 99 -1382 231 -1228 165 -496 97 -968 265 -1452 99 -4736 131 -3916 65 -1282 65 -364 65 -3530 97 -1352 97 -1742 133 -5274 99 -3490 65 -3418 65 -1850 97 -2782 99 -1720 133 -2258 65 -100 65 -1620 65 -1160 65 -1558 99 -662 65 -1458 99 -230 129 -98 163 -392 +RAW_Data: 129 -694 401 -1526 67 -298 65 -1258 231 -102 199 -298 99 -790 99 -100 97 -100 131 -100 97 -164 161 -266 65 -234 133 -132 299 -628 65 -702 197 -330 65 -962 231 -366 165 -330 133 -792 65 -628 2059 -196 633 -166 231 -264 97 -166 163 -336 231 -202 65 -266 65 -266 131 -134 99 -200 197 -330 165 -132 65 -200 99 -266 197 -264 97 -198 559 -66 163 -754 229 -98 65 -64 363 -164 229 -196 363 -426 231 -68 201 -1288 97 -634 331 -2022 99 -264 67 -166 197 -464 3065 -98 97 -132 97 -66 327 -132 853 -132 97 -164 99 -396 63 -100 393 -196 131 -1052 465 -1458 427 -198 97 -198 391 -262 65 -66 165 -494 131 -262 97 -264 97 -264 265 -168 197 -764 97 -232 163 -464 65 -66 131 -398 65 -896 133 -598 67 -430 165 -1230 165 -200 65 -1130 65 -198 263 -230 2753 -66 565 -100 1129 -132 99 -134 67 -532 99 -400 299 -166 131 -134 65 -464 231 -234 329 -132 231 -262 163 -132 65 -394 131 -98 131 -66 397 -100 65 -68 461 -198 99 -296 199 -500 231 -1552 195 -66 65 -1586 195 -1350 197 -1418 131 -488 2647 -396 229 -526 129 -262 97 -262 97 -328 165 -664 99 -166 99 -232 133 -234 131 -726 129 -130 65 -198 129 -132 161 -330 65 -426 97 -694 531 -364 99 -862 165 -694 301 -66 163 -302 65 -232 233 -700 65 -98 165 -628 65 -100 163 -1516 327 -362 65 -956 231 -626 131 -464 65 -232 99 -828 131 -164 99 -400 363 -1324 99 -264 97 -1560 101 -66 65 -464 65 -498 99 -300 297 -100 65 -200 65 -600 97 -166 2321 -100 603 -200 67 -468 299 -300 65 -100 133 -796 131 -66 67 -700 165 -432 97 -332 233 -534 197 -398 199 -166 297 -362 131 -1132 233 -562 165 -166 99 -530 197 -700 131 -856 133 -398 65 -892 97 -2990 65 -4596 99 -130 163 -1770 65 -2256 99 -860 65 -232 131 -1662 267 -232 101 -1166 165 -1160 99 -466 163 -100 97 -366 65 -2828 65 -1624 263 -1786 65 -164 131 -1214 131 -460 227 -2998 63 -494 67 -1658 97 -3456 65 -3618 99 -2554 99 -2484 231 -4088 97 -560 165 -296 129 -2144 197 -528 363 -166 231 -428 163 -296 197 -132 129 -1354 199 -664 163 -624 131 -98 131 -688 131 -590 263 -164 97 -494 197 -362 131 -298 133 -3478 65 -334 583 -1526 509 -1526 481 -514 1509 -1544 475 -1024 1011 -1012 1017 -506 1501 -528 1507 -1530 473 -538 1493 -520 1507 -1014 1011 -520 1515 -1512 491 -1046 1007 -482 1529 -1016 1007 -1512 507 -1004 1039 -990 1015 -60210 1503 -1524 513 -998 1015 -1542 483 -520 1505 -516 1507 -522 1519 -516 +RAW_Data: 1503 -1508 487 -554 1477 -1526 513 -514 1501 -1028 1005 -1526 481 -514 1541 -518 1503 -498 1515 -1506 501 -1544 499 -1020 1005 -1002 1001 -59198 529 -1518 481 -1544 507 -514 1497 -1536 473 -1044 1001 -1018 1009 -490 1539 -482 1529 -1512 507 -526 1507 -512 1503 -1016 1011 -524 1513 -1504 505 -1020 1005 -526 1507 -1008 1001 -1530 517 -1010 1013 -1012 1013 -60178 1557 -1508 489 -1016 1009 -1522 513 -514 1505 -520 1513 -524 1505 -512 1499 -1546 475 -526 1513 -1506 505 -506 1527 -1014 997 -1542 483 -522 1513 -518 1503 -516 1501 -1534 505 -1508 523 -1012 1007 -1014 987 -59186 515 -1578 419 -1608 449 -544 1471 -1546 485 -1050 977 -1042 991 -518 1507 -524 1487 -1538 489 -518 1503 -518 1529 -1002 1005 -524 1511 -1508 503 -1008 1035 -486 1541 -1014 987 -1538 495 -1018 1007 -1008 1001 -60188 453 -4246 817 -1716 295 -674 1393 -594 1449 -586 1447 -546 1467 -1578 447 -550 1497 -1530 511 -510 1489 -1038 1003 -1514 513 -512 1525 -478 1535 -492 1525 -1506 515 -1534 475 -1014 1031 -1000 1011 -59180 507 -11528 557 -686 1341 -674 1363 -1646 383 -620 1409 -610 1431 -1090 947 -554 1477 -1566 477 -1032 981 -516 1505 -1016 1005 -1522 511 -1012 1019 -1020 1005 -60176 1469 -1672 337 -1166 889 -1606 449 -578 1439 -566 1485 -518 1509 -516 1503 -1546 479 -514 1497 -1528 511 -512 1523 -1008 1003 -1514 513 -512 1525 -478 1541 -486 1517 -1522 511 -1508 521 -1010 995 -1010 1033 -133296 65 -1252 99 -332 65 -1220 131 -594 129 -394 99 -1546 131 -856 65 -1494 433 -132 99 -334 263 -164 199 -198 133 -3348 131 -626 65 -2598 65 -66 99 -1284 131 -1588 197 -1664 63 -694 65 -2206 197 -134 131 -300 65 -1146 67 -3524 197 -296 99 -1226 65 -1360 131 -1620 165 -260 231 -786 131 -1018 129 -1224 131 -302 65 -796 129 -396 97 -1744 67 -464 67 -166 131 -766 99 -398 65 -98 233 -66 97 -396 65 -1096 65 -298 99 -500 99 -3474 99 -996 97 -232 67 -2218 197 -1420 131 -1692 297 -6442 99 -368 99 -366 131 -164 65 -2038 65 -232 99 -1526 233 -5196 65 -298 65 -498 65 -1064 263 -232 627 -364 67 -132 129 -728 131 -166 65 -200 133 -596 197 -232 197 -390 97 -1088 331 -496 99 -300 65 -430 265 -402 197 -164 163 -596 165 -430 199 -1026 99 -1460 133 -1394 99 -1998 165 -300 65 -2360 165 -600 65 -3364 197 -658 131 -6356 99 -530 97 -166 165 -200 131 -132 133 -600 65 -5300 67 -762 131 -860 97 -1480 67 -1814 99 -1330 65 -266 99 -1918 99 -1360 165 -234 133 -5506 99 -468 65 -1894 131 -98 65 -1624 99 -98 67 -1808 65 -230 63 -786 99 -1970 131 -3506 99 -196 163 -1058 99 -164 67 -1730 165 -3516 +RAW_Data: 99 -666 99 -700 133 -98 133 -1086 163 -768 65 -1026 2523 -166 2747 -964 195 -362 265 -966 131 -198 197 -100 331 -330 65 -164 131 -528 163 -230 229 -68 97 -332 393 -134 197 -132 197 -330 165 -268 165 -198 133 -564 65 -232 233 -266 267 -432 199 -232 99 -66 131 -532 97 -132 299 -1252 133 -166 199 -796 99 -98 233 -398 197 -1590 163 -826 65 -764 165 -1658 163 -66 165 -698 165 -198 67 -164 99 -998 2029 -232 331 -100 691 -66 523 -98 561 -166 725 -560 65 -362 163 -132 395 -526 67 -166 67 -960 265 -298 131 -464 131 -200 329 -598 199 -132 163 -294 129 -754 99 -294 197 -432 165 -232 67 -202 99 -234 199 -326 163 -824 229 -132 259 -462 99 -266 65 -328 131 -326 229 -562 97 -230 97 -132 3077 -100 1031 -100 131 -100 165 -132 295 -68 97 -364 233 -264 65 -200 131 -562 331 -396 195 -228 197 -166 167 -266 165 -266 133 -662 165 -100 65 -466 531 -364 297 -526 65 -560 163 -364 99 -1678 131 -562 99 -268 65 -200 133 -1714 263 -986 2071 -624 99 -392 359 -296 99 -264 97 -230 295 -230 165 -766 165 -232 129 -302 97 -562 197 -66 97 -526 461 -166 131 -1146 131 -264 229 -788 65 -68 165 -66 97 -100 133 -100 99 -400 65 -198 97 -526 65 -360 195 -854 163 -362 97 -198 65 -362 97 -230 97 -690 99 -424 295 -200 197 -1052 2919 -134 565 -634 99 -498 331 -634 99 -300 65 -598 131 -330 131 -166 163 -132 65 -98 231 -130 65 -296 65 -166 259 -396 99 -362 65 -464 165 -232 131 -196 97 -526 97 -824 261 -330 229 -68 297 -560 397 -466 131 -796 329 -334 231 -166 133 -100 167 -236 335 -364 529 -762 199 -232 201 -1130 131 -866 99 -698 133 -1556 97 -664 99 -300 165 -598 131 -1688 199 -1062 97 -398 331 -164 65 -922 657 -198 393 -98 229 -428 555 -130 163 -394 397 -132 261 -264 65 -130 65 -262 493 -132 363 -134 165 -66 133 -402 265 -330 199 -132 565 -366 99 -134 163 -134 165 -200 99 -132 167 -332 431 -66 399 -200 199 -266 65 -830 133 -2050 97 -888 129 -2404 97 -2646 133 -2058 65 -1924 65 -530 97 -1646 65 -234 97 -3752 65 -1550 165 -2670 99 -328 97 -5326 97 -2246 65 -1094 165 -1672 97 -1582 97 -3722 65 -5080 65 -1676 197 -2936 665 -462 131 -264 65 -168 233 -298 65 -132 65 -600 67 -132 163 -296 99 -1318 131 -562 495 -396 263 -132 133 -200 131 -132 129 -264 263 -164 97 -132 131 -2308 99 -1956 167 -298 99 -592 163 -462 67 -3200 295 -620 65 -824 133 -64 131 -1552 +RAW_Data: 165 -1526 131 -690 65 -526 97 -132 129 -362 65 -198 97 -456 131 -262 575 -1010 1019 -1008 1003 -520 1513 -1016 999 -1012 1009 -522 1511 -1504 517 -1012 1011 -1514 511 -1010 1021 -514 1501 -1514 511 -1504 517 -1510 521 -492 1525 -1506 517 -514 1505 -522 1515 -484 1531 -1012 1011 -60190 1519 -1538 493 -1018 1005 -1514 515 -514 1495 -1528 513 -1502 515 -1010 1011 -1516 517 -514 1489 -1538 475 -1024 1003 -1534 515 -1498 505 -1036 987 -1018 1033 -1510 483 -1538 507 -1000 1009 -526 1505 -1534 491 -59172 529 -1018 1007 -1008 1001 -518 1507 -1024 1009 -1008 1035 -518 1499 -1526 481 -1044 979 -1546 475 -1026 1011 -516 1503 -1516 503 -1524 513 -1512 519 -482 1525 -1540 473 -510 1513 -518 1507 -518 1505 -1048 983 -60204 1495 -1594 439 -1062 983 -1542 461 -548 1503 -1548 449 -1540 507 -1034 1003 -1514 489 -516 1537 -1510 507 -1014 993 -1542 481 -1512 521 -1012 1015 -1006 1007 -1510 503 -1548 495 -1018 1007 -482 1531 -1514 505 -59196 507 -1042 979 -1048 973 -530 1515 -1012 1015 -1018 1005 -522 1505 -1508 519 -1014 993 -1542 483 -1018 997 -514 1529 -1508 517 -1528 473 -1546 495 -524 1505 -1504 501 -518 1505 -518 1505 -518 1513 -1016 997 -60198 495 -7704 1361 -1648 391 -1632 407 -1100 949 -1576 425 -566 1495 -1526 481 -1042 981 -1552 481 -1534 513 -1010 1013 -990 1007 -1536 511 -1506 487 -1020 1011 -526 1511 -1504 503 -59194 513 -1022 1013 -1016 989 -552 1465 -1046 1009 -1014 987 -518 1507 -1544 483 -1016 1017 -1508 515 -1010 1009 -488 1545 -1506 515 -1504 505 -1542 477 -516 1529 -1508 523 -486 1535 -500 1511 -516 1509 -1018 1011 -60166 1513 -1600 431 -1088 945 -1568 447 -580 1471 -1548 479 -1540 475 -1046 973 -1554 479 -510 1533 -1514 481 -1038 1017 -1506 487 -1548 509 -994 1013 -1008 1017 -1514 505 -1514 509 -1004 1015 -520 1517 -1516 513 -136452 65 -496 99 -796 131 -830 197 -168 99 -166 67 -2820 97 -134 65 -298 65 -168 99 -2792 97 -800 67 -3482 231 -166 99 -564 67 -266 99 -932 99 -68 397 -462 165 -66 165 -100 199 -68 497 -98 265 -498 593 -130 99 -360 561 -164 721 -66 131 -392 133 -198 201 -134 233 -66 99 -66 265 -558 163 -232 99 -66 729 -66 165 -164 99 -2250 65 -2340 131 -2166 99 -3386 63 -786 99 -426 197 -1022 197 -1564 131 -5336 99 -294 231 -166 65 -8582 133 -530 133 -234 131 -660 133 -1922 99 -3746 197 -402 65 -302 99 -1456 65 -954 65 -2616 197 -1694 165 -1584 261 -432 65 -986 65 -890 229 -132 97 -298 197 -266 67 -66 65 -200 229 -1018 99 -524 195 -228 165 -166 101 -398 99 -332 331 -1514 259 -164 97 -198 63 -198 95 -690 657 -232 233 -66 133 -68 +RAW_Data: 131 -298 99 -560 199 -984 227 -294 265 -462 97 -230 2307 -68 201 -100 99 -132 2079 -134 163 -234 399 -366 67 -366 131 -268 65 -202 165 -100 97 -364 99 -200 65 -234 199 -230 297 -132 199 -100 99 -696 133 -100 333 -534 165 -166 67 -498 331 -266 165 -696 459 -592 197 -330 131 -98 261 -1578 131 -1016 97 -66 97 -426 99 -630 263 -166 4367 -198 99 -166 99 -334 65 -400 299 -330 67 -926 265 -134 231 -134 197 -66 459 -200 265 -166 131 -132 67 -166 197 -400 165 -134 165 -664 197 -1196 99 -398 65 -564 167 -730 97 -266 165 -430 265 -634 133 -566 199 -66 2627 -366 297 -98 97 -100 131 -164 163 -628 197 -98 97 -428 397 -466 131 -68 99 -132 131 -1286 231 -98 165 -430 97 -364 129 -98 97 -562 65 -200 133 -996 131 -166 65 -234 67 -796 99 -630 297 -1058 165 -134 133 -1230 1931 -98 783 -196 99 -66 97 -532 65 -330 165 -400 333 -696 131 -398 65 -166 297 -198 65 -368 133 -366 199 -132 65 -134 197 -166 167 -266 99 -666 65 -458 197 -1418 229 -130 65 -562 131 -762 99 -564 97 -1064 65 -1158 99 -1364 2125 -132 231 -232 1221 -68 133 -200 165 -198 65 -664 231 -332 261 -494 97 -788 99 -166 131 -368 99 -762 197 -66 131 -134 331 -922 293 -200 165 -198 131 -132 163 -362 395 -64 263 -986 297 -724 163 -888 195 -164 65 -264 129 -196 493 -896 131 -332 165 -434 65 -232 101 -98 97 -598 99 -566 99 -398 165 -200 133 -100 267 -396 65 -332 131 -624 65 -558 63 -396 97 -596 261 -1120 99 -786 131 -130 131 -360 363 -462 233 -366 97 -166 265 -230 65 -756 131 -1646 195 -166 295 -1658 65 -66 195 -1684 65 -6928 99 -1488 65 -164 197 -556 99 -330 97 -528 195 -1352 197 -1590 99 -66 133 -1328 131 -366 97 -2218 65 -600 65 -66 265 -232 133 -1496 133 -462 97 -66 131 -2352 99 -196 67 -2794 99 -2374 97 -100 99 -198 63 -2074 65 -5114 65 -166 99 -3616 133 -1588 97 -1622 163 -98 97 -888 131 -328 195 -196 197 -362 99 -792 161 -164 131 -266 133 -100 65 -234 65 -500 97 -864 131 -132 99 -664 99 -300 99 -300 65 -98 99 -1296 165 -168 231 -796 99 -232 233 -1092 131 -264 361 -964 165 -100 99 -200 263 -2502 165 -630 65 -134 65 -3342 131 -436 199 -564 65 -466 131 -1458 131 -662 131 -936 65 -2260 99 -630 163 -132 65 -4312 197 -330 65 -1126 265 -1694 65 -166 97 -558 97 -694 97 -1754 65 -1656 65 -366 97 -1118 263 -1550 295 -1448 165 -1618 99 -132 163 -1622 165 -1198 +RAW_Data: 231 -730 99 -432 63 -1350 131 -226 197 -432 2459 -66 165 -64 493 -98 1215 -232 229 -494 131 -396 197 -726 165 -196 195 -330 197 -130 99 -134 399 -334 131 -532 99 -1018 99 -164 227 -230 97 -592 295 -66 131 -66 229 -132 559 -724 97 -164 297 -1396 65 -662 65 -1086 97 -1226 65 -166 133 -232 65 -1196 331 -234 67 -564 2619 -132 131 -164 1089 -68 97 -100 997 -66 165 -98 463 -198 133 -266 199 -100 333 -234 197 -198 199 -564 197 -564 163 -792 65 -230 329 -98 65 -234 99 -598 99 -330 327 -198 197 -166 163 -130 131 -1678 575 -1000 1041 -990 1009 -1532 503 -502 1527 -1516 499 -488 1541 -1506 505 -1014 1031 -482 1543 -1504 503 -504 1527 -480 1547 -476 1527 -1002 1021 -514 1527 -1010 1013 -1518 481 -1036 1015 -480 1537 -1516 485 -60180 1555 -994 1009 -512 1503 -506 1531 -518 1505 -1008 1009 -1016 997 -1544 487 -1546 483 -1512 519 -1012 1017 -1508 489 -1544 477 -530 1515 -1510 519 -1506 489 -1048 1005 -1010 1001 -1526 509 -992 1011 -1038 1005 -59156 527 -1090 885 -1112 909 -1604 439 -572 1457 -1580 457 -548 1463 -1562 481 -1046 981 -506 1527 -1510 523 -482 1539 -482 1529 -520 1503 -1018 1011 -514 1497 -1016 1011 -1520 511 -1014 1019 -488 1537 -1510 515 -60180 1501 -1080 947 -546 1493 -538 1485 -518 1505 -1044 973 -1058 983 -1538 465 -1542 501 -1512 509 -1006 1011 -1532 513 -1502 515 -514 1503 -1516 517 -1506 515 -1012 1009 -1018 1001 -1510 527 -1014 1009 -1014 987 -59196 515 -1014 1009 -1016 1015 -1538 483 -516 1507 -1542 479 -512 1531 -1506 489 -1018 1009 -530 1515 -1506 519 -488 1533 -514 1509 -488 1545 -1008 1015 -512 1497 -1016 999 -1548 497 -1014 1009 -482 1543 -1514 499 -60192 493 -7688 1397 -1156 881 -1120 891 -1632 397 -1618 417 -1580 479 -1042 967 -1548 483 -1542 475 -542 1505 -1516 515 -1504 505 -1018 1007 -1018 1009 -1504 537 -984 1013 -1022 1007 -59174 501 -11466 659 -1656 353 -1180 847 -632 1425 -1592 451 -550 1473 -548 1463 -570 1481 -1042 971 -540 1495 -1014 1001 -1544 479 -1034 1001 -518 1509 -1514 513 -60202 1527 -1042 963 -554 1471 -550 1499 -516 1503 -1018 1009 -1012 1019 -1512 501 -1518 513 -1508 501 -1038 1005 -1508 513 -1506 521 -488 1531 -1508 521 -1512 513 -990 1009 -1038 1003 -1514 515 -1008 1017 -1010 1011 -132210 97 -1712 231 -2272 97 -4094 65 -526 65 -2118 67 -432 99 -300 131 -364 165 -1226 199 -134 99 -100 465 -232 99 -726 133 -532 199 -266 133 -232 65 -234 265 -1586 131 -528 99 -696 99 -132 297 -398 67 -464 131 -166 267 -466 165 -764 197 -100 65 -1026 65 -3972 65 -1718 133 -630 99 -200 131 -68 65 -4004 163 -2078 65 -464 131 -496 +RAW_Data: 99 -134 131 -398 65 -1090 295 -132 65 -1646 65 -1396 233 -1296 199 -100 97 -134 65 -764 265 -760 197 -296 65 -526 197 -100 197 -198 63 -1414 163 -1316 195 -98 229 -200 97 -824 99 -100 131 -66 3137 -198 393 -164 131 -824 101 -66 399 -200 67 -232 133 -168 99 -198 65 -366 597 -898 197 -98 65 -330 131 -362 133 -864 97 -632 131 -654 195 -1260 231 -398 99 -626 65 -460 131 -722 99 -300 65 -464 165 -1060 165 -366 67 -132 2189 -66 299 -166 97 -464 99 -200 165 -596 231 -596 65 -134 65 -166 197 -232 265 -266 67 -232 133 -400 199 -232 333 -200 65 -466 65 -430 363 -230 97 -64 197 -758 131 -66 65 -592 131 -558 165 -266 133 -264 165 -1102 131 -134 97 -926 67 -496 197 -1252 2593 -66 229 -66 687 -98 1119 -66 659 -98 197 -960 297 -166 99 -524 429 -1022 99 -364 201 -200 65 -100 199 -498 99 -198 67 -132 399 -432 99 -492 295 -66 197 -66 131 -3066 395 -1156 131 -302 99 -792 161 -264 329 -66 163 -98 259 -762 131 -994 165 -1742 229 -830 165 -430 323 -98 295 -130 99 -368 65 -266 265 -1554 197 -492 2511 -68 795 -132 699 -132 99 -66 633 -562 197 -204 499 -364 99 -200 99 -794 231 -266 99 -564 65 -200 197 -68 429 -198 99 -830 165 -794 99 -166 133 -534 359 -298 99 -234 199 -492 67 -98 167 -528 65 -1858 97 -856 65 -64 131 -462 129 -592 131 -198 97 -396 131 -690 99 -232 2427 -68 2469 -396 467 -264 99 -532 133 -232 63 -362 229 -462 525 -264 97 -260 97 -230 165 -132 131 -992 133 -796 129 -1682 129 -362 99 -230 99 -132 99 -100 65 -1590 265 -1690 197 -1590 97 -392 231 -1454 133 -1298 65 -2296 65 -230 133 -300 99 -2750 65 -560 131 -2966 97 -230 129 -1054 133 -1296 65 -992 67 -5244 167 -200 65 -6756 229 -1608 229 -166 65 -66 97 -396 97 -130 197 -728 163 -2338 197 -132 131 -66 99 -100 97 -300 99 -664 265 -432 99 -696 133 -132 131 -866 233 -134 97 -266 199 -266 229 -1126 99 -100 131 -1424 199 -1594 131 -2186 99 -5780 67 -760 133 -1630 167 -832 99 -2854 65 -2846 65 -5308 231 -1616 97 -1684 131 -236 65 -3044 99 -1594 131 -2108 99 -1660 97 -3448 99 -3556 65 -2690 97 -1648 165 -1858 65 -1492 165 -2882 199 -402 99 -1196 131 -132 99 -66 65 -1728 67 -132 99 -1164 265 -398 99 -166 129 -132 131 -2468 65 -1658 201 -1688 99 -1712 131 -132 99 -992 65 -428 65 -100 165 -498 165 -666 199 -500 329 -732 99 -132 67 -692 65 -362 197 -132 97 -1314 325 -596 +RAW_Data: 165 -66 165 -666 165 -632 65 -198 263 -564 263 -198 99 -230 97 -228 263 -524 231 -98 133 -498 265 -166 99 -924 325 -328 65 -360 165 -196 129 -166 327 -822 99 -398 99 -266 131 -562 99 -460 97 -164 295 -200 197 -964 99 -796 99 -596 165 -1088 65 -200 129 -724 131 -662 295 -724 65 -398 131 -234 99 -430 3857 -66 163 -66 1023 -794 99 -198 363 -68 65 -198 99 -132 265 -296 65 -264 197 -66 167 -530 165 -462 131 -66 425 -428 131 -162 65 -594 493 -362 131 -394 165 -130 297 -394 557 -760 97 -1284 197 -1490 163 -1680 131 -392 231 -264 65 -624 229 -1090 2037 -134 457 -98 131 -164 1691 -100 65 -300 199 -798 99 -528 99 -198 97 -296 99 -262 131 -66 197 -292 133 -198 99 -166 197 -66 199 -1454 229 -396 131 -130 131 -690 99 -98 97 -66 65 -362 63 -98 163 -164 397 -1028 65 -232 99 -66 197 -264 67 -166 165 -202 65 -1134 99 -132 567 -364 197 -696 267 -628 133 -200 133 -166 2173 -296 561 -66 765 -164 97 -266 99 -366 263 -332 99 -566 231 -98 99 -100 265 -132 67 -398 65 -166 97 -230 163 -396 99 -164 97 -98 163 -260 99 -164 229 -1448 163 -298 723 -428 99 -366 65 -330 131 -400 97 -366 131 -596 65 -166 133 -332 99 -366 99 -628 65 -532 165 -66 133 -264 131 -2726 267 -270 131 -232 65 -66 67 -432 165 -200 67 -1030 167 -166 165 -630 231 -196 63 -428 65 -764 2901 -132 99 -198 131 -132 359 -198 63 -132 129 -692 65 -200 233 -98 165 -332 67 -330 133 -166 297 -532 497 -68 165 -168 331 -132 165 -230 333 -564 165 -100 65 -1258 165 -266 99 -760 65 -298 133 -532 163 -464 197 -592 165 -1678 97 -1086 99 -460 65 -2510 97 -66 165 -1428 131 -1280 65 -66 97 -2108 99 -394 129 -230 129 -298 97 -1446 97 -266 97 -230 577 -1538 475 -1542 485 -1018 1023 -514 1503 -490 1523 -1014 1021 -1510 519 -1512 513 -992 1011 -1012 1013 -1032 997 -514 1497 -518 1535 -1010 1001 -1530 481 -504 1521 -1534 473 -522 1539 -1492 513 -514 1511 -60178 1531 -1034 971 -518 1509 -518 1505 -518 1533 -488 1509 -516 1509 -1546 475 -1044 989 -1012 1007 -1544 475 -516 1531 -1008 1011 -490 1545 -1002 1017 -1506 487 -552 1501 -500 1517 -516 1511 -504 1501 -1026 1011 -59168 491 -7578 461 -670 1359 -1184 881 -1614 435 -1566 461 -1050 977 -1050 975 -1042 993 -518 1509 -524 1517 -1014 991 -1508 519 -490 1541 -1502 513 -514 1533 -1506 507 -484 1535 -60182 1535 -1060 949 -554 1483 -540 1467 -558 1475 -550 1469 -538 1499 -1554 481 -1008 1001 -1050 975 -1524 511 -516 +RAW_Data: 1503 -1018 1011 -526 1511 -1014 1017 -1518 495 -488 1537 -482 1527 -522 1503 -526 1505 -1006 1015 -59192 495 -1582 451 -1542 479 -1038 975 -568 1481 -514 1499 -1036 1003 -1512 493 -1544 483 -1012 1033 -1016 1003 -1016 1009 -514 1497 -520 1511 -1018 1011 -1506 519 -490 1533 -1508 519 -492 1525 -1508 515 -514 1501 -60200 1545 -1014 1011 -482 1543 -488 1541 -484 1531 -506 1497 -522 1509 -1520 513 -1012 1019 -986 1037 -1514 513 -486 1541 -1006 1009 -486 1539 -1014 987 -1534 501 -490 1545 -482 1539 -488 1545 -484 1533 -1006 1017 -59174 499 -7598 461 -644 1401 -1094 915 -1614 425 -1572 471 -1060 977 -1012 1019 -1012 1007 -524 1505 -514 1497 -1038 983 -1534 513 -478 1535 -1516 519 -480 1523 -1536 503 -504 1527 -60172 1523 -1078 949 -546 1465 -566 1449 -554 1477 -550 1501 -526 1507 -1508 507 -1014 1005 -1022 1011 -1504 505 -520 1511 -1022 1009 -516 1505 -1018 1007 -1516 511 -506 1529 -488 1517 -524 1507 -512 1529 -984 1011 -132432 263 -1692 97 -1216 65 -788 65 -1320 231 -6950 229 -1658 133 -3184 97 -166 131 -1296 99 -196 99 -2900 165 -1658 131 -1856 99 -1952 133 -632 133 -4016 131 -136 99 -166 99 -1352 95 -2420 99 -98 97 -856 129 -5964 99 -1588 163 -66 65 -1720 65 -2716 67 -398 67 -398 97 -1284 65 -100 65 -788 131 -1748 97 -1596 263 -66 163 -332 431 -130 1161 -198 165 -164 133 -100 199 -338 131 -432 163 -736 231 -660 101 -100 99 -266 99 -102 231 -966 99 -402 465 -464 65 -398 463 -492 231 -430 165 -3936 65 -6980 131 -1248 65 -428 133 -434 199 -728 65 -756 99 -198 97 -4038 133 -2028 65 -2102 65 -660 99 -2552 65 -1860 65 -466 131 -798 65 -1780 165 -1710 261 -132 65 -394 65 -1828 165 -730 65 -1394 97 -132 259 -296 63 -1674 97 -3318 133 -1658 133 -502 65 -2886 131 -1626 163 -196 97 -1414 65 -3520 99 -794 195 -2476 65 -1846 131 -2044 99 -1450 99 -922 99 -1908 65 -262 97 -1776 97 -996 233 -1460 231 -232 131 -702 99 -166 67 -166 165 -168 67 -500 131 -396 99 -298 199 -232 65 -934 299 -334 99 -100 65 -632 165 -168 65 -1226 163 -66 265 -202 233 -862 99 -166 233 -202 231 -762 99 -266 65 -300 65 -1390 67 -3772 131 -528 99 -1316 65 -694 63 -864 197 -1228 67 -430 97 -1712 163 -5212 165 -1624 165 -434 99 -1092 165 -3986 131 -5164 65 -496 65 -4734 163 -1648 97 -1710 199 -1714 99 -1460 359 -1578 165 -1096 67 -626 65 -2172 65 -1580 65 -164 65 -1450 131 -3556 163 -4194 165 -6992 233 -264 97 -464 131 -730 65 -366 65 -528 67 -66 197 -796 131 -298 163 -264 131 -262 131 -826 195 -166 127 -130 +RAW_Data: 293 -328 97 -460 197 -624 65 -262 63 -626 295 -100 131 -66 163 -132 163 -294 97 -164 165 -168 65 -400 299 -68 265 -198 331 -1494 97 -66 131 -1094 1955 -66 723 -132 593 -66 391 -132 1063 -264 2121 -100 1093 -66 165 -100 197 -264 233 -730 263 -166 99 -166 397 -234 165 -728 231 -132 261 -130 163 -194 99 -796 199 -668 131 -826 165 -1626 131 -198 99 -1360 131 -200 131 -132 67 -1058 99 -200 67 -200 67 -768 2605 -96 163 -130 691 -64 1149 -98 163 -132 97 -198 261 -98 131 -1258 297 -430 97 -500 65 -430 131 -398 65 -264 165 -298 165 -134 463 -366 131 -432 565 -166 197 -98 97 -198 133 -230 197 -132 261 -100 65 -592 65 -824 65 -3266 231 -68 65 -432 129 -392 2799 -100 1151 -64 883 -98 99 -562 131 -66 197 -430 195 -196 99 -200 463 -400 99 -1032 131 -330 231 -1092 163 -858 97 -164 97 -226 65 -394 163 -1050 261 -950 263 -230 199 -1786 65 -558 65 -168 65 -396 131 -196 197 -264 99 -588 97 -230 163 -692 97 -262 97 -164 2923 -100 131 -66 561 -162 163 -198 97 -732 133 -732 165 -930 67 -1228 361 -298 131 -928 65 -166 201 -1096 329 -134 299 -432 197 -166 133 -630 165 -896 133 -1126 97 -164 295 -266 265 -134 199 -564 129 -896 131 -600 131 -658 65 -166 499 -232 133 -332 195 -332 497 -100 65 -330 97 -230 129 -362 131 -330 199 -1256 65 -660 65 -790 165 -1358 199 -166 133 -1226 2239 -66 627 -100 595 -132 233 -166 99 -102 299 -66 99 -66 133 -198 167 -266 163 -98 197 -200 233 -466 331 -198 233 -98 99 -332 99 -132 629 -330 497 -466 65 -334 65 -166 131 -300 65 -564 165 -168 99 -1462 65 -134 131 -924 99 -266 233 -300 67 -494 129 -364 97 -662 357 -786 197 -1626 131 -200 65 -396 99 -666 131 -896 131 -600 163 -136 65 -1594 65 -2042 65 -1584 99 -1920 65 -3128 195 -3316 99 -890 195 -626 131 -722 161 -98 97 -626 527 -66 465 -100 295 -200 65 -66 233 -66 163 -166 423 -164 65 -458 295 -524 593 -64 197 -162 65 -98 97 -264 131 -100 327 -132 229 -98 131 -556 395 -66 197 -1060 131 -232 233 -134 65 -464 793 -1620 67 -4074 97 -1018 163 -328 97 -5922 65 -624 133 -668 97 -830 267 -166 133 -100 165 -694 99 -134 231 -230 97 -592 65 -100 229 -490 65 -790 229 -954 97 -198 163 -368 99 -664 65 -100 65 -168 199 -166 233 -600 101 -132 99 -68 65 -232 167 -268 199 -330 263 -496 65 -830 133 -892 99 -1450 129 -3654 63 -1680 99 -1384 97 -2114 97 -430 +RAW_Data: 199 -232 65 -530 131 -1814 65 -164 195 -66 97 -164 65 -232 97 -858 231 -296 163 -164 1939 -266 829 -200 1229 -132 167 -200 231 -230 133 -166 99 -300 331 -332 99 -132 167 -232 67 -864 131 -266 65 -266 131 -200 167 -334 99 -132 231 -134 65 -232 133 -500 65 -66 99 -66 165 -660 99 -198 367 -364 97 -396 131 -1158 63 -1312 131 -164 163 -858 99 -628 363 -330 99 -166 99 -430 97 -330 65 -558 165 -562 2495 -164 423 -66 1653 -166 199 -566 165 -134 97 -234 97 -234 265 -234 99 -232 67 -98 99 -98 131 -266 231 -66 67 -168 197 -996 133 -66 165 -132 133 -198 99 -830 295 -530 99 -166 297 -332 199 -296 129 -1284 165 -694 97 -732 263 -1554 65 -2058 231 -432 99 -264 2167 -164 99 -66 261 -98 719 -496 131 -564 231 -364 65 -466 201 -400 199 -200 67 -232 363 -630 99 -98 65 -500 333 -332 99 -200 397 -366 331 -560 99 -394 231 -130 195 -230 165 -1034 97 -66 131 -1060 97 -562 163 -488 131 -822 229 -500 197 -530 65 -796 197 -164 261 -756 163 -430 65 -530 131 -434 133 -168 133 -298 65 -530 427 -494 65 -628 261 -162 129 -196 131 -1624 65 -332 97 -498 231 -328 99 -166 101 -664 1211 -1510 491 -1542 485 -1020 1015 -510 1493 -1540 489 -534 1501 -1526 479 -1034 1001 -1508 507 -1016 1037 -484 1533 -1500 503 -1030 1007 -998 1009 -1038 1009 -1514 511 -496 1511 -512 1533 -486 1507 -1020 1007 -60200 1525 -1016 999 -514 1539 -484 1511 -520 1507 -514 1529 -474 1537 -522 1505 -1508 505 -1002 1033 -492 1531 -1506 523 -1012 1005 -480 1527 -1018 1011 -1024 1007 -1500 535 -1498 513 -1008 1023 -1008 1013 -492 1527 -59182 477 -1646 337 -1694 365 -1122 881 -618 1405 -1638 407 -600 1455 -1546 461 -1076 971 -1552 447 -1042 1015 -518 1503 -1512 515 -1008 1001 -1016 1011 -1024 1009 -1506 501 -512 1539 -484 1541 -484 1543 -1006 1005 -60182 535 -11720 1363 -658 1347 -1682 373 -1136 897 -590 1447 -1582 441 -1072 957 -550 1501 -1018 997 -1044 989 -1546 485 -1516 517 -1010 1011 -1010 1009 -492 1541 -59174 443 -11526 625 -1648 397 -1106 933 -1584 451 -1084 957 -546 1465 -1548 485 -1046 969 -1052 1001 -1018 977 -1540 507 -520 1505 -490 1535 -482 1531 -1018 1009 -60222 1533 -974 1047 -478 1537 -490 1527 -520 1505 -514 1507 -518 1527 -480 1543 -1506 507 -1008 1001 -522 1501 -1520 511 -1008 1033 -486 1515 -1020 1011 -1012 1013 -1532 511 -1488 513 -1006 1033 -1006 997 -516 1523 -59176 497 -1632 329 -1714 353 -1114 905 -608 1429 -1580 453 -580 1433 -1596 451 -1048 981 -1542 473 -1060 979 -518 1505 -1526 509 -996 1013 -1010 1015 -1016 1007 -1520 511 -516 +RAW_Data: 1505 -522 1509 -488 1537 -1014 1017 -60198 1533 -978 1025 -520 1503 -516 1503 -518 1527 -486 1543 -484 1533 -508 1495 -1548 475 -1026 1013 -516 1503 -1514 505 -1024 1009 -516 1503 -1018 1007 -1018 1009 -1504 501 -1544 497 -1020 1009 -1010 1017 -488 1539 -137350 65 -794 165 -166 65 -432 295 -428 329 -164 131 -324 97 -198 65 -230 165 -166 431 -532 263 -232 67 -430 197 -66 893 -1522 165 -3076 65 -328 163 -2006 65 -894 197 -1362 99 -132 99 -1660 231 -1580 263 -1126 99 -266 133 -864 65 -4456 163 -196 199 -3214 167 -398 67 -1322 63 -1148 197 -1698 197 -1014 65 -7018 133 -462 165 -1664 99 -894 65 -634 327 -1222 97 -6562 97 -2512 131 -758 65 -592 131 -1182 97 -1792 65 -230 129 -1284 65 -1020 65 -988 99 -5252 163 -1692 131 -1970 65 -198 197 -728 65 -366 363 -1592 131 -1216 165 -360 163 -526 99 -460 99 -332 201 -232 65 -200 67 -268 165 -532 197 -268 167 -566 265 -132 231 -194 129 -198 163 -198 195 -394 361 -762 99 -166 99 -536 99 -3384 65 -1684 99 -66 99 -790 133 -1716 97 -1710 165 -1624 231 -2062 99 -1362 299 -3378 65 -196 97 -854 65 -1120 99 -200 99 -268 133 -432 131 -1956 67 -664 65 -1556 65 -1050 97 -132 97 -4740 131 -132 99 -1660 199 -864 165 -1582 133 -1614 131 -590 63 -4394 263 -296 231 -3032 197 -1670 65 -756 131 -4392 131 -1654 167 -168 67 -368 65 -832 99 -100 133 -1532 133 -1690 99 -868 131 -662 131 -3508 97 -852 63 -1120 65 -3144 163 -662 97 -594 97 -98 229 -1126 67 -266 65 -132 195 -296 65 -196 129 -262 99 -462 199 -762 65 -396 65 -328 229 -530 231 -264 165 -200 301 -894 65 -264 195 -166 99 -852 195 -1186 97 -66 97 -166 63 -3368 65 -230 65 -1152 99 -1624 165 -1624 65 -1656 165 -1754 99 -430 131 -3440 65 -3044 99 -2126 199 -1190 233 -232 133 -1722 65 -1658 197 -3220 263 -1780 65 -1590 97 -134 133 -1386 97 -3256 165 -164 99 -1856 99 -232 133 -1298 231 -2322 65 -200 131 -3254 97 -2892 131 -534 231 -364 99 -862 99 -68 99 -1388 65 -2078 131 -632 97 -1850 65 -724 97 -166 197 -100 201 -534 99 -264 131 -100 133 -300 133 -334 99 -1158 163 -300 99 -364 99 -300 165 -1024 97 -66 131 -230 525 -298 131 -564 527 -432 65 -692 65 -2642 65 -568 133 -1884 65 -856 131 -922 65 -3040 99 -100 97 -1896 65 -300 165 -466 67 -98 233 -132 297 -5044 231 -2354 65 -3878 65 -626 99 -1746 99 -1850 131 -230 97 -2434 431 -200 199 -100 167 -298 65 -2452 133 -396 199 -1058 65 -624 131 -5426 129 -2438 229 -956 +RAW_Data: 197 -490 163 -662 163 -396 393 -66 163 -262 65 -328 65 -362 2243 -100 595 -100 1361 -334 299 -230 527 -594 199 -498 461 -798 265 -200 329 -166 267 -466 231 -132 197 -98 99 -264 163 -232 99 -364 99 -132 133 -200 131 -132 99 -68 99 -166 297 -66 297 -198 131 -324 67 -232 97 -166 99 -166 99 -830 99 -264 433 -66 133 -2620 65 -232 233 -556 197 -198 129 -428 197 -228 163 -630 265 -200 133 -200 133 -100 165 -264 131 -100 197 -832 97 -400 231 -300 67 -266 99 -232 67 -532 327 -662 65 -268 99 -332 265 -232 99 -498 3293 -98 67 -98 365 -134 97 -626 65 -166 129 -230 229 -798 165 -164 195 -98 65 -166 163 -298 233 -398 199 -232 163 -100 65 -196 261 -264 295 -328 99 -690 361 -264 195 -722 65 -132 261 -328 65 -822 129 -66 559 -624 97 -1390 99 -866 65 -630 163 -398 65 -200 65 -598 4821 -98 99 -360 561 -98 297 -428 197 -98 197 -690 427 -98 97 -66 99 -1128 297 -266 65 -364 165 -432 133 -366 65 -198 199 -166 97 -364 397 -964 67 -1560 165 -100 361 -630 129 -788 131 -818 67 -132 131 -556 99 -558 99 -722 99 -196 2437 -264 2337 -360 197 -166 65 -330 689 -166 395 -98 65 -396 131 -164 97 -66 593 -262 163 -398 331 -100 267 -266 231 -166 65 -232 231 -166 263 -394 97 -66 65 -730 133 -200 131 -100 429 -230 227 -560 65 -100 97 -132 131 -166 65 -662 131 -166 231 -986 99 -132 263 -200 265 -166 65 -164 163 -164 197 -1184 259 -294 2681 -100 1061 -134 133 -100 65 -530 199 -726 97 -566 497 -630 99 -300 199 -132 363 -168 97 -230 165 -100 263 -198 165 -330 99 -826 133 -1166 365 -1224 165 -1130 131 -134 165 -132 229 -828 99 -330 99 -694 67 -230 163 -558 231 -726 97 -132 129 -166 195 -560 65 -262 63 -396 165 -998 65 -134 99 -200 231 -66 131 -266 165 -362 229 -894 65 -3690 133 -132 131 -132 65 -828 67 -666 131 -1430 99 -200 99 -4978 67 -596 67 -132 99 -664 259 -3486 65 -794 63 -2578 165 -592 99 -236 197 -296 129 -2202 131 -892 197 -2080 263 -66 231 -200 131 -402 233 -896 65 -666 131 -4786 99 -3204 99 -2322 165 -2566 97 -1252 197 -1716 65 -198 97 -7054 99 -934 195 -1616 99 -3522 99 -3344 97 -66 131 -1652 299 -966 297 -1494 65 -3432 131 -1792 65 -1586 101 -1624 65 -66 65 -2622 65 -398 65 -852 165 -3880 99 -1660 197 -1592 129 -1386 131 -164 131 -394 97 -66 97 -824 195 -362 163 -66 131 -694 331 -300 65 -332 97 -296 163 -298 295 -464 +RAW_Data: 97 -764 329 -1064 233 -464 165 -64 129 -328 131 -330 229 -166 65 -332 65 -66 165 -162 163 -198 63 -98 63 -166 97 -298 63 -960 231 -394 99 -1128 133 -500 297 -764 97 -166 199 -334 97 -68 131 -330 99 -66 197 -200 65 -332 397 -1648 197 -526 97 -560 2903 -98 493 -98 99 -230 129 -756 231 -164 429 -362 133 -132 167 -432 263 -234 167 -166 265 -296 163 -98 361 -132 67 -164 67 -496 229 -296 193 -364 131 -1226 165 -164 99 -602 99 -132 231 -1394 65 -232 99 -166 165 -1254 165 -298 199 -330 99 -820 129 -928 65 -330 165 -66 133 -630 67 -166 197 -166 2079 -200 791 -98 1263 -564 363 -624 163 -230 131 -360 233 -130 63 -526 65 -528 363 -296 163 -270 131 -200 261 -166 531 -1434 297 -462 99 -100 131 -464 567 -402 67 -462 131 -494 131 -1196 67 -858 165 -230 97 -198 65 -196 197 -362 131 -2038 295 -166 2333 -66 165 -64 327 -98 65 -164 261 -432 165 -134 131 -100 233 -536 65 -266 631 -360 263 -66 97 -68 231 -396 133 -766 329 -230 65 -296 163 -294 65 -66 329 -230 301 -532 197 -334 133 -1160 199 -562 131 -332 131 -298 97 -928 199 -132 197 -664 197 -230 2811 -66 665 -134 165 -102 365 -166 267 -66 131 -198 201 -266 99 -166 131 -232 593 -264 131 -594 131 -100 263 -164 131 -198 97 -362 163 -164 131 -164 329 -262 295 -526 131 -66 197 -434 195 -66 195 -262 97 -98 525 -228 229 -890 429 -198 131 -268 67 -430 131 -1150 265 -198 99 -956 329 -1186 161 -262 163 -918 99 -332 65 -664 195 -262 295 -1480 297 -492 131 -494 231 -990 65 -198 65 -164 163 -1544 167 -868 65 -164 97 -98 97 diff --git a/assets/unit_tests/subghz/security_pls_2_0_raw.sub b/assets/unit_tests/subghz/security_pls_2_0_raw.sub new file mode 100644 index 00000000000..4cd9822c49d --- /dev/null +++ b/assets/unit_tests/subghz/security_pls_2_0_raw.sub @@ -0,0 +1,32 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 390000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: -130 1115 -68 55471 -1962 167 -1664 99 -364 427 -232 759 -132 199 -100 267 -134 527 -132 99 -1292 99 -266 65 -68 131 -762 327 -98 393 -298 37611 -730 131 -428 1487 -3910 327 -100 295 -98 491 -492 65 -98 197 -860 97 -98 131 -856 131 -134 231 -792 229 -66 919 -198 7527 -7444 131 -722 97 -230 65 -98 527 -100 267 -68 229 -262 361 -528 195 -624 131 -164 495 -66 1697 -66 1791 -132 3715 -8320 65 -394 165 -166 461 -1094 297 -532 131 -764 197 -98 261 -230 165 -100 6235 -12144 265 -600 131 -134 65 -298 233 -958 163 -196 97 -756 263 -98 465 -134 97 -164 3051 -16552 431 -68 131 -166 131 -264 331 -298 561 -166 689 -66 557 -264 3173 -8316 65 -166 531 -298 197 -234 233 -134 233 -892 163 -296 65 -890 161 -232 331 -100 397 -15072 199 -100 99 -394 165 -164 129 -132 197 -132 199 -798 99 -1032 67 -398 427 -100 391 -98 363 -166 297 -66 2869 -66 2299 -12300 97 -660 99 -662 263 -594 131 -662 133 -66 199 -332 97 -134 99 -132 65 -134 131 -100 431 -100 2143 -66 429 -8840 97 -6976 97 -66 397 -66 65 -166 131 -230 131 -294 99 -228 97 -230 129 -756 133 -1298 1293 -132 529 -100 2567 -15654 229 -328 97 -198 131 -66 195 -1492 131 -398 99 -134 99 -366 265 -168 99 -100 235 -100 131 -396 299 -200 1029 -66 6461 -6804 99 -1062 65 -960 65 -232 131 -98 195 -1708 63 -196 261 -164 331 -66 261 -12094 65 -298 265 -198 163 -592 131 -2402 63 -66 297 -198 97 -66 393 -264 4003 -15878 231 -98 261 -496 229 -264 65 -858 131 -994 133 -66 331 -66 429 -100 165 -132 297 -15004 99 -1466 97 -266 165 -198 463 -796 231 -66 131 -298 99 -100 133 -134 167 -430 99 -66 365 -100 297 -134 265 -132 563 -98 1217 -66 6399 -8742 99 -592 99 -426 397 -2338 199 -66 995 -134 229 -132 65 -164 3989 -66 3675 -6962 165 -466 65 -564 399 -66 199 -134 263 -396 97 -132 97 -100 97 -428 393 -624 131 -988 229 -66 363 -230 791 -164 7883 -8286 165 -134 99 -66 197 -100 99 -68 131 -164 163 -398 197 -2162 2005 -66 97 -100 4365 -98 1255 -12012 99 -132 165 -462 65 -166 97 -564 65 -100 331 -794 199 -364 261 -496 331 -132 823 -66 6233 -10976 165 -764 165 -200 195 -296 97 -19176 195 -230 129 -658 131 -132 293 -66 133 -860 65 -858 131 -64 229 -66 227 -66 161 -66 9051 -7316 65 -1494 131 -98 165 -198 65 -134 365 -398 297 -100 3969 -14874 99 -998 65 -564 67 -364 263 -132 163 -528 197 -132 65 -264 65 -264 431 -100 301 -66 297 +RAW_Data: -164 6323 -10770 65 -1420 227 -196 263 -198 197 -1086 99 -98 163 -164 163 -426 65 -362 97 -264 295 -132 197 -13586 65 -1808 131 -166 301 -66 465 -432 165 -330 65 -332 297 -962 99 -266 97 -166 265 -132 327 -198 329 -98 293 -14984 99 -862 131 -166 331 -68 165 -98 233 -132 201 -300 197 -364 133 -662 99 -398 99 -166 65 -432 133 -132 1447 -5882 197 -1082 65 -198 163 -1580 129 -264 67 -632 625 -134 165 -68 827 -100 165 -100 99 -164 3949 -9126 67 -164 131 -986 241 -534 309 -208 267 -226 247 -250 247 -248 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 247 -250 249 -504 257 -248 245 -246 247 -248 501 -258 247 -246 245 -248 247 -248 249 -248 249 -504 513 -226 243 -274 243 -500 513 -238 253 -256 253 -492 231 -262 485 -514 223 -244 527 -478 507 -274 255 -218 253 -498 261 -224 251 -250 503 -258 247 -246 243 -246 247 -504 515 -238 251 -472 277 -242 497 -246 289 -220 247 -498 513 -476 255 -68610 311 -208 235 -256 249 -248 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 247 -248 503 -514 479 -274 253 -256 217 -254 247 -236 255 -250 247 -502 513 -240 251 -256 253 -254 249 -240 227 -252 249 -502 259 -246 245 -246 501 -514 237 -254 473 -280 253 -250 239 -230 251 -250 247 -504 257 -246 501 -226 245 -276 245 -246 245 -248 247 -504 515 -478 255 -244 495 -274 253 -476 511 -240 241 -69142 321 -218 243 -230 251 -248 247 -248 247 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -506 257 -248 243 -246 247 -248 501 -258 247 -246 245 -246 247 -248 249 -248 249 -504 513 -238 251 -254 255 -490 499 -228 253 -250 249 -506 259 -248 499 -478 257 -244 495 -510 509 -238 255 -254 253 -494 227 -254 249 -248 505 -258 247 -246 245 -248 247 -504 513 -238 253 -472 279 -254 491 -226 253 -250 249 -504 513 -478 257 -68880 315 -216 241 -258 249 -248 247 -248 247 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 249 -504 257 -246 245 -246 247 -248 503 -516 477 -274 253 -256 217 -254 247 -236 255 -250 249 -502 481 -272 253 -254 255 -254 249 -238 227 -250 249 -504 257 -248 243 -246 501 -516 237 -254 473 -280 253 -250 239 -230 251 -250 247 -504 257 -248 499 -228 245 -274 245 -246 245 -248 247 +RAW_Data: -504 513 -478 257 -244 495 -274 253 -500 483 -232 265 -69136 287 -256 249 -238 227 -250 249 -248 249 -248 249 -248 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -260 245 -246 245 -246 247 -248 249 -250 247 -504 513 -238 251 -256 253 -496 499 -228 249 -250 249 -504 257 -248 499 -478 257 -244 495 -510 509 -238 255 -254 255 -492 227 -256 249 -248 505 -258 247 -246 245 -248 245 -504 513 -238 253 -472 279 -254 491 -228 253 -250 249 -504 513 -478 257 -68886 309 -208 235 -256 249 -248 249 -248 249 -248 249 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 249 -504 257 -248 245 -246 245 -248 503 -514 477 -274 253 -254 217 -256 247 -238 255 -250 247 -504 513 -238 251 -256 253 -256 249 -240 227 -252 249 -504 257 -248 243 -246 501 -514 237 -252 473 -280 253 -250 241 -228 253 -248 249 -504 257 -246 499 -226 245 -276 245 -246 245 -248 247 -506 511 -478 257 -244 495 -272 255 -474 511 -240 241 -69150 323 -220 251 -242 229 -252 247 -248 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -504 257 -248 243 -248 247 -248 503 -258 245 -246 245 -248 245 -250 247 -250 247 -504 515 -236 253 -254 253 -496 499 -228 251 -250 247 -504 257 -248 499 -478 257 -244 495 -510 509 -240 253 -256 253 -492 229 -254 249 -250 505 -258 247 -246 245 -246 247 -504 513 -238 253 -472 247 -272 501 -246 253 -254 243 -494 513 -476 255 -68934 287 -254 213 -240 257 -250 249 -248 247 -250 247 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 247 -506 257 -248 245 -246 245 -248 503 -516 479 -272 255 -254 217 -256 245 -236 255 -250 247 -504 513 -238 253 -254 253 -256 249 -238 229 -252 249 -504 257 -246 245 -246 501 -514 237 -254 473 -280 253 -250 239 -230 251 -250 247 -504 257 -248 499 -226 245 -276 245 -246 245 -248 247 -504 511 -478 255 -244 495 -256 243 -496 509 -274 253 -69130 309 -218 253 -256 249 -240 227 -252 249 -250 247 -248 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -504 259 -246 245 -246 247 -248 501 -258 247 -244 245 -248 247 -248 247 -250 249 -504 511 -226 245 -276 243 -500 477 -272 253 -254 255 -494 231 -262 481 -514 225 -246 527 -478 507 -256 241 -244 243 -494 257 -244 243 +RAW_Data: -246 527 -228 243 -276 245 -246 245 -500 513 -238 253 -474 279 -254 489 -228 251 -250 249 -506 513 -478 255 -68936 287 -218 249 -236 255 -248 247 -248 247 -248 249 -248 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -506 257 -246 245 -246 245 -248 503 -514 477 -272 255 -254 255 -218 247 -240 255 -250 247 -502 511 -226 273 -244 243 -244 247 -246 247 -250 247 -506 259 -246 245 -246 501 -512 225 -244 527 -238 251 -256 253 -254 251 -242 227 -508 257 -216 527 -226 275 -244 243 -246 245 -248 247 -504 513 -478 257 -242 527 -238 255 -472 511 -242 281 -119614 299 -200 65 -470 65 -466 297 -630 97 -1592 133 -166 299 -66 231 -100 131 -98 265 -134 165 -166 433 -100 2287 -9916 231 -166 65 -98 199 -166 133 -166 165 -756 65 -724 195 -428 231 -260 263 -98 229 -130 261 -66 163 -264 65 -132 1181 -66 6315 -6798 131 -296 559 -334 131 -166 233 -132 165 -66 133 -264 99 -66 65 -366 99 -630 301 -166 97 -100 167 -164 535 -202 7269 -8266 197 -1022 131 -756 99 -98 99 -164 163 -990 65 -530 163 -230 297 -136 635 -66 2113 -8426 67 -6674 97 -722 197 -362 263 -232 165 -134 99 -234 297 -362 129 -198 131 -556 297 -68 167 -98 331 -200 165 -66 295 -66 8689 -4994 65 -1750 165 -762 163 -864 135 -100 167 -694 1093 -66 695 -102 99 -100 9899 -1650 297 -1216 97 -66 99 -396 65 -198 165 -164 233 -1658 199 -98 465 -134 463 -166 1883 -98 6283 -7302 99 -932 133 -696 263 -298 97 -98 165 -1708 131 -820 229 -98 231 -130 163 -590 131 -130 99 -66 97 -16220 261 -1062 265 -998 197 -1290 97 -362 165 -494 895 -264 7839 -7804 99 -66 99 -364 231 -630 133 -166 427 -496 131 -1252 263 -100 233 -66 133 -132 165 -66 259 -98 3109 -10438 101 -5322 99 -100 65 -666 65 -166 331 -98 197 -132 233 -662 261 -1516 559 -66 263 -130 689 -132 229 -64 3613 -15976 231 -166 133 -66 399 -264 99 -132 295 -366 97 -1692 99 -398 529 -68 397 -130 899 -164 3559 -98 1197 -12106 199 -98 65 -166 99 -266 99 -134 231 -100 133 -132 297 -430 99 -1394 299 -64 397 -166 99 -100 465 -200 331 -132 599 -100 2333 -15214 65 -1230 231 -266 265 -432 165 -398 65 -532 333 -632 65 -232 957 -98 9785 -6320 97 -830 167 -166 133 -732 299 -958 327 -98 197 -66 229 -164 327 -98 653 -66 7993 -6418 65 -1284 97 -458 129 -196 197 -166 393 -134 99 -332 427 -132 131 -66 133 -98 233 -66 133 -364 163 -566 4873 -16030 97 +RAW_Data: -360 65 -364 65 -68 857 -98 65 -232 131 -264 63 -98 391 -396 65 -130 99 -98 65 -66 861 -166 265 -166 7611 -10336 65 -1822 165 -300 165 -166 295 -134 199 -100 67 -264 165 -166 99 -500 99 -198 97 -200 165 -268 197 -130 65 -300 629 -166 561 -132 333 -132 7459 -6294 131 -1096 165 -964 197 -332 65 -166 129 -132 99 -130 99 -100 97 -134 65 -164 131 -494 165 -396 97 -164 131 -198 99 -232 229 -66 821 -64 131 -14954 97 -788 65 -100 263 -66 99 -300 65 -400 131 -198 293 -294 163 -132 65 -692 99 -132 131 -200 1847 -132 8773 -5968 133 -330 65 -66 295 -430 197 -166 565 -132 467 -98 65 -430 165 -262 131 -528 131 -296 131 -100 131 -66 557 -166 787 -98 3221 -16236 299 -166 133 -562 199 -1692 99 -66 65 -364 65 -366 231 -168 367 -100 5541 -14968 297 -164 97 -132 163 -328 99 -532 99 -134 131 -370 397 -66 397 -98 293 -98 197 -98 1151 -66 7019 -6746 129 -296 163 -954 261 -230 229 -64 231 -264 431 -100 99 -466 165 -100 333 -166 133 -666 695 -200 67 -134 397 -100 1667 -7686 97 -426 195 -266 97 -330 63 -98 99 -594 97 -132 133 -270 131 -600 131 -362 833 -98 297 -166 199 -66 99 -200 65 -66 197 -100 2963 -98 1125 -2238 199 -554 275 -242 273 -212 271 -242 241 -242 271 -244 241 -244 273 -244 245 -246 247 -248 247 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -246 247 -248 249 -250 247 -504 513 -228 243 -244 273 -246 245 -500 513 -478 257 -242 241 -244 273 -244 499 -512 225 -244 525 -228 273 -496 475 -508 507 -240 253 -254 255 -494 261 -222 505 -258 245 -246 245 -246 245 -250 247 -506 513 -478 257 -242 241 -244 273 -244 499 -68858 319 -218 245 -230 251 -248 245 -248 247 -250 247 -250 249 -248 249 -248 249 -250 249 -250 249 -248 249 -248 249 -250 249 -248 249 -250 247 -506 257 -246 245 -246 247 -248 503 -516 477 -274 253 -474 511 -478 527 -484 511 -240 253 -472 281 -254 489 -484 513 -478 513 -480 255 -242 523 -472 507 -276 253 -462 275 -240 491 -258 247 -244 245 -246 247 -502 515 -238 253 -254 253 -492 497 -230 253 -250 247 -250 247 -250 247 -250 247 -506 257 -68880 279 -248 241 -266 223 -252 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -506 225 -280 213 -278 245 -248 503 -260 215 -276 245 -246 247 -248 247 -250 247 -504 481 -272 251 +RAW_Data: -254 255 -254 213 -506 483 -514 271 -254 217 -292 217 -248 497 -516 237 -254 473 -278 251 -488 489 -516 477 -272 253 -254 219 -494 261 -260 481 -260 215 -278 247 -248 247 -248 247 -504 481 -514 235 -290 217 -256 253 -244 497 -69132 311 -212 235 -258 249 -248 247 -248 249 -248 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -506 257 -248 245 -246 245 -248 503 -512 479 -272 253 -474 513 -478 527 -482 513 -238 253 -472 281 -254 487 -486 515 -478 509 -480 255 -242 529 -480 509 -240 255 -496 271 -234 487 -260 247 -244 245 -248 247 -504 511 -226 243 -244 275 -498 479 -272 253 -254 255 -254 249 -238 225 -252 247 -504 257 -68882 319 -188 265 -280 235 -228 251 -250 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 245 -250 247 -250 249 -504 515 -238 251 -256 253 -256 249 -472 515 -480 271 -256 253 -218 255 -248 497 -482 271 -252 473 -280 253 -490 487 -516 477 -274 253 -256 217 -496 261 -224 507 -258 249 -246 245 -248 247 -248 249 -504 511 -478 255 -244 243 -244 275 -246 499 -69134 311 -208 231 -254 249 -246 247 -250 247 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -248 249 -506 259 -246 245 -246 247 -246 503 -516 479 -274 253 -464 519 -496 487 -516 477 -274 255 -498 249 -248 469 -514 479 -516 483 -488 277 -254 491 -498 487 -260 247 -498 227 -244 529 -228 243 -274 245 -246 245 -502 515 -238 251 -256 253 -496 497 -226 251 -248 249 -248 249 -248 249 -250 249 -504 257 -68898 247 -274 213 -312 185 -312 185 -312 185 -312 185 -312 185 -312 185 -310 185 -310 185 -310 215 -278 217 -278 215 -278 217 -278 217 -280 215 -532 237 -288 217 -290 215 -276 461 -260 219 -280 217 -280 217 -278 215 -280 247 -506 481 -270 251 -256 217 -290 213 -502 483 -514 271 -254 253 -218 255 -246 499 -482 271 -254 473 -282 253 -488 485 -516 477 -274 253 -256 217 -496 263 -224 507 -260 247 -246 245 -246 247 -248 249 -504 513 -478 255 -242 243 -244 275 -246 499 -69122 319 -220 243 -228 251 -248 247 -248 247 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -504 257 -248 245 -246 247 -246 505 -514 479 -274 253 -476 511 -476 493 -516 481 -270 253 -474 279 -254 487 -484 513 +RAW_Data: -478 507 -506 225 -272 495 -482 505 -254 241 -494 255 -242 525 -226 241 -274 243 -242 243 -496 509 -274 253 -254 219 -494 491 -258 249 -248 247 -248 249 -248 249 -248 249 -504 257 -68896 281 -214 241 -260 247 -248 247 -248 247 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -260 245 -246 245 -248 247 -248 247 -248 249 -504 513 -238 251 -254 255 -254 251 -474 515 -478 273 -254 255 -218 253 -248 499 -514 237 -254 473 -280 253 -490 485 -516 479 -274 253 -256 217 -496 263 -224 507 -258 247 -248 245 -246 247 -250 247 -504 513 -478 257 -244 241 -244 275 -246 499 -69128 321 -218 241 -230 249 -248 247 -246 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -504 257 -248 245 -246 245 -250 503 -514 477 -272 255 -474 515 -480 491 -518 479 -274 253 -474 281 -254 483 -486 479 -512 507 -506 223 -242 527 -482 509 -240 253 -496 273 -236 487 -260 247 -246 245 -246 247 -504 513 -238 251 -256 253 -492 495 -228 253 -250 249 -250 249 -250 249 -248 249 -504 257 -68860 273 -242 233 -256 249 -250 247 -248 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 247 -248 247 -248 249 -504 513 -238 253 -254 253 -256 249 -474 515 -480 273 -254 255 -218 253 -248 497 -516 237 -252 473 -280 253 -490 487 -514 479 -274 253 -254 219 -496 263 -224 507 -258 247 -246 245 -246 247 -248 249 -504 513 -476 257 -242 243 -244 273 -246 499 -68728 129 -604 249 -242 243 -276 213 -276 245 -244 245 -246 245 -278 215 -278 215 -278 247 -248 247 -248 247 -248 249 -248 247 -250 247 -250 247 -250 247 -504 259 -246 245 -246 247 -248 503 -514 477 -272 255 -474 511 -478 527 -484 481 -272 253 -472 281 -254 485 -486 511 -478 511 -480 255 -242 527 -482 505 -254 241 -494 253 -242 495 -254 241 -244 273 -244 243 -494 509 -238 255 -254 255 -492 489 -260 247 -248 245 -248 247 -248 249 -248 249 -504 257 -129658 99 -98 131 -132 97 -100 97 -132 131 -98 131 -496 297 -266 163 -198 99 -398 165 -626 133 -198 531 -166 67 -66 431 -132 331 -100 65 -132 99 -100 2725 -9960 65 -3686 295 -1552 99 -362 195 -100 887 -98 263 -100 1495 -8372 67 -298 99 -100 131 -332 133 -198 233 -398 65 -1060 99 -164 327 +RAW_Data: -460 129 -262 97 -100 755 -132 6515 -12306 229 -296 625 -198 131 -200 131 -398 165 -1634 231 -68 331 -166 133 -132 5259 -8900 67 -6298 99 -264 199 -66 133 -100 429 -200 131 -132 195 -266 163 -100 229 -462 165 -334 199 -132 63 -264 163 -264 231 -66 363 -68 331 -66 563 -100 6577 -10216 67 -962 99 -794 131 -198 133 -132 299 -66 133 -66 331 -630 163 -266 163 -132 99 -500 97 -232 195 -394 231 -66 133 -100 329 -400 7509 -12254 65 -166 65 -328 361 -266 65 -68 131 -100 65 -926 65 -758 99 -592 459 -66 557 -98 327 -66 1317 -100 3491 -16028 263 -132 227 -96 297 -68 165 -1160 133 -1030 97 -796 199 -134 65 -132 361 -100 389 -198 3891 -16112 131 -98 229 -1120 163 -1648 131 -392 429 -166 231 -926 2655 -16140 395 -230 227 -296 65 -98 199 -200 99 -1062 99 -134 695 -66 231 -100 97 -198 265 -198 67 -100 2705 -16076 99 -66 263 -398 229 -264 131 -132 63 -100 129 -1780 65 -362 229 -98 295 -132 555 -266 4985 -11336 65 -924 99 -200 263 -330 265 -298 133 -100 163 -628 97 -528 163 -228 459 -132 65 -66 297 -100 261 -100 131 -198 295 -98 229 -66 3967 -10946 131 -830 131 -102 663 -66 361 -396 165 -66 131 -1394 99 -98 131 -166 327 -66 559 -98 295 -134 65 -98 97 -132 427 -328 2763 -15960 131 -432 299 -798 131 -1030 295 -732 197 -132 231 -100 99 -98 199 -134 233 -134 331 -200 7663 -7818 163 -532 99 -264 267 -266 229 -1188 97 -98 99 -1492 463 -132 233 -168 97 -132 825 -66 6395 -13604 131 -430 133 -166 133 -864 65 -1162 397 -198 365 -134 165 -100 365 -66 8413 -8042 163 -164 131 -398 65 -1722 229 -428 97 -130 65 -596 395 -100 429 -100 131 -200 331 -98 433 -68 2937 -7902 65 -332 131 -7288 333 -396 65 -366 99 -232 99 -232 333 -1126 131 -594 99 -398 65 -100 893 -296 163 -66 525 -98 3767 -15992 265 -694 199 -366 231 -1000 65 -1358 97 -134 463 -100 231 -134 3623 -15876 129 -328 129 -132 65 -596 199 -566 231 -530 99 -596 595 -166 593 -200 97 -68 3353 -16312 131 -134 231 -202 133 -134 97 -234 131 -66 165 -628 101 -596 1027 -134 331 -198 3715 -66 195 -10652 229 -164 591 -362 97 -560 359 -464 97 -68 197 -266 165 -332 7019 -9984 199 -1166 363 -132 97 -100 131 -198 133 -232 229 -1058 67 -200 529 -198 65 -98 897 -66 265 -134 6685 -9926 297 -530 589 -66 97 -230 131 -98 99 -724 163 -164 163 -196 229 -164 267 -132 167 -68 333 -66 199 -100 131 -66 497 -66 4929 -9050 97 -5010 65 -1394 99 +RAW_Data: -562 165 -98 493 -66 65 -494 63 -132 397 -502 263 -1020 363 -68 8779 -5986 133 -1590 99 -894 165 -66 167 -136 99 -732 265 -66 133 -166 131 -266 267 -564 197 -68 941 -100 3631 -66 4059 -6506 263 -958 165 -568 167 -334 397 -530 231 -166 367 -364 133 -100 131 -134 133 -598 99 -200 2261 -8366 65 -6804 97 -262 263 -132 65 -98 231 -430 97 -164 97 -428 65 -134 99 -668 131 -296 233 -200 499 -98 889 -98 6325 -502 211 -558 271 -240 265 -224 249 -248 247 -248 249 -248 249 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -258 247 -246 245 -246 247 -248 249 -504 257 -246 499 -480 507 -256 241 -244 273 -496 509 -224 243 -526 477 -510 507 -240 253 -498 245 -244 497 -260 245 -246 243 -502 255 -248 243 -246 501 -258 247 -244 245 -500 511 -476 257 -242 527 -476 505 -254 241 -494 507 -480 255 -68596 289 -214 247 -250 249 -252 249 -250 249 -250 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -504 257 -248 245 -246 247 -248 503 -514 477 -272 255 -254 217 -496 491 -516 481 -512 255 -242 497 -274 253 -254 219 -496 263 -224 251 -250 505 -514 477 -256 243 -244 243 -276 243 -500 225 -278 497 -478 509 -512 473 -256 241 -244 273 -496 255 -242 243 -244 495 -274 251 -474 279 -254 487 -486 257 -248 243 -68886 271 -238 265 -226 251 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 247 -250 249 -504 257 -248 245 -248 245 -248 503 -260 245 -246 243 -248 247 -248 249 -504 257 -248 499 -480 507 -256 241 -244 243 -530 475 -256 243 -494 509 -482 507 -274 255 -484 237 -244 499 -260 247 -246 245 -504 257 -246 245 -244 501 -258 245 -246 245 -500 513 -480 273 -256 473 -484 509 -262 225 -508 513 -478 255 -68906 287 -254 211 -272 225 -252 247 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -248 249 -506 227 -278 245 -246 247 -246 505 -514 477 -272 253 -254 217 -496 491 -516 479 -510 257 -244 497 -272 253 -254 217 -498 261 -224 253 -250 505 -516 475 -256 243 -246 245 -244 245 -530 225 -246 529 -478 507 -510 483 -276 217 -292 217 -486 259 -248 247 -250 501 -258 215 -532 225 -244 529 -478 257 -242 243 -68922 239 -244 271 -226 251 -248 247 -250 247 -250 247 -250 247 -250 249 -248 249 +RAW_Data: -250 249 -250 249 -248 249 -248 249 -250 249 -250 247 -250 247 -506 257 -248 245 -246 245 -248 503 -258 245 -246 245 -248 247 -248 247 -506 257 -248 497 -480 509 -272 255 -254 255 -460 525 -226 249 -500 511 -478 507 -238 291 -476 245 -252 481 -260 247 -246 245 -502 255 -248 245 -246 501 -258 245 -246 245 -500 511 -476 255 -244 525 -478 505 -254 243 -492 507 -480 255 -68946 283 -250 241 -226 251 -248 247 -248 247 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -506 257 -248 245 -246 245 -248 503 -512 477 -274 253 -254 255 -460 493 -518 479 -510 255 -244 495 -274 253 -256 217 -496 261 -226 251 -250 503 -514 477 -274 253 -256 253 -218 249 -500 259 -246 499 -480 513 -482 505 -254 241 -244 243 -526 223 -272 243 -244 495 -272 255 -500 249 -246 473 -516 227 -244 243 -68908 317 -218 243 -258 247 -246 245 -248 247 -248 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -248 249 -250 249 -250 247 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 245 -250 247 -504 257 -248 499 -480 507 -274 253 -254 255 -460 527 -224 249 -502 511 -476 505 -256 241 -494 255 -242 527 -240 253 -254 255 -458 261 -262 223 -252 505 -260 245 -246 245 -500 511 -476 257 -242 525 -474 509 -238 289 -464 519 -496 225 -68914 283 -252 243 -266 223 -252 249 -252 249 -248 249 -250 249 -250 249 -250 247 -248 247 -250 247 -250 247 -250 249 -250 247 -250 247 -250 249 -506 225 -278 245 -246 247 -248 503 -516 479 -274 215 -292 217 -494 491 -516 477 -510 255 -244 497 -272 217 -290 219 -494 261 -258 221 -252 505 -514 479 -272 251 -256 217 -254 247 -500 227 -278 499 -480 509 -514 477 -276 253 -256 217 -520 225 -252 247 -248 503 -260 215 -530 225 -246 495 -510 257 -244 245 -68932 283 -218 247 -240 257 -250 247 -248 247 -248 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 247 -506 259 -246 245 -246 245 -248 503 -260 245 -246 245 -246 247 -248 249 -504 259 -248 497 -482 509 -274 255 -218 253 -498 491 -258 247 -500 511 -478 507 -238 289 -466 283 -210 503 -258 247 -244 245 -500 257 -246 245 -244 501 -260 245 -244 245 -500 511 -476 257 -242 525 -474 509 -238 289 -464 519 -496 225 -68912 285 -250 243 -230 253 -250 247 -250 247 -250 247 -250 247 -250 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -248 249 +RAW_Data: -250 247 -504 227 -280 245 -246 247 -248 501 -514 477 -272 253 -254 219 -496 493 -514 481 -512 223 -276 495 -274 217 -290 217 -496 229 -256 253 -250 507 -516 477 -258 243 -244 245 -244 245 -530 225 -246 497 -512 511 -482 509 -240 253 -256 251 -482 257 -250 247 -248 505 -258 215 -532 235 -252 473 -518 243 -280 235 -68898 281 -248 239 -230 253 -250 247 -248 247 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -250 249 -248 249 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 505 -258 247 -244 245 -248 247 -248 247 -504 257 -246 501 -480 513 -238 289 -220 253 -494 489 -260 247 -502 479 -508 509 -238 253 -482 277 -248 479 -260 247 -248 247 -502 257 -246 245 -246 499 -258 247 -244 245 -502 515 -476 257 -242 495 -512 475 -272 255 -496 481 -492 259 -68570 131 -550 315 -218 253 -256 245 -236 255 -248 247 -250 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -250 249 -504 257 -248 243 -248 245 -248 503 -512 477 -274 253 -254 255 -458 525 -482 515 -478 255 -242 495 -274 253 -256 217 -496 261 -226 253 -250 505 -514 475 -256 243 -244 273 -244 245 -498 257 -246 499 -478 507 -506 507 -238 255 -254 255 -492 227 -254 249 -248 503 -258 247 -498 257 -214 527 -480 271 -256 253 -138338 231 -728 97 -596 199 -556 163 -262 427 -330 359 -164 727 -66 663 -396 4171 -7546 65 -864 131 -362 529 -326 131 -2650 231 -298 197 -66 335 -264 529 -66 2745 -16072 201 -132 133 -664 265 -2520 433 -132 465 -134 459 -364 267 -66 1303 -8330 297 -368 133 -890 197 -1992 131 -462 67 -66 265 -266 561 -296 197 -198 195 -132 459 -66 3345 -16118 99 -164 297 -66 229 -332 97 -234 65 -166 65 -764 97 -700 67 -232 465 -134 563 -200 363 -100 1487 -96 5715 -8386 195 -298 163 -130 295 -100 97 -494 99 -754 327 -164 295 -132 195 -66 425 -66 3351 -64 1925 -6840 231 -64 97 -66 131 -462 99 -98 131 -494 197 -2274 397 -68 163 -166 565 -166 197 -100 3691 -64 3991 -8380 65 -164 197 -194 327 -100 367 -860 233 -596 629 -100 231 -132 1957 -100 1993 -66 3287 -6542 97 -1854 331 -132 131 -662 297 -494 99 -100 201 -1730 365 -166 559 -100 199 -66 331 -198 2209 -130 3295 -13088 99 -332 131 -790 263 -98 163 -1252 165 -196 263 -130 99 -132 361 -132 291 -262 99 -196 6531 -12274 133 -630 65 -302 165 -334 99 -1590 165 -828 291 -98 691 -198 561 -132 133 -68 7049 -9118 331 -662 165 -66 65 -132 65 +RAW_Data: -364 129 -98 265 -98 97 -66 589 -5626 67 -2546 231 -230 197 -232 197 -262 261 -464 97 -594 229 -296 165 -130 65 -166 99 -166 97 -66 229 -100 99 -66 131 -132 3567 -7898 95 -6038 99 -802 163 -68 97 -232 131 -326 65 -298 97 -132 231 -302 99 -298 65 -132 231 -1024 97 -100 331 -100 397 -232 99 -66 263 -68 231 -298 7371 -8180 165 -100 261 -68 165 -430 229 -198 67 -132 131 -300 65 -266 165 -498 165 -66 531 -232 263 -68 593 -134 131 -13852 65 -198 133 -634 97 -1128 97 -264 131 -66 165 -198 293 -494 99 -428 99 -962 99 -132 133 -264 833 -98 233 -14108 65 -1496 131 -230 67 -100 133 -666 131 -132 133 -232 65 -268 99 -400 99 -1854 597 -132 263 -98 493 -230 893 -98 3963 -15854 197 -130 165 -98 195 -330 261 -330 97 -132 97 -664 65 -500 5941 -132 1485 -11064 97 -992 163 -132 65 -434 197 -532 97 -134 297 -922 329 -658 163 -132 421 -264 429 -100 265 -298 229 -134 3353 -15986 131 -362 131 -132 459 -230 199 -66 393 -1060 99 -1096 131 -134 263 -66 163 -132 259 -130 97 -328 331 -66 99 -166 2561 -14808 65 -762 65 -66 197 -100 299 -398 133 -134 131 -66 65 -98 297 -10702 97 -464 131 -1526 133 -198 129 -100 131 -164 99 -132 163 -1098 129 -962 163 -300 65 -66 963 -166 3181 -8734 363 -2112 163 -1062 297 -98 427 -100 165 -100 231 -100 7535 -6418 65 -1522 65 -196 97 -64 131 -166 97 -332 65 -166 197 -100 265 -1564 65 -132 67 -696 133 -198 535 -98 297 -164 263 -8472 97 -560 327 -100 129 -64 65 -228 165 -162 163 -2146 561 -100 827 -232 463 -66 731 -66 4783 -10516 131 -300 131 -832 99 -100 331 -198 133 -232 99 -234 165 -266 165 -362 231 -66 297 -134 495 -98 165 -266 99 -132 859 -66 163 -98 165 -98 5587 -12622 131 -200 165 -1460 99 -432 265 -860 65 -262 591 -66 195 -100 425 -166 259 -66 227 -100 9819 -556 65 -3310 295 -562 199 -98 267 -200 131 -66 131 -168 99 -962 131 -534 99 -1848 197 -100 365 -132 1031 -66 2057 -66 2023 -7754 97 -7222 263 -698 165 -264 131 -366 97 -464 65 -466 65 -298 231 -430 97 -98 263 -64 953 -66 4093 -100 4171 -6616 65 -1220 99 -268 99 -98 99 -200 201 -134 97 -98 165 -164 295 -132 357 -396 165 -98 65 -230 163 -164 423 -130 651 -64 3641 -130 859 -7392 165 -100 165 -166 99 -66 167 -132 101 -132 67 -166 165 -100 333 -660 99 -162 97 -162 63 -424 131 -98 129 -392 131 -68 395 -132 389 -66 161 -17386 261 -298 99 -134 131 +RAW_Data: -100 65 -366 131 -166 197 -68 97 -166 165 -788 131 -198 97 -132 129 -164 163 -132 199 -66 267 -232 165 -68 165 -98 199 -134 1197 -568 273 -256 253 -256 249 -240 225 -252 247 -248 247 -248 247 -250 247 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 245 -250 247 -504 257 -248 499 -226 277 -496 255 -216 525 -480 257 -242 273 -242 497 -480 511 -274 253 -474 513 -478 263 -224 253 -250 247 -250 503 -260 245 -246 245 -500 257 -248 243 -248 499 -514 477 -272 255 -474 511 -478 263 -260 479 -514 477 -68856 257 -248 247 -248 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 249 -250 249 -248 249 -248 249 -250 247 -250 249 -250 249 -250 247 -504 257 -248 245 -246 247 -248 503 -514 477 -274 253 -256 217 -494 523 -228 249 -502 513 -238 253 -254 253 -492 231 -264 227 -254 505 -258 247 -246 245 -248 245 -250 247 -504 257 -248 499 -478 509 -274 253 -500 249 -246 237 -228 509 -516 477 -516 483 -490 501 -518 479 -262 225 -512 257 -248 499 -69120 321 -218 245 -234 253 -250 247 -250 247 -250 247 -250 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -506 257 -248 245 -246 245 -248 503 -260 245 -246 245 -246 247 -248 249 -504 257 -248 499 -228 243 -530 225 -244 529 -478 257 -242 243 -244 529 -476 509 -238 255 -512 479 -506 259 -226 251 -252 249 -250 505 -258 245 -246 245 -504 257 -246 245 -244 501 -516 479 -274 253 -476 479 -508 261 -226 511 -514 477 -69158 271 -240 263 -226 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -250 249 -504 257 -246 245 -246 247 -248 505 -514 475 -256 243 -244 243 -526 479 -272 255 -474 511 -240 243 -270 225 -508 257 -246 245 -246 501 -258 245 -244 245 -248 247 -248 247 -504 257 -248 499 -480 509 -274 253 -464 285 -246 239 -228 507 -482 509 -506 509 -482 507 -486 515 -240 241 -500 259 -248 499 -69138 283 -254 241 -230 251 -248 247 -248 249 -248 249 -248 249 -250 247 -250 249 -248 249 -250 249 -250 249 -248 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -258 247 -246 243 -248 247 -248 247 -504 257 -248 499 -228 245 -530 237 -252 503 -486 279 -246 237 -230 507 -516 479 -274 253 -464 517 -496 227 -254 249 -250 247 -250 505 -258 247 -246 245 -502 257 -246 245 +RAW_Data: -244 501 -512 477 -272 255 -474 511 -478 263 -228 511 -514 475 -69198 287 -218 249 -238 255 -250 249 -248 247 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 247 -250 247 -250 249 -250 249 -504 257 -248 245 -246 247 -248 503 -514 477 -272 255 -254 217 -498 493 -258 249 -504 479 -272 253 -254 255 -490 231 -262 225 -252 507 -258 247 -246 245 -248 245 -250 247 -504 257 -248 499 -480 513 -238 255 -498 247 -280 237 -228 507 -514 479 -516 483 -490 503 -506 505 -248 253 -492 229 -254 505 -69150 317 -284 135 -324 159 -348 157 -346 157 -346 157 -314 189 -312 187 -314 187 -312 187 -312 187 -312 185 -312 187 -280 217 -280 215 -312 185 -566 195 -278 215 -278 215 -278 469 -306 213 -290 219 -288 207 -268 223 -510 225 -280 467 -272 249 -506 247 -254 489 -490 257 -248 245 -248 501 -516 477 -256 243 -494 509 -508 237 -256 253 -256 249 -240 487 -260 245 -246 245 -500 257 -248 243 -246 501 -512 475 -274 253 -476 511 -478 263 -260 477 -514 479 -69176 271 -240 265 -224 251 -250 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -506 257 -248 245 -246 245 -248 503 -514 477 -256 243 -244 243 -530 477 -274 253 -476 479 -272 239 -266 225 -508 259 -248 245 -246 501 -258 215 -276 245 -246 247 -248 247 -504 257 -248 501 -480 511 -256 243 -496 255 -242 243 -244 497 -512 475 -516 509 -520 477 -510 495 -226 251 -504 257 -248 499 -69162 285 -218 249 -240 257 -250 247 -248 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -246 247 -248 249 -504 257 -248 499 -226 277 -498 225 -244 527 -478 257 -244 243 -244 527 -476 507 -258 241 -494 507 -510 237 -256 253 -254 251 -242 491 -226 277 -244 245 -500 255 -248 243 -246 501 -512 477 -256 243 -494 507 -506 253 -244 495 -480 505 -69176 261 -258 221 -252 251 -250 249 -250 249 -250 249 -250 249 -250 249 -248 249 -250 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -506 227 -280 245 -246 245 -248 503 -516 477 -256 243 -244 245 -496 509 -256 243 -496 509 -238 255 -254 255 -490 229 -254 251 -250 505 -258 215 -278 245 -246 247 -250 247 -504 227 -278 499 -480 511 -274 217 -514 243 -248 243 -266 483 -514 481 -512 475 -520 473 -506 507 -248 243 -500 249 -244 497 -69180 273 -256 217 +RAW_Data: -290 219 -246 235 -256 251 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -504 227 -278 245 -246 247 -246 505 -258 215 -278 245 -246 247 -248 247 -506 225 -278 499 -228 245 -530 225 -244 497 -508 257 -244 243 -246 497 -512 477 -272 255 -482 511 -500 229 -254 251 -250 249 -250 503 -260 215 -278 215 -534 225 -246 245 -276 499 -482 513 -238 253 -500 483 -528 227 -252 505 -514 479 -68732 173 -546 275 -240 233 -256 247 -250 247 -250 247 -250 247 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -504 257 -248 245 -246 247 -248 503 -514 477 -272 255 -254 217 -498 493 -260 249 -500 479 -272 253 -254 255 -494 233 -262 223 -252 505 -258 247 -246 245 -246 247 -250 247 -504 257 -248 499 -482 511 -238 255 -498 245 -280 237 -228 507 -516 479 -512 477 -518 475 -518 481 -270 237 -494 259 -250 501 -136574 65 -1160 65 -770 395 -198 199 -66 65 -330 231 -436 65 -1228 165 -664 727 -198 199 -166 229 -196 457 -64 493 -66 1987 -15790 99 -100 131 -234 231 -496 893 -234 297 -66 8071 -8244 99 -236 165 -134 199 -132 67 -198 165 -1094 65 -1782 195 -66 921 -66 229 -100 391 -132 7785 -7282 65 -402 65 -166 267 -266 165 -100 231 -166 461 -166 65 -696 65 -298 131 -166 99 -232 263 -100 397 -166 499 -66 165 -364 7435 -8394 331 -198 99 -198 99 -234 99 -1738 991 -198 333 -198 499 -132 891 -98 3239 -15978 165 -896 97 -100 131 -198 97 -532 65 -300 67 -1330 329 -66 859 -66 199 -232 397 -100 7707 -8162 363 -232 165 -98 231 -130 165 -294 131 -858 99 -932 65 -164 131 -264 565 -198 165 -132 233 -366 7109 -6100 65 -3046 165 -500 131 -232 67 -1028 99 -232 97 -300 65 -434 727 -166 363 -100 367 -64 263 -100 3147 -15114 65 -164 197 -296 97 -66 229 -264 497 -332 67 -98 99 -432 163 -132 65 -794 199 -166 297 -200 6509 -12574 199 -234 65 -132 99 -334 67 -264 131 -100 331 -168 65 -266 99 -166 397 -266 431 -98 565 -166 527 -100 3021 -68 3551 -12844 163 -294 165 -300 461 -856 331 -66 99 -1160 131 -132 293 -132 493 -166 261 -196 1149 -132 2177 -68 961 -15018 65 -992 99 -266 99 -200 229 -164 197 -956 231 -368 67 -100 99 -930 297 -360 623 -166 695 -134 1631 -66 957 -100 3451 -10430 65 -100 65 -1120 65 -198 65 -98 567 -200 199 -560 297 -792 65 -196 97 -690 197 -164 295 -66 295 -132 6963 -7554 131 -952 197 -228 131 +RAW_Data: -332 97 -264 295 -492 65 -1418 131 -396 363 -66 265 -134 731 -100 165 -68 133 -66 7537 -7378 65 -922 197 -164 229 -230 529 -66 165 -98 199 -132 65 -726 65 -164 97 -824 97 -230 427 -166 1363 -8016 97 -3030 65 -892 133 -164 99 -162 395 -230 163 -230 163 -230 197 -626 65 -166 97 -498 97 -700 495 -66 1215 -164 327 -10158 129 -1690 595 -198 163 -232 165 -164 365 -100 97 -732 99 -498 197 -364 365 -166 165 -134 797 -100 563 -100 3113 -9966 97 -426 165 -5434 393 -332 65 -98 99 -164 97 -232 65 -726 99 -266 265 -232 67 -298 461 -100 663 -68 9469 -8388 165 -396 231 -134 197 -166 67 -1556 97 -132 95 -230 65 -130 99 -98 657 -66 327 -68 527 -98 4249 -7974 97 -300 131 -264 397 -132 165 -562 99 -1060 65 -732 497 -134 531 -100 199 -66 203 -66 2987 -100 1657 -12228 97 -364 265 -200 165 -792 65 -396 129 -1312 623 -164 261 -98 165 -162 465 -66 3855 -8016 97 -6056 65 -1896 65 -366 99 -266 133 -132 99 -332 231 -864 133 -100 725 -98 261 -328 363 -98 293 -66 4765 -12278 99 -434 165 -64 65 -166 197 -498 65 -166 231 -500 99 -398 199 -398 695 -132 431 -100 131 -132 165 -66 199 -302 1463 -3364 241 -526 317 -212 235 -254 247 -248 245 -248 247 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -258 247 -246 245 -246 247 -248 249 -248 249 -248 249 -506 513 -238 251 -256 253 -490 499 -488 513 -476 509 -274 255 -474 479 -272 237 -266 225 -508 511 -226 245 -244 275 -500 225 -246 275 -244 501 -228 245 -528 225 -246 529 -478 257 -244 243 -244 245 -276 499 -226 245 -276 245 -246 245 -68834 321 -218 243 -232 253 -248 245 -248 247 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -504 257 -248 245 -246 247 -248 503 -512 477 -272 255 -500 483 -500 489 -514 479 -274 253 -254 219 -254 247 -236 255 -250 247 -504 257 -248 497 -226 245 -530 477 -274 253 -254 255 -458 525 -484 511 -476 509 -482 507 -274 255 -254 217 -488 259 -250 247 -248 245 -250 503 -260 245 -500 479 -272 255 -69110 309 -218 253 -256 253 -246 231 -254 247 -248 247 -248 247 -248 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 247 -506 257 -248 245 -246 245 -248 503 -260 245 -246 245 -248 245 -248 249 -248 249 -250 247 -506 513 -226 273 -244 243 -498 513 -476 509 +RAW_Data: -482 519 -240 255 -496 505 -228 253 -250 247 -504 513 -226 273 -244 243 -498 257 -246 245 -244 499 -258 245 -500 257 -214 527 -478 257 -242 273 -244 243 -246 501 -258 245 -246 245 -246 247 -69160 247 -274 213 -274 245 -242 245 -276 213 -276 245 -244 245 -246 245 -278 213 -278 245 -248 249 -248 247 -250 249 -248 249 -250 247 -248 249 -504 257 -246 245 -246 247 -248 503 -512 477 -274 251 -476 509 -512 461 -518 479 -258 243 -244 245 -276 245 -246 247 -248 247 -504 257 -248 501 -226 245 -530 477 -256 243 -244 245 -532 479 -480 509 -520 485 -488 509 -262 221 -252 249 -506 257 -248 245 -246 247 -248 503 -258 247 -498 477 -258 243 -69136 303 -236 227 -256 247 -250 247 -250 247 -250 249 -250 249 -248 249 -248 249 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -248 249 -506 257 -248 243 -246 247 -248 505 -258 247 -244 245 -246 247 -250 247 -248 249 -250 247 -506 513 -226 243 -274 245 -498 511 -476 507 -482 507 -274 255 -484 475 -264 261 -222 251 -506 513 -238 251 -256 253 -496 233 -264 225 -252 505 -260 247 -498 225 -246 529 -478 257 -244 243 -244 275 -244 499 -258 245 -244 245 -246 247 -69174 321 -218 253 -242 231 -252 249 -248 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 247 -504 259 -246 245 -248 245 -248 505 -514 479 -274 253 -476 511 -478 493 -516 481 -272 255 -254 253 -220 247 -240 257 -250 247 -502 257 -248 499 -228 245 -528 479 -272 255 -254 253 -460 525 -482 515 -476 509 -482 505 -254 241 -242 243 -526 225 -272 243 -242 243 -244 529 -238 253 -472 511 -276 247 -69140 309 -212 241 -244 273 -242 243 -242 243 -274 243 -244 241 -244 245 -276 245 -244 247 -248 247 -248 249 -250 247 -250 249 -250 247 -250 247 -506 257 -248 245 -246 245 -248 503 -258 245 -246 247 -246 247 -248 249 -248 249 -250 249 -504 513 -238 251 -254 255 -494 501 -484 513 -478 509 -238 253 -514 481 -270 235 -264 223 -506 513 -238 253 -254 255 -490 231 -266 225 -254 507 -258 247 -500 225 -246 529 -480 271 -256 253 -256 217 -248 501 -258 247 -244 245 -246 247 -69188 287 -218 247 -234 255 -250 247 -248 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -504 257 -248 245 -248 245 -250 503 -514 479 -274 253 -498 483 -500 487 -514 477 -258 241 -244 243 -246 275 -244 245 -248 245 -504 257 -248 499 -228 245 +RAW_Data: -528 477 -256 243 -244 245 -530 475 -508 509 -482 509 -492 505 -246 253 -254 243 -494 227 -278 245 -248 245 -248 503 -258 215 -530 479 -272 251 -69146 297 -230 225 -252 249 -250 249 -250 249 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -248 249 -250 247 -506 259 -246 245 -246 247 -248 501 -258 247 -244 245 -248 247 -248 249 -248 249 -250 247 -506 513 -238 251 -254 255 -494 501 -484 513 -478 509 -238 253 -514 479 -270 237 -264 223 -508 513 -238 253 -254 255 -494 233 -262 225 -252 505 -258 247 -500 225 -246 529 -478 257 -242 243 -244 275 -246 499 -258 215 -276 245 -246 245 -69160 287 -254 251 -238 227 -252 249 -248 247 -250 247 -250 247 -250 249 -250 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -506 227 -280 215 -276 245 -248 505 -480 511 -272 253 -476 479 -506 493 -514 479 -260 243 -246 245 -276 245 -246 247 -248 247 -504 227 -278 499 -238 249 -504 473 -280 241 -244 243 -500 505 -520 485 -500 487 -518 479 -274 251 -256 217 -496 263 -224 251 -252 249 -250 503 -258 247 -500 479 -258 243 -131656 133 -100 133 -200 165 -100 97 -232 627 -1028 133 -992 163 -132 635 -264 197 -100 4009 -10800 163 -230 231 -168 65 -132 201 -400 395 -98 99 -296 393 -100 295 -66 1425 -6868 99 -1394 129 -164 65 -392 329 -1518 229 -198 163 -100 665 -66 199 -166 335 -166 165 -98 3141 -8982 65 -6896 163 -262 391 -230 195 -428 163 -526 131 -98 165 -196 65 -98 65 -724 131 -200 1585 -164 6977 -13106 131 -164 65 -692 97 -894 65 -998 297 -66 165 -166 401 -132 233 -66 561 -266 1987 -64 555 -13660 99 -430 131 -232 131 -398 99 -630 99 -100 267 -464 97 -924 99 -66 265 -526 561 -132 165 -68 199 -134 1951 -66 1643 -15920 231 -528 163 -162 65 -458 229 -98 65 -622 97 -68 97 -132 163 -134 631 -398 131 -198 883 -66 759 -64 1083 -16320 699 -464 163 -328 131 -232 231 -230 97 -690 263 -294 557 -100 729 -230 427 -98 65 -130 7841 -8604 131 -262 163 -200 199 -398 99 -98 263 -490 97 -132 97 -130 129 -626 229 -396 557 -66 229 -164 393 -262 395 -98 2347 -16232 297 -300 99 -68 297 -3186 461 -330 229 -68 131 -130 1389 -66 3247 -10450 131 -1522 229 -496 131 -100 195 -132 129 -66 327 -64 99 -196 133 -1794 67 -132 329 -100 197 -498 165 -132 165 -166 263 -132 7439 -7152 99 -502 131 -134 65 -200 199 -164 133 -100 401 -266 367 -1260 197 -366 297 -428 399 -198 897 +RAW_Data: -66 3765 -13986 497 -562 97 -732 297 -266 99 -232 429 -132 65 -298 197 -268 97 -1192 1259 -68 65 -132 97 -100 8047 -6842 97 -362 165 -130 131 -66 459 -164 197 -164 263 -164 359 -462 195 -262 65 -1122 229 -66 755 -100 465 -132 6211 -9870 99 -66 129 -100 163 -98 131 -264 131 -162 97 -198 97 -196 197 -262 229 -958 165 -266 65 -98 697 -200 5723 -12050 299 -66 231 -232 99 -528 99 -66 233 -134 65 -534 131 -1028 97 -300 63 -266 97 -100 133 -134 891 -100 4201 -100 3703 -8722 229 -360 263 -164 459 -66 819 -132 163 -1126 267 -66 231 -200 731 -232 229 -8678 131 -132 229 -198 295 -592 165 -820 65 -756 99 -66 65 -68 99 -200 199 -332 297 -100 565 -7800 65 -500 65 -7518 465 -368 99 -230 65 -832 99 -2356 627 -198 131 -100 361 -130 295 -132 3819 -96 5271 -6210 65 -266 393 -98 131 -64 329 -362 365 -66 133 -132 67 -632 65 -430 265 -166 65 -566 131 -132 461 -66 1429 -134 4601 -10498 65 -402 65 -430 229 -328 359 -98 263 -624 165 -168 199 -166 97 -494 197 -196 99 -98 261 -132 297 -166 99 -66 4183 -66 2927 -6458 99 -1894 427 -498 331 -562 131 -1458 229 -690 1785 -68 231 -100 731 -12140 165 -168 67 -134 131 -100 233 -198 99 -662 265 -730 299 -166 227 -328 97 -164 821 -66 2903 -66 1043 -7904 65 -3146 65 -4854 99 -98 133 -132 133 -760 99 -692 259 -1554 65 -98 495 -230 261 -64 491 -166 163 -98 227 -16058 97 -100 163 -294 197 -164 195 -100 129 -362 163 -626 65 -166 129 -526 65 -132 829 -100 597 -68 197 -366 1025 -66 497 -98 1387 -66 329 -12300 99 -232 99 -232 65 -532 99 -100 165 -402 131 -1326 395 -98 565 -232 131 -168 65 -166 1621 -66 2509 -13018 165 -362 99 -1982 99 -66 65 -764 593 -430 229 -132 329 -164 263 -100 2629 -15978 297 -68 131 -662 65 -98 99 -526 133 -132 133 -498 97 -560 229 -66 855 -98 593 -98 7597 -8606 427 -164 131 -822 65 -98 67 -296 97 -496 131 -198 97 -164 97 -394 1449 -230 397 -66 2897 -8398 165 -236 97 -1752 65 -330 65 -462 231 -134 131 -2680 1025 -132 633 -130 7803 -6500 65 -2808 67 -332 197 -164 97 -66 163 -2234 195 -132 425 -66 755 -98 2687 -66 5177 -6880 65 -1510 97 -232 195 -232 131 -234 197 -200 65 -166 65 -198 165 -134 67 -1262 395 -100 297 -98 165 -402 331 -134 5357 -12090 197 -232 99 -332 97 -2278 265 -66 563 -134 297 -66 3607 -10024 65 -4678 363 -166 201 -200 165 -100 163 -392 131 -98 129 -624 195 -332 65 -962 295 +RAW_Data: -132 165 -132 3857 -11128 241 -562 311 -208 235 -256 249 -250 247 -248 249 -248 247 -250 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -250 247 -504 259 -246 245 -246 247 -248 503 -258 247 -246 245 -248 245 -250 247 -250 247 -250 247 -506 513 -238 251 -256 253 -256 247 -474 259 -248 501 -480 509 -274 217 -514 477 -272 237 -266 223 -508 481 -512 509 -482 509 -490 505 -520 247 -246 241 -230 255 -250 249 -250 247 -250 505 -514 479 -512 475 -274 255 -68824 287 -218 273 -250 237 -230 251 -248 247 -248 247 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -514 477 -256 243 -494 509 -274 253 -476 245 -252 517 -226 249 -502 511 -224 243 -528 475 -508 505 -474 255 -242 273 -242 495 -274 253 -500 485 -498 227 -254 247 -250 503 -260 245 -498 513 -478 511 -472 507 -274 255 -254 255 -212 271 -480 511 -226 241 -69142 299 -230 225 -254 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -250 249 -248 249 -250 249 -248 249 -250 249 -248 249 -250 249 -504 257 -246 245 -246 247 -248 501 -258 247 -246 245 -248 247 -248 247 -250 247 -250 249 -504 513 -226 243 -276 243 -246 245 -502 257 -246 499 -478 509 -274 253 -500 485 -232 263 -226 251 -506 513 -476 509 -480 505 -508 489 -504 249 -242 241 -274 243 -242 241 -274 243 -242 495 -512 507 -482 509 -240 253 -69136 287 -254 249 -240 227 -252 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -516 477 -256 243 -496 509 -238 253 -514 243 -248 479 -260 249 -504 479 -258 243 -498 509 -514 475 -522 241 -254 255 -250 473 -260 249 -502 477 -510 255 -244 243 -246 497 -272 251 -474 509 -512 497 -486 483 -270 253 -254 255 -254 213 -506 481 -272 251 -69172 263 -226 285 -218 249 -250 249 -250 249 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -248 249 -250 249 -248 249 -506 257 -246 245 -246 247 -248 503 -258 247 -244 245 -248 247 -248 247 -250 249 -250 247 -504 513 -228 243 -244 273 -244 245 -502 259 -246 499 -480 511 -274 255 -474 513 -240 239 -232 257 -506 513 -476 509 -478 505 -516 503 -472 279 -254 253 -252 239 -228 249 -248 247 -248 503 -514 477 -510 509 -238 253 -69168 273 -254 253 -220 253 -248 237 -256 249 -248 247 -250 247 +RAW_Data: -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 247 -250 249 -504 257 -248 245 -246 247 -248 501 -514 479 -272 255 -500 483 -234 263 -486 257 -248 501 -226 247 -528 479 -274 253 -474 511 -510 497 -482 259 -246 245 -244 501 -258 247 -498 477 -510 257 -242 243 -244 495 -272 251 -474 509 -512 497 -486 511 -226 245 -276 243 -246 245 -502 513 -240 251 -69164 295 -228 223 -252 249 -250 251 -250 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -506 257 -248 243 -246 247 -248 503 -258 245 -246 245 -248 247 -248 247 -250 249 -248 249 -504 513 -226 243 -246 275 -246 243 -502 257 -246 499 -478 509 -274 255 -474 479 -272 241 -266 223 -508 515 -478 509 -482 487 -520 481 -508 263 -228 253 -252 249 -250 249 -250 247 -250 503 -514 475 -508 507 -226 241 -69190 287 -218 249 -240 257 -250 247 -248 249 -248 247 -250 249 -250 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -248 249 -506 257 -248 245 -246 245 -248 503 -514 477 -274 253 -474 511 -240 241 -500 259 -248 499 -258 245 -498 477 -274 253 -474 511 -512 495 -484 257 -246 245 -246 501 -258 245 -500 481 -512 253 -244 241 -244 495 -272 255 -474 517 -480 493 -516 511 -240 251 -256 253 -254 249 -470 515 -240 251 -69160 255 -244 243 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -506 257 -248 245 -246 247 -248 503 -258 215 -278 245 -246 247 -248 249 -248 249 -248 249 -506 481 -270 253 -254 253 -256 213 -506 257 -250 501 -482 513 -238 255 -514 477 -270 233 -262 223 -508 479 -514 509 -508 475 -520 475 -518 247 -248 243 -268 223 -250 249 -250 247 -250 505 -516 479 -514 475 -256 241 -69148 295 -226 223 -252 249 -250 249 -250 249 -250 249 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -514 475 -256 243 -494 513 -238 289 -464 283 -210 505 -258 247 -498 513 -238 255 -474 509 -514 497 -484 257 -248 243 -246 499 -258 247 -498 509 -474 257 -242 243 -244 527 -238 251 -502 503 -490 515 -496 481 -258 245 -246 245 -246 247 -504 513 -238 253 -124420 65 -360 97 -98 129 -328 97 -426 99 -296 65 -232 231 -168 497 -232 163 -592 197 -392 131 -728 1593 -134 365 -66 97 -100 3173 -66 2309 -11768 163 -724 457 -100 197 +RAW_Data: -200 461 -66 165 -496 131 -134 99 -98 133 -98 97 -494 165 -230 97 -166 963 -266 3041 -15870 131 -98 231 -166 133 -68 199 -100 133 -132 633 -100 265 -198 65 -334 365 -198 131 -466 1129 -166 299 -234 3643 -16164 99 -364 231 -68 233 -598 133 -232 197 -100 133 -66 229 -66 297 -394 1219 -100 163 -166 3307 -7734 65 -4936 95 -1288 333 -232 233 -200 65 -364 333 -300 131 -100 165 -634 65 -564 131 -200 761 -232 563 -13840 133 -200 67 -464 65 -1318 231 -302 263 -100 199 -132 99 -166 99 -166 197 -328 163 -66 691 -262 497 -66 5665 -9958 99 -364 65 -1028 165 -398 265 -196 65 -132 561 -230 165 -66 461 -266 331 -364 131 -398 165 -166 595 -100 199 -102 729 -132 5765 -10908 65 -1388 129 -658 97 -98 295 -132 99 -132 131 -1152 265 -66 199 -98 731 -98 197 -66 751 -98 2631 -100 1691 -11754 263 -198 131 -132 133 -168 199 -132 99 -66 97 -1580 231 -100 4231 -14088 65 -1810 97 -690 65 -98 99 -164 397 -232 299 -2124 565 -64 267 -15924 99 -266 67 -132 565 -66 331 -266 165 -664 231 -1358 663 -264 297 -134 5749 -12972 197 -854 97 -1782 131 -100 63 -428 461 -66 891 -98 329 -64 1185 -15082 99 -468 97 -68 231 -396 165 -232 65 -134 65 -264 201 -430 231 -98 1097 -68 233 -132 5943 -12230 261 -756 99 -596 97 -132 97 -362 229 -198 163 -194 65 -64 395 -98 199 -100 133 -66 299 -11664 129 -658 97 -66 131 -98 263 -394 163 -132 129 -100 229 -1714 231 -166 99 -66 231 -132 599 -100 1127 -68 431 -100 1119 -14044 65 -1032 131 -826 99 -596 499 -266 199 -862 133 -1292 395 -100 921 -198 331 -132 363 -15244 97 -624 231 -134 163 -500 131 -530 201 -134 133 -132 67 -464 131 -998 965 -66 365 -100 3769 -9910 65 -6926 265 -264 133 -166 131 -166 233 -130 99 -132 65 -396 195 -196 65 -98 97 -98 557 -98 165 -66 397 -66 7539 -8488 199 -332 65 -200 199 -1458 65 -466 99 -66 65 -698 297 -68 361 -132 531 -134 165 -68 6531 -11410 65 -896 99 -264 67 -132 197 -98 165 -532 99 -100 165 -562 99 -100 297 -728 983 -98 131 -98 229 -230 63 -262 4137 -16250 427 -298 329 -430 99 -360 131 -724 131 -264 97 -796 825 -166 265 -134 3663 -14070 97 -1750 197 -68 163 -132 229 -530 165 -428 65 -132 65 -98 65 -1684 229 -100 229 -66 97 -330 131 -134 231 -100 3781 -8504 65 -7400 67 -164 131 -66 495 -164 133 -166 131 -202 65 -102 165 -568 65 -134 65 -498 229 -132 129 -394 197 -98 295 -66 427 -66 397 -68 2533 +RAW_Data: -16126 133 -268 131 -200 63 -196 229 -394 295 -758 131 -358 65 -164 263 -594 427 -66 131 -66 393 -5360 199 -132 165 -526 65 -230 165 -262 65 -66 97 -296 131 -556 65 -792 131 -402 331 -132 97 -168 429 -100 365 -66 401 -4724 65 -1924 99 -300 65 -1066 65 -266 65 -332 165 -366 65 -332 131 -166 233 -166 499 -264 65 -300 67 -132 99 -132 65 -432 397 -164 657 -64 263 -66 555 -66 2729 -10288 65 -5204 97 -100 591 -166 99 -496 97 -100 65 -98 99 -296 97 -428 265 -100 229 -164 263 -100 765 -100 263 -66 3453 -7586 133 -7046 99 -962 131 -98 131 -134 565 -66 131 -134 593 -66 131 -1384 97 -330 131 -402 5065 -15884 65 -664 297 -266 167 -134 101 -134 99 -596 165 -496 99 -564 2351 -66 6223 -11750 65 -330 365 -68 99 -132 99 -634 131 -860 163 -130 65 -1226 197 -98 861 -134 495 -266 2219 -11598 65 -1316 99 -758 229 -2510 131 -100 167 -68 303 -100 499 -164 131 -100 397 -7704 65 -7902 299 -100 131 -100 199 -166 531 -66 133 -298 199 -398 131 -100 65 -166 133 -66 199 -100 635 -132 599 -66 199 -134 361 -66 3253 -226 425 -15180 133 -568 297 -132 199 -132 793 -330 65 -526 97 -132 425 -526 331 -68 303 -548 297 -230 225 -254 249 -250 249 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -506 257 -248 245 -246 245 -248 503 -260 245 -246 243 -248 247 -502 515 -238 253 -472 277 -242 499 -508 481 -504 489 -516 477 -274 253 -256 253 -460 495 -260 249 -248 247 -250 247 -504 257 -248 245 -246 501 -512 475 -508 255 -242 243 -242 245 -274 499 -478 257 -244 243 -244 529 -476 509 -274 253 -218 255 -68836 285 -252 243 -228 249 -248 245 -248 247 -250 247 -250 249 -248 249 -248 249 -250 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 249 -504 259 -248 243 -246 247 -248 503 -514 475 -256 243 -494 509 -274 253 -218 255 -254 247 -496 257 -246 497 -226 275 -496 511 -474 507 -480 255 -242 273 -242 495 -274 253 -464 523 -498 225 -250 503 -258 245 -244 245 -502 511 -476 509 -510 473 -508 521 -488 249 -252 481 -516 225 -256 289 -68864 259 -224 249 -252 251 -250 251 -250 249 -248 249 -250 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -250 249 -248 249 -250 247 -504 257 -248 245 -246 247 -248 503 -258 245 -246 245 -248 247 -504 513 -240 251 -474 247 -272 499 -508 483 -506 489 -516 477 -274 253 -256 217 -496 491 -260 247 +RAW_Data: -248 249 -248 247 -504 257 -248 245 -246 501 -512 477 -512 253 -244 241 -244 243 -246 529 -478 257 -242 243 -244 529 -478 509 -238 253 -254 255 -69126 287 -254 251 -240 227 -252 247 -248 247 -250 247 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 249 -504 257 -248 245 -246 245 -248 503 -516 479 -272 255 -476 511 -238 241 -268 223 -252 249 -504 257 -248 499 -228 243 -530 477 -512 505 -474 255 -242 243 -274 495 -274 255 -474 485 -506 261 -222 507 -260 247 -246 245 -502 511 -478 509 -480 507 -488 499 -510 277 -246 471 -516 225 -256 253 -68936 271 -238 231 -256 249 -248 249 -248 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -260 245 -246 245 -246 247 -504 513 -238 251 -504 249 -254 489 -488 513 -476 509 -512 475 -274 255 -254 253 -488 483 -258 215 -276 245 -246 245 -504 255 -248 245 -246 503 -514 477 -512 225 -242 273 -242 243 -244 529 -476 255 -244 243 -244 529 -478 509 -238 253 -254 255 -69140 307 -220 253 -254 253 -246 231 -256 247 -248 247 -250 247 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 247 -250 249 -506 257 -248 245 -246 245 -248 503 -514 477 -272 255 -474 515 -242 239 -268 223 -252 247 -504 259 -246 501 -226 245 -530 479 -512 509 -482 253 -242 241 -244 529 -238 253 -498 481 -528 225 -250 503 -260 245 -244 245 -502 511 -478 509 -482 505 -506 505 -486 249 -252 487 -516 227 -256 251 -68924 311 -210 233 -258 247 -250 247 -250 247 -248 249 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -250 247 -250 249 -248 249 -250 249 -506 257 -248 245 -244 247 -246 505 -258 247 -244 245 -246 247 -504 515 -238 253 -472 281 -254 487 -486 513 -478 509 -512 475 -274 253 -256 253 -488 483 -228 255 -290 217 -254 255 -494 229 -254 249 -250 505 -514 477 -512 255 -242 243 -242 243 -244 529 -478 257 -242 243 -244 529 -480 513 -240 253 -254 255 -69136 321 -218 253 -246 229 -254 247 -246 247 -248 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -514 479 -272 255 -474 511 -240 241 -270 225 -252 247 -504 259 -246 499 -228 273 -498 511 -476 509 -480 253 -242 273 -242 491 -256 241 -494 507 -504 255 -242 491 -256 243 -242 243 -526 475 -506 505 -506 473 -504 505 +RAW_Data: -504 251 -242 495 -490 249 -242 271 -68916 273 -238 229 -256 249 -248 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -250 247 -506 257 -248 245 -246 245 -248 503 -258 245 -246 247 -246 247 -504 481 -258 243 -528 225 -244 495 -512 509 -482 507 -504 475 -276 255 -254 249 -474 515 -238 251 -254 255 -254 249 -474 257 -250 245 -248 501 -514 479 -512 225 -242 273 -244 243 -246 495 -508 255 -244 243 -246 497 -512 483 -272 255 -254 253 -69136 283 -254 241 -230 251 -248 245 -248 249 -248 249 -248 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -250 247 -504 259 -246 245 -246 247 -248 503 -514 477 -274 253 -500 483 -232 265 -228 253 -250 249 -506 259 -248 499 -226 245 -528 477 -508 509 -484 253 -244 241 -244 497 -272 255 -496 479 -528 225 -252 505 -260 215 -276 245 -500 479 -510 509 -482 507 -510 491 -508 245 -246 479 -518 227 -292 215 -68942 321 -218 233 -274 235 -260 223 -250 249 -250 249 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -506 225 -280 213 -278 245 -248 503 -260 215 -276 215 -278 245 -504 479 -258 245 -496 257 -246 497 -514 475 -508 507 -508 461 -280 251 -252 241 -496 481 -272 251 -256 253 -254 249 -470 259 -248 245 -248 499 -512 475 -510 237 -256 253 -256 251 -244 493 -514 223 -244 245 -276 497 -480 509 -256 243 -244 243 -68750 131 -586 287 -220 253 -246 233 -254 249 -248 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -250 247 -250 249 -504 259 -248 243 -248 245 -248 501 -514 477 -274 253 -474 513 -240 241 -268 227 -250 249 -504 257 -248 499 -226 245 -530 477 -510 507 -482 255 -242 241 -244 523 -256 241 -494 505 -474 257 -242 525 -224 273 -242 243 -494 507 -508 481 -506 505 -504 471 -506 249 -242 527 -472 251 -242 271 -119988 65 -164 163 -1380 229 -262 65 -1322 65 -564 99 -860 65 -566 501 -66 499 -164 395 -132 199 -100 895 -11996 131 -166 295 -132 165 -234 65 -164 231 -102 199 -134 97 -498 199 -164 265 -66 197 -132 65 -100 99 -664 1297 -98 8085 -7700 99 -634 365 -134 363 -954 99 -2236 261 -66 789 -98 425 -100 459 -12258 99 -198 267 -100 99 -102 97 -200 133 -300 67 -166 163 -464 133 -66 99 -828 927 -132 331 -166 9065 -7016 67 -98 67 -1290 131 -396 165 -134 131 -1026 97 -1118 65 -1048 919 -134 699 +RAW_Data: -100 3443 -13736 133 -1852 65 -232 363 -202 431 -100 133 -98 265 -166 197 -66 299 -526 131 -100 163 -832 727 -168 131 -200 65 -132 197 -102 331 -16028 99 -132 99 -198 99 -68 133 -364 163 -432 197 -464 131 -100 133 -298 97 -466 165 -200 133 -396 331 -66 823 -66 7065 -12144 97 -428 359 -164 65 -100 593 -198 163 -164 131 -132 99 -98 131 -1448 1193 -100 365 -132 10335 -1482 65 -364 63 -1844 97 -134 231 -630 131 -200 265 -232 65 -166 65 -368 197 -1126 297 -132 131 -66 1259 -134 129 -66 99 -66 8323 -6196 263 -298 97 -164 97 -492 231 -794 131 -166 67 -428 65 -954 755 -98 261 -66 261 -230 131 -230 1425 -11490 167 -562 197 -364 63 -428 65 -228 463 -166 65 -19728 165 -134 363 -100 131 -168 197 -198 101 -826 99 -1678 99 -66 561 -98 161 -66 229 -230 163 -398 265 -166 699 -9874 67 -2192 165 -200 67 -1096 131 -2282 227 -332 231 -98 165 -68 165 -364 3503 -7996 65 -430 99 -662 231 -266 165 -66 133 -134 199 -164 99 -168 65 -398 65 -730 231 -100 297 -198 67 -132 863 -134 231 -102 267 -68 871 -68 765 -66 823 -9234 99 -4694 231 -134 197 -166 99 -368 363 -100 233 -694 231 -400 65 -464 131 -234 99 -230 65 -400 297 -66 8683 -7160 233 -1030 129 -298 263 -100 299 -264 165 -100 229 -792 65 -164 131 -294 65 -264 459 -426 525 -132 229 -298 5509 -9856 131 -100 263 -232 163 -266 531 -232 99 -398 65 -332 165 -534 131 -68 293 -596 887 -232 4775 -16286 197 -364 65 -132 99 -98 163 -1350 131 -100 167 -398 99 -432 533 -100 929 -66 65 -228 3861 -3258 99 -434 65 -232 99 -332 133 -860 265 -66 233 -166 131 -100 197 -100 99 -66 99 -530 65 -564 65 -132 165 -232 265 -200 199 -100 165 -100 67 -98 531 -132 427 -10628 165 -232 199 -132 131 -366 199 -464 65 -2290 399 -198 333 -168 597 -166 533 -66 2453 -66 4151 -7656 99 -1062 131 -232 133 -98 131 -68 163 -198 133 -334 67 -596 923 -132 161 -98 327 -362 4939 -12358 195 -230 131 -528 65 -1744 65 -360 97 -396 63 -166 1047 -198 65 -196 231 -130 97 -12510 131 -198 99 -668 97 -166 199 -1224 99 -1128 65 -98 429 -132 365 -198 765 -132 1227 -9838 65 -5956 295 -266 297 -430 229 -1286 65 -392 197 -988 163 -132 625 -100 165 -66 525 -66 4229 -16222 129 -132 295 -66 163 -132 97 -66 97 -692 97 -462 65 -1026 265 -132 827 -166 163 -166 167 -234 6731 -12228 233 -166 99 -200 131 -632 133 -332 65 -498 263 -100 229 -262 463 -100 199 -100 733 +RAW_Data: -100 3989 -11100 131 -894 131 -464 65 -332 99 -132 133 -132 101 -236 99 -1328 165 -100 133 -198 1027 -360 3341 -9980 133 -1858 65 -166 133 -166 67 -134 395 -166 99 -930 97 -100 199 -234 99 -428 99 -164 1051 -66 657 -100 9339 -3804 197 -624 65 -2224 131 -900 529 -264 197 -296 231 -98 727 -132 199 -100 265 -66 99 -68 6671 -12588 165 -132 165 -132 233 -928 165 -934 99 -200 1557 -100 331 -166 7333 -8240 295 -164 263 -98 97 -132 97 -198 261 -230 197 -298 229 -692 197 -662 661 -200 231 -66 197 -15936 199 -960 65 -234 165 -466 231 -2022 431 -98 801 -232 463 -66 229 -164 3261 -8456 67 -5980 65 -1990 133 -364 97 -400 65 -132 99 -134 99 -132 99 -1292 429 -166 265 -68 3517 -8746 65 -862 165 -332 267 -198 67 -200 65 -166 299 -100 165 -2022 465 -430 165 -134 301 -136 297 -66 3287 -100 951 -132 3825 -8094 197 -132 129 -364 129 -66 163 -164 295 -428 131 -392 99 -394 459 -396 463 -164 4081 -10550 99 -266 67 -2688 203 -582 261 -260 223 -252 249 -250 249 -250 249 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -248 249 -506 257 -248 245 -246 245 -248 503 -260 245 -246 245 -246 247 -504 511 -226 243 -528 225 -244 529 -238 253 -472 517 -244 279 -238 227 -252 247 -250 247 -504 513 -226 243 -528 477 -274 253 -256 217 -254 247 -500 259 -246 499 -226 245 -274 245 -246 245 -502 513 -476 255 -244 495 -274 253 -254 255 -218 247 -502 513 -476 257 -68588 311 -208 233 -256 249 -248 249 -248 247 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -514 477 -272 255 -254 217 -498 263 -226 509 -514 475 -274 253 -256 253 -460 525 -482 513 -478 507 -506 223 -244 271 -244 495 -274 253 -476 243 -252 247 -238 259 -248 503 -260 245 -246 245 -246 247 -248 249 -504 257 -248 245 -246 501 -514 479 -274 253 -218 255 -254 247 -234 255 -69132 319 -220 243 -232 251 -248 247 -248 247 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -258 247 -246 245 -246 247 -504 515 -238 251 -474 279 -254 489 -228 253 -506 513 -238 251 -256 253 -254 251 -240 227 -510 479 -258 243 -528 475 -274 253 -256 217 -254 247 -500 257 -248 499 -226 245 -276 243 -246 245 -502 513 -478 257 -242 495 -274 253 -256 217 -254 247 -500 513 diff --git a/assets/unit_tests/subghz/test_random_raw.sub b/assets/unit_tests/subghz/test_random_raw.sub index 77e81f23a0a..96c324a8da3 100644 --- a/assets/unit_tests/subghz/test_random_raw.sub +++ b/assets/unit_tests/subghz/test_random_raw.sub @@ -63,3 +63,26 @@ RAW_Data: 231 -196 1265 -100 133 -68 933 -100 7293 -66 331 -132 295 -68 1157 -98 RAW_Data: 823 -420 417 -848 797 -472 381 -876 791 -428 413 -844 817 -426 379 -878 385 -848 403 -852 807 -452 379 -878 801 -452 801 -438 385 -838 419 -846 399 -852 379 -850 315 -110416 645 -1548 1691 -486 1667 -518 1695 -488 1671 -498 1697 -508 571 -1588 583 -1570 561 -1574 1689 -504 583 -1560 1679 -520 587 -1574 1677 -488 1701 -484 1697 -520 1677 -492 1693 -488 581 -1566 591 -1574 601 -1546 607 -1568 577 -1566 581 -1576 579 -16394 591 -1548 1679 -518 1671 -520 1679 -516 1663 -514 1689 -486 583 -1580 579 -1578 579 -1566 1701 -494 571 -1568 1697 -514 563 -1570 1693 -506 1669 -516 1695 -496 1681 -518 1667 -506 573 -1576 603 -1544 613 -1568 597 -1538 607 -1566 581 -1580 577 -16400 619 -1534 1703 -494 1677 -480 1697 -506 1675 -518 1669 -518 587 -1580 581 -1562 579 -1576 1683 -488 589 -1582 1677 -524 583 -1570 1653 -510 1703 -518 1641 -518 1693 -502 1677 -516 579 -1570 579 -1578 581 -1566 615 -1566 585 -1564 585 -1580 585 -16408 595 -1546 1685 -518 1673 -490 1669 -548 1665 -518 1675 -494 587 -1552 595 -1570 605 -1556 1673 -520 581 -1578 1665 -520 581 -1558 1701 -484 1681 -516 1667 -516 1697 -508 1675 -490 603 -1570 577 -1566 593 -1572 603 -1576 575 -1568 579 -1578 579 -16400 625 -1554 1667 -500 1699 -482 1691 -506 1679 -518 1673 -520 585 -1566 579 -1560 611 -1548 1697 -488 577 -1602 1651 -518 583 -1578 1667 -508 1691 -522 1675 -512 1665 -502 1699 -482 605 -1574 585 -1566 601 -1570 577 -1576 581 -1576 579 -1566 579 -16452 591 -1534 1693 -508 1683 -518 1673 -520 1673 -488 1711 -514 575 -1562 589 -1570 603 -1568 1667 -518 589 -1578 1677 -486 605 -1570 1701 -484 1701 -504 1697 -514 1667 -510 1717 -518 581 -1578 615 -91426 233 -298 197 -332 593 -162 261 -98 131 -68 163 -692 821 -132 227 -64 131 -66 197 -132 163 -66 263 -68 363 -134 461 -98 65 -66 229 -298 295 -66 3173 -64 987 -164 425 -98 193 -98 693 -66 723 -196 391 -496 431 -100 229 -68 499 -100 63 -66 165 -66 397 -98 133 -100 533 -166 1179 -166 361 -100 3973 -98 825 -100 131 -98 723 -66 1053 -66 131 -68 197 -100 199 -100 331 -66 165 -100 429 -68 231 -66 567 -66 533 -100 593 -68 1463 -66 2093 -100 599 -66 361 -66 361 -132 261 -462 263 -66 621 -98 555 -100 131 -68 4609 -200 199 -164 1033 -66 863 -132 131 -68 331 -100 4565 -98 229 -66 1313 -130 589 -166 3959 -100 531 -100 263 -132 361 -166 229 -64 165 -66 231 -328 261 -66 229 -66 165 -100 235 -100 299 -132 265 -266 165 -66 4417 -100 261 -68 1625 -64 165 -98 229 -160 259 -98 99 -332 593 -166 167 -102 RAW_Data: 199 -66 1063 -98 267 -100 263 -332 5513 -64 229 -232 685 -232 661 -98 431 -66 1021 -66 4085 -64 655 -66 2313 -66 531 -66 263 -100 197 -134 67 -132 901 -66 1591 -66 4217 -100 827 -100 165 -66 299 -166 1987 -166 4097 -66 365 -66 131 -332 131 -100 625 -66 361 -98 131 -196 1679 -66 163 -98 293 -100 2275 -98 1689 -66 825 -98 627 -164 297 -398 461 -66 4707 -66 795 -134 329 -132 597 -66 777 -6038 371 -1818 167 -668 693 -622 1573 -638 465 -1666 503 -1626 541 -1622 1635 -518 577 -1578 1669 -512 567 -1606 1667 -502 1677 -516 1693 -500 1673 -518 1675 -522 587 -1562 581 -1558 625 -1546 587 -1558 611 -1560 571 -1568 609 -16352 633 -1548 1689 -476 1707 -490 1687 -482 1709 -502 1675 -520 579 -1578 577 -1568 577 -1568 1705 -486 581 -1586 1695 -486 579 -1568 1679 -520 1673 -520 1669 -508 1707 -498 1677 -514 577 -1566 615 -1550 581 -1568 615 -1532 617 -1546 617 -1532 615 -16406 599 -1530 1691 -514 1695 -484 1679 -530 1659 -518 1669 -514 601 -1568 577 -1578 577 -1568 1699 -492 573 -1576 1707 -486 577 -1600 1655 -518 1669 -530 1691 -486 1673 -514 1691 -502 585 -1576 585 -1580 577 -1592 573 -1576 571 -1570 613 -1570 559 -16430 619 -1538 1703 -462 1723 -484 1697 -488 1691 -488 1715 -462 635 -1534 607 -1556 589 -1580 1685 -488 621 -1538 1711 -492 589 -1548 1717 -478 1693 -514 1687 -504 1693 -484 1705 -482 605 -1570 579 -1566 619 -1550 581 -1580 579 -1568 615 -1536 619 -16382 625 -1534 1709 -490 1683 -514 1673 -504 1677 -518 1671 -518 587 -1560 577 -1588 587 -1580 1681 -482 609 -1558 1677 -520 581 -1576 1663 -530 1659 -518 1673 -514 1691 -504 1697 -510 587 -1572 575 -1564 591 -1570 603 -1574 577 -1568 579 -1578 579 -16430 599 -1564 1693 -484 1695 -486 1675 -500 1713 -484 1709 -488 579 -1568 593 -1576 603 -1570 1665 -520 581 -1560 1699 -482 603 -1580 1677 -518 1667 -520 1671 -488 1711 -482 1699 -516 599 -1570 577 -1578 577 -1568 579 -1570 617 -1566 581 -1560 587 -16424 629 -1542 1677 -482 1695 -514 1687 -484 1711 -494 1675 -514 571 -1584 587 -1572 599 -1542 1695 -520 585 -1544 1701 -510 593 -1568 1665 -514 1689 -506 1669 -508 1679 -528 1669 -520 579 -1576 579 -1568 581 -1582 581 -1578 579 -1568 615 -1564 585 -16412 631 -1540 1683 -516 1671 -510 1653 -506 1691 -518 1671 -514 601 -1570 577 -1578 577 -1578 1665 -498 603 -1566 1693 -514 563 -1576 1699 -506 1663 -514 1701 -478 1687 -520 1669 -500 603 -1568 605 -1558 589 -1574 601 -1542 607 -1576 577 -1576 577 -16434 597 -1534 1695 -516 1687 -488 1707 -486 1683 -518 1693 -496 583 -1574 599 -1542 605 -1578 1665 -500 611 -1550 1711 -478 605 -1558 RAW_Data: 1679 -518 1675 -502 1699 -482 1693 -506 1679 -510 613 -1562 581 -1590 569 -1570 605 -1560 587 -1572 599 -1542 607 -16400 625 -1560 1669 -508 1677 -518 1667 -518 1695 -486 1709 -464 601 -1566 607 -1560 589 -1576 1691 -476 615 -1562 1677 -486 625 -1542 1709 -486 1703 -484 1697 -520 1673 -506 1695 -498 585 -1570 603 -1544 609 -1572 579 -1570 583 -1580 581 -1582 579 -16410 629 -1524 1715 -484 1679 -518 1673 -516 1663 -518 1697 -504 583 -1576 577 -1592 587 -1552 1681 -514 579 -1580 1681 -516 577 -1566 1705 -494 1689 -488 1705 -486 1695 -520 1675 -522 587 -1574 579 -1584 581 -1576 599 -1570 575 -1578 579 -1564 613 -89724 99 -1166 129 -1158 167 -532 163 -98 361 -198 299 -298 197 -66 2489 -66 3797 -66 1937 -66 1479 -98 557 -66 361 -66 1709 -66 6741 -98 1889 -132 5693 -68 7367 -100 8643 -100 2655 -100 3727 -66 1023 -66 865 -66 1161 -100 6287 -66 3987 -66 1961 -132 3307 -68 2183 -66 2429 -132 4179 -66 753 -66 461 -66 621 -64 5761 -100 331 -66 1683 -198 465 -66 629 -68 7341 -66 357 -198 261 -66 593 -234 331 -100 593 -64 293 -64 1611 -100 459 -100 297 -100 561 -134 1725 -66 6901 -100 1407 -68 8017 -200 1989 -66 5721 -100 199 -166 1251 -66 359 -130 9965 -66 4361 -100 819 -100 1051 -66 2187 -64 555 -66 861 -66 5889 -66 +RAW_Data: 361 -4326 2555 -28090 65 -302 65 -1890 131 -2062 2547 -95068 2565 -48020 67 -47036 2551 -30016 2561 -47778 67 -14884 2481 -95118 2537 -95132 2549 -48496 65 -21526 2571 -16342 97 -4142 65 -1938 2543 -95008 2551 -44030 1579 -548 1469 -588 433 -1568 469 -1540 479 -1550 1489 -538 473 -1574 1467 -538 1493 -566 443 -22130 693 -3742 321 -1702 341 -1690 1353 -628 391 -1666 1401 -584 1445 -596 391 -22192 1487 -554 1471 -550 447 -1584 453 -1568 445 -1578 1469 -550 459 -1598 1465 -540 1461 -576 445 -22164 1479 -546 1501 -544 453 -1568 447 -1580 445 -1584 1451 -560 443 -1594 1473 -548 1479 -556 441 -22160 1475 -548 1487 -554 449 -1578 451 -1586 451 -1572 1469 -552 449 -1578 1473 -558 1469 -552 449 -22142 1507 -546 1479 -548 457 -1574 447 -1580 447 -1584 1475 -554 441 -1592 1465 -546 1473 -546 483 -22132 1157 -1082 67 -166 65 -198 65 -1150 257 -1706 339 -1666 365 -1642 1409 -610 407 -1626 1417 -620 1435 -580 409 -22184 1495 -572 1463 -552 447 -1584 453 -1574 447 -1580 1473 -548 459 -1568 1501 -520 1501 -552 463 -22124 535 -7674 339 -1680 1345 -678 361 -1664 1395 -618 1411 -646 373 -22194 1511 -526 1477 -550 483 -1542 479 -1562 471 -1566 1483 -546 445 -1574 1471 -534 1497 -548 483 -169938 2539 -89172 167 -5768 2551 -93014 967 -252 1571 -5844 2503 -87590 65 -5948 2523 -64008 1605 -520 1473 -554 449 -1584 449 -1576 447 -1546 1505 -546 451 -1574 1469 -546 1475 -548 459 -22160 1525 -506 1501 -516 479 -1550 469 -1570 469 -1570 1471 -538 471 -1568 1489 -516 1501 -554 443 -22152 1507 -522 1511 -518 481 -1580 451 -1542 483 -1548 1505 -546 451 -1570 1471 -552 1473 -548 455 -22180 1505 -522 1501 -544 451 -1560 475 -1548 481 -1556 1477 -552 475 -1546 1505 -516 1517 -516 473 -22148 1515 -518 1499 -546 485 -1570 443 -1580 447 -1582 1475 -526 483 -1548 1507 -546 1479 -558 449 -22138 1495 -586 1437 -616 403 -1594 429 -1608 417 -1606 1465 -556 433 -1606 1465 -536 1499 -544 445 -22170 1401 -792 1245 -770 271 -1716 325 -1680 359 -1664 1397 -620 393 -1644 1407 -614 1433 -586 429 -22202 1477 -572 1469 -548 449 -1576 457 -1578 479 -1544 1473 -590 429 -1570 1491 -540 1509 -554 429 -22196 1481 -556 1467 -580 439 -1592 431 -1608 415 -1608 1441 -586 463 -1568 1467 -552 1489 -534 473 -22166 1485 -574 1469 -580 453 -1572 443 -1578 447 -1578 1477 -554 447 -1580 1479 -550 1481 -550 475 -22160 1525 -542 1467 -540 483 -1574 447 -1582 451 -1578 1481 -558 447 -1560 1493 -550 1505 -544 449 -22182 1435 -646 1391 -664 369 -1642 385 -1652 395 -1600 1463 -584 417 -1606 1467 -576 1443 -586 429 -148588 275 -106 847 -128 877 -100 281 -97826 2541 -92318 2505 -12474 2563 -73674 2555 -41600 2543 -76554 1601 -516 1471 -554 +RAW_Data: 487 -1556 453 -1570 441 -1590 1467 -556 469 -1538 1501 -522 1501 -552 463 -22124 1513 -514 1509 -548 445 -1582 461 -1568 443 -1574 1467 -536 465 -1574 1499 -516 1503 -556 441 -22150 1537 -484 1495 -544 479 -1558 459 -1574 447 -1580 1471 -548 459 -1576 1471 -554 1471 -550 459 -22160 1517 -516 1503 -546 447 -1574 473 -1546 481 -1576 1479 -520 467 -1572 1497 -550 1469 -556 441 -22156 1533 -528 1495 -530 469 -1568 445 -1566 485 -1548 1505 -544 451 -1572 1471 -554 1503 -516 495 -22160 1511 -520 1477 -546 483 -1542 485 -1546 481 -1542 1509 -526 455 -1578 1507 -544 1481 -524 485 -22146 1543 -510 1481 -552 475 -1546 473 -1568 481 -1540 1503 -522 473 -1556 1507 -558 1491 -518 479 -22164 1523 -520 1503 -544 453 -1566 479 -1550 469 -1572 1493 -546 447 -1576 1477 -552 1509 -544 451 -22178 639 -596 65 -926 63 -1954 237 -1680 355 -1670 383 -1636 1423 -596 439 -1578 1471 -574 1465 -576 445 -22182 1439 -676 1335 -702 339 -1648 387 -1648 409 -1608 1429 -618 419 -1612 1447 -578 1439 -614 425 -22186 1497 -530 1505 -556 471 -1540 479 -1582 431 -1570 1497 -546 481 -1536 1497 -554 1501 -556 463 -22178 1503 -566 1433 -586 433 -1604 445 -1576 441 -1580 1503 -548 453 -1572 1473 -578 1467 -558 469 -149080 311 -1034 895 -1084 939 -1006 337 -78790 97 -6890 2535 -28048 2511 -64482 2573 -88138 65 -6956 2515 -95140 2509 -61986 1589 -522 1475 -548 449 -1576 475 -1548 481 -1546 1475 -564 443 -1564 1477 -580 1477 -554 449 -22166 1503 -532 1481 -544 447 -1576 449 -1572 473 -1548 1473 -580 451 -1568 1463 -552 1477 -552 461 -22164 1521 -528 1493 -548 443 -1580 461 -1540 475 -1574 1473 -554 471 -1568 1489 -516 1497 -538 471 -22154 1385 -786 1245 -796 261 -1702 341 -1650 391 -1644 1411 -608 409 -1620 1415 -624 1409 -614 413 -22178 1533 -498 1519 -546 445 -1576 449 -1578 457 -1568 1503 -546 451 -1570 1467 -554 1503 -552 463 -22162 1401 -774 1257 -754 297 -1678 353 -1650 383 -1666 1397 -618 385 -1642 1437 -612 1433 -586 427 -22194 1483 -552 1477 -546 485 -1544 453 -1576 481 -1576 1479 -560 449 -1548 1507 -546 1479 -558 447 -22170 1413 -786 1245 -776 295 -1664 337 -1680 387 -1652 1385 -638 407 -1614 1441 -582 1451 -606 409 -22204 1503 -528 1507 -550 465 -1534 481 -1584 429 -1572 1497 -548 447 -1580 1481 -550 1503 -546 455 -22166 1519 -552 1469 -580 419 -1612 419 -1596 447 -1582 1479 -554 447 -1582 1479 -550 1519 -518 479 -134730 169 -172 559 -194 579 -676 257 -87040 99 -7384 2269 -488 313 -37888 65 -12084 2515 -33298 2247 -474 309 -42656 63 -51970 2233 -456 309 -94658 2233 -430 325 -90692 357 -186 2417 -518 1517 -514 475 -1550 467 -1570 471 -1538 1499 -556 443 -1564 1483 -552 1501 -524 +RAW_Data: 481 -22144 1433 -668 1373 -666 337 -1680 355 -1634 383 -1634 1431 -622 399 -1606 1443 -582 1443 -586 431 -22166 1521 -512 1497 -548 447 -1580 459 -1568 447 -1574 1473 -554 465 -1572 1497 -516 1507 -554 453 -22148 1503 -540 1489 -546 479 -1542 449 -1578 457 -1576 1475 -546 483 -1540 1507 -552 1473 -548 453 -22154 1539 -516 1469 -586 431 -1574 447 -1576 479 -1558 1485 -554 439 -1580 1501 -550 1457 -552 473 -22154 1521 -550 1485 -540 447 -1578 457 -1578 447 -1572 1471 -556 485 -1540 1483 -552 1501 -556 443 -22186 1437 -662 1345 -704 339 -1688 361 -1646 375 -1640 1399 -616 421 -1612 1441 -614 1435 -586 429 -22200 1513 -520 1503 -544 453 -1572 447 -1580 483 -1550 1475 -552 475 -1548 1501 -554 1491 -540 475 -22184 1499 -530 1485 -548 457 -1570 477 -1578 443 -1576 1501 -546 449 -1562 1499 -538 1493 -572 443 -22166 1471 -612 1429 -624 401 -1608 417 -1620 431 -1600 1461 -582 419 -1610 1441 -582 1473 -548 459 -205658 1761 -436 863 -68558 2597 -23434 1775 -438 519 -94592 1803 -422 829 -86706 1727 -434 527 -66 319 -94536 1753 -444 865 -238 1489 -652 1385 -656 357 -1668 365 -1628 403 -1612 1439 -614 403 -1626 1425 -588 1443 -584 409 -22168 1531 -528 1491 -530 469 -1568 443 -1564 483 -1538 1505 -546 455 -1570 1469 -556 1503 -518 491 -22128 1455 -660 1359 -686 355 -1632 385 -1632 411 -1640 1411 -596 423 -1606 1437 -580 1443 -596 423 -22188 1495 -550 1467 -534 473 -1566 481 -1540 483 -1572 1477 -552 449 -1582 1477 -558 1471 -552 449 -22174 543 -3692 235 -1680 357 -1668 353 -1698 1375 -636 371 -1644 1409 -610 1437 -578 449 -22180 1499 -542 1491 -542 479 -1540 481 -1566 449 -1562 1499 -554 465 -1568 1463 -554 1493 -536 473 -22168 1405 -774 1257 -788 267 -1676 355 -1672 369 -1660 1387 -624 417 -1606 1427 -624 1425 -586 415 -22208 1507 -552 1489 -548 443 -1562 483 -1550 481 -1546 1505 -558 447 -1586 1473 -548 1481 -554 479 -22166 1383 -786 1245 -776 295 -1664 373 -1646 387 -1644 1403 -642 411 -1624 1417 -594 1445 -612 409 -22210 1515 -516 1503 -554 453 -1564 457 -1572 447 -1580 1501 -554 465 -1570 1467 -554 1493 -570 443 -195814 1353 -442 1267 -37900 99 -53710 411 -142 2207 -8336 2487 -46990 1301 -452 1317 -86162 65 -8376 1289 -444 1327 -94552 1311 -488 1251 -1726 1531 -544 1467 -580 417 -1578 457 -1578 443 -1576 1475 -566 441 -1568 1503 -512 1509 -526 455 -22168 1473 -582 1469 -538 483 -1538 459 -1574 447 -1580 1471 -582 429 -1572 1469 -552 1473 -548 461 -22170 1437 -640 1401 -620 393 -1636 385 -1634 409 -1604 1457 -588 415 -1608 1431 -590 1459 -554 449 -22188 1483 -556 1487 -542 445 -1578 459 -1576 443 -1574 1473 -556 469 -1570 1459 -550 1503 -554 443 -22160 1469 -590 +RAW_Data: 1469 -582 409 -1620 429 -1608 415 -1602 1455 -568 441 -1578 1475 -552 1479 -560 467 -22166 1483 -572 1463 -546 451 -1580 453 -1580 481 -1542 1475 -588 451 -1570 1453 -550 1503 -540 469 -22158 1505 -554 1475 -554 487 -1556 453 -1562 477 -1546 1495 -546 479 -1544 1511 -554 1477 -532 471 -22180 1471 -602 1437 -602 407 -1610 421 -1614 421 -1606 1433 -582 457 -1578 1475 -550 1469 -586 465 -22164 1515 -546 1469 -546 483 -1572 447 -1558 471 -1580 1471 -578 451 -1568 1495 -542 1497 -530 471 -22194 1433 -644 1393 -662 371 -1640 385 -1642 413 -1628 1431 -584 431 -1602 1469 -540 1501 -576 443 -22180 1479 -592 1439 -608 407 -1620 427 -1610 415 -1606 1465 -570 441 -1612 1441 -586 1451 -576 445 -22196 1533 -522 1489 -540 477 -1574 481 -1544 455 -1568 1505 -546 459 -1572 1501 -556 1497 -530 471 -210202 685 -540 475 -138 839 -138 239 -9950 2501 -71112 761 -462 511 -66 1297 -85614 97 -8850 745 -466 1821 -94546 827 -468 481 -140 815 -164 237 -32934 1583 -540 1477 -554 441 -1582 447 -1580 453 -1568 1465 -554 479 -1556 1487 -558 1477 -550 453 -22174 1503 -516 1483 -584 429 -1572 449 -1576 447 -1588 1475 -558 449 -1580 1473 -546 1485 -556 449 -22168 1469 -586 1443 -614 401 -1624 401 -1608 415 -1608 1463 -570 441 -1574 1471 -586 1449 -572 445 -22164 1401 -772 1255 -756 301 -1674 353 -1708 329 -1662 1397 -650 387 -1632 1405 -614 1433 -584 431 -22200 1489 -566 1463 -582 419 -1580 457 -1596 447 -1576 1473 -554 443 -1580 1469 -582 1451 -550 479 -22174 1387 -786 1251 -792 257 -1704 331 -1690 337 -1706 1377 -632 395 -1632 1433 -586 1451 -584 413 -22198 1541 -512 1485 -554 481 -1574 445 -1560 461 -1568 1495 -556 469 -1568 1495 -518 1503 -554 469 -22160 1541 -516 1501 -556 443 -1564 495 -1536 479 -1550 1517 -544 445 -1576 1507 -556 1485 -542 445 -22202 1501 -530 1503 -554 465 -1574 445 -1582 461 -1574 1469 -546 479 -1568 1471 -556 1513 -550 463 -22170 1473 -614 1419 -602 439 -1614 417 -1610 415 -1590 1465 -588 429 -1606 1469 -586 1455 -570 441 -22200 1407 -760 1277 -772 267 -1692 363 -1678 355 -1668 1393 -660 369 -1642 1441 -584 1449 -574 445 -22206 1533 -528 1497 -530 471 -1572 449 -1576 455 -1578 1507 -544 455 -1572 1503 -556 1467 -560 469 -22188 1439 -678 1347 -672 375 -1648 393 -1646 387 -1636 1431 -588 431 -1610 1439 -618 1437 -596 437 -143610 67 -510 99 -66 223 -272 173 -70 273 -204 235 -64 483 -26542 2521 -65448 297 -348 2417 -76720 65 -8388 65 -9450 203 -332 587 -72 885 -92 899 -27534 67 -39500 221 -406 521 -72 885 -98 919 -29920 1581 -534 1491 -548 445 -1580 461 -1544 477 -1574 1465 -556 473 -1568 1455 -554 1501 -524 483 -22136 1529 -498 +RAW_Data: -754 361 -17246 131 -8734 65 -71908 65 -27774 65 -1230 65 -13826 99 -800 65 -634 67 -796 99 -47716 65 -18338 67 -18176 131 -7986 65 -1084 131 -2090 65 -48694 163 -40926 65 -4538 65 -10224 65 -9874 20955 -1970 1023 -4928 1007 -4946 1011 -7910 981 -1992 1021 -7898 1013 -1962 1007 -7896 1019 -4930 995 -4962 987 -1974 1029 -4924 1019 -4920 1025 -7896 1005 -1964 1027 -7894 1007 -4932 1033 -1948 1009 -7916 1009 -1982 1001 -4942 1011 -7880 1011 -2000 1003 -13820 1011 -1990 985 -4944 1021 -4932 995 -7916 1025 -1944 1025 -7892 1015 -1970 1025 -7892 1001 -4934 1031 -4926 1015 -1970 989 -4938 1007 -4954 1019 -7874 1013 -2000 985 -7896 1011 -4950 1001 -1968 1023 -7900 999 -1968 1007 -4968 973 -7936 985 -1970 1009 -13856 1013 -1968 981 -4962 1009 -4926 1005 -7924 1003 -1968 1013 -7892 1003 -1992 985 -7904 1011 -4936 1023 -4948 997 -1960 1015 -4950 987 -4970 993 -7896 1005 -1970 1009 -7928 1005 -4914 1023 -1984 1001 -7894 1011 -1970 999 -4962 1003 -7890 1007 -1992 1013 -13810 1011 -1994 987 -4938 1005 -4964 999 -7904 1013 -1974 987 -7910 1021 -1964 1015 -7894 1021 -4912 1019 -4948 1007 -1970 1017 -4916 1021 -4946 985 -7914 1003 -1972 1009 -7898 1041 -4912 1013 -1994 985 -7892 1027 -1964 1013 -4938 1003 -7904 1023 -1966 1017 -13824 1025 -1968 983 -4950 1007 -4944 999 -7900 1029 -1964 1015 -7914 981 -2000 981 -7932 979 -4936 1021 -4926 1013 -1998 979 -4946 1035 -4908 1031 -7896 999 -1964 1025 -7902 1021 -4914 1023 -1966 1015 -7908 1007 -1970 1003 -4952 981 -7910 1001 -1974 1003 -13832 1015 -1976 999 -4958 1019 -4938 985 -7900 1025 -1966 1011 -7914 1015 -1964 1009 -7906 1017 -4908 1027 -4916 1011 -2000 981 -4954 1007 -4926 1017 -7920 1011 -1958 1009 -7906 1019 -4912 1025 -1980 1009 -7900 1013 -1948 1027 -4916 1011 -7918 1005 -1976 1003 -13846 1013 -1970 1005 -4914 1041 -4916 1007 -7918 987 -2000 987 -7902 1013 -1970 1015 -7894 1007 -4936 1019 -4944 1009 -1970 1013 -4918 1019 -4954 977 -7914 1019 -1964 1007 -7906 1003 -4956 983 -1982 1027 -7896 1005 -1962 1027 -4930 1007 -7906 999 -1972 1009 -13850 1009 -1952 1027 -4944 983 -4954 1023 -7894 1007 -1952 1031 -7882 1035 -1970 1011 -7894 1007 -4936 1025 -4920 1023 -1968 1011 -4928 1009 -4920 1015 -7902 1015 -1966 1021 -7894 1011 -4948 997 -1970 1009 -7902 1027 -1978 1011 -4930 999 -7918 1007 -1966 1013 -13824 1015 -1966 1027 -4918 1027 -4912 1021 -7888 1009 -1998 989 -7918 1019 -1960 989 -7930 983 -4946 1025 -4920 1013 -1970 1015 -4950 1009 -4926 1005 -7892 1037 -1942 1011 -7926 1005 -4918 1007 -1996 985 -7928 1011 -1964 993 -4946 1025 -7880 1003 -1972 1009 -13854 1011 -1948 1019 -4956 983 -4946 1025 -7898 1003 -1966 1025 -7900 1019 -1964 1011 -7890 1021 -4912 1017 -4930 1013 -1968 1015 -4952 1009 -4932 1007 -7920 1009 -1972 979 -7924 1009 -4944 1003 -1970 1015 -7894 1017 +RAW_Data: 131 -534 99 -798 2211 -134 297 -66 361 -66 197 -198 97 -398 199 -100 163 -100 65 -464 133 -134 233 -68 229 -696 199 -200 265 -330 65 -1218 163 -166 97 -426 229 -698 165 -100 99 -134 165 -372 65 -1426 65 -266 99 -794 65 -832 199 -464 165 -698 99 -266 165 -794 99 -298 133 -734 165 -266 99 -864 131 -232 1893 -166 1465 -1484 263 -560 99 -230 65 -462 197 -66 97 -890 165 -130 97 -132 163 -232 97 -132 161 -162 263 -262 99 -362 65 -432 65 -830 97 -234 99 -628 199 -66 99 -166 101 -268 265 -594 131 -1030 97 -1156 595 -800 167 -1920 65 -464 165 -264 131 -66 167 -134 233 -632 329 -100 97 -166 199 -466 199 -98 267 -200 97 -266 199 -300 65 -496 563 -100 101 -166 165 -730 233 -166 131 -590 97 -232 131 -164 359 -428 3159 -792 65 -624 197 -98 229 -132 393 -398 199 -200 133 -366 99 -132 67 -528 265 -730 197 -166 65 -200 397 -1358 131 -1712 363 -1462 299 -132 67 -1792 65 -794 99 -368 131 -134 165 -134 67 -266 265 -430 2315 -98 1473 -100 129 -66 229 -198 261 -166 97 -426 97 -100 229 -496 197 -162 163 -392 231 -166 229 -660 131 -366 297 -166 299 -232 97 -332 301 -866 133 -596 267 -364 99 -502 99 -1988 131 -134 65 -66 165 -366 231 -266 165 -690 99 -234 65 -498 67 -166 133 -762 2459 -166 1019 -264 99 -200 265 -562 65 -328 295 -330 197 -360 131 -98 227 -232 65 -426 259 -166 99 -496 131 -500 399 -992 67 -432 133 -66 99 -1394 231 -1524 133 -430 65 -886 65 -1716 131 -2818 63 -430 229 -296 97 -1706 131 -164 65 -1478 131 -458 99 -1568 165 -756 197 -890 99 -1088 359 -660 97 -98 229 -166 65 -500 99 -266 65 -566 65 -432 365 -200 99 -798 99 -296 327 -1218 165 -132 99 -466 165 -168 133 -632 363 -1482 163 -802 131 -862 133 -1332 65 -100 431 -830 97 -596 165 -3422 99 -896 65 -766 97 -3766 65 -132 65 -1152 163 -1810 99 -230 97 -654 229 -458 165 -200 67 -166 297 -134 99 -4840 133 -762 67 -764 231 -1248 97 -1780 97 -3332 65 -100 261 -1186 99 -3360 99 -364 97 -1738 163 -294 97 -4918 129 -1550 295 -1028 199 -1264 99 -1560 99 -2156 167 -1556 231 -1852 167 -998 67 -1116 65 -562 167 -334 133 -266 165 -394 99 -166 97 -3082 99 -232 301 -5148 131 -502 67 -732 197 -434 199 -200 99 -432 65 -232 199 -464 133 -1060 97 -1582 97 -98 97 -924 129 -462 229 -560 65 -132 97 -166 161 -164 97 -166 229 -360 97 -132 63 -198 131 -162 525 -1714 67 -732 99 -958 +RAW_Data: 65 -1166 165 -200 199 -166 133 -100 65 -1294 99 -166 265 -992 297 -728 65 -332 431 -166 261 -132 65 -132 65 -98 363 -230 163 -430 165 -230 129 -660 129 -66 131 -398 2453 -132 1329 -166 1187 -232 1657 -166 499 -68 99 -132 233 -894 99 -232 99 -134 363 -628 67 -998 131 -234 99 -266 197 -398 97 -200 167 -334 197 -430 429 -168 263 -1160 99 -364 131 -264 97 -1318 131 -790 99 -432 131 -132 199 -100 131 -930 133 -1424 99 -398 165 -1486 299 -166 165 -334 2325 -66 795 -102 397 -100 533 -100 429 -98 131 -464 65 -532 329 -366 165 -332 99 -432 295 -132 99 -662 67 -332 331 -1226 131 -102 199 -562 469 -430 97 -232 63 -328 65 -1914 133 -466 131 -832 163 -1660 331 -464 199 -828 131 -696 65 -132 2139 -66 2051 -66 263 -790 99 -566 429 -428 99 -330 297 -698 65 -200 197 -68 461 -1292 131 -168 165 -634 131 -234 133 -594 163 -360 165 -700 99 -964 133 -1026 65 -532 197 -1520 263 -688 65 -888 295 -658 65 -824 67 -598 97 -426 65 -130 161 -132 63 -658 99 -64 165 -522 199 -298 65 -428 197 -560 65 -200 165 -100 167 -594 229 -100 297 -268 65 -100 459 -200 97 -334 2997 -200 597 -498 97 -626 97 -134 363 -166 333 -266 65 -664 331 -300 299 -568 529 -662 263 -626 67 -594 99 -266 165 -230 361 -462 67 -66 131 -694 397 -1490 167 -132 165 -768 165 -130 165 -466 99 -298 99 -952 163 -428 97 -296 97 -360 99 -196 65 -658 65 -4052 229 -6240 165 -228 65 -426 99 -994 99 -398 363 -1512 161 -2042 65 -592 131 -2866 65 -500 167 -5246 97 -462 67 -1156 99 -2428 99 -960 65 -132 99 -164 65 -166 329 -2484 263 -232 67 -1368 99 -996 267 -498 67 -4612 131 -4866 65 -100 363 -464 231 -264 231 -262 297 -1594 99 -1596 65 -136 133 -1662 67 -1694 429 -1290 197 -198 293 -858 99 -1976 165 -66 97 -460 131 -460 97 -328 163 -1624 397 -300 67 -166 97 -430 299 -300 299 -1792 65 -4438 131 -622 67 -500 131 -1064 65 -400 65 -426 261 -1644 131 -3468 165 -1684 99 -866 101 -66 231 -464 65 -498 133 -492 97 -1712 99 -98 197 -66 265 -1586 199 -1334 99 -1948 97 -200 99 -266 65 -666 131 -132 99 -264 195 -3066 99 -3512 99 -1746 65 -598 97 -6068 167 -600 99 -1262 65 -166 65 -134 65 -132 131 -1520 99 -1254 97 -1828 197 -1294 129 -66 65 -1248 97 -754 165 -6542 231 -662 197 -560 359 -98 97 -130 99 -3080 63 -952 129 -296 65 -230 63 -428 99 -1788 133 -100 65 -462 199 -66 165 -1094 99 -66 +RAW_Data: 167 -3190 265 -1128 195 -298 525 -166 65 -594 597 -664 131 -498 165 -232 65 -296 129 -296 65 -494 297 -498 297 -596 201 -332 2027 -132 593 -68 891 -66 893 -98 365 -396 97 -398 99 -300 199 -366 163 -598 99 -100 131 -234 65 -132 331 -532 165 -166 231 -1660 133 -532 265 -100 131 -100 131 -298 199 -396 199 -334 197 -166 67 -334 131 -1662 165 -298 97 -534 65 -628 65 -534 65 -266 97 -826 133 -696 65 -294 233 -198 165 -134 2081 -66 929 -198 167 -300 99 -232 297 -234 199 -662 67 -166 99 -66 233 -132 433 -232 265 -300 297 -132 65 -132 97 -496 199 -360 465 -132 65 -132 297 -460 293 -64 161 -262 97 -492 199 -200 233 -132 97 -396 99 -858 199 -864 65 -66 99 -532 131 -1608 297 -1550 163 -432 229 -66 163 -394 1953 -134 1491 -100 991 -66 165 -232 265 -130 299 -432 167 -724 363 -134 167 -200 231 -66 199 -98 395 -66 165 -266 99 -332 197 -268 265 -466 265 -166 493 -362 65 -132 99 -360 199 -200 133 -758 99 -330 165 -298 163 -428 199 -368 165 -334 131 -500 163 -986 97 -394 329 -196 97 -558 195 -230 97 -532 2373 -232 165 -232 795 -132 267 -168 363 -166 297 -298 131 -134 65 -466 131 -464 65 -232 67 -266 229 -364 231 -232 297 -464 65 -198 133 -398 529 -134 65 -364 163 -732 233 -298 299 -134 231 -66 129 -264 397 -132 131 -200 329 -430 131 -132 265 -1292 65 -362 131 -264 97 -1020 165 -398 131 -364 65 -300 265 -924 195 -396 331 -166 167 -132 433 -198 99 -464 297 -266 165 -396 131 -1226 165 -694 65 -230 197 -896 65 -594 2969 -164 461 -298 133 -330 133 -234 65 -134 131 -66 65 -68 97 -66 99 -132 231 -694 363 -298 267 -268 231 -368 131 -300 99 -134 65 -166 461 -396 263 -66 165 -298 131 -66 229 -1644 163 -1610 229 -658 97 -132 129 -162 97 -428 65 -66 129 -1912 65 -1194 233 -2218 133 -360 65 -132 229 -3428 65 -262 65 -3208 133 -1224 99 -296 65 -2212 65 -496 65 -200 199 -498 65 -1144 65 -1764 165 -1726 65 -434 65 -898 165 -2354 67 -134 99 -464 99 -792 263 -954 1161 -100 295 -296 131 -132 457 -462 363 -200 725 -298 131 -134 231 -68 531 -166 667 -298 99 -66 595 -794 165 -202 199 -68 99 -298 165 -68 231 -202 201 -200 97 -1360 197 -266 165 -334 99 -234 165 -200 165 -100 131 -664 65 -566 397 -100 165 -132 199 -132 165 -988 197 -394 99 -164 65 -294 99 -262 63 -1288 233 -132 199 -168 265 -64 99 -728 133 -1192 65 -334 165 -132 199 -200 +RAW_Data: 131 -400 65 -398 165 -866 131 -264 393 -1680 231 -1494 299 -894 265 -364 65 -132 131 -960 99 -296 165 -824 65 -1716 99 -664 97 -134 165 -1526 165 -634 131 -166 135 -466 231 -696 2331 -100 329 -100 961 -198 65 -164 199 -98 331 -132 65 -298 731 -66 163 -332 265 -894 65 -132 265 -300 97 -334 229 -100 65 -1026 233 -366 329 -922 99 -266 329 -428 97 -462 361 -758 163 -1886 65 -498 229 -558 65 -600 267 -68 65 -1592 133 -202 2299 -332 393 -132 329 -326 231 -232 97 -590 231 -136 201 -1226 265 -530 199 -134 65 -232 297 -398 65 -564 65 -1458 65 -500 99 -302 99 -1120 65 -66 131 -98 197 -66 133 -66 65 -730 99 -200 197 -730 165 -664 297 -1462 165 -664 133 -168 65 -168 133 -368 197 -466 1957 -66 1525 -266 131 -366 65 -394 65 -98 163 -296 99 -130 265 -696 65 -398 131 -1128 197 -134 67 -894 97 -296 231 -166 401 -98 131 -928 265 -398 131 -798 131 -298 165 -830 65 -230 231 -168 97 -1252 131 -590 65 -460 229 -692 97 -332 65 -366 265 -732 2297 -66 197 -66 131 -166 231 -100 99 -298 365 -168 361 -130 129 -66 161 -198 97 -626 593 -66 99 -98 99 -556 297 -132 65 -134 65 -526 295 -196 197 -68 163 -264 327 -130 855 -66 393 -132 131 -100 65 -98 227 -164 197 -758 131 -268 99 -430 65 -1686 131 -1652 197 -788 63 -726 165 -100 131 -264 197 -1026 197 -1250 131 -1650 65 -1980 97 -132 63 -1424 97 -198 99 -100 65 -1090 65 -398 99 -1686 99 -754 63 -1714 97 -1842 65 -2988 65 -4980 165 -1624 65 -232 67 -1464 65 -3048 65 -166 97 -1986 65 -1062 99 -862 131 -2732 99 -2360 97 -1620 65 -1326 65 -330 197 -3238 67 -266 131 -2968 67 -132 135 -1688 131 -1718 97 -1648 65 -166 65 -1292 65 -1908 99 -424 131 -1222 197 -798 99 -700 97 -1758 165 -1562 99 -396 165 -166 99 -98 65 -366 65 -762 131 -332 233 -498 133 -98 163 -562 65 -68 131 -858 65 -896 65 -366 233 -532 197 -168 65 -68 65 -630 195 -724 231 -296 361 -164 261 -2862 233 -232 99 -3186 67 -232 163 -496 165 -1620 97 -1622 131 -7022 267 -268 165 -466 63 -528 295 -200 197 -332 65 -1656 131 -5478 65 -1296 99 -130 161 -694 67 -1694 131 -734 99 -2590 99 -1056 65 -432 327 -66 165 -164 65 -1120 229 -1656 165 -1128 131 -1232 99 -1560 65 -568 131 -360 231 -1598 99 -3250 67 -1818 65 -1216 263 -3328 65 -1508 133 -2600 65 -528 65 -2418 65 -460 97 -100 97 -164 65 -1560 133 -1822 163 -296 165 -1090 165 -168 133 -1264 +RAW_Data: 229 -1458 165 -66 133 -1626 197 -132 65 -394 65 -724 229 -132 65 -200 263 -296 97 -264 131 -130 229 -132 161 -1230 431 -132 99 -234 233 -362 99 -698 67 -334 65 -366 299 -398 99 -328 131 -396 165 -1458 99 -926 2239 -66 763 -68 1727 -266 65 -364 65 -464 365 -366 97 -664 165 -200 265 -234 261 -264 395 -362 329 -690 261 -164 495 -232 131 -326 165 -264 99 -198 397 -928 299 -268 299 -166 99 -298 167 -436 65 -266 67 -498 231 -896 367 -428 97 -332 133 -628 165 -1394 231 -926 131 -232 3127 -132 921 -428 263 -66 97 -230 97 -1022 329 -430 97 -166 65 -198 63 -100 65 -66 97 -66 361 -132 67 -232 131 -268 99 -366 99 -98 331 -364 99 -428 97 -66 491 -164 99 -164 65 -428 131 -260 429 -1380 263 -1564 65 -300 65 -498 99 -364 167 -200 231 -264 67 -264 365 -266 231 -262 65 -724 65 -130 2213 -130 361 -166 2065 -166 165 -100 133 -264 299 -332 99 -98 229 -198 65 -328 131 -100 263 -628 131 -330 231 -98 65 -132 129 -264 65 -130 163 -692 131 -66 99 -532 133 -234 99 -232 367 -298 401 -702 165 -498 399 -166 65 -132 131 -400 165 -1232 165 -1296 65 -232 165 -300 97 -396 2033 -198 463 -230 67 -68 563 -262 295 -330 197 -1190 197 -66 167 -66 263 -430 263 -100 163 -198 167 -102 165 -100 99 -234 67 -66 267 -396 197 -296 131 -1190 331 -200 67 -234 231 -530 263 -1610 263 -264 329 -196 129 -98 131 -132 227 -132 425 -526 129 -694 299 -856 63 -132 165 -166 165 -436 297 -1430 65 -66 99 -198 167 -266 65 -864 267 -996 65 -500 265 -1456 297 -726 163 -66 579 -1508 523 -1504 509 -1006 1033 -486 1513 -1514 507 -510 1537 -982 1011 -528 1509 -512 1495 -1034 999 -1016 999 -516 1539 -1014 989 -1510 527 -486 1537 -1508 517 -1512 485 -1546 483 -524 1519 -484 1529 -60168 1539 -1506 507 -1006 1015 -1016 1007 -1512 509 -1006 1033 -506 1495 -1544 497 -1014 1007 -1008 1001 -1544 477 -1024 1011 -1538 485 -1512 525 -1010 1005 -482 1529 -1018 1005 -1020 1009 -1532 475 -540 1507 -512 1491 -59188 513 -1506 515 -1512 519 -1020 985 -506 1519 -1538 491 -504 1533 -998 1013 -516 1505 -522 1505 -1018 1005 -1002 1035 -494 1525 -1014 995 -1546 483 -524 1513 -1504 515 -1502 509 -1512 509 -514 1527 -514 1501 -60186 1539 -1506 509 -1008 1003 -1016 1009 -1520 515 -1014 989 -518 1509 -1544 485 -1016 999 -1016 1003 -1544 483 -1016 1017 -1506 515 -1534 475 -1036 987 -520 1507 -1012 1035 -1006 1017 -1502 503 -526 1503 -508 1533 -59160 523 -1508 507 -1502 537 -984 1013 -528 1505 -1504 503 -520 1537 -994 +RAW_Data: -1968 997 -4952 1011 -7896 1013 -1954 1005 -13860 985 -2000 979 -4952 1005 -4946 993 -7930 979 -1990 1009 -7908 1017 -1968 1011 -7900 985 -4946 1027 -4920 1009 -1964 1015 -4942 1009 -263646 67 -9708 99 -68890 97 -48712 65 -62028 65 -4652 65 -108870 99 -71758 99 -3200 97 -47548 65 -7036 65 -104448 97 -38184 99 -6502 97 -17756 65 -10136 20983 -1968 999 -4950 1005 -4940 1001 -7898 1025 -1966 1011 -7876 1017 -1966 1023 -7918 981 -4936 1027 -4946 975 -2006 979 -4946 1017 -4954 977 -7930 983 -1980 1003 -7920 989 -4952 1007 -1970 1013 -7896 1007 -1970 1015 -4954 987 -7900 1007 -1970 1007 -13860 993 -1972 1007 -4956 1013 -4926 1005 -7908 995 -1972 1029 -7914 987 -1986 1009 -7906 981 -4956 1009 -4930 1005 -1966 1039 -4938 1007 -4916 1009 -7918 1019 -1968 989 -7892 1017 -4934 1027 -1956 1039 -7898 985 -1974 1007 -4960 981 -7930 985 -1996 989 -13824 1045 -1946 1025 -4928 1009 -4942 997 -7926 1011 -1968 1003 -7894 1023 -1962 993 -7902 1017 -4948 999 -4948 1007 -1968 1015 -4918 1045 -4926 999 -7888 1039 -1972 1013 -7888 1005 -4948 1001 -1970 1011 -7886 1013 -1974 1023 -4942 1005 -7890 1033 -1952 1021 -13806 1047 -1964 1001 -4936 1009 -4950 1001 -7882 1031 -1962 1007 -7906 1021 -1966 1011 -7908 985 -4946 1027 -4918 1011 -1968 1017 -4948 1009 -4932 1015 -7882 1009 -1964 1013 -7900 1017 -4950 1001 -1970 1013 -7916 1013 -1944 1031 -4916 1029 -7888 1007 -1976 1005 -13848 1013 -1968 995 -4952 1003 -4946 991 -7920 1019 -1968 983 -7904 1015 -1966 1019 -7894 1011 -4942 1027 -4924 1011 -1966 1015 -4944 1005 -4926 1007 -7914 1007 -1972 1013 -7884 1013 -4940 1027 -1968 1007 -7906 1001 -1980 999 -4944 1013 -7880 1009 -2000 1003 -13830 997 -1974 1009 -4930 1029 -4938 1013 -7880 1011 -1998 1001 -7908 997 -1966 1025 -7902 1013 -4938 983 -4962 979 -1998 1011 -4932 1005 -4924 1011 -7922 1009 -1970 1015 -7890 1011 -4946 1003 -1970 1013 -7892 1013 -1964 1027 -4928 1021 -7886 1007 -1980 1001 -13846 1013 -1968 999 -4948 1009 -4938 993 -7926 1011 -1964 991 -7926 1011 -1962 993 -7898 1041 -4906 1009 -4960 999 -1964 1023 -4932 1007 -4928 1013 -7898 1015 -1968 1013 -7894 1017 -4948 997 -1968 1031 -7892 1027 -1970 1005 -4914 1039 -7884 1023 -1964 1011 -13838 1013 -1948 1023 -4924 1015 -4942 1025 -7872 1029 -1964 1007 -7898 1025 -1960 1025 -7898 1021 -4912 1023 -4920 1011 -1970 1013 -4954 1011 -4926 1003 -7910 1011 -1968 1013 -7890 1009 -4938 1023 -1982 1007 -7902 1013 -1940 1023 -4926 1011 -7922 1007 -1980 997 -13816 1045 -1964 1001 -4948 1005 -4938 993 -7904 1005 -1966 1035 -7888 1027 -1964 1011 -7906 1015 -4916 1027 -4920 1011 -1968 1019 -4944 1009 -4928 1001 -7924 1009 -1972 979 -7914 1013 -4948 1001 -1970 1013 -7892 1015 -1966 1027 -4928 1021 -7872 1035 -1968 1011 -13832 1011 -1980 983 -4956 987 -4948 1025 -7892 1005 -1966 1007 -7914 1021 -1962 1007 +RAW_Data: -7912 985 -4942 1023 -4926 1007 -1992 981 -4944 1035 -4920 1007 -7904 1025 -1962 991 -7934 981 -4948 995 -2004 1007 -7880 1007 -1992 983 -4946 1027 -7890 1007 -1982 999 -13830 1011 -1968 1025 -4926 1013 -4942 997 -7898 1027 -1960 1023 -7910 983 -2000 979 -7906 1015 -4940 1025 -4920 1011 -1968 1013 -225644 65 -2082 65 -155560 133 -5172 65 -1102 131 -48576 99 -24714 67 -6858 65 -1314 67 -38246 65 -64888 65 -4564 67 -59374 99 -20160 99 -17606 65 -42096 97 -11950 131 -29302 65 -19034 99 -32020 97 -366 65 -4430 131 -14620 99 -17318 65 -5556 +RAW_Data: 297 -1592 167 -1594 231 -366 65 -598 65 -600 197 -98 199 -1098 99 -98 65 -862 133 -628 165 -597 361 -6828 65 -1668 231 -632 65 -792 163 -1284 163 -5554 199 -1588 165 -5300 97 -992 65 -432 197 -2566 99 -2340 63 -5932 65 -1462 65 -1062 131 -2454 65 -1446 133 -1682 65 -1260 65 -368 131 -1482 65 -134 131 -1512 197 -1710 131 -824 99 -66 133 -464 131 -866 65 -698 65 -200 65 -894 99 -1692 233 -1130 97 -2160 265 -1392 99 -132 131 -166 65 -1318 327 -1548 163 -6980 165 -994 65 -698 131 -1580 129 -132 63 -758 97 -466 99 -1590 395 -1024 97 -600 99 -732 63 -228 129 -98 165 -292 99 -696 231 -232 197 -166 133 -132 131 -430 165 -664 199 -1596 197 -530 65 -1054 63 -3474 165 -4504 65 -2980 99 -268 133 -2356 131 -798 99 -132 99 -796 97 -1692 97 -3804 199 -166 67 -66 97 -132 99 -5058 129 -1512 163 -1290 65 -298 199 -398 65 -1034 65 -1332 167 -3448 65 -1750 65 -1186 131 -462 65 -920 65 -166 97 -362 131 -1704 131 -1748 65 -2124 65 -1064 133 -1694 197 -5148 99 -566 131 -1696 99 -598 65 -698 231 -692 267 -2490 99 -1618 165 -1760 197 -2152 165 -1226 195 -100 99 -66 131 -100 99 -400 65 -456 131 -198 165 -368 261 -826 365 -858 99 -132 163 -460 229 -264 65 -664 165 -234 231 -98 165 -100 99 -1986 99 -2526 65 -832 167 -1762 231 -728 67 -530 133 -2082 97 -960 67 -498 199 -1658 133 -1488 99 -2652 99 -1258 165 -5284 99 -1660 65 -1790 65 -432 65 -3804 197 -2170 131 -196 129 -66 97 -832 99 -2466 97 -1622 99 -1624 163 -394 163 -1018 133 -1856 99 -430 67 -826 197 -3156 65 -166 97 -558 65 -1690 131 -1498 99 -66 65 -2716 161 -658 99 -1054 65 -230 65 -2074 97 -2042 65 -3074 263 -1698 165 -492 65 -400 131 -196 131 -368 165 -134 203 -168 201 -134 165 -398 301 -628 99 -1032 99 -830 65 -66 65 -432 229 -230 161 -394 197 -228 197 -330 327 -66 197 -822 231 -392 131 -892 393 -1456 131 -64 163 -1418 65 -166 165 -1428 133 -1526 163 -954 65 -888 99 -1956 133 -1194 131 -3514 65 -1728 97 -662 67 -1590 167 -2714 65 -930 65 -166 65 -728 131 -2752 65 -434 133 -1828 99 -3704 129 -1912 133 -1544 227 -494 133 -202 97 -466 65 -200 131 -1580 263 -1708 65 -626 65 -626 199 -166 133 -3446 99 -3420 99 -398 131 -1164 131 -7018 131 -3468 63 -1658 199 -956 101 -598 99 -1790 97 -1192 65 -362 133 -630 65 -100 429 -794 65 -696 231 -1130 65 -268 395 -730 131 -466 431 -66 233 -168 197 -998 97 -264 65 -796 163 -236 +RAW_Data: 265 -100 133 -1464 99 -464 67 -592 229 -362 131 -262 163 -134 325 -164 163 -130 97 -164 65 -724 97 -132 97 -958 131 -594 131 -264 161 -98 229 -100 97 -890 131 -364 99 -198 97 -262 131 -234 2497 -134 65 -68 165 -400 563 -400 433 -496 99 -100 131 -266 99 -100 65 -200 231 -894 65 -166 463 -200 201 -1228 131 -266 65 -496 99 -300 97 -202 165 -896 365 -132 163 -1698 165 -132 99 -168 67 -166 67 -796 165 -400 131 -200 165 -796 165 -98 2161 -66 65 -166 293 -228 887 -66 395 -656 297 -100 97 -530 97 -66 97 -594 65 -428 97 -332 65 -400 131 -164 261 -66 299 -334 65 -596 97 -166 99 -1184 161 -460 131 -132 229 -398 299 -664 165 -722 165 -166 263 -300 99 -232 199 -266 267 -660 97 -758 133 -530 65 -632 99 -264 329 -1028 67 -166 2451 -562 427 -464 163 -198 229 -264 229 -790 295 -164 297 -132 263 -726 267 -66 99 -364 197 -564 99 -1162 67 -960 97 -198 163 -630 133 -66 163 -132 195 -1288 197 -430 197 -1546 65 -890 97 -394 231 -924 2173 -100 65 -594 165 -100 99 -528 99 -166 99 -298 497 -66 65 -100 131 -198 265 -362 131 -198 293 -294 129 -1150 263 -262 65 -100 131 -494 231 -166 231 -468 99 -66 165 -1262 197 -298 65 -298 397 -432 297 -498 361 -200 65 -466 131 -166 101 -496 231 -364 233 -64 197 -196 65 -426 265 -198 99 -1218 97 -200 67 -232 131 -200 167 -200 99 -66 165 -928 67 -1722 99 -764 65 -892 99 -232 133 -300 133 -1080 621 -1526 487 -1504 507 -506 1517 -1524 519 -1508 509 -1512 447 -546 1503 -1038 1035 -1482 547 -976 1007 -1208 823 -490 1503 -532 1481 -1048 989 -1534 499 -524 1507 -514 1499 -1014 1007 -524 1503 -1530 473 -60198 1533 -1516 481 -1040 985 -1044 981 -1554 479 -1530 479 -1044 1007 -1502 511 -1538 483 -516 1503 -1542 473 -1016 1033 -1510 483 -1542 505 -1002 1003 -508 1521 -1010 1015 -1512 507 -526 1515 -518 1505 -1016 1007 -59156 529 -1528 463 -1580 447 -542 1507 -1544 469 -1554 481 -1512 499 -518 1507 -1016 1007 -1512 511 -1012 1021 -1010 1007 -518 1529 -472 1555 -982 1023 -1502 505 -508 1537 -488 1545 -1012 1003 -480 1531 -1516 507 -60180 493 -12296 821 -1698 299 -1686 387 -590 1465 -1570 459 -1046 979 -1546 475 -1534 489 -1044 1009 -482 1529 -1032 973 -1538 513 -480 1537 -492 1523 -1012 1017 -59154 497 -11798 301 -704 1325 -1148 913 -1612 417 -1102 897 -1118 945 -586 1437 -568 1465 -1058 977 -1534 477 -550 1495 -502 1515 -1006 1037 -494 1527 -1510 489 -60174 531 -16794 355 -640 1399 -1608 449 -1050 989 -1540 461 -1546 477 -1068 973 -518 +RAW_Data: 1503 -1024 1009 -1536 473 -552 1503 -498 1517 -1010 1017 -59162 513 -9838 227 -1670 371 -604 1425 -1116 949 -1554 477 -1030 981 -1042 973 -550 1477 -532 1511 -1010 1003 -1544 511 -496 1515 -516 1509 -1018 1007 -488 1539 -1504 503 -60216 1525 -1530 485 -1018 999 -1012 1019 -1538 475 -1546 477 -1012 1025 -1506 517 -1530 505 -510 1507 -1512 513 -1010 999 -1516 507 -1520 513 -1012 1015 -506 1527 -1014 991 -1542 483 -524 1517 -482 1529 -1008 1005 -137640 165 -1660 165 -1362 231 -3114 67 -2286 131 -1652 197 -1448 195 -1648 97 -3534 163 -988 65 -556 65 -132 133 -2594 199 -2054 65 -1918 65 -1458 163 -690 65 -1134 131 -1194 67 -1158 131 -1656 199 -198 99 -298 199 -2676 67 -2122 231 -1762 263 -1560 131 -1228 99 -198 197 -830 99 -166 97 -6274 99 -1058 163 -1676 97 -1788 65 -5742 99 -3890 131 -2682 195 -166 65 -1394 265 -432 99 -368 99 -100 67 -198 163 -564 133 -992 131 -266 133 -962 233 -200 131 -196 231 -560 131 -66 65 -764 131 -1058 133 -564 99 -1792 133 -2820 65 -3480 165 -9536 99 -66 97 -626 97 -1828 199 -1860 99 -66 197 -1060 99 -1746 65 -1690 99 -198 99 -1660 165 -1764 65 -1558 199 -1456 99 -164 65 -1318 395 -5966 131 -928 165 -1026 99 -534 65 -434 99 -100 97 -100 97 -3272 65 -2168 131 -2904 231 -1564 67 -958 263 -3780 65 -166 99 -3506 99 -1594 165 -1492 197 -164 63 -1382 197 -1162 65 -364 133 -822 65 -498 495 -230 165 -366 65 -464 231 -666 231 -198 65 -332 163 -566 65 -164 67 -332 231 -232 265 -198 97 -1254 361 -200 65 -2056 129 -430 131 -100 65 -1588 263 -198 97 -2992 97 -528 297 -134 97 -368 427 -66 67 -132 65 -132 367 -330 65 -266 229 -66 65 -66 65 -198 231 -66 133 -528 363 -162 161 -230 525 -230 65 -230 461 -132 327 -330 295 -130 197 -230 165 -270 265 -464 65 -698 265 -264 229 -400 99 -3476 97 -1490 199 -134 99 -2970 165 -1618 167 -1598 65 -1162 99 -234 167 -1162 135 -464 65 -664 165 -1126 197 -362 97 -1222 65 -3496 65 -7024 131 -1592 131 -530 97 -6464 231 -998 263 -428 65 -698 131 -198 131 -1414 63 -1346 165 -1060 65 -1664 167 -566 263 -666 165 -566 331 -100 131 -1522 167 -368 199 -896 229 -232 99 -968 99 -168 231 -66 197 -68 131 -168 133 -400 131 -268 233 -596 233 -132 97 -494 131 -1710 197 -1616 67 -592 99 -1226 267 -268 65 -266 133 -1986 165 -332 99 -366 131 -2700 97 -1398 65 -130 269 -198 65 -1664 131 -3180 165 -992 65 -866 99 -166 163 -2782 65 -2354 265 -5176 65 -66 163 -1290 67 -164 99 -2584 67 -3084 +RAW_Data: 195 -364 65 -164 229 -958 63 -166 193 -130 65 -556 99 -332 199 -430 197 -996 297 -1426 235 -1160 2053 -166 1063 -100 501 -132 535 -198 67 -66 165 -98 165 -460 365 -366 97 -432 329 -264 133 -100 165 -328 197 -360 1087 -264 97 -166 63 -166 233 -98 195 -294 97 -264 163 -266 197 -100 359 -66 65 -1958 165 -694 99 -166 99 -596 299 -466 97 -66 99 -696 231 -1492 297 -1554 165 -1680 165 -368 99 -166 99 -168 65 -794 197 -194 2581 -98 1151 -592 99 -426 197 -328 295 -164 65 -232 163 -530 165 -264 129 -98 229 -294 493 -426 99 -66 163 -164 261 -264 129 -166 229 -68 65 -558 131 -132 65 -132 197 -1550 361 -98 67 -132 99 -132 131 -786 99 -198 301 -366 165 -530 99 -234 2159 -264 1691 -166 367 -132 231 -100 197 -166 97 -366 163 -68 131 -366 165 -268 133 -430 233 -100 133 -132 199 -932 561 -1416 231 -794 199 -1296 165 -564 165 -666 99 -490 97 -760 163 -1582 295 -464 267 -330 2561 -134 931 -66 65 -132 99 -264 63 -132 99 -198 97 -364 129 -460 65 -230 263 -164 163 -100 365 -100 131 -398 97 -530 65 -266 299 -1028 133 -100 97 -166 65 -296 65 -166 133 -498 331 -962 99 -98 199 -1328 165 -200 65 -234 99 -400 231 -632 65 -232 199 -530 65 -866 429 -958 197 -368 165 -668 65 -984 163 -100 129 -1088 259 -752 97 -522 131 -892 65 -298 67 -364 199 -132 65 -788 97 -396 363 -1052 99 -228 131 -98 99 -1526 463 -330 131 -898 263 -332 97 -996 163 -494 99 -2950 65 -798 131 -2490 165 -1424 65 -1694 65 -1822 65 -1756 67 -3820 65 -2536 97 -2410 65 -1030 131 -404 263 -732 165 -1566 197 -1554 199 -400 65 -100 99 -566 165 -3584 65 -764 101 -2630 65 -2896 163 -364 67 -100 65 -1228 263 -232 63 -884 65 -4092 133 -1622 325 -166 99 -2352 65 -500 65 -1324 99 -366 65 -1592 297 -5134 131 -1130 65 -1962 99 -66 99 -1454 67 -1130 99 -134 199 -134 165 -1222 229 -166 131 -464 197 -196 263 -234 99 -534 65 -132 131 -166 133 -134 199 -1590 231 -66 131 -1160 131 -300 65 -698 199 -462 133 -3446 99 -2876 65 -596 65 -1716 133 -2886 97 -134 199 -1628 131 -1790 67 -2556 615 -1510 453 -1584 443 -1566 485 -1014 977 -1054 1003 -516 1501 -1010 1007 -520 1495 -1034 1005 -1530 481 -514 1541 -492 1523 -1012 1001 -1508 521 -1016 999 -512 1527 -1506 509 -488 1521 -1040 989 -1538 473 -60194 1519 -1540 511 -1010 1001 -1020 1009 -1516 515 -1010 1001 -518 1507 -524 1503 -1534 493 -1510 501 -1022 1011 -516 1507 -522 1507 -1512 509 -1506 519 -516 +RAW_Data: -130 1115 -68 55471 -1962 167 -1664 99 -364 427 -232 759 -132 199 -100 267 -134 527 -132 99 -1292 99 -266 65 -68 131 -762 327 -98 393 -298 37611 -730 131 -428 1487 -3910 327 -100 295 -98 491 -492 65 -98 197 -860 97 -98 131 -856 131 -134 231 -792 229 -66 919 -198 7527 -7444 131 -722 97 -230 65 -98 527 -100 267 -68 229 -262 361 -528 195 -624 131 -164 495 -66 1697 -66 1791 -132 3715 -8320 65 -394 165 -166 461 -1094 297 -532 131 -764 197 -98 261 -230 165 -100 6235 -12144 265 -600 131 -134 65 -298 233 -958 163 -196 97 -756 263 -98 465 -134 97 -164 3051 -16552 431 -68 131 -166 131 -264 331 -298 561 -166 689 -66 557 -264 3173 -8316 65 -166 531 -298 197 -234 233 -134 233 -892 163 -296 65 -890 161 -232 331 -100 397 -15072 199 -100 99 -394 165 -164 129 -132 197 -132 199 -798 99 -1032 67 -398 427 -100 391 -98 363 -166 297 -66 2869 -66 2299 -12300 97 -660 99 -662 263 -594 131 -662 133 -66 199 -332 97 -134 99 -132 65 -134 131 -100 431 -100 2143 -66 429 -8840 97 -6976 97 -66 397 -66 65 -166 131 -230 131 -294 99 -228 97 -230 129 -756 133 -1298 1293 -132 529 -100 2567 -15654 229 -328 97 -198 131 -66 195 -1492 131 -398 99 -134 99 -366 265 -168 99 -100 235 -100 131 -396 299 -200 1029 -66 6461 -6804 99 -1062 65 -960 65 -232 131 -98 195 -1708 63 -196 261 -164 331 -66 261 -12094 65 -298 265 -198 163 -592 131 -2402 63 -66 297 -198 97 -66 393 -264 4003 -15878 231 -98 261 -496 229 -264 65 -858 131 -994 133 -66 331 -66 429 -100 165 -132 297 -15004 99 -1466 97 -266 165 -198 463 -796 231 -66 131 -298 99 -100 133 -134 167 -430 99 -66 365 -100 297 -134 265 -132 563 -98 1217 -66 6399 -8742 99 -592 99 -426 397 -2338 199 -66 995 -134 229 -132 65 -164 3989 -66 3675 -6962 165 -466 65 -564 399 -66 199 -134 263 -396 97 -132 97 -100 97 -428 393 -624 131 -988 229 -66 363 -230 791 -164 7883 -8286 165 -134 99 -66 197 -100 99 -68 131 -164 163 -398 197 -2162 2005 -66 97 -100 4365 -98 1255 -12012 99 -132 165 -462 65 -166 97 -564 65 -100 331 -794 199 -364 261 -496 331 -132 823 -66 6233 -10976 165 -764 165 -200 195 -296 97 -19176 195 -230 129 -658 131 -132 293 -66 133 -860 65 -858 131 -64 229 -66 227 -66 161 -66 9051 -7316 65 -1494 131 -98 165 -198 65 -134 365 -398 297 -100 3969 -14874 99 -998 65 -564 67 -364 263 -132 163 -528 197 -132 65 -264 65 -264 431 -100 301 -66 297 +RAW_Data: -164 6323 -10770 65 -1420 227 -196 263 -198 197 -1086 99 -98 163 -164 163 -426 65 -362 97 -264 295 -132 197 -13586 65 -1808 131 -166 301 -66 465 -432 165 -330 65 -332 297 -962 99 -266 97 -166 265 -132 327 -198 329 -98 293 -14984 99 -862 131 -166 331 -68 165 -98 233 -132 201 -300 197 -364 133 -662 99 -398 99 -166 65 -432 133 -132 1447 -5882 197 -1082 65 -198 163 -1580 129 -264 67 -632 625 -134 165 -68 827 -100 165 -100 99 -164 3949 -9126 67 -164 131 -986 241 -534 309 -208 267 -226 247 -250 247 -248 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 247 -250 249 -504 257 -248 245 -246 247 -248 501 -258 247 -246 245 -248 247 -248 249 -248 249 -504 513 -226 243 -274 243 -500 513 -238 253 -256 253 -492 231 -262 485 -514 223 -244 527 -478 507 -274 255 -218 253 -498 261 -224 251 -250 503 -258 247 -246 243 -246 247 -504 515 -238 251 -472 277 -242 497 -246 289 -220 247 -498 513 -476 255 -68610 311 -208 235 -256 249 -248 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 247 -248 503 -514 479 -274 253 -256 217 -254 247 -236 255 -250 247 -502 513 -240 251 -256 253 -254 249 -240 227 -252 249 -502 259 -246 245 -246 501 -514 237 -254 473 -280 253 -250 239 -230 251 -250 247 -504 257 -246 501 -226 245 -276 245 -246 245 -248 247 -504 515 -478 255 -244 495 -274 253 -476 511 -240 241 -69142 321 -218 243 -230 251 -248 247 -248 247 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -506 257 -248 243 -246 247 -248 501 -258 247 -246 245 -246 247 -248 249 -248 249 -504 513 -238 251 -254 255 -490 499 -228 253 -250 249 -506 259 -248 499 -478 257 -244 495 -510 509 -238 255 -254 253 -494 227 -254 249 -248 505 -258 247 -246 245 -248 247 -504 513 -238 253 -472 279 -254 491 -226 253 -250 249 -504 513 -478 257 -68880 315 -216 241 -258 249 -248 247 -248 247 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 249 -504 257 -246 245 -246 247 -248 503 -516 477 -274 253 -256 217 -254 247 -236 255 -250 249 -502 481 -272 253 -254 255 -254 249 -238 227 -250 249 -504 257 -248 243 -246 501 -516 237 -254 473 -280 253 -250 239 -230 251 -250 247 -504 257 -248 499 -228 245 -274 245 -246 245 -248 247 +RAW_Data: -504 513 -478 257 -244 495 -274 253 -500 483 -232 265 -69136 287 -256 249 -238 227 -250 249 -248 249 -248 249 -248 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -260 245 -246 245 -246 247 -248 249 -250 247 -504 513 -238 251 -256 253 -496 499 -228 249 -250 249 -504 257 -248 499 -478 257 -244 495 -510 509 -238 255 -254 255 -492 227 -256 249 -248 505 -258 247 -246 245 -248 245 -504 513 -238 253 -472 279 -254 491 -228 253 -250 249 -504 513 -478 257 -68886 309 -208 235 -256 249 -248 249 -248 249 -248 249 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 249 -504 257 -248 245 -246 245 -248 503 -514 477 -274 253 -254 217 -256 247 -238 255 -250 247 -504 513 -238 251 -256 253 -256 249 -240 227 -252 249 -504 257 -248 243 -246 501 -514 237 -252 473 -280 253 -250 241 -228 253 -248 249 -504 257 -246 499 -226 245 -276 245 -246 245 -248 247 -506 511 -478 257 -244 495 -272 255 -474 511 -240 241 -69150 323 -220 251 -242 229 -252 247 -248 247 -248 249 -248 249 -248 249 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -248 249 -250 249 -504 257 -248 243 -248 247 -248 503 -258 245 -246 245 -248 245 -250 247 -250 247 -504 515 -236 253 -254 253 -496 499 -228 251 -250 247 -504 257 -248 499 -478 257 -244 495 -510 509 -240 253 -256 253 -492 229 -254 249 -250 505 -258 247 -246 245 -246 247 -504 513 -238 253 -472 247 -272 501 -246 253 -254 243 -494 513 -476 255 -68934 287 -254 213 -240 257 -250 249 -248 247 -250 247 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -248 249 -250 247 -250 249 -250 247 -506 257 -248 245 -246 245 -248 503 -516 479 -272 255 -254 217 -256 245 -236 255 -250 247 -504 513 -238 253 -254 253 -256 249 -238 229 -252 249 -504 257 -246 245 -246 501 -514 237 -254 473 -280 253 -250 239 -230 251 -250 247 -504 257 -248 499 -226 245 -276 245 -246 245 -248 247 -504 511 -478 255 -244 495 -256 243 -496 509 -274 253 -69130 309 -218 253 -256 249 -240 227 -252 249 -250 247 -248 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 247 -250 249 -250 249 -504 259 -246 245 -246 247 -248 501 -258 247 -244 245 -248 247 -248 247 -250 249 -504 511 -226 245 -276 243 -500 477 -272 253 -254 255 -494 231 -262 481 -514 225 -246 527 -478 507 -256 241 -244 243 -494 257 -244 243 +RAW_Data: -246 527 -228 243 -276 245 -246 245 -500 513 -238 253 -474 279 -254 489 -228 251 -250 249 -506 513 -478 255 -68936 287 -218 249 -236 255 -248 247 -248 247 -248 249 -248 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -506 257 -246 245 -246 245 -248 503 -514 477 -272 255 -254 255 -218 247 -240 255 -250 247 -502 511 -226 273 -244 243 -244 247 -246 247 -250 247 -506 259 -246 245 -246 501 -512 225 -244 527 -238 251 -256 253 -254 251 -242 227 -508 257 -216 527 -226 275 -244 243 -246 245 -248 247 -504 513 -478 257 -242 527 -238 255 -472 511 -242 281 -119614 299 -200 65 -470 65 -466 297 -630 97 -1592 133 -166 299 -66 231 -100 131 -98 265 -134 165 -166 433 -100 2287 -9916 231 -166 65 -98 199 -166 133 -166 165 -756 65 -724 195 -428 231 -260 263 -98 229 -130 261 -66 163 -264 65 -132 1181 -66 6315 -6798 131 -296 559 -334 131 -166 233 -132 165 -66 133 -264 99 -66 65 -366 99 -630 301 -166 97 -100 167 -164 535 -202 7269 -8266 197 -1022 131 -756 99 -98 99 -164 163 -990 65 -530 163 -230 297 -136 635 -66 2113 -8426 67 -6674 97 -722 197 -362 263 -232 165 -134 99 -234 297 -362 129 -198 131 -556 297 -68 167 -98 331 -200 165 -66 295 -66 8689 -4994 65 -1750 165 -762 163 -864 135 -100 167 -694 1093 -66 695 -102 99 -100 9899 -1650 297 -1216 97 -66 99 -396 65 -198 165 -164 233 -1658 199 -98 465 -134 463 -166 1883 -98 6283 -7302 99 -932 133 -696 263 -298 97 -98 165 -1708 131 -820 229 -98 231 -130 163 -590 131 -130 99 -66 97 -16220 261 -1062 265 -998 197 -1290 97 -362 165 -494 895 -264 7839 -7804 99 -66 99 -364 231 -630 133 -166 427 -496 131 -1252 263 -100 233 -66 133 -132 165 -66 259 -98 3109 -10438 101 -5322 99 -100 65 -666 65 -166 331 -98 197 -132 233 -662 261 -1516 559 -66 263 -130 689 -132 229 -64 3613 -15976 231 -166 133 -66 399 -264 99 -132 295 -366 97 -1692 99 -398 529 -68 397 -130 899 -164 3559 -98 1197 -12106 199 -98 65 -166 99 -266 99 -134 231 -100 133 -132 297 -430 99 -1394 299 -64 397 -166 99 -100 465 -200 331 -132 599 -100 2333 -15214 65 -1230 231 -266 265 -432 165 -398 65 -532 333 -632 65 -232 957 -98 9785 -6320 97 -830 167 -166 133 -732 299 -958 327 -98 197 -66 229 -164 327 -98 653 -66 7993 -6418 65 -1284 97 -458 129 -196 197 -166 393 -134 99 -332 427 -132 131 -66 133 -98 233 -66 133 -364 163 -566 4873 -16030 97 +RAW_Data: -360 65 -364 65 -68 857 -98 65 -232 131 -264 63 -98 391 -396 65 -130 99 -98 65 -66 861 -166 265 -166 7611 -10336 65 -1822 165 -300 165 -166 295 -134 199 -100 67 -264 165 -166 99 -500 99 -198 97 -200 165 -268 197 -130 65 -300 629 -166 561 -132 333 -132 7459 -6294 131 -1096 165 -964 197 -332 65 -166 129 -132 99 -130 99 -100 97 -134 65 -164 131 -494 165 -396 97 -164 131 -198 99 -232 229 -66 821 -64 131 -14954 97 -788 65 -100 263 -66 99 -300 65 -400 131 -198 293 -294 163 -132 65 -692 99 -132 131 -200 1847 -132 8773 -5968 133 -330 65 -66 295 -430 197 -166 565 -132 467 -98 65 -430 165 -262 131 -528 131 -296 131 -100 131 -66 557 -166 787 -98 3221 -16236 299 -166 133 -562 199 -1692 99 -66 65 -364 65 -366 231 -168 367 -100 5541 -14968 297 -164 97 -132 163 -328 99 -532 99 -134 131 -370 397 -66 397 -98 293 -98 197 -98 1151 -66 7019 -6746 129 -296 163 -954 261 -230 229 -64 231 -264 431 -100 99 -466 165 -100 333 -166 133 -666 695 -200 67 -134 397 -100 1667 -7686 97 -426 195 -266 97 -330 63 -98 99 -594 97 -132 133 -270 131 -600 131 -362 833 -98 297 -166 199 -66 99 -200 65 -66 197 -100 2963 -98 1125 -2238 199 -554 275 -242 273 -212 271 -242 241 -242 271 -244 241 -244 273 -244 245 -246 247 -248 247 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -246 247 -248 249 -250 247 -504 513 -228 243 -244 273 -246 245 -500 513 -478 257 -242 241 -244 273 -244 499 -512 225 -244 525 -228 273 -496 475 -508 507 -240 253 -254 255 -494 261 -222 505 -258 245 -246 245 -246 245 -250 247 -506 513 -478 257 -242 241 -244 273 -244 499 -68858 319 -218 245 -230 251 -248 245 -248 247 -250 247 -250 249 -248 249 -248 249 -250 249 -250 249 -248 249 -248 249 -250 249 -248 249 -250 247 -506 257 -246 245 -246 247 -248 503 -516 477 -274 253 -474 511 -478 527 -484 511 -240 253 -472 281 -254 489 -484 513 -478 513 -480 255 -242 523 -472 507 -276 253 -462 275 -240 491 -258 247 -244 245 -246 247 -502 515 -238 253 -254 253 -492 497 -230 253 -250 247 -250 247 -250 247 -250 247 -506 257 -68880 279 -248 241 -266 223 -252 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -506 225 -280 213 -278 245 -248 503 -260 215 -276 245 -246 247 -248 247 -250 247 -504 481 -272 251 +RAW_Data: -254 255 -254 213 -506 483 -514 271 -254 217 -292 217 -248 497 -516 237 -254 473 -278 251 -488 489 -516 477 -272 253 -254 219 -494 261 -260 481 -260 215 -278 247 -248 247 -248 247 -504 481 -514 235 -290 217 -256 253 -244 497 -69132 311 -212 235 -258 249 -248 247 -248 249 -248 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -506 257 -248 245 -246 245 -248 503 -512 479 -272 253 -474 513 -478 527 -482 513 -238 253 -472 281 -254 487 -486 515 -478 509 -480 255 -242 529 -480 509 -240 255 -496 271 -234 487 -260 247 -244 245 -248 247 -504 511 -226 243 -244 275 -498 479 -272 253 -254 255 -254 249 -238 225 -252 247 -504 257 -68882 319 -188 265 -280 235 -228 251 -250 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 245 -250 247 -250 249 -504 515 -238 251 -256 253 -256 249 -472 515 -480 271 -256 253 -218 255 -248 497 -482 271 -252 473 -280 253 -490 487 -516 477 -274 253 -256 217 -496 261 -224 507 -258 249 -246 245 -248 247 -248 249 -504 511 -478 255 -244 243 -244 275 -246 499 -69134 311 -208 231 -254 249 -246 247 -250 247 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -248 249 -506 259 -246 245 -246 247 -246 503 -516 479 -274 253 -464 519 -496 487 -516 477 -274 255 -498 249 -248 469 -514 479 -516 483 -488 277 -254 491 -498 487 -260 247 -498 227 -244 529 -228 243 -274 245 -246 245 -502 515 -238 251 -256 253 -496 497 -226 251 -248 249 -248 249 -248 249 -250 249 -504 257 -68898 247 -274 213 -312 185 -312 185 -312 185 -312 185 -312 185 -312 185 -310 185 -310 185 -310 215 -278 217 -278 215 -278 217 -278 217 -280 215 -532 237 -288 217 -290 215 -276 461 -260 219 -280 217 -280 217 -278 215 -280 247 -506 481 -270 251 -256 217 -290 213 -502 483 -514 271 -254 253 -218 255 -246 499 -482 271 -254 473 -282 253 -488 485 -516 477 -274 253 -256 217 -496 263 -224 507 -260 247 -246 245 -246 247 -248 249 -504 513 -478 255 -242 243 -244 275 -246 499 -69122 319 -220 243 -228 251 -248 247 -248 247 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -504 257 -248 245 -246 247 -246 505 -514 479 -274 253 -476 511 -476 493 -516 481 -270 253 -474 279 -254 487 -484 513 +RAW_Data: -478 507 -506 225 -272 495 -482 505 -254 241 -494 255 -242 525 -226 241 -274 243 -242 243 -496 509 -274 253 -254 219 -494 491 -258 249 -248 247 -248 249 -248 249 -248 249 -504 257 -68896 281 -214 241 -260 247 -248 247 -248 247 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -260 245 -246 245 -248 247 -248 247 -248 249 -504 513 -238 251 -254 255 -254 251 -474 515 -478 273 -254 255 -218 253 -248 499 -514 237 -254 473 -280 253 -490 485 -516 479 -274 253 -256 217 -496 263 -224 507 -258 247 -248 245 -246 247 -250 247 -504 513 -478 257 -244 241 -244 275 -246 499 -69128 321 -218 241 -230 249 -248 247 -246 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -504 257 -248 245 -246 245 -250 503 -514 477 -272 255 -474 515 -480 491 -518 479 -274 253 -474 281 -254 483 -486 479 -512 507 -506 223 -242 527 -482 509 -240 253 -496 273 -236 487 -260 247 -246 245 -246 247 -504 513 -238 251 -256 253 -492 495 -228 253 -250 249 -250 249 -250 249 -248 249 -504 257 -68860 273 -242 233 -256 249 -250 247 -248 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 247 -248 247 -248 249 -504 513 -238 253 -254 253 -256 249 -474 515 -480 273 -254 255 -218 253 -248 497 -516 237 -252 473 -280 253 -490 487 -514 479 -274 253 -254 219 -496 263 -224 507 -258 247 -246 245 -246 247 -248 249 -504 513 -476 257 -242 243 -244 273 -246 499 -68728 129 -604 249 -242 243 -276 213 -276 245 -244 245 -246 245 -278 215 -278 215 -278 247 -248 247 -248 247 -248 249 -248 247 -250 247 -250 247 -250 247 -504 259 -246 245 -246 247 -248 503 -514 477 -272 255 -474 511 -478 527 -484 481 -272 253 -472 281 -254 485 -486 511 -478 511 -480 255 -242 527 -482 505 -254 241 -494 253 -242 495 -254 241 -244 273 -244 243 -494 509 -238 255 -254 255 -492 489 -260 247 -248 245 -248 247 -248 249 -248 249 -504 257 -129658 99 -98 131 -132 97 -100 97 -132 131 -98 131 -496 297 -266 163 -198 99 -398 165 -626 133 -198 531 -166 67 -66 431 -132 331 -100 65 -132 99 -100 2725 -9960 65 -3686 295 -1552 99 -362 195 -100 887 -98 263 -100 1495 -8372 67 -298 99 -100 131 -332 133 -198 233 -398 65 -1060 99 -164 327 \ No newline at end of file From dfdc33b0768db3bdd65bcc16a31a2d020fb8694c Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Tue, 10 May 2022 22:11:16 +0400 Subject: [PATCH 15/24] SubGhz: add protocol Holtek (#1214) * SubGhz: add protocol Holtek * SubGhz: add unit_test Holtek --- applications/unit_tests/subghz/subghz_test.c | 18 +- assets/unit_tests/subghz/holtek.sub | 7 + assets/unit_tests/subghz/holtek_raw.sub | 19 + assets/unit_tests/subghz/test_random_raw.sub | 16 +- lib/subghz/protocols/holtek.c | 360 +++++++++++++++++++ lib/subghz/protocols/holtek.h | 109 ++++++ lib/subghz/protocols/registry.c | 2 +- lib/subghz/protocols/registry.h | 1 + 8 files changed, 529 insertions(+), 3 deletions(-) create mode 100644 assets/unit_tests/subghz/holtek.sub create mode 100644 assets/unit_tests/subghz/holtek_raw.sub create mode 100644 lib/subghz/protocols/holtek.c create mode 100644 lib/subghz/protocols/holtek.h diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index 51699a81e94..3a65429a52f 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -13,7 +13,7 @@ #define CAME_ATOMO_DIR_NAME "/ext/subghz/assets/came_atomo" #define NICE_FLOR_S_DIR_NAME "/ext/subghz/assets/nice_flor_s" #define TEST_RANDOM_DIR_NAME "/ext/unit_tests/subghz/test_random_raw.sub" -#define TEST_RANDOM_COUNT_PARSE 109 +#define TEST_RANDOM_COUNT_PARSE 116 #define TEST_TIMEOUT 10000 static SubGhzEnvironment* environment_handler; @@ -206,6 +206,7 @@ MU_TEST(subghz_keystore_test) { "Test keystore error"); } +//test decoders MU_TEST(subghz_decoder_came_atomo_test) { mu_assert( subghz_decoder_test( @@ -354,6 +355,13 @@ MU_TEST(subghz_decoder_secplus_v2_test) { "Test decoder " SUBGHZ_PROTOCOL_SECPLUS_V2_NAME " error\r\n"); } +MU_TEST(subghz_decoder_holtek_test) { + mu_assert( + subghz_decoder_test("/ext/unit_tests/subghz/holtek_raw.sub", SUBGHZ_PROTOCOL_HOLTEK_NAME), + "Test decoder " SUBGHZ_PROTOCOL_HOLTEK_NAME " error\r\n"); +} + +//test encoders MU_TEST(subghz_encoder_princeton_test) { mu_assert( subghz_encoder_test("/ext/unit_tests/subghz/princeton.sub"), @@ -402,6 +410,12 @@ MU_TEST(subghz_encoder_megacode_test) { "Test encoder " SUBGHZ_PROTOCOL_MEGACODE_NAME " error\r\n"); } +MU_TEST(subghz_encoder_holtek_test) { + mu_assert( + subghz_encoder_test("/ext/unit_tests/subghz/holtek.sub"), + "Test encoder " SUBGHZ_PROTOCOL_HOLTEK_NAME " error\r\n"); +} + MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } @@ -432,6 +446,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_megacode_test); MU_RUN_TEST(subghz_decoder_secplus_v1_test); MU_RUN_TEST(subghz_decoder_secplus_v2_test); + MU_RUN_TEST(subghz_decoder_holtek_test); MU_RUN_TEST(subghz_encoder_princeton_test); MU_RUN_TEST(subghz_encoder_came_test); @@ -441,6 +456,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_keelog_test); MU_RUN_TEST(subghz_encoder_firefly_test); MU_RUN_TEST(subghz_encoder_megacode_test); + MU_RUN_TEST(subghz_encoder_holtek_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); diff --git a/assets/unit_tests/subghz/holtek.sub b/assets/unit_tests/subghz/holtek.sub new file mode 100644 index 00000000000..b77a759d2ee --- /dev/null +++ b/assets/unit_tests/subghz/holtek.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 418000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Holtek +Bit: 40 +Key: 00 00 00 50 00 00 AA BA diff --git a/assets/unit_tests/subghz/holtek_raw.sub b/assets/unit_tests/subghz/holtek_raw.sub new file mode 100644 index 00000000000..8eac0a398d1 --- /dev/null +++ b/assets/unit_tests/subghz/holtek_raw.sub @@ -0,0 +1,19 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 418000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 2243 -98 331 -100 1129 -66 761 -100 1393 -100 165 -66 2883 -64 357 -66 4703 -68 927 -98 233 -134 461 -66 3855 -134 165 -98 1281 -100 2053 -66 3061 -98 331 -98 8981 -66 365 -66 631 -100 1027 -100 4521 -134 597 -66 3187 -66 2619 -100 3011 -98 1151 -66 953 -100 1423 -66 1755 -166 333 -98 1557 -66 761 -66 865 -66 4837 -132 357 -132 2419 -100 1023 -66 65 -66 2507 -66 131 -66 761 -66 997 -66 333 -100 2259 -68 431 -100 2523 -66 987 -100 363 -66 363 -66 1197 -68 1589 -164 951 -96 5351 -66 697 -100 163 -100 4683 -66 2265 -68 2051 -64 457 -64 3005 -132 1057 -66 2221 -100 1661 -98 695 -100 99 -66 861 -66 1957 -100 731 -132 1857 -100 3177 -98 1807 -98 463 -66 499 -134 1129 -100 3737 -100 1889 -66 263 -98 623 -66 2103 -98 3165 -66 131 -100 195 -66 691 -66 67 -132 531 -66 1857 -100 199 -68 97 -68 197 -68 697 -68 233 -100 3749 -134 1691 -68 3289 -66 3751 -68 65 -100 853 -66 531 -132 1299 -66 1585 -98 65 -98 1577 -66 785 -98 1151 -66 165 -68 397 -100 4255 -100 857 -100 1017 -66 1575 -130 1255 -234 1923 -66 199 -102 301 -66 231 -66 691 -64 227 -64 195 -66 1257 -100 2353 -100 235 -100 1163 -66 5423 -66 2049 -66 1807 -66 523 -198 693 -100 367 -100 597 -100 4013 -100 233 -166 365 -66 1827 -100 1491 -100 785 -64 885 -66 599 -134 2847 -100 667 -100 4943 -98 3319 -98 6729 -98 361 -96 391 -66 723 -132 503 -66 1583 -166 297 -234 2045 -66 1185 -134 661 -66 195 -66 291 -164 523 -98 1679 -134 233 -132 761 -394 855 -100 2003 -164 261 -66 229 -96 953 -66 3889 -66 929 -66 993 -68 3099 -132 1673 -66 1833 -100 563 -100 1131 -100 3219 -232 4411 -100 1095 -100 5315 -100 631 -198 461 -198 1907 -100 1743 -68 863 -132 4013 -64 295 -66 3883 -100 2707 -198 923 -100 2539 -166 629 -100 563 -100 3783 -68 893 -66 2987 -98 2357 -98 1665 -66 599 -66 1259 -232 165 -66 1361 -66 1645 -166 1543 -66 565 -66 401 -134 465 -100 831 -98 2405 -100 1055 -66 2109 -100 1161 -68 431 -100 265 -68 235 -66 463 -66 3453 -100 433 -66 2693 -132 263 -166 729 -134 763 -134 1327 -100 397 -234 795 -68 563 -66 1625 -98 267 -66 4835 -66 197 -66 589 -66 7575 -100 1959 -100 131 -68 297 -134 261 -98 433 -66 1427 -66 2421 -100 2925 -166 1921 -134 1645 -66 97 -132 5423 -100 2423 -98 1065 -66 1715 -132 963 -66 2403 -66 1117 -328 1981 -66 527 -100 427 -164 865 -66 2129 -232 165 -68 165 -66 131 -366 131 -100 2613 -450 +RAW_Data: 937 -900 447 -454 969 -884 479 -466 939 -452 935 -454 981 -454 943 -452 955 -458 945 -452 979 -444 943 -486 945 -448 951 -464 977 -440 967 -478 935 -480 951 -456 969 -460 975 -450 973 -450 979 -470 977 -450 981 -910 485 -466 939 -928 489 -448 971 -940 445 -484 951 -928 485 -484 945 -948 479 -456 973 -918 481 -944 451 -928 471 -478 995 -912 487 -472 977 -15948 479 -444 1021 -910 521 -444 995 -942 471 -480 991 -450 1013 -452 1023 -446 1001 -484 981 -486 1007 -458 1015 -470 1007 -450 1033 -452 1005 -480 1005 -458 1013 -470 1007 -482 1015 -450 1023 -482 1009 -462 1015 -468 1011 -484 983 -482 1021 -944 487 -484 1015 -942 471 -486 1003 -948 503 -478 991 -948 501 -478 1031 -914 521 -486 991 -946 519 -916 511 -944 485 -474 1009 -974 487 -482 1015 -16224 521 -468 1005 -970 503 -478 1001 -954 505 -458 1035 -484 1019 -482 1039 -482 1019 -486 1031 -490 1009 -478 1033 -486 1033 -486 1011 -494 1039 -478 1039 -450 1049 -486 1033 -488 1005 -476 1071 -448 1067 -486 1017 -468 1045 -482 1045 -484 1015 -952 515 -482 1043 -944 519 -482 1049 -950 519 -454 1039 -956 523 -484 1011 -960 505 -486 1065 -956 509 -926 539 -944 519 -480 1017 -984 521 -454 1037 -16440 553 -440 1043 -976 507 -460 1069 -940 513 -486 1041 -480 1067 -482 1033 -476 1061 -472 1043 -510 1049 -486 1041 -482 1043 -482 1065 -476 1037 -486 1069 -492 1037 -484 1047 -504 1047 -486 1041 -484 1041 -514 1015 -520 1049 -476 1053 -490 1041 -980 519 -486 1043 -962 507 -482 1049 -994 507 -500 1043 -946 507 -516 1033 -982 517 -478 1049 -984 509 -976 505 -950 527 -490 1039 -980 519 -486 1047 -111258 195 -428 263 -162 163 -362 97 -132 65 -98 163 -132 825 -100 795 -100 1795 -134 587 -66 229 -100 1349 -164 3261 -66 2305 -132 2219 -66 5549 -234 497 -132 201 -66 667 -298 2369 -68 4381 -66 3909 -134 923 -98 723 -100 1651 -168 1197 -100 65 -66 199 -68 195 -100 197 -134 1135 -66 2787 -66 3163 -68 231 -68 197 -100 6675 -100 667 -98 1125 -66 67 -98 2423 -66 2017 -332 2949 -100 1129 -68 1655 -100 1229 -66 1285 -130 163 -132 1315 -66 525 -98 295 -100 131 -64 427 -132 2207 -98 1153 -66 99 -100 697 -98 1397 -166 863 -66 1393 -132 5005 -66 497 -100 1753 -100 597 -66 1667 -66 397 -100 961 -66 763 -134 859 -64 689 -98 1917 -134 199 -234 167 -100 131 -166 2061 -66 1521 -98 759 -100 983 -66 825 -166 459 -66 2049 -166 1615 -100 829 -234 631 -66 465 -66 1493 -68 433 -66 1623 -132 65 -100 1133 -132 3083 -66 199 -132 199 -68 1257 -66 +RAW_Data: 265 -68 1061 -98 533 -100 1233 -68 1721 -68 995 -100 2535 -66 4193 -232 727 -100 727 -100 2773 -66 133 -98 399 -134 233 -232 67 -66 497 -100 267 -132 1127 -134 1063 -66 565 -132 97 -132 523 -132 919 -66 891 -66 855 -98 495 -66 3363 -296 3199 -98 563 -66 133 -100 495 -98 1165 -134 1161 -166 1849 -98 853 -132 5647 -134 563 -98 1827 -100 131 -100 1125 -132 1659 -132 265 -68 1121 -66 465 -232 431 -68 3589 -98 197 -68 97 -164 1717 -66 1645 -66 397 -66 97 -68 231 -166 631 -100 627 -66 1757 -66 131 -164 527 -98 1285 -328 1213 -134 2059 -100 1791 -68 931 -66 1611 -66 1511 -66 2211 -66 2597 -100 2545 -98 197 -162 1089 -98 589 -360 495 -132 1685 -202 1095 -100 729 -100 2825 -100 231 -100 567 -100 231 -66 1027 -66 131 -68 525 -132 1613 -232 461 -232 1597 -66 627 -198 231 -98 131 -98 65 -100 1229 -68 2507 -64 1349 -66 195 -134 97 -66 1321 -100 855 -132 163 -132 1151 -100 1025 -164 329 -66 891 -98 951 -132 163 -166 591 -98 1149 -132 955 -66 1329 -98 923 -66 331 -64 4269 -66 797 -134 399 -98 267 -170 197 -100 429 -198 1225 -100 331 -100 231 -132 1463 -100 597 -164 331 -66 1863 -134 659 -98 5507 -100 719 -100 131 -64 655 -164 1579 -98 1423 -130 1381 -98 1317 -132 467 -66 495 -132 361 -132 4417 -98 631 -364 299 -100 1499 -132 267 -68 663 -98 691 -100 2433 -66 953 -98 721 -66 1355 -232 897 -134 897 -134 365 -100 267 -132 2059 -132 199 -102 797 -68 695 -66 601 -66 265 -68 499 -66 1327 -164 1355 -64 1279 -66 3257 -66 1351 -66 131 -96 359 -132 499 -232 623 -96 427 -68 1909 -98 591 -98 4671 -100 4541 -66 1491 -66 3347 -98 1277 -100 1679 -198 295 -130 357 -98 697 -98 865 -100 2817 -66 329 -98 787 -64 1117 -66 3313 -202 1721 -100 199 -100 399 -66 199 -132 1891 -100 235 -100 201 -134 765 -166 761 -132 1529 -66 629 -202 861 -130 3501 -98 1377 -100 1741 -164 1509 -66 735 -68 733 -66 265 -166 2015 -134 131 -100 663 -100 2995 -132 1577 -98 1885 -66 2461 -100 1189 -66 1425 -100 201 -100 1691 -100 199 -98 499 -166 233 -100 233 -134 661 -68 1393 -100 295 -164 2079 -66 1289 -66 329 -198 599 -100 465 -98 3995 -98 199 -268 2045 -264 199 -66 1593 -66 165 -68 1561 -164 629 -66 635 -100 1251 -230 2733 -66 1727 -66 629 -100 1229 -132 731 -66 163 -198 131 -100 693 -66 3223 -68 565 -132 1091 -134 531 -100 3223 -68 729 -100 1527 -134 895 -166 1265 -66 527 -100 201 -200 1463 -66 1233 -132 +RAW_Data: 2397 -200 167 -234 1803 -66 821 -100 1351 -66 1687 -100 165 -66 233 -66 1125 -100 2203 -132 197 -98 97 -66 593 -164 4187 -102 529 -66 1161 -68 799 -66 427 -232 263 -66 589 -68 495 -68 197 -100 525 -66 327 -98 427 -130 1551 -66 727 -102 133 -234 265 -98 459 -66 2337 -64 585 -68 297 -68 691 -98 1857 -134 665 -132 365 -66 931 -166 495 -430 689 -196 1191 -98 465 -100 931 -366 1351 -102 3185 -164 1151 -98 2465 -66 2193 -100 331 -134 165 -98 267 -166 1985 -98 889 -132 765 -66 531 -100 1449 -166 457 -98 1715 -66 299 -166 3131 -130 197 -98 817 -294 793 -100 97 -66 3415 -164 1019 -98 1675 -132 197 -100 133 -68 199 -134 3319 -298 297 -66 791 -66 1029 -134 2153 -100 1629 -132 1391 -68 1229 -100 665 -66 2039 -164 461 -64 261 -66 395 -202 395 -166 3159 -134 2253 -166 265 -132 395 -66 887 -98 163 -66 589 -98 227 -130 1151 -230 293 -66 591 -68 527 -132 2883 -100 231 -66 99 -232 761 -134 499 -64 929 -100 167 -300 2259 -100 691 -164 459 -66 493 -132 163 -64 1283 -164 757 -132 295 -264 1023 -100 197 -198 6635 -198 2407 -100 2091 -132 1531 -66 1889 -100 199 -134 3567 -100 2981 -100 263 -198 425 -164 595 -100 231 -68 2691 -66 965 -100 2907 -98 367 -132 885 -198 1721 -100 659 -100 97 -296 495 -166 299 -134 397 -132 699 -66 1165 -66 465 -68 197 -66 659 -66 1543 -66 819 -164 2913 -98 1061 -66 5475 -132 167 -100 1035 -66 3427 -298 429 -166 2723 -66 831 -98 133 -66 133 -66 495 -98 701 -66 1063 -98 1991 -100 3319 -66 263 -66 233 -66 695 -66 593 -132 595 -66 553 -66 459 -66 197 -164 2241 -66 165 -68 959 -98 1587 -166 65 -102 233 -66 465 -134 1227 -100 2359 -66 1959 -198 331 -232 165 -102 531 -100 63 -66 1999 -68 265 -100 429 -66 657 -166 297 -132 823 -100 129 -132 4511 -164 659 -68 299 -66 593 -66 99 -134 65 -100 397 -66 1561 -66 697 -100 429 -66 265 -134 361 -132 195 -130 1319 -66 133 -66 265 -100 397 -268 895 -100 363 -134 433 -66 133 -100 2321 -68 +RAW_Data: -98 3573 -98 533 -68 961 -68 729 -132 559 -166 2189 -100 131 -68 657 -100 1387 -132 133 -68 2255 -68 429 -66 231 -134 793 -100 887 -98 361 -166 2141 -66 227 -130 663 -100 759 -100 1161 -134 1821 -66 327 -98 985 -130 757 -132 131 -132 1693 -66 361 -98 1411 -100 591 -132 1025 -66 663 -66 1065 -166 1059 -166 365 -66 723 -100 1659 -132 1883 -98 785 -132 1031 -66 261 -66 2501 -98 297 -66 1195 -100 691 -134 3009 -100 3921 -66 861 -66 363 -132 3361 -132 723 -66 459 -164 163 -164 333 -66 1291 -98 821 -230 591 -164 97 -262 361 -66 689 -66 733 -66 233 -134 1627 -66 533 -66 195 -100 521 -100 493 -98 493 -98 2173 -66 2037 -132 165 -100 429 -132 695 -100 67 -132 465 -68 1491 -100 1257 -66 965 -100 365 -68 929 -132 561 -66 899 -132 597 -132 861 -100 2627 -166 197 -98 2079 -66 2223 -100 1791 -364 895 -132 1027 -132 235 -68 599 -132 829 -66 197 -132 695 -66 133 -66 531 -68 333 -64 563 -66 265 -132 369 -134 2239 -164 4269 -100 793 -66 1495 -198 821 -164 133 -66 867 -66 797 -66 429 -66 365 -166 1729 -168 959 -100 1417 -66 233 -100 2579 -166 993 -164 461 -66 1529 -68 961 -66 1049 -98 1061 -132 2847 -66 229 -66 397 -134 263 -100 3285 -66 4115 -66 1547 -134 297 -132 431 -100 2895 -100 563 -66 1491 -66 399 -100 721 -66 395 -68 399 -66 1289 -66 293 -164 2307 -98 525 -66 3663 -64 927 -132 499 -134 1127 -264 397 -98 399 -198 131 -100 333 -100 663 -164 921 -166 1481 -262 691 -64 659 -64 2167 -98 3689 -100 833 -100 2085 -66 697 -100 595 -66 923 -134 893 -232 265 -98 367 -66 1157 -66 263 -130 1017 -66 623 -66 753 -100 2873 -132 395 -198 2787 -100 861 -132 3847 -100 297 -66 233 -98 1333 -100 495 -100 1325 -134 367 -66 595 -66 361 -230 4931 -66 1821 -98 329 -98 365 -168 333 -300 897 -100 2777 -66 1945 -132 2601 -66 951 -66 425 -98 789 -98 359 -64 1051 -66 1443 -132 851 -98 625 -100 97 -66 731 -232 263 -134 2757 -68 3021 -166 265 -100 1633 -132 427 -66 233 -98 799 -100 1059 -100 263 -98 557 -68 1063 -66 461 -100 1023 -98 163 -198 1481 -132 1227 -98 327 -100 327 -66 1317 -66 1853 -66 1061 -134 1287 -66 1315 -66 1345 -132 723 -66 1225 -68 1463 -166 3261 -98 2883 -66 563 -100 821 -100 2077 -166 3137 -66 565 -66 1355 -234 1415 -132 165 -66 397 -132 493 -132 563 -166 893 -66 1193 -66 1249 -100 333 -132 2083 -66 921 -100 1225 -262 861 -166 1321 -100 895 -100 591 -98 1249 +RAW_Data: -98 97 -66 6825 -66 231 -68 14077 -66 1787 -66 1547 -64 2617 -66 2925 -66 1723 -132 1529 -66 865 -166 827 -198 431 -66 495 -66 1121 -198 1327 -100 397 -130 557 -66 97 -100 261 -98 723 -98 557 -98 463 -98 463 -100 325 -66 3703 -100 465 -198 1123 -98 2545 -66 361 -66 857 -64 3455 -132 663 -98 1991 -200 825 -100 919 -98 893 -164 1749 -66 7759 -132 3321 -66 1807 -132 527 -66 393 -100 817 -130 657 -164 1485 -98 2367 -66 4171 -100 197 -130 3665 -134 1059 -132 597 -66 533 -66 1023 -98 1253 -134 2021 -100 231 -100 233 -66 197 -66 199 -66 1961 -168 729 -100 531 -100 461 -98 1361 -100 11161 -100 659 -166 229 -98 1675 -98 1027 -100 2063 -298 431 -100 99 -134 1059 -66 199 -100 763 -134 231 -66 233 -102 1761 -98 331 -68 757 -132 425 -64 457 -132 99 -66 2091 -66 567 -164 2121 -68 2125 -132 595 -200 759 -102 797 -132 1345 -66 429 -132 1019 -66 195 -66 791 -68 1227 -68 797 -132 1591 -200 199 -134 165 -66 1053 -66 559 -98 853 -164 825 -100 329 -98 891 -196 689 -132 657 -100 2341 -98 1119 -66 1883 -100 2607 -100 467 -100 1067 -164 6935 -66 2409 -132 855 -66 1809 -98 1119 -164 65 -66 199 -100 233 -132 931 -132 563 -66 1393 -132 567 -66 301 -68 1295 -66 529 -98 793 -66 131 -134 533 -132 827 -132 731 -332 1251 -98 921 -98 327 -198 361 -234 529 -66 1577 -132 97 -134 199 -100 1099 -68 1193 -132 991 -100 953 -98 2895 -166 1679 -98 161 -130 129 -66 1019 -100 261 -264 531 -100 263 -134 299 -68 495 -98 831 -100 531 -66 1357 -100 2051 -100 229 -98 829 -66 427 -66 859 -134 995 -68 665 -66 1793 -134 361 -100 2349 -66 331 -100 197 -66 1591 -66 959 -66 431 -234 2219 -332 661 -66 1487 -100 3381 -68 261 -164 463 -134 3377 -68 1127 -134 691 -66 529 -132 99 -66 6687 -98 889 -132 197 -164 725 -100 963 -66 2947 -132 327 -132 889 -66 393 -98 1581 -100 193 -130 97 -66 293 -66 1675 -100 1887 -98 2017 -100 597 -66 293 -98 557 -100 259 -98 985 -100 1727 -100 165 -100 301 -232 329 -100 533 -98 727 -100 761 -66 961 -68 2759 -100 2019 -66 855 -230 859 -98 1215 -98 1887 -98 131 -98 819 -166 227 -130 723 -132 625 -66 501 -66 429 -66 831 -66 1291 -66 331 -132 431 -132 1389 -100 265 -166 1461 -66 1907 -490 911 -962 409 -508 919 -944 419 -486 913 -526 915 -480 925 -488 911 -488 943 -476 925 -486 947 -462 945 -482 933 -484 951 -460 977 -440 967 -484 945 -468 945 -466 975 -450 983 +RAW_Data: -444 977 -458 975 -456 975 -444 965 -940 485 -430 967 -928 487 -448 981 -910 489 -446 963 -944 485 -430 975 -930 489 -912 485 -896 487 -452 977 -916 509 -454 977 -922 479 -448 985 -15898 487 -456 973 -926 493 -448 1001 -918 481 -484 981 -478 979 -450 1013 -476 977 -450 1017 -476 983 -448 999 -480 985 -484 983 -478 985 -484 981 -480 983 -476 1001 -474 979 -496 973 -486 1015 -476 977 -476 1005 -484 973 -486 1007 -920 505 -456 1011 -918 509 -458 1011 -950 497 -452 1011 -920 507 -458 1007 -950 477 -958 483 -942 481 -480 1003 -918 515 -446 1039 -922 505 -458 1007 -16154 501 -462 1013 -934 517 -474 999 -958 483 -478 993 -484 1037 -450 1027 -482 1027 -452 1037 -482 1025 -444 1035 -490 1009 -482 1013 -484 1001 -484 1039 -474 1003 -484 1045 -464 1011 -480 1049 -446 1037 -492 1007 -482 1013 -510 1005 -494 1005 -970 485 -482 1017 -974 473 -498 1007 -974 481 -486 1047 -948 479 -482 1051 -948 497 -952 519 -938 485 -482 1041 -946 517 -478 1013 -944 503 -472 415 -83640 97 -200 65 -632 131 -300 365 -364 231 -132 1061 -100 3047 -100 1393 -66 499 -66 1091 -66 333 -66 2353 -100 2273 -66 1427 -166 563 -132 1559 -132 427 -100 925 -98 13469 -100 2019 -98 821 -132 1097 -68 297 -100 897 -100 1129 -166 465 -166 961 -66 597 -100 165 -66 267 -100 201 -100 765 -134 297 -66 165 -66 3081 -100 1293 -100 1289 -136 233 -66 357 -66 1155 -166 295 -100 1197 -68 1089 -98 425 -132 1187 -100 523 -98 463 -98 197 -98 131 -98 493 -66 393 -98 2797 -164 359 -232 325 -66 229 -164 625 -98 1215 -164 425 -66 589 -98 195 -66 1083 -100 197 -68 1557 -66 1427 -66 525 -66 429 -132 863 -66 1129 -166 831 -98 265 -98 1183 -66 3157 -100 2735 -98 2819 -166 4645 -66 301 -68 1395 -132 1097 -100 897 -198 629 -200 1419 -132 493 -66 521 -132 697 -100 695 -66 459 -298 859 -66 559 -100 1029 -100 4113 -66 1167 -66 14017 -66 2123 -68 525 -132 861 -100 329 -66 399 -134 1523 -132 327 -64 691 -98 463 -132 1803 -132 853 -166 715 -66 953 -66 525 -98 723 -132 989 -132 461 -98 459 -164 2239 -66 1185 -66 589 -100 1945 -230 1483 -66 399 -66 265 -168 965 -66 197 -168 699 -68 1125 -68 529 -98 491 -66 987 -130 525 -168 397 -66 597 -100 561 -132 1353 -66 391 -132 393 -66 591 -98 557 -98 787 -66 463 -100 199 -134 395 -100 759 -66 295 -130 261 -98 229 -100 99 -100 1595 -66 699 -100 499 -66 595 -98 327 -132 957 -132 331 -100 493 -100 1313 -66 295 -132 197 -198 1279 +RAW_Data: -66 9461 -100 329 -68 27921 -66 24331 -68 13415 -66 6439 -98 133 -66 4193 -98 395 -66 653 -66 983 -66 163 -66 955 -132 1791 -66 861 -100 363 -132 1659 -132 667 -166 467 -134 429 -166 265 -66 4065 -98 293 -98 3183 -130 555 -98 163 -162 259 -100 661 -100 7057 -100 931 -100 1297 -66 2559 -98 1193 -100 333 -100 563 -132 65 -100 793 -66 855 -64 659 -100 929 -102 893 -132 689 -66 3475 -68 1361 -198 331 -134 691 -66 295 -66 425 -164 731 -266 921 -100 599 -100 165 -66 227 -98 1091 -66 263 -66 1215 -100 227 -164 657 -66 953 -132 359 -66 1845 -66 1779 -132 753 -164 393 -66 731 -66 1195 -66 533 -66 797 -132 1623 -98 1281 -100 493 -98 659 -98 2417 -166 799 -132 1259 -100 559 -134 595 -166 199 -66 1461 -198 865 -100 459 -66 463 -166 165 -100 497 -66 1097 -66 1579 -100 1449 -98 885 -98 263 -100 1097 -132 627 -68 329 -132 487 -132 427 -132 361 -66 525 -98 687 -66 1161 -100 263 -66 729 -100 229 -98 559 -66 1213 -100 1015 -66 795 -66 5475 -66 4043 -66 1683 -166 1151 -132 429 -98 1447 -68 261 -98 985 -100 429 -100 1289 -198 2269 -132 7999 -98 1591 -132 3233 -66 861 -66 2087 -98 557 -98 719 -66 981 -98 563 -100 199 -100 523 -100 2319 -134 833 -100 495 -132 197 -66 295 -64 989 -66 1059 -198 7343 -66 2023 -66 963 -66 593 -66 2401 -100 491 -100 959 -66 297 -134 999 -132 99 -68 3609 -230 97 -198 1911 -66 265 -100 1195 -132 633 -132 595 -66 1381 -66 491 -66 1681 -100 297 -100 1827 -132 2269 -100 1351 -132 1513 -66 1225 -134 231 -66 1523 -100 363 -200 1227 -66 2943 -66 923 -134 2249 -66 1809 -100 1121 -132 265 -66 827 -98 199 -66 201 -100 3279 -100 565 -132 1689 -66 395 -66 2979 -134 1065 -66 367 -168 3585 -200 463 -100 563 -66 97 -166 2293 -66 265 -134 1255 -132 2401 -66 1579 -166 365 -100 861 -298 261 -98 761 -66 363 -132 657 -130 63 -130 557 -66 131 -130 2041 -100 233 -66 1791 -100 925 -134 265 -100 1063 -100 301 -168 661 -66 657 -64 263 -64 197 -66 1853 -100 663 -98 231 -66 731 -100 5539 -166 197 -68 1423 -134 361 -68 1727 -68 929 -100 1397 -134 1885 -66 1661 -66 265 -66 1183 -66 295 -166 263 -166 165 -66 329 -66 465 -100 1159 -134 697 -100 2443 -100 393 -98 1093 -66 953 -296 787 -132 425 -66 2019 -66 461 -98 1201 -100 397 -132 3551 -100 1431 -264 725 -330 1455 -66 263 -100 531 -296 499 -100 265 -100 163 -66 1145 -132 1313 -98 2101 -98 261 -132 1083 -66 5403 +RAW_Data: -66 2223 -66 11583 -66 131 -66 5071 -66 3723 -132 1415 -132 6905 -64 9685 -102 4739 -66 3355 -66 5301 -98 29993 -508 897 -950 437 -490 909 -974 423 -510 935 -486 925 -508 943 -490 937 -494 947 -482 941 -484 979 -440 979 -456 1003 -462 975 -460 971 -458 977 -468 973 -484 975 -472 971 -450 1011 -452 1003 -446 983 -480 979 -450 1017 -908 487 -472 971 -944 471 -450 999 -944 485 -468 977 -918 493 -448 1011 -934 499 -920 487 -914 487 -452 1011 -912 521 -446 1009 -904 517 -468 1007 -16000 531 -444 1009 -908 519 -468 1009 -912 515 -466 1009 -452 1021 -466 1011 -450 1019 -480 1017 -448 1045 -448 1019 -460 1041 -450 1019 -480 1019 -450 1039 -474 1001 -480 1021 -484 1005 -476 1015 -480 1017 -484 1011 -486 1017 -464 1041 -446 1047 -922 503 -458 1037 -946 513 -442 1047 -938 503 -480 1023 -916 537 -450 1049 -926 521 -904 519 -942 519 -450 1055 -910 519 -486 1033 -916 519 -486 1029 -16258 533 -464 1015 -940 515 -456 1053 -946 511 -482 1051 -434 1075 -442 1075 -448 1065 -440 1065 -450 1049 -480 1067 -462 1041 -446 1075 -450 1063 -460 1053 -480 1047 -450 1075 -446 1079 -452 1055 -478 1051 -448 1067 -444 1065 -480 753 -66842 99 -1090 465 -332 131 -68 131 -134 99 -132 167 -200 429 -100 1809 -132 2385 -230 265 -102 597 -134 1025 -66 365 -100 361 -66 825 -168 1331 -100 797 -132 431 -132 299 -198 661 -168 501 -100 463 -164 329 -66 559 -98 391 -98 1085 -198 1939 -66 1871 -164 2251 -134 493 -66 719 -198 361 -98 361 -64 197 -132 391 -164 691 -300 489 -98 2139 -66 1413 -66 1875 -196 557 -66 263 -132 1359 -66 1397 -66 631 -100 793 -132 723 -100 65 -66 529 -134 463 -68 789 -100 227 -66 923 -100 2649 -166 363 -66 395 -200 295 -130 1757 -68 2057 -100 1023 -66 359 -66 391 -132 1679 -66 359 -66 1217 -98 663 -98 463 -100 821 -98 165 -98 1589 -132 2367 -98 559 -132 1079 -100 9617 -66 3669 -134 1787 -68 1679 -132 361 -66 555 -100 661 -66 1523 -100 2057 -198 1025 -66 4177 -100 165 -66 265 -132 465 -134 299 -232 265 -100 1125 -132 1461 -132 1295 -100 499 -132 367 -68 263 -66 331 -66 365 -100 1643 -130 197 -132 997 -98 867 -98 1191 -100 2945 -100 2339 -98 1779 -66 295 -132 597 -66 165 -100 665 -100 463 -66 331 -66 593 -100 459 -68 489 -164 855 -66 261 -64 163 -100 4449 -100 859 -100 699 -132 199 -100 1685 -66 301 -132 2317 -68 231 -100 827 -66 1749 -132 99 -64 1185 -100 329 -100 1253 -66 1127 -98 827 -198 363 -132 265 -134 365 -66 297 -66 1125 -66 261 +RAW_Data: -266 29863 -66 2443 -66 5113 -100 5947 -21026 99 -134 301 -132 199 -132 131 -266 163 -196 131 -66 365 -66 465 -98 13819 -98 525 -98 329 -100 893 -66 1259 -66 431 -98 427 -130 1051 -392 463 -200 795 -164 399 -66 1489 -66 1377 -100 1423 -132 597 -100 689 -68 1559 -100 2263 -100 1327 -98 1059 -98 497 -66 595 -132 265 -66 299 -66 199 -66 563 -134 627 -66 165 -134 889 -66 2751 -232 893 -264 231 -66 299 -132 467 -132 861 -68 1263 -164 795 -66 2601 -100 429 -66 1525 -66 961 -98 265 -98 997 -66 233 -68 695 -100 697 -66 795 -66 1195 -66 1223 -68 2173 -66 467 -66 827 -66 535 -68 697 -100 1221 -166 165 -100 365 -132 723 -66 829 -132 2091 -232 265 -66 195 -66 459 -262 499 -100 461 -68 759 -100 1087 -66 259 -164 2845 -66 1365 -98 561 -200 331 -168 201 -166 1397 -198 197 -66 697 -68 1713 -68 293 -134 1317 -66 593 -328 395 -100 499 -132 2251 -100 563 -134 333 -134 1921 -134 1187 -68 561 -132 933 -66 797 -100 631 -100 399 -132 929 -66 2769 -66 851 -130 2047 -66 265 -100 7219 -66 1987 -66 299 -98 2199 -134 1063 -98 2843 -98 655 -132 231 -66 1123 -198 2137 -64 327 -66 3183 -66 1127 -66 631 -100 263 -102 3173 -132 267 -68 1289 -98 1593 -66 2415 -66 1185 -66 359 -132 1051 -66 2169 -66 427 -98 395 -132 793 -98 293 -166 727 -134 131 -100 1287 -98 427 -98 687 -164 823 -64 853 -66 865 -100 763 -66 2025 -100 959 -66 1891 -64 793 -100 763 -66 729 -166 99 -98 399 -134 763 -100 4203 -66 1321 -230 4023 -98 1053 -66 985 -98 1383 -66 3559 -164 1515 -100 2899 -66 797 -134 1169 -100 3055 -134 1615 -66 429 -100 495 -64 1583 -134 923 -66 921 -66 723 -68 1359 -98 787 -98 425 -100 393 -64 1189 -98 263 -98 491 -100 1455 -98 +RAW_Data: -202 531 -66 531 -66 1093 -66 1389 -66 1551 -134 2699 -66 1291 -132 65 -64 657 -98 1083 -164 393 -98 1359 -134 1461 -66 393 -100 561 -130 2113 -132 597 -66 431 -102 1759 -302 985 -66 235 -100 1395 -66 901 -66 1061 -100 463 -66 5673 -66 227 -66 225 -66 855 -66 1581 -132 2503 -100 657 -66 2535 -98 259 -64 1015 -66 231 -132 1197 -66 827 -166 9641 -66 1823 -132 1565 -132 299 -66 797 -66 1631 -132 327 -132 2227 -232 433 -68 499 -100 1793 -66 1161 -132 525 -66 129 -100 361 -66 1765 -132 229 -66 491 -132 2255 -100 3043 -332 299 -100 499 -100 267 -68 2967 -66 991 -100 729 -100 633 -66 529 -98 825 -100 1033 -100 331 -66 723 -100 725 -264 2987 -68 825 -66 2601 -134 333 -100 3181 -134 1059 -100 299 -134 3279 -100 1221 -132 659 -66 3157 -98 1595 -132 1561 -98 201 -134 465 -66 1843 -130 589 -66 1413 -66 331 -100 333 -66 661 -100 265 -68 201 -234 1027 -166 297 -100 1161 -132 1561 -134 629 -66 431 -66 1025 -98 427 -198 1527 -66 793 -66 1903 -66 131 -130 1285 -66 299 -134 397 -98 229 -132 499 -132 4747 -100 2355 -100 263 -132 1915 -132 1749 -132 759 -66 2253 -100 4545 -66 391 -100 521 -100 1083 -100 929 -134 565 -66 2355 -66 1331 -66 167 -100 465 -100 1727 -132 633 -330 433 -66 897 -132 165 -134 331 -98 627 -66 231 -66 167 -66 1397 -66 729 -132 1397 -68 165 -66 1627 -134 2187 -66 231 -134 795 -200 6469 -232 829 -66 3929 -66 891 -98 1977 -100 525 -68 859 -66 921 -264 1029 -68 959 -134 1555 -66 259 -100 687 -66 429 -264 663 -66 1559 -100 1127 -100 2327 -132 1913 -64 4193 -132 293 -98 99 -100 5613 -132 1351 -66 1545 -66 1677 -66 295 -64 1943 -100 595 -132 1959 -166 765 -66 1389 -100 823 -66 1749 -66 1217 -100 597 -100 297 -66 2019 -98 165 -100 4165 -100 67 -100 2477 -262 295 -66 919 -200 3555 -66 229 -66 2531 -98 557 -66 2525 -66 1463 -100 1293 -68 197 -68 1391 -66 1421 -66 595 -164 327 -68 2285 -66 593 -98 99 -68 463 -98 1063 -100 165 -68 99 -100 631 -66 1085 -66 859 -98 6599 -66 1429 -66 233 -66 397 -98 231 -132 1975 -132 333 -66 131 -134 3373 -100 4277 -66 1363 -232 2893 -166 3133 -64 951 -66 2815 -100 425 -98 327 -66 599 -68 1031 -98 133 -68 633 -68 429 -100 1129 -66 327 -130 2679 -66 1321 -100 463 -200 367 -98 667 -66 493 -132 885 -98 2183 -166 559 -98 981 -66 3201 -164 593 -66 493 -130 1923 -166 565 -100 2421 -98 461 -66 1427 -130 1955 -64 197 -66 1643 +RAW_Data: -132 2291 -66 3057 -68 2521 -166 333 -134 503 -400 3235 -66 2329 -68 995 -100 333 -100 97 -166 1757 -100 397 -100 165 -66 2755 -132 297 -134 163 -100 565 -100 1793 -100 1813 -162 1293 -98 97 -66 999 -66 1763 -68 261 -68 2391 -100 765 -364 859 -100 1855 -98 1399 -230 463 -134 301 -198 397 -100 961 -68 431 -134 695 -202 133 -100 365 -66 925 -98 165 -66 365 -132 663 -98 4573 -134 1479 -66 1019 -66 629 -66 233 -68 201 -66 569 -66 295 -134 1755 -296 3199 -100 3261 -168 3373 -132 1425 -100 759 -66 895 -98 201 -100 265 -166 99 -66 695 -66 1091 -66 855 -168 299 -100 229 -164 589 -66 521 -66 655 -134 329 -98 493 -200 429 -66 929 -66 673 -100 953 -66 823 -66 1283 -66 1979 -68 233 -66 1547 -164 589 -132 597 -66 131 -66 265 -100 761 -200 759 -66 689 -332 263 -100 1227 -68 1067 -164 2945 -100 959 -100 995 -100 399 -100 1193 -100 625 -66 399 -66 3021 -134 393 -66 4805 -66 1095 -68 231 -332 399 -166 1663 -68 561 -66 927 -98 1085 -164 1155 -98 627 -66 265 -132 263 -130 2211 -66 2159 -66 1029 -264 2669 -66 295 -66 8747 -100 329 -232 625 -134 429 -68 1329 -168 1355 -98 987 -66 1545 -98 1015 -98 699 -134 133 -134 1263 -66 4687 -166 8299 -66 1349 -434 933 -906 443 -452 949 -894 441 -480 909 -486 907 -456 947 -448 949 -434 969 -454 931 -460 941 -448 933 -450 979 -450 945 -450 935 -458 935 -486 927 -456 947 -450 951 -482 945 -428 975 -446 967 -452 955 -458 945 -912 485 -434 971 -902 481 -450 949 -926 451 -478 941 -920 481 -450 949 -920 473 -450 955 -916 471 -452 981 -918 449 -486 945 -910 483 -924 473 -15780 479 -450 967 -948 449 -482 943 -944 485 -468 941 -484 979 -446 1001 -444 999 -446 967 -484 969 -482 979 -478 947 -484 985 -470 973 -458 983 -492 971 -458 979 -494 971 -458 983 -494 973 -458 981 -498 975 -458 1013 -466 973 -952 475 -458 973 -950 489 -450 1011 -916 481 -478 1001 -918 481 -478 1001 -916 481 -478 1001 -920 483 -480 983 -946 479 -458 1013 -932 485 -952 479 -16040 493 -476 1009 -912 515 -464 1007 -910 517 -464 1007 -450 1001 -488 1001 -484 1011 -450 1019 -458 1039 -450 1031 -454 1005 -484 1009 -458 1015 -476 1009 -478 1035 -462 1015 -468 1007 -480 1001 -486 1015 -460 1041 -450 1017 -484 1019 -482 1009 -952 477 -494 1003 -944 485 -478 1013 -944 519 -482 1013 -942 487 -482 1013 -946 487 -484 1015 -944 487 -484 1015 -946 519 -454 1019 -942 505 -952 487 -16238 517 -468 1007 -942 521 -482 1011 -944 519 +RAW_Data: -450 1019 -482 1035 -480 1033 -460 1047 -476 1017 -484 1007 -484 1051 -484 1027 -452 1039 -478 1035 -458 1049 -480 1017 -480 1035 -480 1035 -472 1047 -484 1027 -454 1039 -480 1033 -488 1031 -488 1009 -962 521 -486 1017 -966 485 -490 1015 -139210 229 -98 461 -364 165 -334 131 -168 2121 -66 1049 -66 1215 -166 297 -136 1449 -100 3877 -100 1495 -234 331 -64 1345 -262 393 -100 529 -132 2921 -164 1223 -132 1807 -66 765 -66 397 -98 3405 -132 2123 -230 231 -66 2541 -100 2489 -98 4397 -132 461 -98 293 -64 991 -66 1125 -166 401 -100 131 -100 99 -100 265 -100 2555 -100 499 -98 1361 -134 265 -166 895 -100 2253 -100 1057 -100 129 -296 1147 -198 197 -66 1163 -66 1935 -98 1675 -66 1103 -100 891 -100 989 -164 1019 -66 2967 -68 1293 -166 3161 -66 133 -264 1065 -100 731 -66 1693 -66 529 -100 165 -68 865 -66 825 -232 1117 -196 2401 -66 3051 -296 229 -132 1843 -132 1687 -68 1119 -68 299 -68 97 -66 4741 -66 197 -200 2319 -100 1097 -66 3765 -66 131 -100 695 -132 2753 -66 2287 -100 1129 -68 331 -98 1433 -132 893 -100 465 -100 801 -66 529 -66 1515 -264 393 -98 263 -66 1831 -166 3533 -100 633 -100 1051 -100 331 -98 795 -134 959 -132 1229 -100 627 -132 2517 -66 165 -98 131 -66 2301 -166 163 -134 465 -66 2767 -66 1019 -66 401 -134 397 -232 893 -66 397 -66 833 -66 199 -66 303 -66 2775 -66 2069 -98 1841 -100 399 -66 793 -98 2793 -68 3769 -100 867 -66 861 -100 399 -66 1859 -100 631 -132 755 -100 689 -66 163 -64 2045 -64 2191 -102 1127 -68 727 -68 625 -164 1381 -66 1153 -132 1115 -98 1017 -100 491 -100 593 -132 991 -98 1415 -98 4813 -66 331 -98 131 -102 1847 -98 197 -68 263 -100 3265 -66 431 -100 493 -98 435 -134 133 -68 1185 -134 395 -100 131 -66 399 -134 767 -134 1125 -66 429 -198 3185 -100 2261 -66 523 -230 2475 -168 1297 -66 3243 -66 1853 -100 1657 -66 459 -66 827 -100 263 -66 303 -234 197 -166 1167 -100 2299 -66 1329 -68 461 -100 763 -132 3819 -366 757 -66 591 -164 621 -98 1445 -100 2155 -100 231 -100 631 -68 1161 -66 131 -166 67 -98 1915 -166 1891 -66 1261 -68 999 -164 165 -132 133 -168 2695 -68 1055 -198 97 -98 229 -66 229 -66 1215 -66 885 -100 303 -132 297 -164 619 -198 459 -64 989 -66 229 -66 597 -134 693 -64 1255 -100 65 -132 331 -66 199 -98 529 -100 2831 -98 1259 -66 4855 -100 1163 -166 299 -66 395 -98 3141 -66 1319 -66 2139 -100 161 -132 261 -130 821 -200 263 -134 931 -330 65 -98 99 -134 793 +RAW_Data: -66 597 -100 231 -68 167 -66 1659 -100 733 -66 1631 -100 165 -66 199 -66 233 -166 165 -100 1925 -68 595 -198 1785 -134 2177 -134 131 -66 1049 -98 3087 -132 195 -64 589 -66 397 -134 329 -66 2565 -164 327 -100 689 -64 1775 -100 5183 -132 1187 -66 329 -66 395 -132 165 -98 261 -98 1247 -64 1217 -66 927 -66 997 -66 199 -98 1419 -66 531 -166 1231 -66 697 -100 97 -66 563 -66 161 -264 3205 -200 525 -98 293 -100 291 -100 133 -66 759 -66 659 -100 983 -64 523 -130 431 -166 919 -66 1097 -100 1757 -66 1119 -66 917 -98 2647 -166 1247 -66 165 -264 1189 -100 899 -134 597 -68 2323 -66 1893 -66 1095 -100 533 -64 965 -100 1817 -130 1215 -66 1879 -64 821 -164 1117 -132 263 -132 131 -66 557 -66 431 -132 661 -100 1183 -98 629 -100 1679 -132 259 -66 623 -98 431 -66 399 -164 923 -100 297 -66 165 -166 2521 -198 99 -66 431 -132 1225 -66 1063 -68 131 -136 631 -66 163 -100 99 -298 965 -68 465 -68 465 -298 2545 -134 2639 -230 1489 -66 299 -66 1991 -234 65 -132 693 -134 429 -102 101 -68 461 -66 3333 -64 1229 -68 333 -66 265 -66 885 -64 3163 -100 467 -66 2651 -164 1221 -100 1527 -66 1259 -134 431 -232 1259 -100 6029 -164 297 -98 1151 -66 1415 -100 5289 -66 2467 -100 493 -132 495 -200 1121 -66 129 -66 757 -166 327 -130 5477 -66 1227 -230 395 -100 265 -132 497 -132 1133 -132 361 -100 1051 -164 3089 -132 1583 -100 65 -68 2315 -100 529 -132 2157 -68 1257 -66 1975 -98 427 -98 1347 -66 719 -164 857 -66 165 -66 1029 -132 297 -132 467 -100 731 -130 1985 -98 199 -166 899 -100 1391 -166 3425 -100 261 -132 721 -66 4845 -98 1193 -68 1225 -66 721 -100 1015 -64 983 -66 557 -130 693 -98 99 -64 1091 -98 197 -100 2321 -66 431 -134 727 -66 467 -102 891 -98 167 -134 2619 -66 393 -64 97 -100 589 -98 1583 -164 301 -68 1481 -98 295 -98 959 -66 365 -98 1253 -66 231 -100 1255 -132 1813 -132 1645 -100 361 -132 395 -100 427 -164 1197 -98 1001 -100 861 -66 1161 -98 195 -100 197 -66 1429 -66 663 -66 1427 -98 665 -66 699 -100 663 -66 855 -196 161 -100 361 -98 823 -66 227 -66 621 -132 1853 -230 461 -230 623 -100 557 -98 229 -98 133 -134 1291 -66 533 -166 627 -134 195 -134 593 -64 591 -66 1019 -66 1049 -262 297 -100 2921 -66 133 -66 963 -134 165 -100 diff --git a/assets/unit_tests/subghz/test_random_raw.sub b/assets/unit_tests/subghz/test_random_raw.sub index 96c324a8da3..9d1cdd67087 100644 --- a/assets/unit_tests/subghz/test_random_raw.sub +++ b/assets/unit_tests/subghz/test_random_raw.sub @@ -85,4 +85,18 @@ RAW_Data: -504 513 -478 257 -244 495 -274 253 -500 483 -232 265 -69136 287 -256 RAW_Data: -246 527 -228 243 -276 245 -246 245 -500 513 -238 253 -474 279 -254 489 -228 251 -250 249 -506 513 -478 255 -68936 287 -218 249 -236 255 -248 247 -248 247 -248 249 -248 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -250 247 -250 249 -506 257 -246 245 -246 245 -248 503 -514 477 -272 255 -254 255 -218 247 -240 255 -250 247 -502 511 -226 273 -244 243 -244 247 -246 247 -250 247 -506 259 -246 245 -246 501 -512 225 -244 527 -238 251 -256 253 -254 251 -242 227 -508 257 -216 527 -226 275 -244 243 -246 245 -248 247 -504 513 -478 257 -242 527 -238 255 -472 511 -242 281 -119614 299 -200 65 -470 65 -466 297 -630 97 -1592 133 -166 299 -66 231 -100 131 -98 265 -134 165 -166 433 -100 2287 -9916 231 -166 65 -98 199 -166 133 -166 165 -756 65 -724 195 -428 231 -260 263 -98 229 -130 261 -66 163 -264 65 -132 1181 -66 6315 -6798 131 -296 559 -334 131 -166 233 -132 165 -66 133 -264 99 -66 65 -366 99 -630 301 -166 97 -100 167 -164 535 -202 7269 -8266 197 -1022 131 -756 99 -98 99 -164 163 -990 65 -530 163 -230 297 -136 635 -66 2113 -8426 67 -6674 97 -722 197 -362 263 -232 165 -134 99 -234 297 -362 129 -198 131 -556 297 -68 167 -98 331 -200 165 -66 295 -66 8689 -4994 65 -1750 165 -762 163 -864 135 -100 167 -694 1093 -66 695 -102 99 -100 9899 -1650 297 -1216 97 -66 99 -396 65 -198 165 -164 233 -1658 199 -98 465 -134 463 -166 1883 -98 6283 -7302 99 -932 133 -696 263 -298 97 -98 165 -1708 131 -820 229 -98 231 -130 163 -590 131 -130 99 -66 97 -16220 261 -1062 265 -998 197 -1290 97 -362 165 -494 895 -264 7839 -7804 99 -66 99 -364 231 -630 133 -166 427 -496 131 -1252 263 -100 233 -66 133 -132 165 -66 259 -98 3109 -10438 101 -5322 99 -100 65 -666 65 -166 331 -98 197 -132 233 -662 261 -1516 559 -66 263 -130 689 -132 229 -64 3613 -15976 231 -166 133 -66 399 -264 99 -132 295 -366 97 -1692 99 -398 529 -68 397 -130 899 -164 3559 -98 1197 -12106 199 -98 65 -166 99 -266 99 -134 231 -100 133 -132 297 -430 99 -1394 299 -64 397 -166 99 -100 465 -200 331 -132 599 -100 2333 -15214 65 -1230 231 -266 265 -432 165 -398 65 -532 333 -632 65 -232 957 -98 9785 -6320 97 -830 167 -166 133 -732 299 -958 327 -98 197 -66 229 -164 327 -98 653 -66 7993 -6418 65 -1284 97 -458 129 -196 197 -166 393 -134 99 -332 427 -132 131 -66 133 -98 233 -66 133 -364 163 -566 4873 -16030 97 RAW_Data: -360 65 -364 65 -68 857 -98 65 -232 131 -264 63 -98 391 -396 65 -130 99 -98 65 -66 861 -166 265 -166 7611 -10336 65 -1822 165 -300 165 -166 295 -134 199 -100 67 -264 165 -166 99 -500 99 -198 97 -200 165 -268 197 -130 65 -300 629 -166 561 -132 333 -132 7459 -6294 131 -1096 165 -964 197 -332 65 -166 129 -132 99 -130 99 -100 97 -134 65 -164 131 -494 165 -396 97 -164 131 -198 99 -232 229 -66 821 -64 131 -14954 97 -788 65 -100 263 -66 99 -300 65 -400 131 -198 293 -294 163 -132 65 -692 99 -132 131 -200 1847 -132 8773 -5968 133 -330 65 -66 295 -430 197 -166 565 -132 467 -98 65 -430 165 -262 131 -528 131 -296 131 -100 131 -66 557 -166 787 -98 3221 -16236 299 -166 133 -562 199 -1692 99 -66 65 -364 65 -366 231 -168 367 -100 5541 -14968 297 -164 97 -132 163 -328 99 -532 99 -134 131 -370 397 -66 397 -98 293 -98 197 -98 1151 -66 7019 -6746 129 -296 163 -954 261 -230 229 -64 231 -264 431 -100 99 -466 165 -100 333 -166 133 -666 695 -200 67 -134 397 -100 1667 -7686 97 -426 195 -266 97 -330 63 -98 99 -594 97 -132 133 -270 131 -600 131 -362 833 -98 297 -166 199 -66 99 -200 65 -66 197 -100 2963 -98 1125 -2238 199 -554 275 -242 273 -212 271 -242 241 -242 271 -244 241 -244 273 -244 245 -246 247 -248 247 -250 247 -250 249 -250 249 -248 249 -248 249 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -246 247 -248 249 -250 247 -504 513 -228 243 -244 273 -246 245 -500 513 -478 257 -242 241 -244 273 -244 499 -512 225 -244 525 -228 273 -496 475 -508 507 -240 253 -254 255 -494 261 -222 505 -258 245 -246 245 -246 245 -250 247 -506 513 -478 257 -242 241 -244 273 -244 499 -68858 319 -218 245 -230 251 -248 245 -248 247 -250 247 -250 249 -248 249 -248 249 -250 249 -250 249 -248 249 -248 249 -250 249 -248 249 -250 247 -506 257 -246 245 -246 247 -248 503 -516 477 -274 253 -474 511 -478 527 -484 511 -240 253 -472 281 -254 489 -484 513 -478 513 -480 255 -242 523 -472 507 -276 253 -462 275 -240 491 -258 247 -244 245 -246 247 -502 515 -238 253 -254 253 -492 497 -230 253 -250 247 -250 247 -250 247 -250 247 -506 257 -68880 279 -248 241 -266 223 -252 249 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -506 225 -280 213 -278 245 -248 503 -260 215 -276 245 -246 247 -248 247 -250 247 -504 481 -272 251 RAW_Data: -254 255 -254 213 -506 483 -514 271 -254 217 -292 217 -248 497 -516 237 -254 473 -278 251 -488 489 -516 477 -272 253 -254 219 -494 261 -260 481 -260 215 -278 247 -248 247 -248 247 -504 481 -514 235 -290 217 -256 253 -244 497 -69132 311 -212 235 -258 249 -248 247 -248 249 -248 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -506 257 -248 245 -246 245 -248 503 -512 479 -272 253 -474 513 -478 527 -482 513 -238 253 -472 281 -254 487 -486 515 -478 509 -480 255 -242 529 -480 509 -240 255 -496 271 -234 487 -260 247 -244 245 -248 247 -504 511 -226 243 -244 275 -498 479 -272 253 -254 255 -254 249 -238 225 -252 247 -504 257 -68882 319 -188 265 -280 235 -228 251 -250 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 247 -250 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 245 -250 247 -250 249 -504 515 -238 251 -256 253 -256 249 -472 515 -480 271 -256 253 -218 255 -248 497 -482 271 -252 473 -280 253 -490 487 -516 477 -274 253 -256 217 -496 261 -224 507 -258 249 -246 245 -248 247 -248 249 -504 511 -478 255 -244 243 -244 275 -246 499 -69134 311 -208 231 -254 249 -246 247 -250 247 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -248 249 -506 259 -246 245 -246 247 -246 503 -516 479 -274 253 -464 519 -496 487 -516 477 -274 255 -498 249 -248 469 -514 479 -516 483 -488 277 -254 491 -498 487 -260 247 -498 227 -244 529 -228 243 -274 245 -246 245 -502 515 -238 251 -256 253 -496 497 -226 251 -248 249 -248 249 -248 249 -250 249 -504 257 -68898 247 -274 213 -312 185 -312 185 -312 185 -312 185 -312 185 -312 185 -310 185 -310 185 -310 215 -278 217 -278 215 -278 217 -278 217 -280 215 -532 237 -288 217 -290 215 -276 461 -260 219 -280 217 -280 217 -278 215 -280 247 -506 481 -270 251 -256 217 -290 213 -502 483 -514 271 -254 253 -218 255 -246 499 -482 271 -254 473 -282 253 -488 485 -516 477 -274 253 -256 217 -496 263 -224 507 -260 247 -246 245 -246 247 -248 249 -504 513 -478 255 -242 243 -244 275 -246 499 -69122 319 -220 243 -228 251 -248 247 -248 247 -250 247 -250 249 -248 249 -250 249 -248 249 -248 249 -250 249 -250 247 -250 249 -250 247 -250 249 -504 257 -248 245 -246 247 -246 505 -514 479 -274 253 -476 511 -476 493 -516 481 -270 253 -474 279 -254 487 -484 513 -RAW_Data: -478 507 -506 225 -272 495 -482 505 -254 241 -494 255 -242 525 -226 241 -274 243 -242 243 -496 509 -274 253 -254 219 -494 491 -258 249 -248 247 -248 249 -248 249 -248 249 -504 257 -68896 281 -214 241 -260 247 -248 247 -248 247 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -260 245 -246 245 -248 247 -248 247 -248 249 -504 513 -238 251 -254 255 -254 251 -474 515 -478 273 -254 255 -218 253 -248 499 -514 237 -254 473 -280 253 -490 485 -516 479 -274 253 -256 217 -496 263 -224 507 -258 247 -248 245 -246 247 -250 247 -504 513 -478 257 -244 241 -244 275 -246 499 -69128 321 -218 241 -230 249 -248 247 -246 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -504 257 -248 245 -246 245 -250 503 -514 477 -272 255 -474 515 -480 491 -518 479 -274 253 -474 281 -254 483 -486 479 -512 507 -506 223 -242 527 -482 509 -240 253 -496 273 -236 487 -260 247 -246 245 -246 247 -504 513 -238 251 -256 253 -492 495 -228 253 -250 249 -250 249 -250 249 -248 249 -504 257 -68860 273 -242 233 -256 249 -250 247 -248 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 247 -248 247 -248 249 -504 513 -238 253 -254 253 -256 249 -474 515 -480 273 -254 255 -218 253 -248 497 -516 237 -252 473 -280 253 -490 487 -514 479 -274 253 -254 219 -496 263 -224 507 -258 247 -246 245 -246 247 -248 249 -504 513 -476 257 -242 243 -244 273 -246 499 -68728 129 -604 249 -242 243 -276 213 -276 245 -244 245 -246 245 -278 215 -278 215 -278 247 -248 247 -248 247 -248 249 -248 247 -250 247 -250 247 -250 247 -504 259 -246 245 -246 247 -248 503 -514 477 -272 255 -474 511 -478 527 -484 481 -272 253 -472 281 -254 485 -486 511 -478 511 -480 255 -242 527 -482 505 -254 241 -494 253 -242 495 -254 241 -244 273 -244 243 -494 509 -238 255 -254 255 -492 489 -260 247 -248 245 -248 247 -248 249 -248 249 -504 257 -129658 99 -98 131 -132 97 -100 97 -132 131 -98 131 -496 297 -266 163 -198 99 -398 165 -626 133 -198 531 -166 67 -66 431 -132 331 -100 65 -132 99 -100 2725 -9960 65 -3686 295 -1552 99 -362 195 -100 887 -98 263 -100 1495 -8372 67 -298 99 -100 131 -332 133 -198 233 -398 65 -1060 99 -164 327 \ No newline at end of file +RAW_Data: -478 507 -506 225 -272 495 -482 505 -254 241 -494 255 -242 525 -226 241 -274 243 -242 243 -496 509 -274 253 -254 219 -494 491 -258 249 -248 247 -248 249 -248 249 -248 249 -504 257 -68896 281 -214 241 -260 247 -248 247 -248 247 -250 247 -250 249 -248 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -250 249 -504 257 -248 245 -246 245 -248 503 -260 245 -246 245 -248 247 -248 247 -248 249 -504 513 -238 251 -254 255 -254 251 -474 515 -478 273 -254 255 -218 253 -248 499 -514 237 -254 473 -280 253 -490 485 -516 479 -274 253 -256 217 -496 263 -224 507 -258 247 -248 245 -246 247 -250 247 -504 513 -478 257 -244 241 -244 275 -246 499 -69128 321 -218 241 -230 249 -248 247 -246 249 -248 249 -248 249 -248 249 -250 249 -250 247 -250 247 -250 249 -250 247 -250 249 -250 249 -248 249 -504 257 -248 245 -246 245 -250 503 -514 477 -272 255 -474 515 -480 491 -518 479 -274 253 -474 281 -254 483 -486 479 -512 507 -506 223 -242 527 -482 509 -240 253 -496 273 -236 487 -260 247 -246 245 -246 247 -504 513 -238 251 -256 253 -492 495 -228 253 -250 249 -250 249 -250 249 -248 249 -504 257 -68860 273 -242 233 -256 249 -250 247 -248 247 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -250 247 -250 249 -248 249 -250 249 -248 249 -504 257 -248 245 -246 247 -248 503 -258 247 -244 245 -248 247 -248 247 -248 249 -504 513 -238 253 -254 253 -256 249 -474 515 -480 273 -254 255 -218 253 -248 497 -516 237 -252 473 -280 253 -490 487 -514 479 -274 253 -254 219 -496 263 -224 507 -258 247 -246 245 -246 247 -248 249 -504 513 -476 257 -242 243 -244 273 -246 499 -68728 129 -604 249 -242 243 -276 213 -276 245 -244 245 -246 245 -278 215 -278 215 -278 247 -248 247 -248 247 -248 249 -248 247 -250 247 -250 247 -250 247 -504 259 -246 245 -246 247 -248 503 -514 477 -272 255 -474 511 -478 527 -484 481 -272 253 -472 281 -254 485 -486 511 -478 511 -480 255 -242 527 -482 505 -254 241 -494 253 -242 495 -254 241 -244 273 -244 243 -494 509 -238 255 -254 255 -492 489 -260 247 -248 245 -248 247 -248 249 -248 249 -504 257 -129658 99 -98 131 -132 97 -100 97 -132 131 -98 131 -496 297 -266 163 -198 99 -398 165 -626 133 -198 531 -166 67 -66 431 -132 331 -100 65 -132 99 -100 2725 -9960 65 -3686 295 -1552 99 -362 195 -100 887 -98 263 -100 1495 -8372 67 -298 99 -100 131 -332 133 -198 233 -398 65 -1060 99 -164 327 +RAW_Data: 2243 -98 331 -100 1129 -66 761 -100 1393 -100 165 -66 2883 -64 357 -66 4703 -68 927 -98 233 -134 461 -66 3855 -134 165 -98 1281 -100 2053 -66 3061 -98 331 -98 8981 -66 365 -66 631 -100 1027 -100 4521 -134 597 -66 3187 -66 2619 -100 3011 -98 1151 -66 953 -100 1423 -66 1755 -166 333 -98 1557 -66 761 -66 865 -66 4837 -132 357 -132 2419 -100 1023 -66 65 -66 2507 -66 131 -66 761 -66 997 -66 333 -100 2259 -68 431 -100 2523 -66 987 -100 363 -66 363 -66 1197 -68 1589 -164 951 -96 5351 -66 697 -100 163 -100 4683 -66 2265 -68 2051 -64 457 -64 3005 -132 1057 -66 2221 -100 1661 -98 695 -100 99 -66 861 -66 1957 -100 731 -132 1857 -100 3177 -98 1807 -98 463 -66 499 -134 1129 -100 3737 -100 1889 -66 263 -98 623 -66 2103 -98 3165 -66 131 -100 195 -66 691 -66 67 -132 531 -66 1857 -100 199 -68 97 -68 197 -68 697 -68 233 -100 3749 -134 1691 -68 3289 -66 3751 -68 65 -100 853 -66 531 -132 1299 -66 1585 -98 65 -98 1577 -66 785 -98 1151 -66 165 -68 397 -100 4255 -100 857 -100 1017 -66 1575 -130 1255 -234 1923 -66 199 -102 301 -66 231 -66 691 -64 227 -64 195 -66 1257 -100 2353 -100 235 -100 1163 -66 5423 -66 2049 -66 1807 -66 523 -198 693 -100 367 -100 597 -100 4013 -100 233 -166 365 -66 1827 -100 1491 -100 785 -64 885 -66 599 -134 2847 -100 667 -100 4943 -98 3319 -98 6729 -98 361 -96 391 -66 723 -132 503 -66 1583 -166 297 -234 2045 -66 1185 -134 661 -66 195 -66 291 -164 523 -98 1679 -134 233 -132 761 -394 855 -100 2003 -164 261 -66 229 -96 953 -66 3889 -66 929 -66 993 -68 3099 -132 1673 -66 1833 -100 563 -100 1131 -100 3219 -232 4411 -100 1095 -100 5315 -100 631 -198 461 -198 1907 -100 1743 -68 863 -132 4013 -64 295 -66 3883 -100 2707 -198 923 -100 2539 -166 629 -100 563 -100 3783 -68 893 -66 2987 -98 2357 -98 1665 -66 599 -66 1259 -232 165 -66 1361 -66 1645 -166 1543 -66 565 -66 401 -134 465 -100 831 -98 2405 -100 1055 -66 2109 -100 1161 -68 431 -100 265 -68 235 -66 463 -66 3453 -100 433 -66 2693 -132 263 -166 729 -134 763 -134 1327 -100 397 -234 795 -68 563 -66 1625 -98 267 -66 4835 -66 197 -66 589 -66 7575 -100 1959 -100 131 -68 297 -134 261 -98 433 -66 1427 -66 2421 -100 2925 -166 1921 -134 1645 -66 97 -132 5423 -100 2423 -98 1065 -66 1715 -132 963 -66 2403 -66 1117 -328 1981 -66 527 -100 427 -164 865 -66 2129 -232 165 -68 165 -66 131 -366 131 -100 2613 -450 +RAW_Data: 937 -900 447 -454 969 -884 479 -466 939 -452 935 -454 981 -454 943 -452 955 -458 945 -452 979 -444 943 -486 945 -448 951 -464 977 -440 967 -478 935 -480 951 -456 969 -460 975 -450 973 -450 979 -470 977 -450 981 -910 485 -466 939 -928 489 -448 971 -940 445 -484 951 -928 485 -484 945 -948 479 -456 973 -918 481 -944 451 -928 471 -478 995 -912 487 -472 977 -15948 479 -444 1021 -910 521 -444 995 -942 471 -480 991 -450 1013 -452 1023 -446 1001 -484 981 -486 1007 -458 1015 -470 1007 -450 1033 -452 1005 -480 1005 -458 1013 -470 1007 -482 1015 -450 1023 -482 1009 -462 1015 -468 1011 -484 983 -482 1021 -944 487 -484 1015 -942 471 -486 1003 -948 503 -478 991 -948 501 -478 1031 -914 521 -486 991 -946 519 -916 511 -944 485 -474 1009 -974 487 -482 1015 -16224 521 -468 1005 -970 503 -478 1001 -954 505 -458 1035 -484 1019 -482 1039 -482 1019 -486 1031 -490 1009 -478 1033 -486 1033 -486 1011 -494 1039 -478 1039 -450 1049 -486 1033 -488 1005 -476 1071 -448 1067 -486 1017 -468 1045 -482 1045 -484 1015 -952 515 -482 1043 -944 519 -482 1049 -950 519 -454 1039 -956 523 -484 1011 -960 505 -486 1065 -956 509 -926 539 -944 519 -480 1017 -984 521 -454 1037 -16440 553 -440 1043 -976 507 -460 1069 -940 513 -486 1041 -480 1067 -482 1033 -476 1061 -472 1043 -510 1049 -486 1041 -482 1043 -482 1065 -476 1037 -486 1069 -492 1037 -484 1047 -504 1047 -486 1041 -484 1041 -514 1015 -520 1049 -476 1053 -490 1041 -980 519 -486 1043 -962 507 -482 1049 -994 507 -500 1043 -946 507 -516 1033 -982 517 -478 1049 -984 509 -976 505 -950 527 -490 1039 -980 519 -486 1047 -111258 195 -428 263 -162 163 -362 97 -132 65 -98 163 -132 825 -100 795 -100 1795 -134 587 -66 229 -100 1349 -164 3261 -66 2305 -132 2219 -66 5549 -234 497 -132 201 -66 667 -298 2369 -68 4381 -66 3909 -134 923 -98 723 -100 1651 -168 1197 -100 65 -66 199 -68 195 -100 197 -134 1135 -66 2787 -66 3163 -68 231 -68 197 -100 6675 -100 667 -98 1125 -66 67 -98 2423 -66 2017 -332 2949 -100 1129 -68 1655 -100 1229 -66 1285 -130 163 -132 1315 -66 525 -98 295 -100 131 -64 427 -132 2207 -98 1153 -66 99 -100 697 -98 1397 -166 863 -66 1393 -132 5005 -66 497 -100 1753 -100 597 -66 1667 -66 397 -100 961 -66 763 -134 859 -64 689 -98 1917 -134 199 -234 167 -100 131 -166 2061 -66 1521 -98 759 -100 983 -66 825 -166 459 -66 2049 -166 1615 -100 829 -234 631 -66 465 -66 1493 -68 433 -66 1623 -132 65 -100 1133 -132 3083 -66 199 -132 199 -68 1257 -66 +RAW_Data: 265 -68 1061 -98 533 -100 1233 -68 1721 -68 995 -100 2535 -66 4193 -232 727 -100 727 -100 2773 -66 133 -98 399 -134 233 -232 67 -66 497 -100 267 -132 1127 -134 1063 -66 565 -132 97 -132 523 -132 919 -66 891 -66 855 -98 495 -66 3363 -296 3199 -98 563 -66 133 -100 495 -98 1165 -134 1161 -166 1849 -98 853 -132 5647 -134 563 -98 1827 -100 131 -100 1125 -132 1659 -132 265 -68 1121 -66 465 -232 431 -68 3589 -98 197 -68 97 -164 1717 -66 1645 -66 397 -66 97 -68 231 -166 631 -100 627 -66 1757 -66 131 -164 527 -98 1285 -328 1213 -134 2059 -100 1791 -68 931 -66 1611 -66 1511 -66 2211 -66 2597 -100 2545 -98 197 -162 1089 -98 589 -360 495 -132 1685 -202 1095 -100 729 -100 2825 -100 231 -100 567 -100 231 -66 1027 -66 131 -68 525 -132 1613 -232 461 -232 1597 -66 627 -198 231 -98 131 -98 65 -100 1229 -68 2507 -64 1349 -66 195 -134 97 -66 1321 -100 855 -132 163 -132 1151 -100 1025 -164 329 -66 891 -98 951 -132 163 -166 591 -98 1149 -132 955 -66 1329 -98 923 -66 331 -64 4269 -66 797 -134 399 -98 267 -170 197 -100 429 -198 1225 -100 331 -100 231 -132 1463 -100 597 -164 331 -66 1863 -134 659 -98 5507 -100 719 -100 131 -64 655 -164 1579 -98 1423 -130 1381 -98 1317 -132 467 -66 495 -132 361 -132 4417 -98 631 -364 299 -100 1499 -132 267 -68 663 -98 691 -100 2433 -66 953 -98 721 -66 1355 -232 897 -134 897 -134 365 -100 267 -132 2059 -132 199 -102 797 -68 695 -66 601 -66 265 -68 499 -66 1327 -164 1355 -64 1279 -66 3257 -66 1351 -66 131 -96 359 -132 499 -232 623 -96 427 -68 1909 -98 591 -98 4671 -100 4541 -66 1491 -66 3347 -98 1277 -100 1679 -198 295 -130 357 -98 697 -98 865 -100 2817 -66 329 -98 787 -64 1117 -66 3313 -202 1721 -100 199 -100 399 -66 199 -132 1891 -100 235 -100 201 -134 765 -166 761 -132 1529 -66 629 -202 861 -130 3501 -98 1377 -100 1741 -164 1509 -66 735 -68 733 -66 265 -166 2015 -134 131 -100 663 -100 2995 -132 1577 -98 1885 -66 2461 -100 1189 -66 1425 -100 201 -100 1691 -100 199 -98 499 -166 233 -100 233 -134 661 -68 1393 -100 295 -164 2079 -66 1289 -66 329 -198 599 -100 465 -98 3995 -98 199 -268 2045 -264 199 -66 1593 -66 165 -68 1561 -164 629 -66 635 -100 1251 -230 2733 -66 1727 -66 629 -100 1229 -132 731 -66 163 -198 131 -100 693 -66 3223 -68 565 -132 1091 -134 531 -100 3223 -68 729 -100 1527 -134 895 -166 1265 -66 527 -100 201 -200 1463 -66 1233 -132 +RAW_Data: 2397 -200 167 -234 1803 -66 821 -100 1351 -66 1687 -100 165 -66 233 -66 1125 -100 2203 -132 197 -98 97 -66 593 -164 4187 -102 529 -66 1161 -68 799 -66 427 -232 263 -66 589 -68 495 -68 197 -100 525 -66 327 -98 427 -130 1551 -66 727 -102 133 -234 265 -98 459 -66 2337 -64 585 -68 297 -68 691 -98 1857 -134 665 -132 365 -66 931 -166 495 -430 689 -196 1191 -98 465 -100 931 -366 1351 -102 3185 -164 1151 -98 2465 -66 2193 -100 331 -134 165 -98 267 -166 1985 -98 889 -132 765 -66 531 -100 1449 -166 457 -98 1715 -66 299 -166 3131 -130 197 -98 817 -294 793 -100 97 -66 3415 -164 1019 -98 1675 -132 197 -100 133 -68 199 -134 3319 -298 297 -66 791 -66 1029 -134 2153 -100 1629 -132 1391 -68 1229 -100 665 -66 2039 -164 461 -64 261 -66 395 -202 395 -166 3159 -134 2253 -166 265 -132 395 -66 887 -98 163 -66 589 -98 227 -130 1151 -230 293 -66 591 -68 527 -132 2883 -100 231 -66 99 -232 761 -134 499 -64 929 -100 167 -300 2259 -100 691 -164 459 -66 493 -132 163 -64 1283 -164 757 -132 295 -264 1023 -100 197 -198 6635 -198 2407 -100 2091 -132 1531 -66 1889 -100 199 -134 3567 -100 2981 -100 263 -198 425 -164 595 -100 231 -68 2691 -66 965 -100 2907 -98 367 -132 885 -198 1721 -100 659 -100 97 -296 495 -166 299 -134 397 -132 699 -66 1165 -66 465 -68 197 -66 659 -66 1543 -66 819 -164 2913 -98 1061 -66 5475 -132 167 -100 1035 -66 3427 -298 429 -166 2723 -66 831 -98 133 -66 133 -66 495 -98 701 -66 1063 -98 1991 -100 3319 -66 263 -66 233 -66 695 -66 593 -132 595 -66 553 -66 459 -66 197 -164 2241 -66 165 -68 959 -98 1587 -166 65 -102 233 -66 465 -134 1227 -100 2359 -66 1959 -198 331 -232 165 -102 531 -100 63 -66 1999 -68 265 -100 429 -66 657 -166 297 -132 823 -100 129 -132 4511 -164 659 -68 299 -66 593 -66 99 -134 65 -100 397 -66 1561 -66 697 -100 429 -66 265 -134 361 -132 195 -130 1319 -66 133 -66 265 -100 397 -268 895 -100 363 -134 433 -66 133 -100 2321 -68 +RAW_Data: -98 3573 -98 533 -68 961 -68 729 -132 559 -166 2189 -100 131 -68 657 -100 1387 -132 133 -68 2255 -68 429 -66 231 -134 793 -100 887 -98 361 -166 2141 -66 227 -130 663 -100 759 -100 1161 -134 1821 -66 327 -98 985 -130 757 -132 131 -132 1693 -66 361 -98 1411 -100 591 -132 1025 -66 663 -66 1065 -166 1059 -166 365 -66 723 -100 1659 -132 1883 -98 785 -132 1031 -66 261 -66 2501 -98 297 -66 1195 -100 691 -134 3009 -100 3921 -66 861 -66 363 -132 3361 -132 723 -66 459 -164 163 -164 333 -66 1291 -98 821 -230 591 -164 97 -262 361 -66 689 -66 733 -66 233 -134 1627 -66 533 -66 195 -100 521 -100 493 -98 493 -98 2173 -66 2037 -132 165 -100 429 -132 695 -100 67 -132 465 -68 1491 -100 1257 -66 965 -100 365 -68 929 -132 561 -66 899 -132 597 -132 861 -100 2627 -166 197 -98 2079 -66 2223 -100 1791 -364 895 -132 1027 -132 235 -68 599 -132 829 -66 197 -132 695 -66 133 -66 531 -68 333 -64 563 -66 265 -132 369 -134 2239 -164 4269 -100 793 -66 1495 -198 821 -164 133 -66 867 -66 797 -66 429 -66 365 -166 1729 -168 959 -100 1417 -66 233 -100 2579 -166 993 -164 461 -66 1529 -68 961 -66 1049 -98 1061 -132 2847 -66 229 -66 397 -134 263 -100 3285 -66 4115 -66 1547 -134 297 -132 431 -100 2895 -100 563 -66 1491 -66 399 -100 721 -66 395 -68 399 -66 1289 -66 293 -164 2307 -98 525 -66 3663 -64 927 -132 499 -134 1127 -264 397 -98 399 -198 131 -100 333 -100 663 -164 921 -166 1481 -262 691 -64 659 -64 2167 -98 3689 -100 833 -100 2085 -66 697 -100 595 -66 923 -134 893 -232 265 -98 367 -66 1157 -66 263 -130 1017 -66 623 -66 753 -100 2873 -132 395 -198 2787 -100 861 -132 3847 -100 297 -66 233 -98 1333 -100 495 -100 1325 -134 367 -66 595 -66 361 -230 4931 -66 1821 -98 329 -98 365 -168 333 -300 897 -100 2777 -66 1945 -132 2601 -66 951 -66 425 -98 789 -98 359 -64 1051 -66 1443 -132 851 -98 625 -100 97 -66 731 -232 263 -134 2757 -68 3021 -166 265 -100 1633 -132 427 -66 233 -98 799 -100 1059 -100 263 -98 557 -68 1063 -66 461 -100 1023 -98 163 -198 1481 -132 1227 -98 327 -100 327 -66 1317 -66 1853 -66 1061 -134 1287 -66 1315 -66 1345 -132 723 -66 1225 -68 1463 -166 3261 -98 2883 -66 563 -100 821 -100 2077 -166 3137 -66 565 -66 1355 -234 1415 -132 165 -66 397 -132 493 -132 563 -166 893 -66 1193 -66 1249 -100 333 -132 2083 -66 921 -100 1225 -262 861 -166 1321 -100 895 -100 591 -98 1249 +RAW_Data: -98 97 -66 6825 -66 231 -68 14077 -66 1787 -66 1547 -64 2617 -66 2925 -66 1723 -132 1529 -66 865 -166 827 -198 431 -66 495 -66 1121 -198 1327 -100 397 -130 557 -66 97 -100 261 -98 723 -98 557 -98 463 -98 463 -100 325 -66 3703 -100 465 -198 1123 -98 2545 -66 361 -66 857 -64 3455 -132 663 -98 1991 -200 825 -100 919 -98 893 -164 1749 -66 7759 -132 3321 -66 1807 -132 527 -66 393 -100 817 -130 657 -164 1485 -98 2367 -66 4171 -100 197 -130 3665 -134 1059 -132 597 -66 533 -66 1023 -98 1253 -134 2021 -100 231 -100 233 -66 197 -66 199 -66 1961 -168 729 -100 531 -100 461 -98 1361 -100 11161 -100 659 -166 229 -98 1675 -98 1027 -100 2063 -298 431 -100 99 -134 1059 -66 199 -100 763 -134 231 -66 233 -102 1761 -98 331 -68 757 -132 425 -64 457 -132 99 -66 2091 -66 567 -164 2121 -68 2125 -132 595 -200 759 -102 797 -132 1345 -66 429 -132 1019 -66 195 -66 791 -68 1227 -68 797 -132 1591 -200 199 -134 165 -66 1053 -66 559 -98 853 -164 825 -100 329 -98 891 -196 689 -132 657 -100 2341 -98 1119 -66 1883 -100 2607 -100 467 -100 1067 -164 6935 -66 2409 -132 855 -66 1809 -98 1119 -164 65 -66 199 -100 233 -132 931 -132 563 -66 1393 -132 567 -66 301 -68 1295 -66 529 -98 793 -66 131 -134 533 -132 827 -132 731 -332 1251 -98 921 -98 327 -198 361 -234 529 -66 1577 -132 97 -134 199 -100 1099 -68 1193 -132 991 -100 953 -98 2895 -166 1679 -98 161 -130 129 -66 1019 -100 261 -264 531 -100 263 -134 299 -68 495 -98 831 -100 531 -66 1357 -100 2051 -100 229 -98 829 -66 427 -66 859 -134 995 -68 665 -66 1793 -134 361 -100 2349 -66 331 -100 197 -66 1591 -66 959 -66 431 -234 2219 -332 661 -66 1487 -100 3381 -68 261 -164 463 -134 3377 -68 1127 -134 691 -66 529 -132 99 -66 6687 -98 889 -132 197 -164 725 -100 963 -66 2947 -132 327 -132 889 -66 393 -98 1581 -100 193 -130 97 -66 293 -66 1675 -100 1887 -98 2017 -100 597 -66 293 -98 557 -100 259 -98 985 -100 1727 -100 165 -100 301 -232 329 -100 533 -98 727 -100 761 -66 961 -68 2759 -100 2019 -66 855 -230 859 -98 1215 -98 1887 -98 131 -98 819 -166 227 -130 723 -132 625 -66 501 -66 429 -66 831 -66 1291 -66 331 -132 431 -132 1389 -100 265 -166 1461 -66 1907 -490 911 -962 409 -508 919 -944 419 -486 913 -526 915 -480 925 -488 911 -488 943 -476 925 -486 947 -462 945 -482 933 -484 951 -460 977 -440 967 -484 945 -468 945 -466 975 -450 983 +RAW_Data: -444 977 -458 975 -456 975 -444 965 -940 485 -430 967 -928 487 -448 981 -910 489 -446 963 -944 485 -430 975 -930 489 -912 485 -896 487 -452 977 -916 509 -454 977 -922 479 -448 985 -15898 487 -456 973 -926 493 -448 1001 -918 481 -484 981 -478 979 -450 1013 -476 977 -450 1017 -476 983 -448 999 -480 985 -484 983 -478 985 -484 981 -480 983 -476 1001 -474 979 -496 973 -486 1015 -476 977 -476 1005 -484 973 -486 1007 -920 505 -456 1011 -918 509 -458 1011 -950 497 -452 1011 -920 507 -458 1007 -950 477 -958 483 -942 481 -480 1003 -918 515 -446 1039 -922 505 -458 1007 -16154 501 -462 1013 -934 517 -474 999 -958 483 -478 993 -484 1037 -450 1027 -482 1027 -452 1037 -482 1025 -444 1035 -490 1009 -482 1013 -484 1001 -484 1039 -474 1003 -484 1045 -464 1011 -480 1049 -446 1037 -492 1007 -482 1013 -510 1005 -494 1005 -970 485 -482 1017 -974 473 -498 1007 -974 481 -486 1047 -948 479 -482 1051 -948 497 -952 519 -938 485 -482 1041 -946 517 -478 1013 -944 503 -472 415 -83640 97 -200 65 -632 131 -300 365 -364 231 -132 1061 -100 3047 -100 1393 -66 499 -66 1091 -66 333 -66 2353 -100 2273 -66 1427 -166 563 -132 1559 -132 427 -100 925 -98 13469 -100 2019 -98 821 -132 1097 -68 297 -100 897 -100 1129 -166 465 -166 961 -66 597 -100 165 -66 267 -100 201 -100 765 -134 297 -66 165 -66 3081 -100 1293 -100 1289 -136 233 -66 357 -66 1155 -166 295 -100 1197 -68 1089 -98 425 -132 1187 -100 523 -98 463 -98 197 -98 131 -98 493 -66 393 -98 2797 -164 359 -232 325 -66 229 -164 625 -98 1215 -164 425 -66 589 -98 195 -66 1083 -100 197 -68 1557 -66 1427 -66 525 -66 429 -132 863 -66 1129 -166 831 -98 265 -98 1183 -66 3157 -100 2735 -98 2819 -166 4645 -66 301 -68 1395 -132 1097 -100 897 -198 629 -200 1419 -132 493 -66 521 -132 697 -100 695 -66 459 -298 859 -66 559 -100 1029 -100 4113 -66 1167 -66 14017 -66 2123 -68 525 -132 861 -100 329 -66 399 -134 1523 -132 327 -64 691 -98 463 -132 1803 -132 853 -166 715 -66 953 -66 525 -98 723 -132 989 -132 461 -98 459 -164 2239 -66 1185 -66 589 -100 1945 -230 1483 -66 399 -66 265 -168 965 -66 197 -168 699 -68 1125 -68 529 -98 491 -66 987 -130 525 -168 397 -66 597 -100 561 -132 1353 -66 391 -132 393 -66 591 -98 557 -98 787 -66 463 -100 199 -134 395 -100 759 -66 295 -130 261 -98 229 -100 99 -100 1595 -66 699 -100 499 -66 595 -98 327 -132 957 -132 331 -100 493 -100 1313 -66 295 -132 197 -198 1279 +RAW_Data: -66 9461 -100 329 -68 27921 -66 24331 -68 13415 -66 6439 -98 133 -66 4193 -98 395 -66 653 -66 983 -66 163 -66 955 -132 1791 -66 861 -100 363 -132 1659 -132 667 -166 467 -134 429 -166 265 -66 4065 -98 293 -98 3183 -130 555 -98 163 -162 259 -100 661 -100 7057 -100 931 -100 1297 -66 2559 -98 1193 -100 333 -100 563 -132 65 -100 793 -66 855 -64 659 -100 929 -102 893 -132 689 -66 3475 -68 1361 -198 331 -134 691 -66 295 -66 425 -164 731 -266 921 -100 599 -100 165 -66 227 -98 1091 -66 263 -66 1215 -100 227 -164 657 -66 953 -132 359 -66 1845 -66 1779 -132 753 -164 393 -66 731 -66 1195 -66 533 -66 797 -132 1623 -98 1281 -100 493 -98 659 -98 2417 -166 799 -132 1259 -100 559 -134 595 -166 199 -66 1461 -198 865 -100 459 -66 463 -166 165 -100 497 -66 1097 -66 1579 -100 1449 -98 885 -98 263 -100 1097 -132 627 -68 329 -132 487 -132 427 -132 361 -66 525 -98 687 -66 1161 -100 263 -66 729 -100 229 -98 559 -66 1213 -100 1015 -66 795 -66 5475 -66 4043 -66 1683 -166 1151 -132 429 -98 1447 -68 261 -98 985 -100 429 -100 1289 -198 2269 -132 7999 -98 1591 -132 3233 -66 861 -66 2087 -98 557 -98 719 -66 981 -98 563 -100 199 -100 523 -100 2319 -134 833 -100 495 -132 197 -66 295 -64 989 -66 1059 -198 7343 -66 2023 -66 963 -66 593 -66 2401 -100 491 -100 959 -66 297 -134 999 -132 99 -68 3609 -230 97 -198 1911 -66 265 -100 1195 -132 633 -132 595 -66 1381 -66 491 -66 1681 -100 297 -100 1827 -132 2269 -100 1351 -132 1513 -66 1225 -134 231 -66 1523 -100 363 -200 1227 -66 2943 -66 923 -134 2249 -66 1809 -100 1121 -132 265 -66 827 -98 199 -66 201 -100 3279 -100 565 -132 1689 -66 395 -66 2979 -134 1065 -66 367 -168 3585 -200 463 -100 563 -66 97 -166 2293 -66 265 -134 1255 -132 2401 -66 1579 -166 365 -100 861 -298 261 -98 761 -66 363 -132 657 -130 63 -130 557 -66 131 -130 2041 -100 233 -66 1791 -100 925 -134 265 -100 1063 -100 301 -168 661 -66 657 -64 263 -64 197 -66 1853 -100 663 -98 231 -66 731 -100 5539 -166 197 -68 1423 -134 361 -68 1727 -68 929 -100 1397 -134 1885 -66 1661 -66 265 -66 1183 -66 295 -166 263 -166 165 -66 329 -66 465 -100 1159 -134 697 -100 2443 -100 393 -98 1093 -66 953 -296 787 -132 425 -66 2019 -66 461 -98 1201 -100 397 -132 3551 -100 1431 -264 725 -330 1455 -66 263 -100 531 -296 499 -100 265 -100 163 -66 1145 -132 1313 -98 2101 -98 261 -132 1083 -66 5403 +RAW_Data: -66 2223 -66 11583 -66 131 -66 5071 -66 3723 -132 1415 -132 6905 -64 9685 -102 4739 -66 3355 -66 5301 -98 29993 -508 897 -950 437 -490 909 -974 423 -510 935 -486 925 -508 943 -490 937 -494 947 -482 941 -484 979 -440 979 -456 1003 -462 975 -460 971 -458 977 -468 973 -484 975 -472 971 -450 1011 -452 1003 -446 983 -480 979 -450 1017 -908 487 -472 971 -944 471 -450 999 -944 485 -468 977 -918 493 -448 1011 -934 499 -920 487 -914 487 -452 1011 -912 521 -446 1009 -904 517 -468 1007 -16000 531 -444 1009 -908 519 -468 1009 -912 515 -466 1009 -452 1021 -466 1011 -450 1019 -480 1017 -448 1045 -448 1019 -460 1041 -450 1019 -480 1019 -450 1039 -474 1001 -480 1021 -484 1005 -476 1015 -480 1017 -484 1011 -486 1017 -464 1041 -446 1047 -922 503 -458 1037 -946 513 -442 1047 -938 503 -480 1023 -916 537 -450 1049 -926 521 -904 519 -942 519 -450 1055 -910 519 -486 1033 -916 519 -486 1029 -16258 533 -464 1015 -940 515 -456 1053 -946 511 -482 1051 -434 1075 -442 1075 -448 1065 -440 1065 -450 1049 -480 1067 -462 1041 -446 1075 -450 1063 -460 1053 -480 1047 -450 1075 -446 1079 -452 1055 -478 1051 -448 1067 -444 1065 -480 753 -66842 99 -1090 465 -332 131 -68 131 -134 99 -132 167 -200 429 -100 1809 -132 2385 -230 265 -102 597 -134 1025 -66 365 -100 361 -66 825 -168 1331 -100 797 -132 431 -132 299 -198 661 -168 501 -100 463 -164 329 -66 559 -98 391 -98 1085 -198 1939 -66 1871 -164 2251 -134 493 -66 719 -198 361 -98 361 -64 197 -132 391 -164 691 -300 489 -98 2139 -66 1413 -66 1875 -196 557 -66 263 -132 1359 -66 1397 -66 631 -100 793 -132 723 -100 65 -66 529 -134 463 -68 789 -100 227 -66 923 -100 2649 -166 363 -66 395 -200 295 -130 1757 -68 2057 -100 1023 -66 359 -66 391 -132 1679 -66 359 -66 1217 -98 663 -98 463 -100 821 -98 165 -98 1589 -132 2367 -98 559 -132 1079 -100 9617 -66 3669 -134 1787 -68 1679 -132 361 -66 555 -100 661 -66 1523 -100 2057 -198 1025 -66 4177 -100 165 -66 265 -132 465 -134 299 -232 265 -100 1125 -132 1461 -132 1295 -100 499 -132 367 -68 263 -66 331 -66 365 -100 1643 -130 197 -132 997 -98 867 -98 1191 -100 2945 -100 2339 -98 1779 -66 295 -132 597 -66 165 -100 665 -100 463 -66 331 -66 593 -100 459 -68 489 -164 855 -66 261 -64 163 -100 4449 -100 859 -100 699 -132 199 -100 1685 -66 301 -132 2317 -68 231 -100 827 -66 1749 -132 99 -64 1185 -100 329 -100 1253 -66 1127 -98 827 -198 363 -132 265 -134 365 -66 297 -66 1125 -66 261 +RAW_Data: -266 29863 -66 2443 -66 5113 -100 5947 -21026 99 -134 301 -132 199 -132 131 -266 163 -196 131 -66 365 -66 465 -98 13819 -98 525 -98 329 -100 893 -66 1259 -66 431 -98 427 -130 1051 -392 463 -200 795 -164 399 -66 1489 -66 1377 -100 1423 -132 597 -100 689 -68 1559 -100 2263 -100 1327 -98 1059 -98 497 -66 595 -132 265 -66 299 -66 199 -66 563 -134 627 -66 165 -134 889 -66 2751 -232 893 -264 231 -66 299 -132 467 -132 861 -68 1263 -164 795 -66 2601 -100 429 -66 1525 -66 961 -98 265 -98 997 -66 233 -68 695 -100 697 -66 795 -66 1195 -66 1223 -68 2173 -66 467 -66 827 -66 535 -68 697 -100 1221 -166 165 -100 365 -132 723 -66 829 -132 2091 -232 265 -66 195 -66 459 -262 499 -100 461 -68 759 -100 1087 -66 259 -164 2845 -66 1365 -98 561 -200 331 -168 201 -166 1397 -198 197 -66 697 -68 1713 -68 293 -134 1317 -66 593 -328 395 -100 499 -132 2251 -100 563 -134 333 -134 1921 -134 1187 -68 561 -132 933 -66 797 -100 631 -100 399 -132 929 -66 2769 -66 851 -130 2047 -66 265 -100 7219 -66 1987 -66 299 -98 2199 -134 1063 -98 2843 -98 655 -132 231 -66 1123 -198 2137 -64 327 -66 3183 -66 1127 -66 631 -100 263 -102 3173 -132 267 -68 1289 -98 1593 -66 2415 -66 1185 -66 359 -132 1051 -66 2169 -66 427 -98 395 -132 793 -98 293 -166 727 -134 131 -100 1287 -98 427 -98 687 -164 823 -64 853 -66 865 -100 763 -66 2025 -100 959 -66 1891 -64 793 -100 763 -66 729 -166 99 -98 399 -134 763 -100 4203 -66 1321 -230 4023 -98 1053 -66 985 -98 1383 -66 3559 -164 1515 -100 2899 -66 797 -134 1169 -100 3055 -134 1615 -66 429 -100 495 -64 1583 -134 923 -66 921 -66 723 -68 1359 -98 787 -98 425 -100 393 -64 1189 -98 263 -98 491 -100 1455 -98 +RAW_Data: -202 531 -66 531 -66 1093 -66 1389 -66 1551 -134 2699 -66 1291 -132 65 -64 657 -98 1083 -164 393 -98 1359 -134 1461 -66 393 -100 561 -130 2113 -132 597 -66 431 -102 1759 -302 985 -66 235 -100 1395 -66 901 -66 1061 -100 463 -66 5673 -66 227 -66 225 -66 855 -66 1581 -132 2503 -100 657 -66 2535 -98 259 -64 1015 -66 231 -132 1197 -66 827 -166 9641 -66 1823 -132 1565 -132 299 -66 797 -66 1631 -132 327 -132 2227 -232 433 -68 499 -100 1793 -66 1161 -132 525 -66 129 -100 361 -66 1765 -132 229 -66 491 -132 2255 -100 3043 -332 299 -100 499 -100 267 -68 2967 -66 991 -100 729 -100 633 -66 529 -98 825 -100 1033 -100 331 -66 723 -100 725 -264 2987 -68 825 -66 2601 -134 333 -100 3181 -134 1059 -100 299 -134 3279 -100 1221 -132 659 -66 3157 -98 1595 -132 1561 -98 201 -134 465 -66 1843 -130 589 -66 1413 -66 331 -100 333 -66 661 -100 265 -68 201 -234 1027 -166 297 -100 1161 -132 1561 -134 629 -66 431 -66 1025 -98 427 -198 1527 -66 793 -66 1903 -66 131 -130 1285 -66 299 -134 397 -98 229 -132 499 -132 4747 -100 2355 -100 263 -132 1915 -132 1749 -132 759 -66 2253 -100 4545 -66 391 -100 521 -100 1083 -100 929 -134 565 -66 2355 -66 1331 -66 167 -100 465 -100 1727 -132 633 -330 433 -66 897 -132 165 -134 331 -98 627 -66 231 -66 167 -66 1397 -66 729 -132 1397 -68 165 -66 1627 -134 2187 -66 231 -134 795 -200 6469 -232 829 -66 3929 -66 891 -98 1977 -100 525 -68 859 -66 921 -264 1029 -68 959 -134 1555 -66 259 -100 687 -66 429 -264 663 -66 1559 -100 1127 -100 2327 -132 1913 -64 4193 -132 293 -98 99 -100 5613 -132 1351 -66 1545 -66 1677 -66 295 -64 1943 -100 595 -132 1959 -166 765 -66 1389 -100 823 -66 1749 -66 1217 -100 597 -100 297 -66 2019 -98 165 -100 4165 -100 67 -100 2477 -262 295 -66 919 -200 3555 -66 229 -66 2531 -98 557 -66 2525 -66 1463 -100 1293 -68 197 -68 1391 -66 1421 -66 595 -164 327 -68 2285 -66 593 -98 99 -68 463 -98 1063 -100 165 -68 99 -100 631 -66 1085 -66 859 -98 6599 -66 1429 -66 233 -66 397 -98 231 -132 1975 -132 333 -66 131 -134 3373 -100 4277 -66 1363 -232 2893 -166 3133 -64 951 -66 2815 -100 425 -98 327 -66 599 -68 1031 -98 133 -68 633 -68 429 -100 1129 -66 327 -130 2679 -66 1321 -100 463 -200 367 -98 667 -66 493 -132 885 -98 2183 -166 559 -98 981 -66 3201 -164 593 -66 493 -130 1923 -166 565 -100 2421 -98 461 -66 1427 -130 1955 -64 197 -66 1643 +RAW_Data: -132 2291 -66 3057 -68 2521 -166 333 -134 503 -400 3235 -66 2329 -68 995 -100 333 -100 97 -166 1757 -100 397 -100 165 -66 2755 -132 297 -134 163 -100 565 -100 1793 -100 1813 -162 1293 -98 97 -66 999 -66 1763 -68 261 -68 2391 -100 765 -364 859 -100 1855 -98 1399 -230 463 -134 301 -198 397 -100 961 -68 431 -134 695 -202 133 -100 365 -66 925 -98 165 -66 365 -132 663 -98 4573 -134 1479 -66 1019 -66 629 -66 233 -68 201 -66 569 -66 295 -134 1755 -296 3199 -100 3261 -168 3373 -132 1425 -100 759 -66 895 -98 201 -100 265 -166 99 -66 695 -66 1091 -66 855 -168 299 -100 229 -164 589 -66 521 -66 655 -134 329 -98 493 -200 429 -66 929 -66 673 -100 953 -66 823 -66 1283 -66 1979 -68 233 -66 1547 -164 589 -132 597 -66 131 -66 265 -100 761 -200 759 -66 689 -332 263 -100 1227 -68 1067 -164 2945 -100 959 -100 995 -100 399 -100 1193 -100 625 -66 399 -66 3021 -134 393 -66 4805 -66 1095 -68 231 -332 399 -166 1663 -68 561 -66 927 -98 1085 -164 1155 -98 627 -66 265 -132 263 -130 2211 -66 2159 -66 1029 -264 2669 -66 295 -66 8747 -100 329 -232 625 -134 429 -68 1329 -168 1355 -98 987 -66 1545 -98 1015 -98 699 -134 133 -134 1263 -66 4687 -166 8299 -66 1349 -434 933 -906 443 -452 949 -894 441 -480 909 -486 907 -456 947 -448 949 -434 969 -454 931 -460 941 -448 933 -450 979 -450 945 -450 935 -458 935 -486 927 -456 947 -450 951 -482 945 -428 975 -446 967 -452 955 -458 945 -912 485 -434 971 -902 481 -450 949 -926 451 -478 941 -920 481 -450 949 -920 473 -450 955 -916 471 -452 981 -918 449 -486 945 -910 483 -924 473 -15780 479 -450 967 -948 449 -482 943 -944 485 -468 941 -484 979 -446 1001 -444 999 -446 967 -484 969 -482 979 -478 947 -484 985 -470 973 -458 983 -492 971 -458 979 -494 971 -458 983 -494 973 -458 981 -498 975 -458 1013 -466 973 -952 475 -458 973 -950 489 -450 1011 -916 481 -478 1001 -918 481 -478 1001 -916 481 -478 1001 -920 483 -480 983 -946 479 -458 1013 -932 485 -952 479 -16040 493 -476 1009 -912 515 -464 1007 -910 517 -464 1007 -450 1001 -488 1001 -484 1011 -450 1019 -458 1039 -450 1031 -454 1005 -484 1009 -458 1015 -476 1009 -478 1035 -462 1015 -468 1007 -480 1001 -486 1015 -460 1041 -450 1017 -484 1019 -482 1009 -952 477 -494 1003 -944 485 -478 1013 -944 519 -482 1013 -942 487 -482 1013 -946 487 -484 1015 -944 487 -484 1015 -946 519 -454 1019 -942 505 -952 487 -16238 517 -468 1007 -942 521 -482 1011 -944 519 +RAW_Data: -450 1019 -482 1035 -480 1033 -460 1047 -476 1017 -484 1007 -484 1051 -484 1027 -452 1039 -478 1035 -458 1049 -480 1017 -480 1035 -480 1035 -472 1047 -484 1027 -454 1039 -480 1033 -488 1031 -488 1009 -962 521 -486 1017 -966 485 -490 1015 -139210 229 -98 461 -364 165 -334 131 -168 2121 -66 1049 -66 1215 -166 297 -136 1449 -100 3877 -100 1495 -234 331 -64 1345 -262 393 -100 529 -132 2921 -164 1223 -132 1807 -66 765 -66 397 -98 3405 -132 2123 -230 231 -66 2541 -100 2489 -98 4397 -132 461 -98 293 -64 991 -66 1125 -166 401 -100 131 -100 99 -100 265 -100 2555 -100 499 -98 1361 -134 265 -166 895 -100 2253 -100 1057 -100 129 -296 1147 -198 197 -66 1163 -66 1935 -98 1675 -66 1103 -100 891 -100 989 -164 1019 -66 2967 -68 1293 -166 3161 -66 133 -264 1065 -100 731 -66 1693 -66 529 -100 165 -68 865 -66 825 -232 1117 -196 2401 -66 3051 -296 229 -132 1843 -132 1687 -68 1119 -68 299 -68 97 -66 4741 -66 197 -200 2319 -100 1097 -66 3765 -66 131 -100 695 -132 2753 -66 2287 -100 1129 -68 331 -98 1433 -132 893 -100 465 -100 801 -66 529 -66 1515 -264 393 -98 263 -66 1831 -166 3533 -100 633 -100 1051 -100 331 -98 795 -134 959 -132 1229 -100 627 -132 2517 -66 165 -98 131 -66 2301 -166 163 -134 465 -66 2767 -66 1019 -66 401 -134 397 -232 893 -66 397 -66 833 -66 199 -66 303 -66 2775 -66 2069 -98 1841 -100 399 -66 793 -98 2793 -68 3769 -100 867 -66 861 -100 399 -66 1859 -100 631 -132 755 -100 689 -66 163 -64 2045 -64 2191 -102 1127 -68 727 -68 625 -164 1381 -66 1153 -132 1115 -98 1017 -100 491 -100 593 -132 991 -98 1415 -98 4813 -66 331 -98 131 -102 1847 -98 197 -68 263 -100 3265 -66 431 -100 493 -98 435 -134 133 -68 1185 -134 395 -100 131 -66 399 -134 767 -134 1125 -66 429 -198 3185 -100 2261 -66 523 -230 2475 -168 1297 -66 3243 -66 1853 -100 1657 -66 459 -66 827 -100 263 -66 303 -234 197 -166 1167 -100 2299 -66 1329 -68 461 -100 763 -132 3819 -366 757 -66 591 -164 621 -98 1445 -100 2155 -100 231 -100 631 -68 1161 -66 131 -166 67 -98 1915 -166 1891 -66 1261 -68 999 -164 165 -132 133 -168 2695 -68 1055 -198 97 -98 229 -66 229 -66 1215 -66 885 -100 303 -132 297 -164 619 -198 459 -64 989 -66 229 -66 597 -134 693 -64 1255 -100 65 -132 331 -66 199 -98 529 -100 2831 -98 1259 -66 4855 -100 1163 -166 299 -66 395 -98 3141 -66 1319 -66 2139 -100 161 -132 261 -130 821 -200 263 -134 931 -330 65 -98 99 -134 793 +RAW_Data: -66 597 -100 231 -68 167 -66 1659 -100 733 -66 1631 -100 165 -66 199 -66 233 -166 165 -100 1925 -68 595 -198 1785 -134 2177 -134 131 -66 1049 -98 3087 -132 195 -64 589 -66 397 -134 329 -66 2565 -164 327 -100 689 -64 1775 -100 5183 -132 1187 -66 329 -66 395 -132 165 -98 261 -98 1247 -64 1217 -66 927 -66 997 -66 199 -98 1419 -66 531 -166 1231 -66 697 -100 97 -66 563 -66 161 -264 3205 -200 525 -98 293 -100 291 -100 133 -66 759 -66 659 -100 983 -64 523 -130 431 -166 919 -66 1097 -100 1757 -66 1119 -66 917 -98 2647 -166 1247 -66 165 -264 1189 -100 899 -134 597 -68 2323 -66 1893 -66 1095 -100 533 -64 965 -100 1817 -130 1215 -66 1879 -64 821 -164 1117 -132 263 -132 131 -66 557 -66 431 -132 661 -100 1183 -98 629 -100 1679 -132 259 -66 623 -98 431 -66 399 -164 923 -100 297 -66 165 -166 2521 -198 99 -66 431 -132 1225 -66 1063 -68 131 -136 631 -66 163 -100 99 -298 965 -68 465 -68 465 -298 2545 -134 2639 -230 1489 -66 299 -66 1991 -234 65 -132 693 -134 429 -102 101 -68 461 -66 3333 -64 1229 -68 333 -66 265 -66 885 -64 3163 -100 467 -66 2651 -164 1221 -100 1527 -66 1259 -134 431 -232 1259 -100 6029 -164 297 -98 1151 -66 1415 -100 5289 -66 2467 -100 493 -132 495 -200 1121 -66 129 -66 757 -166 327 -130 5477 -66 1227 -230 395 -100 265 -132 497 -132 1133 -132 361 -100 1051 -164 3089 -132 1583 -100 65 -68 2315 -100 529 -132 2157 -68 1257 -66 1975 -98 427 -98 1347 -66 719 -164 857 -66 165 -66 1029 -132 297 -132 467 -100 731 -130 1985 -98 199 -166 899 -100 1391 -166 3425 -100 261 -132 721 -66 4845 -98 1193 -68 1225 -66 721 -100 1015 -64 983 -66 557 -130 693 -98 99 -64 1091 -98 197 -100 2321 -66 431 -134 727 -66 467 -102 891 -98 167 -134 2619 -66 393 -64 97 -100 589 -98 1583 -164 301 -68 1481 -98 295 -98 959 -66 365 -98 1253 -66 231 -100 1255 -132 1813 -132 1645 -100 361 -132 395 -100 427 -164 1197 -98 1001 -100 861 -66 1161 -98 195 -100 197 -66 1429 -66 663 -66 1427 -98 665 -66 699 -100 663 -66 855 -196 161 -100 361 -98 823 -66 227 -66 621 -132 1853 -230 461 -230 623 -100 557 -98 229 -98 133 -134 1291 -66 533 -166 627 -134 195 -134 593 -64 591 -66 1019 -66 1049 -262 297 -100 2921 -66 133 -66 963 -134 165 -100 diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c new file mode 100644 index 00000000000..dcb51de4053 --- /dev/null +++ b/lib/subghz/protocols/holtek.c @@ -0,0 +1,360 @@ +#include "holtek.h" + +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +/* + * Help + * https://pdf1.alldatasheet.com/datasheet-pdf/view/82103/HOLTEK/HT640.html + * https://fccid.io/OJM-CMD-HHLR-XXXA + * + */ + +#define TAG "SubGhzProtocolHoltek" + +#define HOLTEK_HEADER_MASK 0xF000000000 +#define HOLTEK_HEADER 0x5000000000 + +static const SubGhzBlockConst subghz_protocol_holtek_const = { + .te_short = 500, + .te_long = 1000, + .te_delta = 100, + .min_count_bit_for_found = 40, +}; + +struct SubGhzProtocolDecoderHoltek { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderHoltek { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + HoltekDecoderStepReset = 0, + HoltekDecoderStepFoundStartBit, + HoltekDecoderStepSaveDuration, + HoltekDecoderStepCheckDuration, +} HoltekDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_holtek_decoder = { + .alloc = subghz_protocol_decoder_holtek_alloc, + .free = subghz_protocol_decoder_holtek_free, + + .feed = subghz_protocol_decoder_holtek_feed, + .reset = subghz_protocol_decoder_holtek_reset, + + .get_hash_data = subghz_protocol_decoder_holtek_get_hash_data, + .serialize = subghz_protocol_decoder_holtek_serialize, + .deserialize = subghz_protocol_decoder_holtek_deserialize, + .get_string = subghz_protocol_decoder_holtek_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_holtek_encoder = { + .alloc = subghz_protocol_encoder_holtek_alloc, + .free = subghz_protocol_encoder_holtek_free, + + .deserialize = subghz_protocol_encoder_holtek_deserialize, + .stop = subghz_protocol_encoder_holtek_stop, + .yield = subghz_protocol_encoder_holtek_yield, +}; + +const SubGhzProtocol subghz_protocol_holtek = { + .name = SUBGHZ_PROTOCOL_HOLTEK_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_315 | + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_holtek_decoder, + .encoder = &subghz_protocol_holtek_encoder, +}; + +void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderHoltek* instance = malloc(sizeof(SubGhzProtocolEncoderHoltek)); + + instance->base.protocol = &subghz_protocol_holtek; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 128; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_runing = false; + return instance; +} + +void subghz_protocol_encoder_holtek_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderHoltek* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderHoltek instance + * @return true On success + */ +static bool subghz_protocol_encoder_holtek_get_upload(SubGhzProtocolEncoderHoltek* instance) { + furi_assert(instance); + + size_t index = 0; + size_t size_upload = (instance->generic.data_count_bit * 2) + 2; + if(size_upload > instance->encoder.size_upload) { + FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); + return false; + } else { + instance->encoder.size_upload = size_upload; + } + + //Send header + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_holtek_const.te_short * 36); + //Send start bit + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_holtek_const.te_short); + //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)subghz_protocol_holtek_const.te_long); + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_holtek_const.te_short); + } else { + //send bit 0 + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_holtek_const.te_short); + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_holtek_const.te_long); + } + } + return true; +} + +bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderHoltek* instance = context; + bool res = false; + do { + if(!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_holtek_get_upload(instance); + instance->encoder.is_runing = true; + + res = true; + } while(false); + + return res; +} + +void subghz_protocol_encoder_holtek_stop(void* context) { + SubGhzProtocolEncoderHoltek* instance = context; + instance->encoder.is_runing = false; +} + +LevelDuration subghz_protocol_encoder_holtek_yield(void* context) { + SubGhzProtocolEncoderHoltek* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) { + instance->encoder.is_runing = 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_holtek_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderHoltek* instance = malloc(sizeof(SubGhzProtocolDecoderHoltek)); + instance->base.protocol = &subghz_protocol_holtek; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_holtek_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHoltek* instance = context; + free(instance); +} + +void subghz_protocol_decoder_holtek_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHoltek* instance = context; + instance->decoder.parser_step = HoltekDecoderStepReset; +} + +void subghz_protocol_decoder_holtek_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderHoltek* instance = context; + + switch(instance->decoder.parser_step) { + case HoltekDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_short * 36) < + subghz_protocol_holtek_const.te_delta * 36)) { + //Found Preambula + instance->decoder.parser_step = HoltekDecoderStepFoundStartBit; + } + break; + case HoltekDecoderStepFoundStartBit: + if((level) && (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_short) < + subghz_protocol_holtek_const.te_delta)) { + //Found StartBit + instance->decoder.parser_step = HoltekDecoderStepSaveDuration; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + } else { + instance->decoder.parser_step = HoltekDecoderStepReset; + } + break; + case HoltekDecoderStepSaveDuration: + //save duration + if(!level) { + if(duration >= ((uint32_t)subghz_protocol_holtek_const.te_short * 10 + + subghz_protocol_holtek_const.te_delta)) { + instance->decoder.parser_step = HoltekDecoderStepSaveDuration; + if(instance->decoder.decode_count_bit == + subghz_protocol_holtek_const.min_count_bit_for_found) { + if((instance->decoder.decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) { + 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 = HoltekDecoderStepFoundStartBit; + break; + } else { + instance->decoder.te_last = duration; + + instance->decoder.parser_step = HoltekDecoderStepCheckDuration; + } + } else { + instance->decoder.parser_step = HoltekDecoderStepReset; + } + break; + case HoltekDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_holtek_const.te_short) < + subghz_protocol_holtek_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_long) < + subghz_protocol_holtek_const.te_delta * 2)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = HoltekDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_holtek_const.te_long) < + subghz_protocol_holtek_const.te_delta * 2) && + (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_short) < + subghz_protocol_holtek_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = HoltekDecoderStepSaveDuration; + } else { + instance->decoder.parser_step = HoltekDecoderStepReset; + } + } else { + instance->decoder.parser_step = HoltekDecoderStepReset; + } + break; + } +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_holtek_check_remote_controller(SubGhzBlockGeneric* instance) { + if((instance->data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) { + instance->serial = + subghz_protocol_blocks_reverse_key((instance->data >> 16) & 0xFFFFF, 20); + uint16_t btn = instance->data & 0xFFFF; + if((btn & 0xf) != 0xA) { + instance->btn = 0x1 << 4 | (btn & 0xF); + } else if(((btn >> 4) & 0xF) != 0xA) { + instance->btn = 0x2 << 4 | ((btn >> 4) & 0xF); + } else if(((btn >> 8) & 0xF) != 0xA) { + instance->btn = 0x3 << 4 | ((btn >> 8) & 0xF); + } else if(((btn >> 12) & 0xF) != 0xA) { + instance->btn = 0x4 << 4 | ((btn >> 12) & 0xF); + } else { + instance->btn = 0; + } + } else { + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + } +} + +uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHoltek* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +bool subghz_protocol_decoder_holtek_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset) { + furi_assert(context); + SubGhzProtocolDecoderHoltek* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); +} + +bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderHoltek* instance = context; + return subghz_block_generic_deserialize(&instance->generic, flipper_format); +} + +void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) { + furi_assert(context); + SubGhzProtocolDecoderHoltek* instance = context; + subghz_protocol_holtek_check_remote_controller(&instance->generic); + + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Sn:0x%05lX BTN:%X ", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)((instance->generic.data >> 32) & 0xFFFFFF), + (uint32_t)(instance->generic.data & 0xFFFFFF), + instance->generic.serial, + instance->generic.btn >> 4); + + if((instance->generic.btn & 0xF) == 0xE) { + string_cat_printf(output, "ON\r\n"); + } else if(((instance->generic.btn & 0xF) == 0xB)) { + string_cat_printf(output, "OFF\r\n"); + } +} diff --git a/lib/subghz/protocols/holtek.h b/lib/subghz/protocols/holtek.h new file mode 100644 index 00000000000..0110fdd321a --- /dev/null +++ b/lib/subghz/protocols/holtek.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_HOLTEK_NAME "Holtek" + +typedef struct SubGhzProtocolDecoderHoltek SubGhzProtocolDecoderHoltek; +typedef struct SubGhzProtocolEncoderHoltek SubGhzProtocolEncoderHoltek; + +extern const SubGhzProtocolDecoder subghz_protocol_holtek_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_holtek_encoder; +extern const SubGhzProtocol subghz_protocol_holtek; + +/** + * Allocate SubGhzProtocolEncoderHoltek. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderHoltek* pointer to a SubGhzProtocolEncoderHoltek instance + */ +void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderHoltek. + * @param context Pointer to a SubGhzProtocolEncoderHoltek instance + */ +void subghz_protocol_encoder_holtek_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderHoltek instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderHoltek instance + */ +void subghz_protocol_encoder_holtek_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderHoltek instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_holtek_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderHoltek. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderHoltek* pointer to a SubGhzProtocolDecoderHoltek instance + */ +void* subghz_protocol_decoder_holtek_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderHoltek. + * @param context Pointer to a SubGhzProtocolDecoderHoltek instance + */ +void subghz_protocol_decoder_holtek_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderHoltek. + * @param context Pointer to a SubGhzProtocolDecoderHoltek instance + */ +void subghz_protocol_decoder_holtek_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderHoltek instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_holtek_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderHoltek instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderHoltek. + * @param context Pointer to a SubGhzProtocolDecoderHoltek instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param frequency The frequency at which the signal was received, Hz + * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @return true On success + */ +bool subghz_protocol_decoder_holtek_serialize( + void* context, + FlipperFormat* flipper_format, + uint32_t frequency, + FuriHalSubGhzPreset preset); + +/** + * Deserialize data SubGhzProtocolDecoderHoltek. + * @param context Pointer to a SubGhzProtocolDecoderHoltek instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderHoltek instance + * @param output Resulting text + */ +void subghz_protocol_decoder_holtek_get_string(void* context, string_t output); diff --git a/lib/subghz/protocols/registry.c b/lib/subghz/protocols/registry.c index 0741da93931..9577b3de232 100644 --- a/lib/subghz/protocols/registry.c +++ b/lib/subghz/protocols/registry.c @@ -8,7 +8,7 @@ const SubGhzProtocol* subghz_protocol_registry[] = { &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis, &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_gate_tx, &subghz_protocol_raw, &subghz_protocol_firefly, &subghz_protocol_secplus_v2, - &subghz_protocol_secplus_v1, &subghz_protocol_megacode, + &subghz_protocol_secplus_v1, &subghz_protocol_megacode, &subghz_protocol_holtek, }; diff --git a/lib/subghz/protocols/registry.h b/lib/subghz/protocols/registry.h index abd5697dac7..a8bc9af4581 100644 --- a/lib/subghz/protocols/registry.h +++ b/lib/subghz/protocols/registry.h @@ -25,6 +25,7 @@ #include "secplus_v2.h" #include "secplus_v1.h" #include "megacode.h" +#include "holtek.h" /** * Registration by name SubGhzProtocol. From 597ee5b939f6b61de72620199715414f37c95d66 Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 11 May 2022 12:45:01 +0300 Subject: [PATCH 16/24] [FL-2527] Updater: Migrating to new manifest path convention (#1213) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updater: Migrating to new manifest path convention * RPC: Added update preparation status to RPC * RPC: bumped protobuf submodule * Bumped protobuf_version.h * FuriCore: add missing include. Lib: make mlib smaller * Explicitly tell where we have doubles and fix random in animations * makefile: added -DLFS_NO_DEBUG * Updater: path len constant dedup * Updater: checking for hardware version match before parsing manifest * LD: moved _DRIVER_CONTEXT sections to .bss, where they belong. * LD: avoiding PROBGITS warning, moved _CONTEXT to data * Updater: Added version check on update package - refusing to install outdated Co-authored-by: あく --- applications/bt/bt_cli.c | 6 +- applications/bt/bt_debug_app/views/bt_test.c | 2 +- .../desktop/animations/animation_manager.c | 3 +- .../animations/views/bubble_animation_view.c | 3 +- .../infrared/helpers/infrared_parser.cpp | 2 +- .../view_modules/lfrfid_view_tune_vm.cpp | 6 +- applications/rpc/rpc_system.c | 17 +- applications/subghz/subghz_cli.c | 2 +- applications/unit_tests/test_index.c | 2 +- applications/updater/cli/updater_cli.c | 2 +- applications/updater/util/update_task.c | 30 ++- .../updater/util/update_task_worker_backup.c | 3 +- assets/compiled/flipper.pb.h | 6 +- assets/compiled/protobuf_version.h | 2 +- assets/compiled/system.pb.c | 4 + assets/compiled/system.pb.h | 30 +++ assets/protobuf | 2 +- core/furi/memmgr_heap.c | 1 + firmware/targets/f7/Src/main.c | 2 +- firmware/targets/f7/Src/update.c | 65 +++-- .../targets/f7/furi_hal/furi_hal_random.c | 8 +- .../targets/f7/furi_hal/furi_hal_subghz.c | 6 +- firmware/targets/f7/stm32wb55xx_flash.ld | 5 +- firmware/targets/f7/target.mk | 4 +- lib/flipper_format/flipper_format_stream.c | 2 +- lib/lib.mk | 2 +- lib/subghz/subghz_tx_rx_worker.c | 5 +- lib/update_util/update_manifest.c | 9 +- lib/update_util/update_manifest.h | 2 + lib/update_util/update_operation.c | 234 +++++++++--------- lib/update_util/update_operation.h | 24 +- scripts/update.py | 14 +- 32 files changed, 289 insertions(+), 216 deletions(-) diff --git a/applications/bt/bt_cli.c b/applications/bt/bt_cli.c index 122eedf96fa..1c9b198bebc 100644 --- a/applications/bt/bt_cli.c +++ b/applications/bt/bt_cli.c @@ -68,7 +68,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { while(!cli_cmd_interrupt_received(cli)) { osDelay(250); - printf("RSSI: %6.1f dB\r", furi_hal_bt_get_rssi()); + printf("RSSI: %6.1f dB\r", (double)furi_hal_bt_get_rssi()); fflush(stdout); } @@ -140,11 +140,9 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { printf("Press CTRL+C to stop\r\n"); furi_hal_bt_start_packet_rx(channel, datarate); - float rssi_raw = 0; while(!cli_cmd_interrupt_received(cli)) { osDelay(250); - rssi_raw = furi_hal_bt_get_rssi(); - printf("RSSI: %03.1f dB\r", rssi_raw); + printf("RSSI: %03.1f dB\r", (double)furi_hal_bt_get_rssi()); fflush(stdout); } uint16_t packets_received = furi_hal_bt_stop_packet_test(); diff --git a/applications/bt/bt_debug_app/views/bt_test.c b/applications/bt/bt_debug_app/views/bt_test.c index ac10e0a82b0..70f57c12c18 100755 --- a/applications/bt/bt_debug_app/views/bt_test.c +++ b/applications/bt/bt_debug_app/views/bt_test.c @@ -99,7 +99,7 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str(canvas, 6, 60, model->message); if(model->state == BtTestStateStarted) { if(model->rssi != 0.0f) { - snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", model->rssi); + snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", (double)model->rssi); canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str); } } else if(model->state == BtTestStateStopped) { diff --git a/applications/desktop/animations/animation_manager.c b/applications/desktop/animations/animation_manager.c index f8e937162bf..75d45ef7b39 100644 --- a/applications/desktop/animations/animation_manager.c +++ b/applications/desktop/animations/animation_manager.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -391,7 +392,7 @@ static StorageAnimation* } } - uint32_t lucky_number = random() % whole_weight; + uint32_t lucky_number = furi_hal_random_get() % whole_weight; uint32_t weight = 0; StorageAnimation* selected = NULL; diff --git a/applications/desktop/animations/views/bubble_animation_view.c b/applications/desktop/animations/views/bubble_animation_view.c index 9b60d45c825..380664c8dff 100644 --- a/applications/desktop/animations/views/bubble_animation_view.c +++ b/applications/desktop/animations/views/bubble_animation_view.c @@ -100,7 +100,8 @@ static const FrameBubble* return NULL; } - uint8_t index = random() % (active ? model->active_bubbles : model->passive_bubbles); + uint8_t index = + furi_hal_random_get() % (active ? model->active_bubbles : model->passive_bubbles); const BubbleAnimation* animation = model->current; for(int i = 0; i < animation->frame_bubble_sequences_count; ++i) { diff --git a/applications/infrared/helpers/infrared_parser.cpp b/applications/infrared/helpers/infrared_parser.cpp index 12a9392460a..d85a7269b96 100644 --- a/applications/infrared/helpers/infrared_parser.cpp +++ b/applications/infrared/helpers/infrared_parser.cpp @@ -145,7 +145,7 @@ bool infrared_parser_is_raw_signal_valid( frequency); result = false; } else if((duty_cycle <= 0) || (duty_cycle > 1)) { - FURI_LOG_E(TAG, "Duty cycle is out of range (0 - 1): %f", duty_cycle); + FURI_LOG_E(TAG, "Duty cycle is out of range (0 - 1): %f", (double)duty_cycle); result = false; } else if((timings_cnt <= 0) || (timings_cnt > MAX_TIMINGS_AMOUNT)) { FURI_LOG_E( diff --git a/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp b/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp index 3039517e0bf..5c244b92ca3 100644 --- a/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp +++ b/applications/lfrfid_debug/view_modules/lfrfid_view_tune_vm.cpp @@ -29,6 +29,8 @@ void LfRfidViewTuneVM::view_draw_callback(Canvas* canvas, void* _model) { constexpr uint8_t buffer_size = 128; char buffer[buffer_size + 1]; + double freq = ((float)SystemCoreClock / ((float)model->ARR + 1)); + double duty = ((float)model->CCR + 1) / ((float)model->ARR + 1) * 100.0f; snprintf( buffer, buffer_size, @@ -38,10 +40,10 @@ void LfRfidViewTuneVM::view_draw_callback(Canvas* canvas, void* _model) { "duty = %.4f", model->pos == 0 ? ">" : "", model->ARR, - (float)SystemCoreClock / ((float)model->ARR + 1), + freq, model->pos == 1 ? ">" : "", model->CCR, - ((float)model->CCR + 1) / ((float)model->ARR + 1) * 100.0f); + duty); elements_multiline_text_aligned(canvas, 2, 2, AlignLeft, AlignTop, buffer); } diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c index 9ce7e34a38e..45ae2e5a010 100644 --- a/applications/rpc/rpc_system.c +++ b/applications/rpc/rpc_system.c @@ -275,15 +275,22 @@ static void rpc_system_system_update_request_process(const PB_Main* request, voi RpcSession* session = (RpcSession*)context; furi_assert(session); - bool update_prepare_result = - update_operation_prepare(request->content.system_update_request.update_manifest) == - UpdatePrepareResultOK; + UpdatePrepareResult update_prepare_result = + update_operation_prepare(request->content.system_update_request.update_manifest); + /* RPC enum does not have such entry; setting to closest one */ + if(update_prepare_result == UpdatePrepareResultOutdatedManifestVersion) { + update_prepare_result = UpdatePrepareResultManifestInvalid; + } PB_Main* response = malloc(sizeof(PB_Main)); response->command_id = request->command_id; response->has_next = false; - response->command_status = update_prepare_result ? PB_CommandStatus_OK : - PB_CommandStatus_ERROR_INVALID_PARAMETERS; + response->command_status = (update_prepare_result == UpdatePrepareResultOK) ? + PB_CommandStatus_OK : + PB_CommandStatus_ERROR_INVALID_PARAMETERS; + response->which_content = PB_Main_system_update_response_tag; + response->content.system_update_response.code = + (PB_System_UpdateResponse_UpdateResultCode)update_prepare_result; rpc_send_and_release(session, response); free(response); } diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index d22b86f201e..f919e1cf2b1 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -94,7 +94,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { while(!cli_cmd_interrupt_received(cli)) { osDelay(250); - printf("RSSI: %03.1fdbm\r", furi_hal_subghz_get_rssi()); + printf("RSSI: %03.1fdbm\r", (double)furi_hal_subghz_get_rssi()); fflush(stdout); } diff --git a/applications/unit_tests/test_index.c b/applications/unit_tests/test_index.c index 4045c8e2abb..a1acbed41e8 100644 --- a/applications/unit_tests/test_index.c +++ b/applications/unit_tests/test_index.c @@ -70,7 +70,7 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { cycle_counter = (furi_hal_get_tick() - cycle_counter); - FURI_LOG_I(TAG, "Consumed: %0.2fs", (float)cycle_counter / 1000); + FURI_LOG_I(TAG, "Consumed: %u us", cycle_counter); if(test_result == 0) { furi_hal_delay_ms(200); /* wait for tested services and apps to deallocate */ diff --git a/applications/updater/cli/updater_cli.c b/applications/updater/cli/updater_cli.c index dfc7fbcef86..fb2edeb93c9 100644 --- a/applications/updater/cli/updater_cli.c +++ b/applications/updater/cli/updater_cli.c @@ -52,7 +52,7 @@ static void updater_cli_restore(string_t args) { static void updater_cli_help(string_t args) { UNUSED(args); printf("Commands:\r\n" - "\tinstall /ext/update/PACKAGE/update.fuf - verify & apply update package\r\n" + "\tinstall /ext/path/to/update.fuf - verify & apply update package\r\n" "\tbackup /ext/path/to/backup.tar - create internal storage backup\r\n" "\trestore /ext/path/to/backup.tar - restore internal storage backup\r\n"); } diff --git a/applications/updater/util/update_task.c b/applications/updater/util/update_task.c index 373f680a903..1238bdb0f83 100644 --- a/applications/updater/util/update_task.c +++ b/applications/updater/util/update_task.c @@ -260,16 +260,18 @@ bool update_task_parse_manifest(UpdateTask* update_task) { string_init(manifest_path); do { - update_task_set_progress(update_task, UpdateTaskStageProgress, 10); - if(!update_operation_get_current_package_path( - update_task->storage, update_task->update_path)) { + update_task_set_progress(update_task, UpdateTaskStageProgress, 13); + if(!furi_hal_version_do_i_belong_here()) { break; } - path_concat( - string_get_cstr(update_task->update_path), - UPDATE_MANIFEST_DEFAULT_NAME, - manifest_path); + update_task_set_progress(update_task, UpdateTaskStageProgress, 20); + if(!update_operation_get_current_package_manifest_path( + update_task->storage, manifest_path)) { + break; + } + + path_extract_dirname(string_get_cstr(manifest_path), update_task->update_path); update_task_set_progress(update_task, UpdateTaskStageProgress, 30); UpdateManifest* manifest = update_task->manifest; @@ -277,6 +279,16 @@ bool update_task_parse_manifest(UpdateTask* update_task) { break; } + update_task_set_progress(update_task, UpdateTaskStageProgress, 40); + if(manifest->manifest_version < UPDATE_OPERATION_MIN_MANIFEST_VERSION) { + break; + } + + update_task_set_progress(update_task, UpdateTaskStageProgress, 50); + if(manifest->target != furi_hal_version_get_hw_target()) { + break; + } + update_task->state.groups = update_task_get_task_groups(update_task); for(size_t stage_counter = 0; stage_counter < COUNT_OF(update_task_stage_progress); ++stage_counter) { @@ -286,13 +298,13 @@ bool update_task_parse_manifest(UpdateTask* update_task) { } } - update_task_set_progress(update_task, UpdateTaskStageProgress, 50); + update_task_set_progress(update_task, UpdateTaskStageProgress, 60); if((update_task->state.groups & UpdateTaskStageGroupFirmware) && !update_task_check_file_exists(update_task, manifest->firmware_dfu_image)) { break; } - update_task_set_progress(update_task, UpdateTaskStageProgress, 70); + update_task_set_progress(update_task, UpdateTaskStageProgress, 80); if((update_task->state.groups & UpdateTaskStageGroupRadio) && (!update_task_check_file_exists(update_task, manifest->radio_image) || (manifest->radio_version.version.type == 0))) { diff --git a/applications/updater/util/update_task_worker_backup.c b/applications/updater/util/update_task_worker_backup.c index 485fdd48a75..011510ed961 100644 --- a/applications/updater/util/update_task_worker_backup.c +++ b/applications/updater/util/update_task_worker_backup.c @@ -63,7 +63,6 @@ static bool update_task_post_update(UpdateTask* update_task) { TarArchive* archive = tar_archive_alloc(update_task->storage); do { - CHECK_RESULT(update_task_parse_manifest(update_task)); path_concat( string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, file_path); @@ -114,7 +113,7 @@ int32_t update_task_worker_backup_restore(void* context) { return UPDATE_TASK_NOERR; } - if(!update_operation_get_current_package_path(update_task->storage, update_task->update_path)) { + if(!update_task_parse_manifest(update_task)) { return UPDATE_TASK_FAILED; } diff --git a/assets/compiled/flipper.pb.h b/assets/compiled/flipper.pb.h index 88548beac28..3199090dba6 100644 --- a/assets/compiled/flipper.pb.h +++ b/assets/compiled/flipper.pb.h @@ -103,6 +103,7 @@ typedef struct _PB_Main { PB_Storage_BackupRestoreRequest storage_backup_restore_request; PB_System_PowerInfoRequest system_power_info_request; PB_System_PowerInfoResponse system_power_info_response; + PB_System_UpdateResponse system_update_response; } content; } PB_Main; @@ -171,6 +172,7 @@ extern "C" { #define PB_Main_storage_backup_restore_request_tag 43 #define PB_Main_system_power_info_request_tag 44 #define PB_Main_system_power_info_response_tag 45 +#define PB_Main_system_update_response_tag 46 /* Struct field encoding specification for nanopb */ #define PB_Empty_FIELDLIST(X, a) \ @@ -228,7 +230,8 @@ X(a, STATIC, ONEOF, MSG_W_CB, (content,system_update_request,content.system X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_backup_create_request,content.storage_backup_create_request), 42) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_backup_restore_request,content.storage_backup_restore_request), 43) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,system_power_info_request,content.system_power_info_request), 44) \ -X(a, STATIC, ONEOF, MSG_W_CB, (content,system_power_info_response,content.system_power_info_response), 45) +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_power_info_response,content.system_power_info_response), 45) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_update_response,content.system_update_response), 46) #define PB_Main_CALLBACK NULL #define PB_Main_DEFAULT NULL #define PB_Main_content_empty_MSGTYPE PB_Empty @@ -273,6 +276,7 @@ X(a, STATIC, ONEOF, MSG_W_CB, (content,system_power_info_response,content.s #define PB_Main_content_storage_backup_restore_request_MSGTYPE PB_Storage_BackupRestoreRequest #define PB_Main_content_system_power_info_request_MSGTYPE PB_System_PowerInfoRequest #define PB_Main_content_system_power_info_response_MSGTYPE PB_System_PowerInfoResponse +#define PB_Main_content_system_update_response_MSGTYPE PB_System_UpdateResponse extern const pb_msgdesc_t PB_Empty_msg; extern const pb_msgdesc_t PB_StopSession_msg; diff --git a/assets/compiled/protobuf_version.h b/assets/compiled/protobuf_version.h index 0459d12060e..6b4014116e9 100644 --- a/assets/compiled/protobuf_version.h +++ b/assets/compiled/protobuf_version.h @@ -1,3 +1,3 @@ #pragma once #define PROTOBUF_MAJOR_VERSION 0 -#define PROTOBUF_MINOR_VERSION 6 +#define PROTOBUF_MINOR_VERSION 7 diff --git a/assets/compiled/system.pb.c b/assets/compiled/system.pb.c index 45ab3a010f0..e05ff90e863 100644 --- a/assets/compiled/system.pb.c +++ b/assets/compiled/system.pb.c @@ -48,6 +48,9 @@ PB_BIND(PB_System_ProtobufVersionResponse, PB_System_ProtobufVersionResponse, AU PB_BIND(PB_System_UpdateRequest, PB_System_UpdateRequest, AUTO) +PB_BIND(PB_System_UpdateResponse, PB_System_UpdateResponse, AUTO) + + PB_BIND(PB_System_PowerInfoRequest, PB_System_PowerInfoRequest, AUTO) @@ -56,3 +59,4 @@ PB_BIND(PB_System_PowerInfoResponse, PB_System_PowerInfoResponse, AUTO) + diff --git a/assets/compiled/system.pb.h b/assets/compiled/system.pb.h index 978219ae02b..aef2c75be12 100644 --- a/assets/compiled/system.pb.h +++ b/assets/compiled/system.pb.h @@ -16,6 +16,17 @@ typedef enum _PB_System_RebootRequest_RebootMode { PB_System_RebootRequest_RebootMode_UPDATE = 2 } PB_System_RebootRequest_RebootMode; +typedef enum _PB_System_UpdateResponse_UpdateResultCode { + PB_System_UpdateResponse_UpdateResultCode_OK = 0, + PB_System_UpdateResponse_UpdateResultCode_ManifestPathInvalid = 1, + PB_System_UpdateResponse_UpdateResultCode_ManifestFolderNotFound = 2, + PB_System_UpdateResponse_UpdateResultCode_ManifestInvalid = 3, + PB_System_UpdateResponse_UpdateResultCode_StageMissing = 4, + PB_System_UpdateResponse_UpdateResultCode_StageIntegrityError = 5, + PB_System_UpdateResponse_UpdateResultCode_ManifestPointerError = 6, + PB_System_UpdateResponse_UpdateResultCode_TargetMismatch = 7 +} PB_System_UpdateResponse_UpdateResultCode; + /* Struct definitions */ typedef struct _PB_System_DeviceInfoRequest { char dummy_field; @@ -84,6 +95,10 @@ typedef struct _PB_System_RebootRequest { PB_System_RebootRequest_RebootMode mode; } PB_System_RebootRequest; +typedef struct _PB_System_UpdateResponse { + PB_System_UpdateResponse_UpdateResultCode code; +} PB_System_UpdateResponse; + typedef struct _PB_System_GetDateTimeResponse { bool has_datetime; PB_System_DateTime datetime; @@ -100,6 +115,10 @@ typedef struct _PB_System_SetDateTimeRequest { #define _PB_System_RebootRequest_RebootMode_MAX PB_System_RebootRequest_RebootMode_UPDATE #define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_UPDATE+1)) +#define _PB_System_UpdateResponse_UpdateResultCode_MIN PB_System_UpdateResponse_UpdateResultCode_OK +#define _PB_System_UpdateResponse_UpdateResultCode_MAX PB_System_UpdateResponse_UpdateResultCode_TargetMismatch +#define _PB_System_UpdateResponse_UpdateResultCode_ARRAYSIZE ((PB_System_UpdateResponse_UpdateResultCode)(PB_System_UpdateResponse_UpdateResultCode_TargetMismatch+1)) + #ifdef __cplusplus extern "C" { @@ -120,6 +139,7 @@ extern "C" { #define PB_System_ProtobufVersionRequest_init_default {0} #define PB_System_ProtobufVersionResponse_init_default {0, 0} #define PB_System_UpdateRequest_init_default {NULL} +#define PB_System_UpdateResponse_init_default {_PB_System_UpdateResponse_UpdateResultCode_MIN} #define PB_System_PowerInfoRequest_init_default {0} #define PB_System_PowerInfoResponse_init_default {NULL, NULL} #define PB_System_PingRequest_init_zero {NULL} @@ -136,6 +156,7 @@ extern "C" { #define PB_System_ProtobufVersionRequest_init_zero {0} #define PB_System_ProtobufVersionResponse_init_zero {0, 0} #define PB_System_UpdateRequest_init_zero {NULL} +#define PB_System_UpdateResponse_init_zero {_PB_System_UpdateResponse_UpdateResultCode_MIN} #define PB_System_PowerInfoRequest_init_zero {0} #define PB_System_PowerInfoResponse_init_zero {NULL, NULL} @@ -157,6 +178,7 @@ extern "C" { #define PB_System_ProtobufVersionResponse_major_tag 1 #define PB_System_ProtobufVersionResponse_minor_tag 2 #define PB_System_RebootRequest_mode_tag 1 +#define PB_System_UpdateResponse_code_tag 1 #define PB_System_GetDateTimeResponse_datetime_tag 1 #define PB_System_SetDateTimeRequest_datetime_tag 1 @@ -241,6 +263,11 @@ X(a, POINTER, SINGULAR, STRING, update_manifest, 1) #define PB_System_UpdateRequest_CALLBACK NULL #define PB_System_UpdateRequest_DEFAULT NULL +#define PB_System_UpdateResponse_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, code, 1) +#define PB_System_UpdateResponse_CALLBACK NULL +#define PB_System_UpdateResponse_DEFAULT NULL + #define PB_System_PowerInfoRequest_FIELDLIST(X, a) \ #define PB_System_PowerInfoRequest_CALLBACK NULL @@ -266,6 +293,7 @@ extern const pb_msgdesc_t PB_System_PlayAudiovisualAlertRequest_msg; extern const pb_msgdesc_t PB_System_ProtobufVersionRequest_msg; extern const pb_msgdesc_t PB_System_ProtobufVersionResponse_msg; extern const pb_msgdesc_t PB_System_UpdateRequest_msg; +extern const pb_msgdesc_t PB_System_UpdateResponse_msg; extern const pb_msgdesc_t PB_System_PowerInfoRequest_msg; extern const pb_msgdesc_t PB_System_PowerInfoResponse_msg; @@ -284,6 +312,7 @@ extern const pb_msgdesc_t PB_System_PowerInfoResponse_msg; #define PB_System_ProtobufVersionRequest_fields &PB_System_ProtobufVersionRequest_msg #define PB_System_ProtobufVersionResponse_fields &PB_System_ProtobufVersionResponse_msg #define PB_System_UpdateRequest_fields &PB_System_UpdateRequest_msg +#define PB_System_UpdateResponse_fields &PB_System_UpdateResponse_msg #define PB_System_PowerInfoRequest_fields &PB_System_PowerInfoRequest_msg #define PB_System_PowerInfoResponse_fields &PB_System_PowerInfoResponse_msg @@ -304,6 +333,7 @@ extern const pb_msgdesc_t PB_System_PowerInfoResponse_msg; #define PB_System_ProtobufVersionResponse_size 12 #define PB_System_RebootRequest_size 2 #define PB_System_SetDateTimeRequest_size 24 +#define PB_System_UpdateResponse_size 2 #ifdef __cplusplus } /* extern "C" */ diff --git a/assets/protobuf b/assets/protobuf index 0ad90705b94..ffa62429f3c 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 0ad90705b9434b6f8fb2c4b605069f0d56d8cc70 +Subproject commit ffa62429f3c678537e0e883a3a8c3ae5f1398ed4 diff --git a/core/furi/memmgr_heap.c b/core/furi/memmgr_heap.c index 665fe2e1b38..618d7e74f89 100644 --- a/core/furi/memmgr_heap.c +++ b/core/furi/memmgr_heap.c @@ -37,6 +37,7 @@ #include "memmgr_heap.h" #include "check.h" #include +#include #include #include #include diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c index 2c28265f764..3de1c6ca15a 100644 --- a/firmware/targets/f7/Src/main.c +++ b/firmware/targets/f7/Src/main.c @@ -48,7 +48,7 @@ int main() { flipper_boot_update_exec(); // if things go nice, we shouldn't reach this point. // But if we do, abandon to avoid bootloops - update_operation_disarm(); + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); furi_hal_power_reset(); } else { furi_hal_light_sequence("rgb G"); diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c index f4a434b11bd..a91972e9f41 100644 --- a/firmware/targets/f7/Src/update.c +++ b/firmware/targets/f7/Src/update.c @@ -11,9 +11,10 @@ #include #include -static FATFS* pfs = NULL; +#define FS_ROOT_PATH "/" +#define UPDATE_POINTER_FILE_PATH FS_ROOT_PATH UPDATE_MANIFEST_POINTER_FILE_NAME -static const char FS_ROOT_PATH[] = "/"; +static FATFS* pfs = NULL; #define CHECK_FRESULT(result) \ { \ @@ -100,42 +101,35 @@ static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* m return false; } -static bool flipper_update_get_work_directory(string_t out_dir) { - const uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); - if(update_index == UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC) { - string_set(out_dir, UPDATE_DIR_DEFAULT_REL_PATH); - return true; - } - - DIR dir; - UINT entry_idx = 0; - FILINFO fno; - CHECK_FRESULT(f_opendir(&dir, UPDATE_DIR_DEFAULT_REL_PATH)); - string_set(out_dir, UPDATE_DIR_DEFAULT_REL_PATH); +static bool flipper_update_get_manifest_path(string_t out_path) { + FIL file; + FILINFO stat; + uint16_t size_read = 0; + char manifest_name_buf[UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN] = {0}; - while(f_readdir(&dir, &fno) == FR_OK) { - entry_idx++; - if(fno.fname[0] == '\0') { - return false; - } - if(entry_idx == update_index) { - path_append(out_dir, fno.fname); - return true; + string_reset(out_path); + CHECK_FRESULT(f_stat(UPDATE_POINTER_FILE_PATH, &stat)); + CHECK_FRESULT(f_open(&file, UPDATE_POINTER_FILE_PATH, FA_OPEN_EXISTING | FA_READ)); + do { + if(f_read(&file, manifest_name_buf, UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN, &size_read) != + FR_OK) { + break; } - } - string_reset(out_dir); - return false; + if((size_read == 0) || (size_read == UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN)) { + break; + } + string_set_str(out_path, manifest_name_buf); + string_right(out_path, strlen("/ext")); + } while(0); + f_close(&file); + return !string_empty_p(out_path); } -static UpdateManifest* flipper_update_process_manifest(const string_t work_dir) { +static UpdateManifest* flipper_update_process_manifest(const string_t manifest_path) { FIL file; FILINFO stat; - string_t manifest_path; - string_init_set(manifest_path, work_dir); - path_append(manifest_path, UPDATE_MANIFEST_DEFAULT_NAME); - CHECK_FRESULT(f_stat(string_get_cstr(manifest_path), &stat)); CHECK_FRESULT(f_open(&file, string_get_cstr(manifest_path), FA_OPEN_EXISTING | FA_READ)); @@ -164,7 +158,7 @@ static UpdateManifest* flipper_update_process_manifest(const string_t work_dir) } } while(false); - string_clear(manifest_path); + f_close(&file); free(manifest_data); return manifest; } @@ -174,22 +168,25 @@ void flipper_boot_update_exec() { return; } - string_t work_dir; + string_t work_dir, manifest_path; string_init(work_dir); + string_init(manifest_path); do { - if(!flipper_update_get_work_directory(work_dir)) { + if(!flipper_update_get_manifest_path(manifest_path)) { break; } - UpdateManifest* manifest = flipper_update_process_manifest(work_dir); + UpdateManifest* manifest = flipper_update_process_manifest(manifest_path); if(!manifest) { break; } + path_extract_dirname(string_get_cstr(manifest_path), work_dir); if(!flipper_update_load_stage(work_dir, manifest)) { update_manifest_free(manifest); } } while(false); + string_clear(manifest_path); string_clear(work_dir); free(pfs); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_random.c b/firmware/targets/f7/furi_hal/furi_hal_random.c index 0f282fac818..cd019c0d9ad 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_random.c +++ b/firmware/targets/f7/furi_hal/furi_hal_random.c @@ -7,6 +7,8 @@ #include +#define TAG "FuriHalRandom" + uint32_t furi_hal_random_get() { while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID)) ; @@ -51,9 +53,13 @@ void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len) { } void srand(unsigned seed) { - UNUSED(seed); // FIXME! + UNUSED(seed); } int rand() { return (furi_hal_random_get() & RAND_MAX); } + +long random() { + return (furi_hal_random_get() & RAND_MAX); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index c5b5043b4f0..7f40a152887 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -972,9 +972,9 @@ void furi_hal_subghz_stop_async_tx() { FURI_LOG_D( TAG, "Async TX Radio stats: on %0.0fus, off %0.0fus, DutyCycle: %0.0f%%", - (float)furi_hal_subghz_async_tx.duty_high, - (float)furi_hal_subghz_async_tx.duty_low, - duty_cycle); + (double)furi_hal_subghz_async_tx.duty_high, + (double)furi_hal_subghz_async_tx.duty_low, + (double)duty_cycle); furi_hal_subghz_state = SubGhzStateIdle; } diff --git a/firmware/targets/f7/stm32wb55xx_flash.ld b/firmware/targets/f7/stm32wb55xx_flash.ld index f742ecc1844..1d0e916b064 100644 --- a/firmware/targets/f7/stm32wb55xx_flash.ld +++ b/firmware/targets/f7/stm32wb55xx_flash.ld @@ -135,6 +135,7 @@ SECTIONS _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ + *(*_DRIVER_CONTEXT) . = ALIGN(4); _edata = .; /* define a global symbol at data end */ @@ -158,7 +159,7 @@ SECTIONS } >RAM1 /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : + ._user_heap_stack(NOLOAD): { . = ALIGN(8); __heap_start__ = .; @@ -173,7 +174,7 @@ SECTIONS { __free_flash_start__ = .; . = ORIGIN(FLASH) + LENGTH(FLASH); - } >FLASH + } >FLASH /* Remove information from the standard libraries */ /DISCARD/ : diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index d96dd5e665d..8e58a71c9f4 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -19,9 +19,9 @@ endif MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard # Warnings configuration -CFLAGS += -Wall -Wextra -Wredundant-decls +CFLAGS += -Wall -Wextra -Wredundant-decls -Wdouble-promotion -CFLAGS += $(MCU_FLAGS) -DSTM32WB55xx -fdata-sections -ffunction-sections +CFLAGS += $(MCU_FLAGS) -DSTM32WB55xx -fdata-sections -ffunction-sections -fsingle-precision-constant LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index 93b788a38e1..bd700849e19 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -276,7 +276,7 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa #ifndef FLIPPER_STREAM_LITE case FlipperStreamValueFloat: { const float* data = write_data->data; - string_printf(value, "%f", data[i]); + string_printf(value, "%f", (double)data[i]); }; break; #endif case FlipperStreamValueInt32: { diff --git a/lib/lib.mk b/lib/lib.mk index 1470c89fcfc..cb58fadeba4 100644 --- a/lib/lib.mk +++ b/lib/lib.mk @@ -4,7 +4,7 @@ LIB_DIR = $(PROJECT_ROOT)/lib CFLAGS += -I$(LIB_DIR) # Mlib containers -CFLAGS += -I$(LIB_DIR)/mlib +CFLAGS += -I$(LIB_DIR)/mlib -D'M_MEMORY_FULL(x)=abort()' # U8G2 display library U8G2_DIR = $(LIB_DIR)/u8g2 diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index aad28b88fba..863aaa31e1f 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -83,7 +83,10 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* if(furi_hal_subghz_rx_pipe_not_empty()) { FURI_LOG_I( - TAG, "RSSI: %03.1fdbm LQI: %d", furi_hal_subghz_get_rssi(), furi_hal_subghz_get_lqi()); + TAG, + "RSSI: %03.1fdbm LQI: %d", + (double)furi_hal_subghz_get_rssi(), + furi_hal_subghz_get_lqi()); if(furi_hal_subghz_is_rx_data_crc_valid()) { furi_hal_subghz_read_packet(data, size); ret = true; diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c index 555d7cfb6c9..2fe0a1ef35f 100644 --- a/lib/update_util/update_manifest.c +++ b/lib/update_util/update_manifest.c @@ -26,6 +26,7 @@ UpdateManifest* update_manifest_alloc() { string_init(update_manifest->staged_loader_file); string_init(update_manifest->resource_bundle); update_manifest->target = 0; + update_manifest->manifest_version = 0; memset(update_manifest->ob_reference.bytes, 0, FURI_HAL_FLASH_OB_RAW_SIZE_BYTES); memset(update_manifest->ob_compare_mask.bytes, 0, FURI_HAL_FLASH_OB_RAW_SIZE_BYTES); memset(update_manifest->ob_write_mask.bytes, 0, FURI_HAL_FLASH_OB_RAW_SIZE_BYTES); @@ -49,12 +50,11 @@ static bool furi_assert(flipper_file); string_t filetype; - uint32_t version = 0; // TODO: compare filetype? string_init(filetype); update_manifest->valid = - flipper_format_read_header(flipper_file, filetype, &version) && + flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) && flipper_format_read_string(flipper_file, MANIFEST_KEY_INFO, update_manifest->version) && flipper_format_read_uint32( flipper_file, MANIFEST_KEY_TARGET, &update_manifest->target, 1) && @@ -68,7 +68,7 @@ static bool string_clear(filetype); if(update_manifest->valid) { - /* Optional fields - we can have dfu, radio, or both */ + /* Optional fields - we can have dfu, radio, resources, or any combination */ flipper_format_read_string( flipper_file, MANIFEST_KEY_DFU_FILE, update_manifest->firmware_dfu_image); flipper_format_read_string( @@ -131,8 +131,7 @@ static bool ob_data_check_masked_values_valid( const FuriHalFlashRawOptionByteData* mask) { bool valid = true; for(size_t idx = 0; valid && (idx < FURI_HAL_FLASH_OB_TOTAL_VALUES); ++idx) { - valid &= (data->obs[idx]. dword & mask->obs[idx].dword) == - data->obs[idx].dword; + valid &= (data->obs[idx].dword & mask->obs[idx].dword) == data->obs[idx].dword; } return valid; } diff --git a/lib/update_util/update_manifest.h b/lib/update_util/update_manifest.h index 2893be5a01f..2b1e6857b9f 100644 --- a/lib/update_util/update_manifest.h +++ b/lib/update_util/update_manifest.h @@ -12,6 +12,7 @@ extern "C" { /* Paths don't include /ext -- because at startup SD card is mounted as root */ #define UPDATE_DIR_DEFAULT_REL_PATH "/update" #define UPDATE_MANIFEST_DEFAULT_NAME "update.fuf" +#define UPDATE_MANIFEST_POINTER_FILE_NAME ".fupdate" typedef union { uint8_t raw[6]; @@ -27,6 +28,7 @@ typedef union { _Static_assert(sizeof(UpdateManifestRadioVersion) == 6, "UpdateManifestRadioVersion size error"); typedef struct { + uint32_t manifest_version; string_t version; uint32_t target; string_t staged_loader_file; diff --git a/lib/update_util/update_operation.c b/lib/update_util/update_operation.c index c9a7cd18752..142dcaaaabc 100644 --- a/lib/update_util/update_operation.c +++ b/lib/update_util/update_operation.c @@ -12,7 +12,6 @@ #define UPDATE_ROOT_DIR "/ext" UPDATE_DIR_DEFAULT_REL_PATH #define UPDATE_PREFIX "/ext" UPDATE_DIR_DEFAULT_REL_PATH "/" #define UPDATE_SUFFIX "/" UPDATE_MANIFEST_DEFAULT_NAME -#define MAX_DIR_NAME_LEN 250 static const char* update_prepare_result_descr[] = { [UpdatePrepareResultOK] = "OK", @@ -21,6 +20,8 @@ static const char* update_prepare_result_descr[] = { [UpdatePrepareResultManifestInvalid] = "Invalid manifest data", [UpdatePrepareResultStageMissing] = "Missing Stage2 loader", [UpdatePrepareResultStageIntegrityError] = "Corrupted Stage2 loader", + [UpdatePrepareResultManifestPointerError] = "Failed to create update pointer file", + [UpdatePrepareResultOutdatedManifestVersion] = "Update package is too old", }; const char* update_operation_describe_preparation_result(const UpdatePrepareResult value) { @@ -31,65 +32,7 @@ const char* update_operation_describe_preparation_result(const UpdatePrepareResu } } -bool update_operation_get_package_dir_name(const char* full_path, string_t out_manifest_dir) { - bool path_ok = false; - string_t full_path_str; - string_init_set(full_path_str, full_path); - string_reset(out_manifest_dir); - bool start_end_ok = string_start_with_str_p(full_path_str, UPDATE_PREFIX) && - string_end_with_str_p(full_path_str, UPDATE_SUFFIX); - int16_t dir_name_len = - strlen(full_path) - strlen(UPDATE_PREFIX) - strlen(UPDATE_MANIFEST_DEFAULT_NAME) - 1; - if(dir_name_len == -1) { - path_ok = true; - } else if(start_end_ok && (dir_name_len > 0)) { - string_set_n(out_manifest_dir, full_path_str, strlen(UPDATE_PREFIX), dir_name_len); - path_ok = true; - if(string_search_char(out_manifest_dir, '/') != STRING_FAILURE) { - string_reset(out_manifest_dir); - path_ok = false; - } - } - string_clear(full_path_str); - return path_ok; -} - -int32_t update_operation_get_package_index(Storage* storage, const char* update_package_dir) { - furi_assert(storage); - furi_assert(update_package_dir); - - if(strlen(update_package_dir) == 0) { - return UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC; - } - - bool found = false; - int32_t index = 0; - File* dir = storage_file_alloc(storage); - FileInfo fi = {0}; - char* name_buffer = malloc(MAX_DIR_NAME_LEN); - do { - if(!storage_dir_open(dir, UPDATE_ROOT_DIR)) { - break; - } - - while(storage_dir_read(dir, &fi, name_buffer, MAX_DIR_NAME_LEN)) { - index++; - if(strcmp(name_buffer, update_package_dir)) { - continue; - } else { - found = true; - break; - } - } - } while(false); - - free(name_buffer); - storage_file_free(dir); - - return found ? index : -1; -} - -bool update_operation_get_current_package_path(Storage* storage, string_t out_path) { +static bool update_operation_get_current_package_path_rtc(Storage* storage, string_t out_path) { const uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); string_set_str(out_path, UPDATE_ROOT_DIR); if(update_index == UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC) { @@ -100,13 +43,13 @@ bool update_operation_get_current_package_path(Storage* storage, string_t out_pa uint32_t iter_index = 0; File* dir = storage_file_alloc(storage); FileInfo fi = {0}; - char* name_buffer = malloc(MAX_DIR_NAME_LEN); + char* name_buffer = malloc(UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN); do { if(!storage_dir_open(dir, UPDATE_ROOT_DIR)) { break; } - while(storage_dir_read(dir, &fi, name_buffer, MAX_DIR_NAME_LEN)) { + while(storage_dir_read(dir, &fi, name_buffer, UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN)) { if(++iter_index == update_index) { found = true; path_append(out_path, name_buffer); @@ -124,79 +67,148 @@ bool update_operation_get_current_package_path(Storage* storage, string_t out_pa return found; } -UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { - string_t update_folder; - string_init(update_folder); - if(!update_operation_get_package_dir_name(manifest_file_path, update_folder)) { - string_clear(update_folder); - return UpdatePrepareResultManifestPathInvalid; +#define UPDATE_FILE_POINTER_FN "/ext/" UPDATE_MANIFEST_POINTER_FILE_NAME +#define UPDATE_MANIFEST_MAX_PATH_LEN 256u + +bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path) { + string_reset(out_path); + if(storage_common_stat(storage, UPDATE_FILE_POINTER_FN, NULL) == FSE_OK) { + char* manifest_name_buffer = malloc(UPDATE_MANIFEST_MAX_PATH_LEN); + File* upd_file = NULL; + do { + upd_file = storage_file_alloc(storage); + if(!storage_file_open( + upd_file, UPDATE_FILE_POINTER_FN, FSAM_READ, FSOM_OPEN_EXISTING)) { + break; + } + uint16_t bytes_read = + storage_file_read(upd_file, manifest_name_buffer, UPDATE_MANIFEST_MAX_PATH_LEN); + if((bytes_read == 0) || (bytes_read == UPDATE_MANIFEST_MAX_PATH_LEN)) { + break; + } + if(storage_common_stat(storage, manifest_name_buffer, NULL) != FSE_OK) { + break; + } + string_set_str(out_path, manifest_name_buffer); + } while(0); + free(manifest_name_buffer); + storage_file_free(upd_file); + } else { + /* legacy, will be deprecated */ + string_t rtcpath; + string_init(rtcpath); + do { + if(!update_operation_get_current_package_path_rtc(storage, rtcpath)) { + break; + } + path_concat(string_get_cstr(rtcpath), UPDATE_MANIFEST_DEFAULT_NAME, out_path); + } while(0); + string_clear(rtcpath); } + return !string_empty_p(out_path); +} - Storage* storage = furi_record_open("storage"); - int32_t update_index = - update_operation_get_package_index(storage, string_get_cstr(update_folder)); - string_clear(update_folder); +static bool update_operation_persist_manifest_path(Storage* storage, const char* manifest_path) { + const uint16_t manifest_path_len = strlen(manifest_path); + furi_check(manifest_path && manifest_path_len); + bool success = false; + File* file = storage_file_alloc(storage); + do { + if(manifest_path_len >= UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN) { + break; + } - if(update_index < 0) { - furi_record_close("storage"); - return UpdatePrepareResultManifestFolderNotFound; - } + if(!storage_file_open(file, UPDATE_FILE_POINTER_FN, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + break; + } + + if(storage_file_write(file, manifest_path, manifest_path_len) != manifest_path_len) { + break; + } - string_t update_dir_path; - string_init(update_dir_path); - path_extract_dirname(manifest_file_path, update_dir_path); + success = true; + } while(0); + storage_file_free(file); + return success; +} - UpdatePrepareResult result = UpdatePrepareResultManifestInvalid; +UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { + UpdatePrepareResult result = UpdatePrepareResultManifestFolderNotFound; + Storage* storage = furi_record_open("storage"); UpdateManifest* manifest = update_manifest_alloc(); - if(update_manifest_init(manifest, manifest_file_path)) { - result = UpdatePrepareResultStageMissing; - File* file = storage_file_alloc(storage); + File* file = storage_file_alloc(storage); + + string_t stage_path; + string_init(stage_path); + do { + if(storage_common_stat(storage, manifest_file_path, NULL) != FSE_OK) { + break; + } + + if(!update_manifest_init(manifest, manifest_file_path)) { + result = UpdatePrepareResultManifestInvalid; + break; + } + + if(manifest->manifest_version < UPDATE_OPERATION_MIN_MANIFEST_VERSION) { + result = UpdatePrepareResultOutdatedManifestVersion; + break; + } + + if(furi_hal_version_get_hw_target() != manifest->target) { + result = UpdatePrepareResultTargetMismatch; + break; + } - string_t stage_path; - string_init(stage_path); path_extract_dirname(manifest_file_path, stage_path); path_append(stage_path, string_get_cstr(manifest->staged_loader_file)); - uint32_t crc = 0; - do { - if(!storage_file_open( - file, string_get_cstr(stage_path), FSAM_READ, FSOM_OPEN_EXISTING)) { - break; - } + if(!storage_file_open(file, string_get_cstr(stage_path), FSAM_READ, FSOM_OPEN_EXISTING)) { + result = UpdatePrepareResultStageMissing; + break; + } + uint32_t crc = crc32_calc_file(file, NULL, NULL); + if(crc != manifest->staged_loader_crc) { result = UpdatePrepareResultStageIntegrityError; - crc = crc32_calc_file(file, NULL, NULL); - } while(false); - - string_clear(stage_path); - storage_file_free(file); + break; + } - if(crc == manifest->staged_loader_crc) { - furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); - update_operation_persist_package_index(update_index); - result = UpdatePrepareResultOK; + if(!update_operation_persist_manifest_path(storage, manifest_file_path)) { + result = UpdatePrepareResultManifestPointerError; + break; } - } - furi_record_close("storage"); + + result = UpdatePrepareResultOK; + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); + } while(false); + + string_clear(stage_path); + storage_file_free(file); + update_manifest_free(manifest); + furi_record_close("storage"); return result; } bool update_operation_is_armed() { FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); + const uint32_t rtc_upd_index = + furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); + Storage* storage = furi_record_open("storage"); + const bool upd_fn_ptr_exists = + (storage_common_stat(storage, UPDATE_FILE_POINTER_FN, NULL) == FSE_OK); + furi_record_close("storage"); return (boot_mode >= FuriHalRtcBootModePreUpdate) && (boot_mode <= FuriHalRtcBootModePostUpdate) && - (furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex) > 0); + ((rtc_upd_index != INT_MAX) || upd_fn_ptr_exists); } void update_operation_disarm() { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); - furi_hal_rtc_set_register( - FuriHalRtcRegisterUpdateFolderFSIndex, INT_MAX); -} - -void update_operation_persist_package_index(int32_t index) { - furi_check(index >= 0); - furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, index); -} + furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, INT_MAX); + Storage* storage = furi_record_open("storage"); + storage_simply_remove(storage, UPDATE_FILE_POINTER_FN); + furi_record_close("storage"); +} \ No newline at end of file diff --git a/lib/update_util/update_operation.h b/lib/update_util/update_operation.h index c11f2754ae5..39d58028354 100644 --- a/lib/update_util/update_operation.h +++ b/lib/update_util/update_operation.h @@ -9,6 +9,8 @@ extern "C" { #endif #define UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC 0 +#define UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN 255u +#define UPDATE_OPERATION_MIN_MANIFEST_VERSION 2 /* * Checks if supplied full manifest path is valid @@ -19,6 +21,7 @@ extern "C" { */ bool update_operation_get_package_dir_name(const char* full_path, string_t out_manifest_dir); +/* When updating this enum, also update assets/protobuf/system.proto */ typedef enum { UpdatePrepareResultOK, UpdatePrepareResultManifestPathInvalid, @@ -26,6 +29,9 @@ typedef enum { UpdatePrepareResultManifestInvalid, UpdatePrepareResultStageMissing, UpdatePrepareResultStageIntegrityError, + UpdatePrepareResultManifestPointerError, + UpdatePrepareResultTargetMismatch, + UpdatePrepareResultOutdatedManifestVersion, } UpdatePrepareResult; const char* update_operation_describe_preparation_result(const UpdatePrepareResult value); @@ -37,27 +43,13 @@ const char* update_operation_describe_preparation_result(const UpdatePrepareResu */ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path); -/* - * Gets update package index to pass in RTC registers - * @param storage Storage API - * @param update_package_dir Package directory name - * @return int32_t <=0 - error, >0 - update index value - */ -int32_t update_operation_get_package_index(Storage* storage, const char* update_package_dir); - /* * Gets filesystem path for current update package * @param storage Storage API - * @param out_path Path to directory with manifest & related files. Must be initialized + * @param out_path Path to manifest. Must be initialized * @return true if path was restored successfully */ -bool update_operation_get_current_package_path(Storage* storage, string_t out_path); - -/* - * Stores given update index in RTC registers - * @param index Value to store - */ -void update_operation_persist_package_index(int32_t index); +bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path); /* * Checks if an update operation step is pending after reset diff --git a/scripts/update.py b/scripts/update.py index 3e8daab07aa..4769565ca95 100755 --- a/scripts/update.py +++ b/scripts/update.py @@ -13,6 +13,7 @@ class Main(App): + UPDATE_MANIFEST_VERSION = 2 UPDATE_MANIFEST_NAME = "update.fuf" # No compression, plain tar @@ -93,7 +94,9 @@ def generate(self): ) file = FlipperFormatFile() - file.setHeader("Flipper firmware upgrade configuration", 1) + file.setHeader( + "Flipper firmware upgrade configuration", self.UPDATE_MANIFEST_VERSION + ) file.writeKey("Info", self.args.version) file.writeKey("Target", self.args.target[1:]) # dirty 'f' strip file.writeKey("Loader", stage_basename) @@ -102,7 +105,7 @@ def generate(self): file.writeKey("Firmware", dfu_basename) file.writeKey("Radio", radiobin_basename or "") file.writeKey("Radio address", self.int2ffhex(radio_addr)) - file.writeKey("Radio version", self.int2ffhex(radio_version)) + file.writeKey("Radio version", self.int2ffhex(radio_version, 12)) if radiobin_basename: file.writeKey("Radio CRC", self.int2ffhex(self.crc(self.args.radiobin))) else: @@ -149,11 +152,10 @@ def bytes2ffhex(value: bytes): return " ".join(f"{b:02X}" for b in value) @staticmethod - def int2ffhex(value: int): - n_hex_bytes = 4 + def int2ffhex(value: int, n_hex_syms=8): if value: - n_hex_bytes = math.ceil(math.ceil(math.log2(value)) / 8) * 2 - fmtstr = f"%0{n_hex_bytes}X" + n_hex_syms = math.ceil(math.ceil(math.log2(value)) / 8) * 2 + fmtstr = f"%0{n_hex_syms}X" hexstr = fmtstr % value return " ".join(list(Main.batch(hexstr, 2))[::-1]) From b4125f1f9cf7c3dca9355b481a7ea2442cc544ee Mon Sep 17 00:00:00 2001 From: Gary Date: Wed, 11 May 2022 06:19:32 -0400 Subject: [PATCH 17/24] Fix for issue #1019, HardFault on certain types of credit/bank cards. (#1211) The country_code does not always have extra pad bytes, so incrementing the index by 2 in emv_decode_read_sfi_record() was too much. Co-authored-by: Gary Co-authored-by: gornekich --- lib/nfc_protocols/emv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nfc_protocols/emv.c b/lib/nfc_protocols/emv.c index 81a05e359c2..8e14cf48e61 100644 --- a/lib/nfc_protocols/emv.c +++ b/lib/nfc_protocols/emv.c @@ -292,7 +292,7 @@ static bool emv_decode_read_sfi_record(uint8_t* buff, uint16_t len, EmvApplicati i += 2; } else if(emv_decode_search_tag_u16_r(EMV_TAG_COUNTRY_CODE, buff, &i)) { app->country_code = (buff[i] << 8) | buff[i + 1]; - i += 2; + i += 1; } } From 7f8d82bd98b2f9cfa4a2ea6212c018749c8f8c7f Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 11 May 2022 13:40:08 +0300 Subject: [PATCH 18/24] Updated lib/libusb_stm32 to match upstream (#1216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/libusb_stm32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libusb_stm32 b/lib/libusb_stm32 index 6e64179d64e..6a88ec4d770 160000 --- a/lib/libusb_stm32 +++ b/lib/libusb_stm32 @@ -1 +1 @@ -Subproject commit 6e64179d64e5582014a637a108d0870191f7818d +Subproject commit 6a88ec4d7709ca8605b5ec3e609057c330ca2a70 From a5bb417fd7ba93960260ec99d06d1f3c539b00bd Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 11 May 2022 15:19:15 +0400 Subject: [PATCH 19/24] SubGhz: fix holtek protocol (#1217) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: fix holtek protocol * SubGhz: fix Princeton false positive on GateTx receive Co-authored-by: あく --- applications/unit_tests/subghz/subghz_test.c | 2 +- lib/subghz/protocols/holtek.c | 8 ++++---- lib/subghz/protocols/princeton.c | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index 3a65429a52f..879deae8204 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -13,7 +13,7 @@ #define CAME_ATOMO_DIR_NAME "/ext/subghz/assets/came_atomo" #define NICE_FLOR_S_DIR_NAME "/ext/subghz/assets/nice_flor_s" #define TEST_RANDOM_DIR_NAME "/ext/unit_tests/subghz/test_random_raw.sub" -#define TEST_RANDOM_COUNT_PARSE 116 +#define TEST_RANDOM_COUNT_PARSE 113 #define TEST_TIMEOUT 10000 static SubGhzEnvironment* environment_handler; diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c index dcb51de4053..174d023e538 100644 --- a/lib/subghz/protocols/holtek.c +++ b/lib/subghz/protocols/holtek.c @@ -19,8 +19,8 @@ #define HOLTEK_HEADER 0x5000000000 static const SubGhzBlockConst subghz_protocol_holtek_const = { - .te_short = 500, - .te_long = 1000, + .te_short = 430, + .te_long = 870, .te_delta = 100, .min_count_bit_for_found = 40, }; @@ -347,8 +347,8 @@ void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) { "Sn:0x%05lX BTN:%X ", instance->generic.protocol_name, instance->generic.data_count_bit, - (uint32_t)((instance->generic.data >> 32) & 0xFFFFFF), - (uint32_t)(instance->generic.data & 0xFFFFFF), + (uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF), + (uint32_t)(instance->generic.data & 0xFFFFFFFF), instance->generic.serial, instance->generic.btn >> 4); diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index 7579a3cac09..046484c7503 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -245,7 +245,8 @@ void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t instance->decoder.parser_step = PrincetonDecoderStepSaveDuration; if(instance->decoder.decode_count_bit == subghz_protocol_princeton_const.min_count_bit_for_found) { - if(instance->last_data == instance->decoder.decode_data) { + if((instance->last_data == instance->decoder.decode_data) && + instance->last_data) { instance->te /= (instance->decoder.decode_count_bit * 4 + 1); instance->generic.data = instance->decoder.decode_data; From 6cc30f405dec50fa2abdc7d9742613ae37105f3e Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 11 May 2022 16:50:46 +0300 Subject: [PATCH 20/24] [FL-2521] Added OTA-related docs (#1219) * Added update-related docs * Docs: formatting --- documentation/OTA.md | 105 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 documentation/OTA.md diff --git a/documentation/OTA.md b/documentation/OTA.md new file mode 100644 index 00000000000..472e81b6b76 --- /dev/null +++ b/documentation/OTA.md @@ -0,0 +1,105 @@ +# Executing code from RAM + +In Flipper firmware, we have a special boot mode that loads a specially crafted system image into RAM and transfers control to it. System image executing in RAM has full write access to whole Flipper's flash memory — something that's not possible when running main code from same flash. + +We leverage that boot mode to perform OTA firmware updates, including operations on radio stack running on second MCU core. + + +# How does Flipper OTA work? + +Installation of OTA updates goes through 3 stages: + +## 1. Backing up internal storage (`/int/`) + +It is a special partition of Flipper's flash memory, taking up all available space not used by firmware code. Newer versions of firmware may be of different size, and simply installing them would cause flash repartitioning and data loss. + +So, before taking any action upon the firmware, we back up current configuration from `/int/` into a plain tar archive on SD card. + + +## 2. Performing device update + +For that, main firmware loads an updater image - a customized build of main Flipper firmware — into RAM and runs it. Updater performs operations on system flash that are described by an Update manifest file. + +First, if there's a Radio stack image bundled with the update, updater compares its version with currently installed one. If they don't match, updater performs stack deinstallation followed by writing and installing a new one. The installation itself is performed by proprietary software, FUS, running on Core2, and leads to a series of system restarts. + +Then updater validates and corrects Option Bytes — a special memory region containing low-level configuration for Flipper's MCU. + +After that, updater loads a `.dfu` file with firmware to be flashed, checks its integrity using CRC32, writes it to system flash and validates written data. + + +## 3. Restoring internal storage and updating resources + +After performing operations on flash memory, system restarts into newly flashed firmware. Then it performs restoration of previously backed up `/int` contents. + +If update package contains an additional resources archive, it is extracted onto SD card. + + +# Update manifest + +Update packages come with a manifest that contains a description of its contents. The manifest is in Flipper File Format — a simple text file, comprised of key-value pairs. + +## Mandatory fields + +Update manifest must contain the following keys in given order: + +* __Filetype__: a constant string, "Flipper firmware upgrade configuration"; + +* __Version__: manifest version. Current value is 2; + +* __Info__: arbitraty string, describing package contents; + +* __Target__: hardware revision the package is built for; + +* __Loader__: file name of stage 2 loader that is executed from RAM; + +* __Loader CRC__: CRC32 of loader file. Note that it is represented in little-endian hex. + +## Optional fields + +Other fields may have empty values, is such case updater skips all operations related to such values. + +* __Radio__: file name of radio stack image, provided by STM; + +* __Radio address__: address to install the radio stack at. It is specified in Release Notes by STM; + +* __Radio version__: Radio major, minor and sub versions followed by branch, release, and stack type packed into 6 hex-encoded bytes; + +* __Radio CRC__: CRC32 of radio image; + +* __Resources__: file name of TAR acrhive with resources to be extracted on SD card; + +* __OB reference__, __OB mask__, __OB write mask__: reference values for validating and correcting option bytes. + + +# OTA update error codes + +We designed the OTA update process to be as fail-safe as possible. We don't start any risky operation before validating all related pieces of data to ensure we don't leave the device in partially updated, or bricked, state. + +Even if something goes wrong, Updater gives you an option to retry failed operations, and reports its state with an error code. These error codes have an `[XX-YY]` format, where `XX` encodes an operation that failed, and `YY` contains extra details on its progress where the error occured. + +| Stage description | Code | Progress | Description | +|:-----------------------:|-------:|------------|--------------------------------------------| +| Loading update manifest | **1** | **13** | Updater reported hardware version mismatch | +| | | **20** | Failed to get saved manifest path | +| | | **30** | Failed to load manifest | +| | | **40** | Unsupported update package version | +| | | **50** | Package has mismatching HW target | +| | | **60** | Missing DFU file | +| | | **80** | Missing radio firmware file | +| Checking DFU file | **2** | **0** | Error opening DFU file | +| | | **1-98** | Error reading DFU file | +| | | **99-100** | Corrupted DFU file | +| Writing flash | **3** | **0-100** | Block read/write error | +| Validating flash | **4** | **0-100** | Block read/write error | +| Checking radio FW | **5** | **0-99** | Error reading radio firmware file | +| | | **100** | CRC mismatch | +| Uninstalling radio FW | **6** | **0** | SHCI Install command error | +| | | **80** | Error awaiting command status | +| Writing radio FW | **7** | **0-100** | Block read/write error | +| Installing radio FW | **8** | **0** | SHCI Install command error | +| | | **80** | Error awaiting command status | +| Radio is updating | **9** | **10** | Error waiting for operation completion | +| Validating opt. bytes | **10** | **yy** | Option byte code | +| Backing up LFS | **11** | **0-100** | Block read/write error | +| Restoring LFS | **12** | **0-100** | Block read/write error | +| Updating resources | **13** | **0-100** | SD card read/write error | From 9a11d3996de57004cedff4890d52e26218807c2e Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 11 May 2022 19:09:11 +0400 Subject: [PATCH 21/24] SubGhz: fix Princeton false positive on GateTx receive (#1218) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/subghz/scenes/subghz_scene_receiver.c | 2 +- lib/subghz/protocols/registry.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index bfc39e91842..01005148b33 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -60,7 +60,6 @@ static void subghz_scene_add_to_history_callback( if(subghz_history_add_to_history( subghz->txrx->history, decoder_base, subghz->txrx->frequency, subghz->txrx->preset)) { - subghz_receiver_reset(receiver); string_reset(str_buff); subghz->state_notifications = SubGhzNotificationStateRxDone; @@ -75,6 +74,7 @@ static void subghz_scene_add_to_history_callback( subghz_scene_receiver_update_statusbar(subghz); } + subghz_receiver_reset(receiver); string_clear(str_buff); subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } diff --git a/lib/subghz/protocols/registry.c b/lib/subghz/protocols/registry.c index 9577b3de232..b90e535c3a2 100644 --- a/lib/subghz/protocols/registry.c +++ b/lib/subghz/protocols/registry.c @@ -1,12 +1,12 @@ #include "registry.h" const SubGhzProtocol* subghz_protocol_registry[] = { - &subghz_protocol_princeton, &subghz_protocol_keeloq, &subghz_protocol_star_line, + &subghz_protocol_gate_tx, &subghz_protocol_keeloq, &subghz_protocol_star_line, &subghz_protocol_nice_flo, &subghz_protocol_came, &subghz_protocol_faac_slh, &subghz_protocol_nice_flor_s, &subghz_protocol_came_twee, &subghz_protocol_came_atomo, &subghz_protocol_nero_sketch, &subghz_protocol_ido, &subghz_protocol_kia, &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis, - &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_gate_tx, + &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_princeton, &subghz_protocol_raw, &subghz_protocol_firefly, &subghz_protocol_secplus_v2, &subghz_protocol_secplus_v1, &subghz_protocol_megacode, &subghz_protocol_holtek, From 85a129b89f18c0d9f713fa80e2d24a5b9af42c52 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Wed, 11 May 2022 18:47:01 +0300 Subject: [PATCH 22/24] [FL-2528] Fix iButton crash on successful emulation #1220 --- lib/one_wire/ibutton/ibutton_worker.c | 11 +++++++++++ lib/one_wire/ibutton/ibutton_worker_i.h | 1 + lib/one_wire/ibutton/ibutton_worker_modes.c | 4 +--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/one_wire/ibutton/ibutton_worker.c b/lib/one_wire/ibutton/ibutton_worker.c index 74734e75681..82c3d688621 100644 --- a/lib/one_wire/ibutton/ibutton_worker.c +++ b/lib/one_wire/ibutton/ibutton_worker.c @@ -9,6 +9,7 @@ typedef enum { iButtonMessageRead, iButtonMessageWrite, iButtonMessageEmulate, + iButtonMessageNotifyEmulate, } iButtonMessageType; typedef struct { @@ -145,6 +146,11 @@ void ibutton_worker_switch_mode(iButtonWorker* worker, iButtonWorkerMode mode) { ibutton_worker_modes[worker->mode_index].start(worker); } +void ibutton_worker_notify_emulate(iButtonWorker* worker) { + iButtonMessage message = {.type = iButtonMessageNotifyEmulate}; + furi_check(osMessageQueuePut(worker->messages, &message, 0, 0) == osOK); +} + void ibutton_worker_set_key_p(iButtonWorker* worker, iButtonKey* key) { worker->key_p = key; } @@ -183,6 +189,11 @@ static int32_t ibutton_worker_thread(void* thread_context) { ibutton_worker_set_key_p(worker, message.data.key); ibutton_worker_switch_mode(worker, iButtonWorkerEmulate); break; + case iButtonMessageNotifyEmulate: + if(worker->emulate_cb) { + worker->emulate_cb(worker->cb_ctx, true); + } + break; } } else if(status == osErrorTimeout) { ibutton_worker_modes[worker->mode_index].tick(worker); diff --git a/lib/one_wire/ibutton/ibutton_worker_i.h b/lib/one_wire/ibutton/ibutton_worker_i.h index ae2d4dc38fc..93755481e87 100644 --- a/lib/one_wire/ibutton/ibutton_worker_i.h +++ b/lib/one_wire/ibutton/ibutton_worker_i.h @@ -73,6 +73,7 @@ struct iButtonWorker { extern const iButtonWorkerModeType ibutton_worker_modes[]; void ibutton_worker_switch_mode(iButtonWorker* worker, iButtonWorkerMode mode); +void ibutton_worker_notify_emulate(iButtonWorker* worker); #ifdef __cplusplus } diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c index ff5ba35129d..5ee768623ea 100644 --- a/lib/one_wire/ibutton/ibutton_worker_modes.c +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -184,9 +184,7 @@ void ibutton_worker_mode_read_stop(iButtonWorker* worker) { static void onewire_slave_callback(void* context) { furi_assert(context); iButtonWorker* worker = context; - if(worker->emulate_cb != NULL) { - worker->emulate_cb(worker->cb_ctx, true); - } + ibutton_worker_notify_emulate(worker); } void ibutton_worker_emulate_dallas_start(iButtonWorker* worker) { From 5de72e75dfdbd000aded8f64277c94c02c80e6e9 Mon Sep 17 00:00:00 2001 From: SG Date: Thu, 12 May 2022 21:38:33 +1000 Subject: [PATCH 23/24] Compile commands generator (#1223) --- Makefile | 4 +++ make/rules.mk | 16 +++++++++ make/toolchain.mk | 2 +- scripts/compile_db.py | 77 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100755 scripts/compile_db.py diff --git a/Makefile b/Makefile index 136923476f5..5304cfa5465 100644 --- a/Makefile +++ b/Makefile @@ -148,3 +148,7 @@ format: guruguru: @echo "ぐるぐる回る" @$(PROJECT_ROOT)/scripts/guruguru.py $(PROJECT_ROOT) + +.PHONY: generate_compile_db +generate_compile_db: + @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) generate_compile_db \ No newline at end of file diff --git a/make/rules.mk b/make/rules.mk index 32e525b64ff..bdf8a4af043 100644 --- a/make/rules.mk +++ b/make/rules.mk @@ -155,6 +155,22 @@ generate_cscope_db: @cscope -b -k -i $(OBJ_DIR)/source.list -f $(OBJ_DIR)/cscope.out @rm -rf $(OBJ_DIR)/source.list $(OBJ_DIR)/source.list.p +.PHONY: generate_compile_db +generate_compile_db: + @echo "$(ASM_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/db.asm_source.list + @echo "$(C_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/db.c_source.list + @echo "$(CPP_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/db.cpp_source.list + @echo "$(AS)$(CFLAGS)" | tr ' ' '\n' > $(OBJ_DIR)/db.asm_flags.list + @echo "$(CC)$(CFLAGS)" | tr ' ' '\n' > $(OBJ_DIR)/db.c_flags.list + @echo "$(CPP)$(CFLAGS)$(CPPFLAGS)" | tr ' ' '\n' > $(OBJ_DIR)/db.cpp_flags.list + @$(PROJECT_ROOT)/scripts/compile_db.py generate -p $(OBJ_DIR) + @rm $(OBJ_DIR)/db.asm_source.list + @rm $(OBJ_DIR)/db.c_source.list + @rm $(OBJ_DIR)/db.cpp_source.list + @rm $(OBJ_DIR)/db.asm_flags.list + @rm $(OBJ_DIR)/db.c_flags.list + @rm $(OBJ_DIR)/db.cpp_flags.list + # Prevent make from searching targets for real files %.d: ; diff --git a/make/toolchain.mk b/make/toolchain.mk index 2946a2e20e6..f161d3d1e5f 100644 --- a/make/toolchain.mk +++ b/make/toolchain.mk @@ -36,6 +36,6 @@ else CFLAGS += -DFURI_NDEBUG -DNDEBUG -Og -g endif -CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" +CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF "$(@:%.o=%.d)" CPPFLAGS += -fno-threadsafe-statics -fno-use-cxa-atexit -fno-exceptions -fno-rtti LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -n diff --git a/scripts/compile_db.py b/scripts/compile_db.py new file mode 100755 index 00000000000..76c445cf064 --- /dev/null +++ b/scripts/compile_db.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + +from flipper.app import App +import json +import pathlib + + +class Main(App): + def init(self): + self.subparsers = self.parser.add_subparsers(help="sub-command help") + + # generate + self.parser_generate = self.subparsers.add_parser( + "generate", help="Check source code format and file names" + ) + self.parser_generate.add_argument("-p", dest="path", required=True) + self.parser_generate.set_defaults(func=self.generate) + + def parse_sources(self, path, source_path, flags_path): + flags = "" + with open(path + "/" + flags_path) as f: + for line in f: + if line.strip(): + flags += line.strip() + " " + + local_path = str(pathlib.Path().resolve()) + + data = [] + with open(path + "/" + source_path) as f: + for line in f: + if line.strip(): + file = line.strip() + data.append( + { + "directory": local_path, + "command": flags + "-c " + file, + "file": file, + } + ) + return data + + def generate(self): + DB_SOURCE = [ + { + "name": "ASM", + "source": "db.asm_source.list", + "flags": "db.asm_flags.list", + }, + {"name": "C", "source": "db.c_source.list", "flags": "db.c_flags.list"}, + { + "name": "CPP", + "source": "db.cpp_source.list", + "flags": "db.cpp_flags.list", + }, + ] + + path = self.args.path + out_data = [] + out_path = path + "/" + "compile_commands.json" + out_file = open(out_path, mode="w") + + for record in DB_SOURCE: + self.logger.info( + f"Processing {record['name']} ({record['source']}, {record['flags']})" + ) + data = self.parse_sources(path, record["source"], record["flags"]) + out_data += data + + self.logger.info(f"Saving") + json.dump(out_data, out_file, indent=2) + + self.logger.info(f"Compilation DB written to " + out_path) + return 0 + + +if __name__ == "__main__": + Main()() From b72a0944217d327fc2ec9826e559a9d267e0b1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 12 May 2022 16:59:38 +0300 Subject: [PATCH 24/24] MusicPlayer: set default volume in worker thread to 1.0f and fix issue with leaking memory (#1224) --- applications/music_player/music_player.c | 3 +-- applications/music_player/music_player_cli.c | 1 + applications/music_player/music_player_worker.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/applications/music_player/music_player.c b/applications/music_player/music_player.c index 73f4bd2c829..6dfef4920d0 100644 --- a/applications/music_player/music_player.c +++ b/applications/music_player/music_player.c @@ -298,7 +298,7 @@ int32_t music_player_app(void* p) { if(p) { string_cat_str(file_path, p); } else { - char* file_name = malloc(256); + char file_name[256] = {0}; DialogsApp* dialogs = furi_record_open("dialogs"); bool res = dialog_file_select_show( dialogs, @@ -315,7 +315,6 @@ int32_t music_player_app(void* p) { string_cat_str(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); string_cat_str(file_path, "/"); string_cat_str(file_path, file_name); - free(file_name); } if(!music_player_worker_load(music_player->worker, string_get_cstr(file_path))) { diff --git a/applications/music_player/music_player_cli.c b/applications/music_player/music_player_cli.c index 0d98101e73b..febb8b1060f 100644 --- a/applications/music_player/music_player_cli.c +++ b/applications/music_player/music_player_cli.c @@ -23,6 +23,7 @@ static void music_player_cli(Cli* cli, string_t args, void* context) { } printf("Press CTRL+C to stop\r\n"); + music_player_worker_set_volume(music_player_worker, 1.0f); music_player_worker_start(music_player_worker); while(!cli_cmd_interrupt_received(cli)) { osDelay(50); diff --git a/applications/music_player/music_player_worker.c b/applications/music_player/music_player_worker.c index 9a0087aa6a9..7a5847c9d2c 100644 --- a/applications/music_player/music_player_worker.c +++ b/applications/music_player/music_player_worker.c @@ -102,6 +102,8 @@ MusicPlayerWorker* music_player_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, music_player_worker_thread_callback); + instance->volume = 1.0f; + return instance; }