diff --git a/applications/main/subghz/scenes/subghz_scene_radio_settings.c b/applications/main/subghz/scenes/subghz_scene_radio_settings.c index 93afe5e31..8e48d0c91 100644 --- a/applications/main/subghz/scenes/subghz_scene_radio_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_radio_settings.c @@ -55,7 +55,7 @@ const int32_t debug_counter_val[DEBUG_COUNTER_COUNT] = { 10, 50, 65535, - 65534, + -2147483647, 0, -1, -2, diff --git a/applications/main/subghz/scenes/subghz_scene_signal_settings.c b/applications/main/subghz/scenes/subghz_scene_signal_settings.c index 728be91b5..382289513 100644 --- a/applications/main/subghz/scenes/subghz_scene_signal_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_signal_settings.c @@ -13,6 +13,8 @@ static uint32_t counter32 = 0x0; static uint16_t counter16 = 0x0; static uint8_t byte_count = 0; static uint8_t* byte_ptr = NULL; +static uint8_t hex_char_lenght = 0; +static FuriString* byte_input_text; #define COUNTER_MODE_COUNT 7 static const char* const counter_mode_text[COUNTER_MODE_COUNT] = { @@ -50,11 +52,61 @@ static Protocols protocols[] = { #define PROTOCOLS_COUNT (sizeof(protocols) / sizeof(Protocols)); +// our special case function based on strint_to_uint32 from strint.c +StrintParseError strint_to_uint32_base16(const char* str, uint32_t* out, uint8_t* lenght) { + // skip whitespace + while(((*str >= '\t') && (*str <= '\r')) || *str == ' ') { + str++; + } + + // read digits + uint32_t limit = UINT32_MAX; + uint32_t mul_limit = limit / 16; + uint32_t result = 0; + int read_total = 0; + + while(*str != 0) { + int digit_value; + if(*str >= '0' && *str <= '9') { + digit_value = *str - '0'; + } else if(*str >= 'A' && *str <= 'Z') { + digit_value = *str - 'A' + 10; + } else if(*str >= 'a' && *str <= 'z') { + digit_value = *str - 'a' + 10; + } else { + break; + } + + if(digit_value >= 16) { + break; + } + + if(result > mul_limit) return StrintParseOverflowError; + result *= 16; + if(result > limit - digit_value) return StrintParseOverflowError; //-V658 + result += digit_value; + + read_total++; + str++; + } + + if(read_total == 0) { + result = 0; + *lenght = 0; + return StrintParseAbsentError; + } + + if(out) *out = result; + if(lenght) *lenght = read_total; + return StrintParseNoError; +} + void subghz_scene_signal_settings_counter_mode_changed(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, counter_mode_text[index]); counter_mode = counter_mode_value[index]; } + void subghz_scene_signal_settings_byte_input_callback(void* context) { SubGhz* subghz = context; view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); @@ -62,11 +114,15 @@ void subghz_scene_signal_settings_byte_input_callback(void* context) { void subghz_scene_signal_settings_variable_item_list_enter_callback(void* context, uint32_t index) { SubGhz* subghz = context; + // when we click OK on "Edit counter" item if(index == 1) { + furi_string_cat_printf(byte_input_text, "%i", hex_char_lenght * 4); + furi_string_cat_str(byte_input_text, "-bit counter in HEX"); + // Setup byte_input view ByteInput* byte_input = subghz->byte_input; - byte_input_set_header_text(byte_input, "Enter counter in HEX"); + byte_input_set_header_text(byte_input, furi_string_get_cstr(byte_input_text)); byte_input_set_result_callback( byte_input, @@ -75,7 +131,6 @@ void subghz_scene_signal_settings_variable_item_list_enter_callback(void* contex subghz, byte_ptr, byte_count); - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); } } @@ -154,6 +209,8 @@ void subghz_scene_signal_settings_on_enter(void* context) { // ### Counter edit section ### FuriString* tmp_text = furi_string_alloc_set_str(""); FuriString* textCnt = furi_string_alloc_set_str(""); + byte_input_text = furi_string_alloc_set_str("Enter "); + bool counter_not_available = true; SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(subghz->txrx); @@ -176,33 +233,50 @@ void subghz_scene_signal_settings_on_enter(void* context) { place = furi_string_search_str(tmp_text, "Cnt:", 0); if(place > 0) { furi_string_set_n(textCnt, tmp_text, place + 4, 8); + furi_string_trim(textCnt); FURI_LOG_D( - TAG, "Found 8 bytes string starting with Cnt:%s", furi_string_get_cstr(textCnt)); - counter_not_available = false; + TAG, + "Taked 8 bytes hex value starting after 'Cnt:' - %s", + furi_string_get_cstr(textCnt)); - // trim and convert 8 simbols string to uint32 by base 16 (hex) by strint_to_uint32(); + // trim and convert 8 simbols string to uint32 by base 16 (hex); // later we use loaded_counter in subghz_scene_signal_settings_on_event to check is there 0 or not - special case - strint_to_uint32(furi_string_get_cstr(textCnt), NULL, &loaded_counter32, 16); - // Check it there counter 2 (less than 65535) or 4 (more than 65535) hex bytes long and use corresponding variable for ByteInput - // To show hex value we must revert bytes for ByteInput view and display 2 or 4 hex bytes to edit - if(counter32 > 0xFFFF) { - byte_count = 4; - counter32 = loaded_counter32; - furi_string_printf(tmp_text, "%08lX", counter32); - FURI_LOG_D(TAG, "Byte count %i", byte_count); - FURI_LOG_D(TAG, "Counter DEC %li, HEX %lX", counter32, counter32); - counter32 = __bswap32(counter32); - byte_ptr = (uint8_t*)&counter32; + if(strint_to_uint32_base16( + furi_string_get_cstr(textCnt), &loaded_counter32, &hex_char_lenght) == + StrintParseNoError) { + counter_not_available = false; + + // calculate and roundup number of hex bytes do display counter in byte_input (every 2 hex simbols = 1 byte for view) + // later must be used in byte_input to restrict number of available byte to edit + // cnt_byte_count = (hex_char_lenght + 1) / 2; + + FURI_LOG_D( + TAG, + "Result of conversion from String to uint_32 DEC %li, HEX %lX, HEX lenght %i symbols", + loaded_counter32, + loaded_counter32, + hex_char_lenght); + + // Check is there byte_count more than 2 hex bytes long (16 bit) or not (32bit) + // To show hex value we must correct revert bytes for ByteInput view + if(hex_char_lenght > 4) { + counter32 = loaded_counter32; + furi_string_printf(tmp_text, "%lX", counter32); + counter32 = __bswap32(counter32); + byte_ptr = (uint8_t*)&counter32; + byte_count = 4; + } else { + counter16 = loaded_counter32; + furi_string_printf(tmp_text, "%X", counter16); + counter16 = __bswap16(counter16); + byte_ptr = (uint8_t*)&counter16; + byte_count = 2; + } } else { - counter16 = loaded_counter32; - byte_count = 2; - furi_string_printf(tmp_text, "%04X", counter16); - FURI_LOG_D(TAG, "Byte count %i", byte_count); - FURI_LOG_D(TAG, "Counter DEC %i, HEX %X", counter16, counter16); - counter16 = __bswap16(counter16); - byte_ptr = (uint8_t*)&counter16; - } + FURI_LOG_E(TAG, "Cant convert text counter value"); + }; + } else { FURI_LOG_D(TAG, "Counter not available for this protocol"); } @@ -248,14 +322,17 @@ bool subghz_scene_signal_settings_on_event(void* context, SceneManagerEvent even subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); subghz_txrx_stop(subghz->txrx); } + // at this point we must have signal Cnt:00 - // convert back after byte_view and do one send with our new mult (counter16) - at end we must have signal Cnt = counter16 + // convert back after byte_input and do one send with our new mult (counter16) - at end we must have signal Cnt = counter16 counter16 = __bswap16(counter16); + if(counter16 > 0) { furi_hal_subghz_set_rolling_counter_mult(counter16); subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); subghz_txrx_stop(subghz->txrx); } + // restore user definded counter increase value (mult) furi_hal_subghz_set_rolling_counter_mult(tmp_counter); break; @@ -274,11 +351,13 @@ bool subghz_scene_signal_settings_on_event(void* context, SceneManagerEvent even } counter32 = __bswap32(counter32); + if(counter32 > 0) { furi_hal_subghz_set_rolling_counter_mult(counter32); subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); subghz_txrx_stop(subghz->txrx); } + furi_hal_subghz_set_rolling_counter_mult(tmp_counter); break; default: @@ -333,4 +412,5 @@ void subghz_scene_signal_settings_on_exit(void* context) { variable_item_list_reset(subghz->variable_item_list); byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); byte_input_set_header_text(subghz->byte_input, ""); + furi_string_free(byte_input_text); } diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index 5d0f7a6b8..fa64f89f3 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -277,7 +277,7 @@ static bool subghz_protocol_alutech_at_4n_gen_data( if(alutech_at4n_counter_mode == 0) { // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -293,7 +293,7 @@ static bool subghz_protocol_alutech_at_4n_gen_data( if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index ea94e36be..e829c4dfe 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -189,7 +189,7 @@ static void subghz_protocol_encoder_came_atomo_get_upload( if(came_atomo_counter_mode == 0) { // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -205,7 +205,7 @@ static void subghz_protocol_encoder_came_atomo_get_upload( if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index d44385ac7..9ddccad73 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -140,7 +140,7 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst data_prg[0] = 0x00; if(allow_zero_seed || (instance->generic.seed != 0x0)) { - if(!(furi_hal_subghz_get_rolling_counter_mult() >= 0xFFFE)) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFFF) { @@ -158,7 +158,7 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst } if(temp_counter_backup != 0x0) { - if(!(furi_hal_subghz_get_rolling_counter_mult() >= 0xFFFE)) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(temp_counter_backup < 0xFFFFF) { if((temp_counter_backup + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFFF) { diff --git a/lib/subghz/protocols/hay21.c b/lib/subghz/protocols/hay21.c index 0d2c1059e..b6640e570 100644 --- a/lib/subghz/protocols/hay21.c +++ b/lib/subghz/protocols/hay21.c @@ -146,7 +146,7 @@ static void subghz_protocol_encoder_hay21_get_upload(SubGhzProtocolEncoderHay21* // Counter increment // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xF) { instance->generic.cnt = 0; diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index c90cfcf0e..70ccc2f82 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -186,7 +186,7 @@ static bool subghz_protocol_keeloq_gen_data( if(keeloq_counter_mode == 0) { // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { // If counter is 0xFFFF we will reset it to 0 if(instance->generic.cnt < 0xFFFF) { // Increase counter with value set in global settings (mult) @@ -205,7 +205,7 @@ static bool subghz_protocol_keeloq_gen_data( if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } diff --git a/lib/subghz/protocols/kinggates_stylo_4k.c b/lib/subghz/protocols/kinggates_stylo_4k.c index eccff1950..83dbd5298 100644 --- a/lib/subghz/protocols/kinggates_stylo_4k.c +++ b/lib/subghz/protocols/kinggates_stylo_4k.c @@ -156,7 +156,7 @@ static bool subghz_protocol_kinggates_stylo_4k_gen_data( instance->generic.cnt = decrypt & 0xFFFF; // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -172,7 +172,7 @@ static bool subghz_protocol_kinggates_stylo_4k_gen_data( if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index f3e1e33bb..92ca20838 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -154,7 +154,7 @@ static void subghz_protocol_encoder_nice_flor_s_get_upload( } if(nice_flors_counter_mode == 0) { // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -170,7 +170,7 @@ static void subghz_protocol_encoder_nice_flor_s_get_upload( if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index afc2cbb82..6ee6e97d2 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -253,7 +253,7 @@ static bool // Reconstruction of the data // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -269,7 +269,7 @@ static bool if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } @@ -599,7 +599,7 @@ void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* ou "V2 Phoenix %dbit\r\n" "Key:%05lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Cnt:0x%04lX\r\n" + "Cnt:%04lX\r\n" "Btn:%X\r\n", instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index 1225f5d32..7c00a4b71 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -131,7 +131,7 @@ static bool instance->generic.serial = data & 0xFFFFFF; // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -147,7 +147,7 @@ static bool if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 2f9fd1f10..cbf110053 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -125,7 +125,7 @@ static bool subghz_protocol_somfy_telis_gen_data( btn = subghz_protocol_somfy_telis_get_btn_code(); // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -141,7 +141,7 @@ static bool subghz_protocol_somfy_telis_gen_data( if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; } diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index d6706704c..56465481b 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -130,7 +130,7 @@ void subghz_protocol_encoder_star_line_free(void* context) { static bool subghz_protocol_star_line_gen_data(SubGhzProtocolEncoderStarLine* instance, uint8_t btn) { // Check for OFEX (overflow experimental) mode - if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) { + if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; @@ -146,7 +146,7 @@ static bool if((instance->generic.cnt + 0x1) > 0xFFFF) { instance->generic.cnt = 0; } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { - instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult(); + instance->generic.cnt = 0xFFFE; } else { instance->generic.cnt++; }