From 98f6dbaa09a0268e23e9126cbacd3625204ba04c Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:06:36 +0000 Subject: [PATCH] SubGHz: Fix loading region data --- applications/main/subghz/subghz_cli.c | 13 ++-- applications/main/subghz/subghz_start.c | 96 +++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index a00e0b8e38..02b934f334 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -106,7 +106,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, FuriString* args, void* context) { furi_delay_ms(250); } } else { - printf("This frequency can only be used for RX in your settings\r\n"); + printf("This frequency can only be used for RX in your settings/region\r\n"); } furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); @@ -264,7 +264,7 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { subghz_devices_stop_async_tx(device); } else { - printf("Frequency is outside of default range. Check docs.\r\n"); + printf("Transmission on this frequency is restricted by your settings/region\r\n"); } subghz_devices_sleep(device); @@ -800,7 +800,7 @@ void subghz_cli_command_tx_from_file(Cli* cli, FuriString* args, void* context) subghz_devices_stop_async_tx(device); } else { - printf("Transmission on this frequency is restricted in your settings\r\n"); + printf("Transmission on this frequency is restricted in your settings/region\r\n"); } if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) { @@ -936,8 +936,7 @@ static void subghz_cli_command_encrypt_raw(Cli* cli, FuriString* args) { furi_string_free(source); } -static void subghz_cli_command_chat(Cli* cli, FuriString* args, void* context) { - UNUSED(context); +static void subghz_cli_command_chat(Cli* cli, FuriString* args) { uint32_t frequency = 433920000; uint32_t device_ind = 0; // 0 - CC1101_INT, 1 - CC1101_EXT @@ -966,7 +965,7 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args, void* context) { // TODO if(!furi_hal_subghz_is_tx_allowed(frequency)) { printf( - "In your settings, only reception on this frequency (%lu) is allowed,\r\n" + "In your settings/region, only reception on this frequency (%lu) is allowed,\r\n" "the actual operation of the application is not possible\r\n ", frequency); return; @@ -1140,7 +1139,7 @@ static void subghz_cli_command(Cli* cli, FuriString* args, void* context) { } if(furi_string_cmp_str(cmd, "chat") == 0) { - subghz_cli_command_chat(cli, args, NULL); + subghz_cli_command_chat(cli, args); break; } diff --git a/applications/main/subghz/subghz_start.c b/applications/main/subghz/subghz_start.c index 38bf005293..c470998b5f 100644 --- a/applications/main/subghz/subghz_start.c +++ b/applications/main/subghz/subghz_start.c @@ -1,5 +1,11 @@ #include +#include +#include +#include + +#define SUBGHZ_REGION_FILENAME "/int/.region_data" + static void subghz_cli_command_wrapper(Cli* cli, FuriString* args, void* context) { cli_plugin_wrapper("subghz_cli", 1, cli, args, context); } @@ -9,9 +15,99 @@ static void subghz_cli_command_chat_wrapper(Cli* cli, FuriString* args, void* co subghz_cli_command_wrapper(cli, args, context); } +static bool + subghz_on_system_start_istream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { + File* file = istream->state; + size_t ret = storage_file_read(file, buf, count); + return (count == ret); +} + +static bool subghz_on_system_start_istream_decode_band( + pb_istream_t* stream, + const pb_field_t* field, + void** arg) { + (void)field; + FuriHalRegion* region = *arg; + + PB_Region_Band band = {0}; + if(!pb_decode(stream, PB_Region_Band_fields, &band)) { + FURI_LOG_E("SubGhzOnStart", "PB Region band decode error: %s", PB_GET_ERROR(stream)); + return false; + } + + region->bands_count += 1; + region = realloc( //-V701 + region, + sizeof(FuriHalRegion) + sizeof(FuriHalRegionBand) * region->bands_count); + size_t pos = region->bands_count - 1; + region->bands[pos].start = band.start; + region->bands[pos].end = band.end; + region->bands[pos].power_limit = band.power_limit; + region->bands[pos].duty_cycle = band.duty_cycle; + *arg = region; + + FURI_LOG_I( + "SubGhzOnStart", + "Add allowed band: start %luHz, stop %luHz, power_limit %ddBm, duty_cycle %u%%", + band.start, + band.end, + band.power_limit, + band.duty_cycle); + return true; +} + void subghz_on_system_start(void) { Cli* cli = furi_record_open(RECORD_CLI); cli_add_command(cli, "subghz", CliCommandFlagDefault, subghz_cli_command_wrapper, NULL); cli_add_command(cli, "chat", CliCommandFlagDefault, subghz_cli_command_chat_wrapper, NULL); furi_record_close(RECORD_CLI); + +#ifdef SRV_STORAGE + Storage* storage = furi_record_open(RECORD_STORAGE); + File* file = storage_file_alloc(storage); + FileInfo fileinfo = {0}; + PB_Region pb_region = {0}; + pb_region.bands.funcs.decode = subghz_on_system_start_istream_decode_band; + + do { + if(storage_common_stat(storage, SUBGHZ_REGION_FILENAME, &fileinfo) != FSE_OK || + fileinfo.size == 0) { + FURI_LOG_W("SubGhzOnStart", "Region data is missing or empty"); + break; + } + + if(!storage_file_open(file, SUBGHZ_REGION_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E("SubGhzOnStart", "Unable to open region data"); + break; + } + + pb_istream_t istream = { + .callback = subghz_on_system_start_istream_read, + .state = file, + .errmsg = NULL, + .bytes_left = fileinfo.size, + }; + + pb_region.bands.arg = malloc(sizeof(FuriHalRegion)); + if(!pb_decode(&istream, PB_Region_fields, &pb_region)) { + FURI_LOG_E("SubGhzOnStart", "Invalid region data"); + free(pb_region.bands.arg); + break; + } + + FuriHalRegion* region = pb_region.bands.arg; + memcpy( + region->country_code, + pb_region.country_code->bytes, + pb_region.country_code->size < 4 ? pb_region.country_code->size : 3); + furi_hal_region_set(region); + } while(0); + + pb_release(PB_Region_fields, &pb_region); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); +#else + UNUSED(subghz_on_system_start_istream_decode_band); + UNUSED(subghz_on_system_start_istream_read); +#endif }