mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-05 05:09:09 -07:00
Merge branch 'dev' of https://github.com/Flipper-XFW/Xtreme-Firmware into dev
This commit is contained in:
6
.github/workflow_data/devbuild.py
vendored
6
.github/workflow_data/devbuild.py
vendored
@@ -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 (
|
||||
|
||||
2
.github/workflow_data/webhook.py
vendored
2
.github/workflow_data/webhook.py
vendored
@@ -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
|
||||
|
||||
7
.github/workflow_data/webupdater.py
vendored
7
.github/workflow_data/webupdater.py
vendored
@@ -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"]
|
||||
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -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 }}
|
||||
|
||||
1
.github/workflows/hotfix.yml
vendored
1
.github/workflows/hotfix.yml
vendored
@@ -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: |
|
||||
|
||||
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -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: |
|
||||
|
||||
@@ -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="3.3",
|
||||
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",
|
||||
|
||||
230
applications/external/ble_spam/ble_spam.c
vendored
230
applications/external/ble_spam/ble_spam.c
vendored
@@ -30,13 +30,10 @@ static Attack attacks[] = {
|
||||
.payload =
|
||||
{
|
||||
.random_mac = false,
|
||||
.cfg =
|
||||
.cfg.specific.continuity =
|
||||
{
|
||||
.continuity =
|
||||
{
|
||||
.type = ContinuityTypeCustomCrash,
|
||||
.data = {},
|
||||
},
|
||||
.type = ContinuityTypeCustomCrash,
|
||||
.data = {},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -47,13 +44,10 @@ static Attack attacks[] = {
|
||||
.payload =
|
||||
{
|
||||
.random_mac = false,
|
||||
.cfg =
|
||||
.cfg.specific.continuity =
|
||||
{
|
||||
.continuity =
|
||||
{
|
||||
.type = ContinuityTypeNearbyAction,
|
||||
.data = {},
|
||||
},
|
||||
.type = ContinuityTypeNearbyAction,
|
||||
.data = {},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -64,13 +58,10 @@ static Attack attacks[] = {
|
||||
.payload =
|
||||
{
|
||||
.random_mac = false,
|
||||
.cfg =
|
||||
.cfg.specific.continuity =
|
||||
{
|
||||
.continuity =
|
||||
{
|
||||
.type = ContinuityTypeProximityPair,
|
||||
.data = {},
|
||||
},
|
||||
.type = ContinuityTypeProximityPair,
|
||||
.data = {},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -81,10 +72,7 @@ static Attack attacks[] = {
|
||||
.payload =
|
||||
{
|
||||
.random_mac = true,
|
||||
.cfg =
|
||||
{
|
||||
.fastpair = {},
|
||||
},
|
||||
.cfg.specific.fastpair = {},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -94,13 +82,10 @@ static Attack attacks[] = {
|
||||
.payload =
|
||||
{
|
||||
.random_mac = true,
|
||||
.cfg =
|
||||
.cfg.specific.easysetup =
|
||||
{
|
||||
.easysetup =
|
||||
{
|
||||
.type = EasysetupTypeBuds,
|
||||
.data = {},
|
||||
},
|
||||
.type = EasysetupTypeBuds,
|
||||
.data = {},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -111,13 +96,10 @@ static Attack attacks[] = {
|
||||
.payload =
|
||||
{
|
||||
.random_mac = true,
|
||||
.cfg =
|
||||
.cfg.specific.easysetup =
|
||||
{
|
||||
.easysetup =
|
||||
{
|
||||
.type = EasysetupTypeWatch,
|
||||
.data = {},
|
||||
},
|
||||
.type = EasysetupTypeWatch,
|
||||
.data = {},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -128,10 +110,7 @@ static Attack attacks[] = {
|
||||
.payload =
|
||||
{
|
||||
.random_mac = true,
|
||||
.cfg =
|
||||
{
|
||||
.swiftpair = {},
|
||||
},
|
||||
.cfg.specific.swiftpair = {},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -152,8 +131,17 @@ typedef struct {
|
||||
uint8_t delay;
|
||||
FuriThread* thread;
|
||||
int8_t index;
|
||||
bool ignore_bruteforce;
|
||||
} State;
|
||||
|
||||
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,
|
||||
@@ -183,11 +171,17 @@ static int32_t adv_thread(void* _ctx) {
|
||||
uint8_t mac[GAP_MAC_ADDR_SIZE];
|
||||
Payload* payload = &attacks[state->index].payload;
|
||||
const Protocol* protocol = attacks[state->index].protocol;
|
||||
ProtocolCfg* _cfg = &payload->cfg;
|
||||
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) {
|
||||
if(_cfg->mode == ProtocolModeBruteforce && _cfg->bruteforce.counter++ >= 10) {
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value =
|
||||
(_cfg->bruteforce.value + 1) % (1 << (_cfg->bruteforce.size * 8));
|
||||
}
|
||||
protocol->make_packet(&size, &packet, &payload->cfg);
|
||||
} else {
|
||||
protocols[rand() % protocols_count]->make_packet(&size, &packet, NULL);
|
||||
@@ -220,10 +214,11 @@ static void toggle_adv(State* state) {
|
||||
}
|
||||
}
|
||||
|
||||
#define PAGE_MIN (-4)
|
||||
#define PAGE_MIN (-5)
|
||||
#define PAGE_MAX ATTACKS_COUNT
|
||||
enum {
|
||||
PageHelpApps = PAGE_MIN,
|
||||
PageHelpBruteforce = PAGE_MIN,
|
||||
PageHelpApps,
|
||||
PageHelpDelay,
|
||||
PageHelpDistance,
|
||||
PageHelpInfoConfig,
|
||||
@@ -265,6 +260,23 @@ static void draw_callback(Canvas* canvas, void* _ctx) {
|
||||
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");
|
||||
@@ -343,7 +355,7 @@ 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#3.3\e#",
|
||||
" Version \e#4.1\e#",
|
||||
false);
|
||||
break;
|
||||
default: {
|
||||
@@ -355,20 +367,45 @@ static void draw_callback(Canvas* canvas, void* _ctx) {
|
||||
char str[32];
|
||||
|
||||
canvas_set_font(canvas, FontBatteryPercent);
|
||||
snprintf(str, sizeof(str), "%ims", delays[state->delay]);
|
||||
if(payload->cfg.mode == ProtocolModeBruteforce) {
|
||||
snprintf(
|
||||
str,
|
||||
sizeof(str),
|
||||
"0x%0*lX",
|
||||
payload->cfg.bruteforce.size * 2,
|
||||
payload->cfg.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,
|
||||
ATTACKS_COUNT,
|
||||
protocol ? protocol->get_name(&payload->cfg) : "Everything AND");
|
||||
canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 21, str);
|
||||
if(payload->cfg.mode == ProtocolModeBruteforce) {
|
||||
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, "<Send");
|
||||
canvas_draw_str_aligned(canvas, 122, 22, AlignRight, AlignBottom, str);
|
||||
canvas_invert_color(canvas);
|
||||
} else {
|
||||
snprintf(
|
||||
str,
|
||||
sizeof(str),
|
||||
"%02i/%02i: %s",
|
||||
state->index + 1,
|
||||
ATTACKS_COUNT,
|
||||
protocol ? protocol->get_name(&payload->cfg) : "Everything AND");
|
||||
canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 22, str);
|
||||
}
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 4, 33, attack->title);
|
||||
@@ -424,6 +461,7 @@ static bool input_callback(InputEvent* input, void* _ctx) {
|
||||
consumed = true;
|
||||
|
||||
bool is_attack = state->index >= 0 && state->index <= ATTACKS_COUNT - 1;
|
||||
ProtocolCfg* _cfg = is_attack ? &attacks[state->index].payload.cfg : NULL;
|
||||
bool advertising = state->advertising;
|
||||
|
||||
switch(input->key) {
|
||||
@@ -440,27 +478,80 @@ static bool input_callback(InputEvent* input, void* _ctx) {
|
||||
}
|
||||
break;
|
||||
case InputKeyUp:
|
||||
if(is_attack && state->delay < COUNT_OF(delays) - 1) {
|
||||
state->delay++;
|
||||
if(advertising) start_blink(state);
|
||||
if(is_attack) {
|
||||
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value =
|
||||
(_cfg->bruteforce.value + 1) % (1 << (_cfg->bruteforce.size * 8));
|
||||
} else if(state->delay < COUNT_OF(delays) - 1) {
|
||||
state->delay++;
|
||||
if(advertising) start_blink(state);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(is_attack && state->delay > 0) {
|
||||
state->delay--;
|
||||
if(advertising) start_blink(state);
|
||||
if(is_attack) {
|
||||
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value =
|
||||
(_cfg->bruteforce.value - 1) % (1 << (_cfg->bruteforce.size * 8));
|
||||
} else if(state->delay > 0) {
|
||||
state->delay--;
|
||||
if(advertising) start_blink(state);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(state->index > PAGE_MIN) {
|
||||
if(advertising) toggle_adv(state);
|
||||
state->index--;
|
||||
if(input->type == InputTypeLong) {
|
||||
state->ignore_bruteforce = _cfg ? (_cfg->mode != ProtocolModeBruteforce) : true;
|
||||
}
|
||||
if(input->type == InputTypeShort || !is_attack || state->ignore_bruteforce ||
|
||||
_cfg->mode != ProtocolModeBruteforce) {
|
||||
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->cfg);
|
||||
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(state->index < PAGE_MAX) {
|
||||
if(advertising) toggle_adv(state);
|
||||
state->index++;
|
||||
if(input->type == InputTypeLong) {
|
||||
state->ignore_bruteforce = _cfg ? (_cfg->mode != ProtocolModeBruteforce) : true;
|
||||
}
|
||||
if(input->type == InputTypeShort || !is_attack || state->ignore_bruteforce ||
|
||||
_cfg->mode != ProtocolModeBruteforce) {
|
||||
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:
|
||||
@@ -488,9 +579,17 @@ static void lock_timer_callback(void* _ctx) {
|
||||
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) {
|
||||
Ctx* ctx = _ctx;
|
||||
return scene_manager_handle_back_event(ctx->scene_manager);
|
||||
State* state = _ctx;
|
||||
return scene_manager_handle_back_event(state->ctx.scene_manager);
|
||||
}
|
||||
|
||||
int32_t ble_spam(void* p) {
|
||||
@@ -507,7 +606,8 @@ int32_t ble_spam(void* p) {
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
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->ctx);
|
||||
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);
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
#include <core/core_defines.h>
|
||||
#include "../ble_spam.h"
|
||||
|
||||
typedef union ProtocolCfg ProtocolCfg;
|
||||
typedef struct ProtocolCfg ProtocolCfg;
|
||||
|
||||
typedef struct {
|
||||
const Icon* icon;
|
||||
const char* (*get_name)(const ProtocolCfg* _cfg);
|
||||
void (*make_packet)(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg);
|
||||
void (*make_packet)(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg);
|
||||
void (*extra_config)(Ctx* ctx);
|
||||
uint8_t (*config_count)(const ProtocolCfg* _cfg);
|
||||
} Protocol;
|
||||
|
||||
@@ -5,11 +5,25 @@
|
||||
#include "easysetup.h"
|
||||
#include "swiftpair.h"
|
||||
|
||||
union ProtocolCfg {
|
||||
ContinuityCfg continuity;
|
||||
FastpairCfg fastpair;
|
||||
EasysetupCfg easysetup;
|
||||
SwiftpairCfg swiftpair;
|
||||
typedef enum {
|
||||
ProtocolModeRandom,
|
||||
ProtocolModeValue,
|
||||
ProtocolModeBruteforce,
|
||||
} ProtocolMode;
|
||||
|
||||
struct ProtocolCfg {
|
||||
ProtocolMode mode;
|
||||
struct {
|
||||
uint8_t counter;
|
||||
uint32_t value;
|
||||
uint8_t size;
|
||||
} bruteforce;
|
||||
union {
|
||||
ContinuityCfg continuity;
|
||||
FastpairCfg fastpair;
|
||||
EasysetupCfg easysetup;
|
||||
SwiftpairCfg swiftpair;
|
||||
} specific;
|
||||
};
|
||||
|
||||
extern const Protocol* protocols[];
|
||||
|
||||
@@ -71,8 +71,8 @@ static const char* type_names[ContinuityTypeCOUNT] = {
|
||||
[ContinuityTypeNearbyInfo] = "Nearby Info",
|
||||
[ContinuityTypeCustomCrash] = "Continuity Custom",
|
||||
};
|
||||
static const char* continuity_get_name(const ProtocolCfg* _cfg) {
|
||||
const ContinuityCfg* cfg = &_cfg->continuity;
|
||||
static const char* get_name(const ProtocolCfg* _cfg) {
|
||||
const ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
return type_names[cfg->type];
|
||||
}
|
||||
|
||||
@@ -87,11 +87,11 @@ static uint8_t packet_sizes[ContinuityTypeCOUNT] = {
|
||||
[ContinuityTypeNearbyInfo] = HEADER_LEN + 5,
|
||||
[ContinuityTypeCustomCrash] = HEADER_LEN + 11,
|
||||
};
|
||||
static void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) {
|
||||
const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL;
|
||||
static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) {
|
||||
ContinuityCfg* cfg = _cfg ? &_cfg->specific.continuity : NULL;
|
||||
|
||||
ContinuityType type;
|
||||
if(cfg) {
|
||||
if(cfg && cfg->type != 0x00) {
|
||||
type = cfg->type;
|
||||
} else {
|
||||
const ContinuityType types[] = {
|
||||
@@ -139,14 +139,21 @@ static void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const Prot
|
||||
|
||||
case ContinuityTypeProximityPair: {
|
||||
uint16_t model;
|
||||
if(cfg && cfg->data.proximity_pair.model != 0x0000) {
|
||||
model = cfg->data.proximity_pair.model;
|
||||
} else {
|
||||
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model = pp_models[rand() % pp_models_count].value;
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
model = cfg->data.proximity_pair.model;
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
model = cfg->data.proximity_pair.model = _cfg->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)
|
||||
@@ -209,10 +216,17 @@ static void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const Prot
|
||||
|
||||
case ContinuityTypeNearbyAction: {
|
||||
uint8_t action;
|
||||
if(cfg && cfg->data.nearby_action.action != 0x00) {
|
||||
action = cfg->data.nearby_action.action;
|
||||
} else {
|
||||
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
action = na_actions[rand() % na_actions_count].value;
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
action = cfg->data.nearby_action.action;
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
action = cfg->data.nearby_action.action = _cfg->bruteforce.value;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t flags;
|
||||
@@ -293,7 +307,8 @@ enum {
|
||||
};
|
||||
static void config_callback(void* _ctx, uint32_t index) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index);
|
||||
switch(cfg->type) {
|
||||
case ContinuityTypeProximityPair: {
|
||||
@@ -341,19 +356,22 @@ static void config_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
}
|
||||
static void pp_model_changed(VariableItem* item) {
|
||||
ContinuityCfg* cfg = variable_item_get_context(item);
|
||||
ProtocolCfg* _cfg = variable_item_get_context(item);
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
if(index) {
|
||||
index--;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.proximity_pair.model = pp_models[index].value;
|
||||
variable_item_set_current_value_text(item, pp_models[index].name);
|
||||
} else {
|
||||
cfg->data.proximity_pair.model = 0x0000;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
variable_item_set_current_value_text(item, "Random");
|
||||
}
|
||||
}
|
||||
static void pp_prefix_changed(VariableItem* item) {
|
||||
ContinuityCfg* cfg = variable_item_get_context(item);
|
||||
ProtocolCfg* _cfg = variable_item_get_context(item);
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
if(index) {
|
||||
index--;
|
||||
@@ -365,33 +383,39 @@ static void pp_prefix_changed(VariableItem* item) {
|
||||
}
|
||||
}
|
||||
static void na_action_changed(VariableItem* item) {
|
||||
ContinuityCfg* cfg = variable_item_get_context(item);
|
||||
ProtocolCfg* _cfg = variable_item_get_context(item);
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
if(index) {
|
||||
index--;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.nearby_action.action = na_actions[index].value;
|
||||
variable_item_set_current_value_text(item, na_actions[index].name);
|
||||
} else {
|
||||
cfg->data.nearby_action.action = 0x00;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
variable_item_set_current_value_text(item, "Random");
|
||||
}
|
||||
}
|
||||
static void continuity_extra_config(Ctx* ctx) {
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
static void extra_config(Ctx* ctx) {
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.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, cfg);
|
||||
item = variable_item_list_add(
|
||||
list, "Model Code", pp_models_count + 1, pp_model_changed, _cfg);
|
||||
const char* model_name = NULL;
|
||||
char model_name_buf[5];
|
||||
if(cfg->data.proximity_pair.model == 0x0000) {
|
||||
switch(_cfg->mode) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model_name = "Random";
|
||||
value_index = 0;
|
||||
} else {
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
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;
|
||||
@@ -405,12 +429,17 @@ static void continuity_extra_config(Ctx* ctx) {
|
||||
model_name = model_name_buf;
|
||||
value_index = pp_models_count + 1;
|
||||
}
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
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, cfg);
|
||||
variable_item_list_add(list, "Prefix", pp_prefixes_count + 1, pp_prefix_changed, _cfg);
|
||||
const char* prefix_name = NULL;
|
||||
char prefix_name_buf[3];
|
||||
if(cfg->data.proximity_pair.prefix == 0x00) {
|
||||
@@ -440,13 +469,16 @@ static void continuity_extra_config(Ctx* ctx) {
|
||||
}
|
||||
case ContinuityTypeNearbyAction: {
|
||||
item = variable_item_list_add(
|
||||
list, "Action Type", na_actions_count + 1, na_action_changed, cfg);
|
||||
list, "Action Type", na_actions_count + 1, na_action_changed, _cfg);
|
||||
const char* action_name = NULL;
|
||||
char action_name_buf[3];
|
||||
if(cfg->data.nearby_action.action == 0x00) {
|
||||
switch(_cfg->mode) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
action_name = "Random";
|
||||
value_index = 0;
|
||||
} else {
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
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;
|
||||
@@ -463,6 +495,11 @@ static void continuity_extra_config(Ctx* ctx) {
|
||||
action_name = action_name_buf;
|
||||
value_index = na_actions_count + 1;
|
||||
}
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
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);
|
||||
@@ -502,31 +539,40 @@ static uint8_t config_counts[ContinuityTypeCOUNT] = {
|
||||
[ContinuityTypeNearbyInfo] = 0,
|
||||
[ContinuityTypeCustomCrash] = ConfigCcCOUNT - ConfigExtraStart - 1,
|
||||
};
|
||||
static uint8_t continuity_config_count(const ProtocolCfg* _cfg) {
|
||||
const ContinuityCfg* cfg = &_cfg->continuity;
|
||||
static uint8_t config_count(const ProtocolCfg* _cfg) {
|
||||
const ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
return config_counts[cfg->type];
|
||||
}
|
||||
|
||||
const Protocol protocol_continuity = {
|
||||
.icon = &I_apple,
|
||||
.get_name = continuity_get_name,
|
||||
.make_packet = continuity_make_packet,
|
||||
.extra_config = continuity_extra_config,
|
||||
.config_count = continuity_config_count,
|
||||
.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;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
switch(index) {
|
||||
case 0:
|
||||
cfg->data.proximity_pair.model = 0x0000;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
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:
|
||||
_cfg->mode = ProtocolModeBruteforce;
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value = cfg->data.proximity_pair.model;
|
||||
_cfg->bruteforce.size = 2;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
default:
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.proximity_pair.model = pp_models[index - 1].value;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
@@ -534,30 +580,36 @@ static void pp_model_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
void scene_continuity_pp_model_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
Submenu* submenu = ctx->submenu;
|
||||
uint32_t selected = 0;
|
||||
bool found = false;
|
||||
submenu_reset(submenu);
|
||||
|
||||
submenu_add_item(submenu, "Random", 0, pp_model_callback, ctx);
|
||||
if(cfg->data.proximity_pair.model == 0x0000) {
|
||||
found = true;
|
||||
if(_cfg->mode == ProtocolModeRandom) {
|
||||
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 && cfg->data.proximity_pair.model == pp_models[i].value) {
|
||||
if(!found && _cfg->mode == ProtocolModeValue &&
|
||||
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) {
|
||||
found = true;
|
||||
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||
selected = pp_models_count + 1;
|
||||
}
|
||||
|
||||
submenu_add_item(submenu, "Bruteforce", pp_models_count + 2, pp_model_callback, ctx);
|
||||
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||
selected = pp_models_count + 2;
|
||||
}
|
||||
|
||||
submenu_set_selected_item(submenu, selected);
|
||||
|
||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||
@@ -573,12 +625,17 @@ void scene_continuity_pp_model_on_exit(void* _ctx) {
|
||||
|
||||
static void pp_model_custom_callback(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
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;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
ByteInput* byte_input = ctx->byte_input;
|
||||
|
||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||
@@ -597,14 +654,13 @@ bool scene_continuity_pp_model_custom_on_event(void* _ctx, SceneManagerEvent eve
|
||||
return false;
|
||||
}
|
||||
void scene_continuity_pp_model_custom_on_exit(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
cfg->data.proximity_pair.model = (ctx->byte_store[0] << 0x08) + (ctx->byte_store[1] << 0x00);
|
||||
UNUSED(_ctx);
|
||||
}
|
||||
|
||||
static void pp_prefix_callback(void* _ctx, uint32_t index) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
switch(index) {
|
||||
case 0:
|
||||
cfg->data.proximity_pair.prefix = 0x00;
|
||||
@@ -621,7 +677,8 @@ static void pp_prefix_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
void scene_continuity_pp_prefix_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
Submenu* submenu = ctx->submenu;
|
||||
uint32_t selected = 0;
|
||||
bool found = false;
|
||||
@@ -632,6 +689,7 @@ void scene_continuity_pp_prefix_on_enter(void* _ctx) {
|
||||
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) {
|
||||
@@ -641,7 +699,6 @@ void scene_continuity_pp_prefix_on_enter(void* _ctx) {
|
||||
}
|
||||
submenu_add_item(submenu, "Custom", pp_prefixes_count + 1, pp_prefix_callback, ctx);
|
||||
if(!found) {
|
||||
found = true;
|
||||
selected = pp_prefixes_count + 1;
|
||||
}
|
||||
|
||||
@@ -660,12 +717,16 @@ void scene_continuity_pp_prefix_on_exit(void* _ctx) {
|
||||
|
||||
static void pp_prefix_custom_callback(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.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;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
ByteInput* byte_input = ctx->byte_input;
|
||||
|
||||
byte_input_set_header_text(byte_input, "Enter custom Prefix");
|
||||
@@ -683,23 +744,30 @@ bool scene_continuity_pp_prefix_custom_on_event(void* _ctx, SceneManagerEvent ev
|
||||
return false;
|
||||
}
|
||||
void scene_continuity_pp_prefix_custom_on_exit(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
cfg->data.proximity_pair.prefix = (ctx->byte_store[0] << 0x00);
|
||||
UNUSED(_ctx);
|
||||
}
|
||||
|
||||
static void na_action_callback(void* _ctx, uint32_t index) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
switch(index) {
|
||||
case 0:
|
||||
cfg->data.nearby_action.action = 0x00;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
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:
|
||||
_cfg->mode = ProtocolModeBruteforce;
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value = cfg->data.nearby_action.action;
|
||||
_cfg->bruteforce.size = 1;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
default:
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.nearby_action.action = na_actions[index - 1].value;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
@@ -707,30 +775,36 @@ static void na_action_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
void scene_continuity_na_action_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
Submenu* submenu = ctx->submenu;
|
||||
uint32_t selected = 0;
|
||||
bool found = false;
|
||||
submenu_reset(submenu);
|
||||
|
||||
submenu_add_item(submenu, "Random", 0, na_action_callback, ctx);
|
||||
if(cfg->data.nearby_action.action == 0x00) {
|
||||
found = true;
|
||||
if(_cfg->mode == ProtocolModeRandom) {
|
||||
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 && cfg->data.nearby_action.action == na_actions[i].value) {
|
||||
if(!found && _cfg->mode == ProtocolModeValue &&
|
||||
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) {
|
||||
found = true;
|
||||
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||
selected = na_actions_count + 1;
|
||||
}
|
||||
|
||||
submenu_add_item(submenu, "Bruteforce", na_actions_count + 2, na_action_callback, ctx);
|
||||
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||
selected = na_actions_count + 2;
|
||||
}
|
||||
|
||||
submenu_set_selected_item(submenu, selected);
|
||||
|
||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||
@@ -746,12 +820,17 @@ void scene_continuity_na_action_on_exit(void* _ctx) {
|
||||
|
||||
static void na_action_custom_callback(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
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;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
ByteInput* byte_input = ctx->byte_input;
|
||||
|
||||
byte_input_set_header_text(byte_input, "Enter custom Action Type");
|
||||
@@ -769,9 +848,7 @@ bool scene_continuity_na_action_custom_on_event(void* _ctx, SceneManagerEvent ev
|
||||
return false;
|
||||
}
|
||||
void scene_continuity_na_action_custom_on_exit(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
cfg->data.nearby_action.action = (ctx->byte_store[0] << 0x00);
|
||||
UNUSED(_ctx);
|
||||
}
|
||||
|
||||
static void na_flags_callback(void* _ctx) {
|
||||
@@ -780,7 +857,8 @@ static void na_flags_callback(void* _ctx) {
|
||||
}
|
||||
void scene_continuity_na_flags_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
ByteInput* byte_input = ctx->byte_input;
|
||||
|
||||
byte_input_set_header_text(byte_input, "Press back for automatic");
|
||||
@@ -801,6 +879,7 @@ bool scene_continuity_na_flags_on_event(void* _ctx, SceneManagerEvent event) {
|
||||
}
|
||||
void scene_continuity_na_flags_on_exit(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||
cfg->data.nearby_action.flags = (ctx->byte_store[0] << 0x00);
|
||||
}
|
||||
|
||||
202
applications/external/ble_spam/protocols/easysetup.c
vendored
202
applications/external/ble_spam/protocols/easysetup.c
vendored
@@ -36,9 +36,9 @@ const struct {
|
||||
const char* name;
|
||||
} watch_models[] = {
|
||||
{0x1A, "Fallback Watch"},
|
||||
{0x01, "White Watch4 Classic 44"},
|
||||
{0x02, "Black Watch4 Classic 40"},
|
||||
{0x03, "White Watch4 Classic 40"},
|
||||
{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"},
|
||||
@@ -59,8 +59,8 @@ const struct {
|
||||
{0x1B, "Black Watch6 Pink 40mm"},
|
||||
{0x1C, "Gold Watch6 Gold 40mm"},
|
||||
{0x1D, "Silver Watch6 Cyan 44mm"},
|
||||
{0x1E, "Black Watch6 Classic 43mm"},
|
||||
{0x20, "Green Watch6 Classic 43mm"},
|
||||
{0x1E, "Black Watch6 Classic 43m"},
|
||||
{0x20, "Green Watch6 Classic 43m"},
|
||||
};
|
||||
const uint8_t watch_models_count = COUNT_OF(watch_models);
|
||||
|
||||
@@ -68,8 +68,8 @@ static const char* type_names[EasysetupTypeCOUNT] = {
|
||||
[EasysetupTypeBuds] = "EasySetup Buds",
|
||||
[EasysetupTypeWatch] = "EasySetup Watch",
|
||||
};
|
||||
static const char* easysetup_get_name(const ProtocolCfg* _cfg) {
|
||||
const EasysetupCfg* cfg = &_cfg->easysetup;
|
||||
static const char* get_name(const ProtocolCfg* _cfg) {
|
||||
const EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
return type_names[cfg->type];
|
||||
}
|
||||
|
||||
@@ -77,14 +77,18 @@ static uint8_t packet_sizes[EasysetupTypeCOUNT] = {
|
||||
[EasysetupTypeBuds] = 31,
|
||||
[EasysetupTypeWatch] = 15,
|
||||
};
|
||||
void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const ProtocolCfg* _cfg) {
|
||||
const EasysetupCfg* cfg = _cfg ? &_cfg->easysetup : NULL;
|
||||
void make_packet(uint8_t* out_size, uint8_t** out_packet, ProtocolCfg* _cfg) {
|
||||
EasysetupCfg* cfg = _cfg ? &_cfg->specific.easysetup : NULL;
|
||||
|
||||
EasysetupType type;
|
||||
if(cfg) {
|
||||
if(cfg && cfg->type != 0x00) {
|
||||
type = cfg->type;
|
||||
} else {
|
||||
type = rand() % EasysetupTypeCOUNT;
|
||||
const EasysetupType types[] = {
|
||||
EasysetupTypeBuds,
|
||||
EasysetupTypeWatch,
|
||||
};
|
||||
type = types[rand() % COUNT_OF(types)];
|
||||
}
|
||||
|
||||
uint8_t size = packet_sizes[type];
|
||||
@@ -94,10 +98,17 @@ void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const Protoc
|
||||
switch(type) {
|
||||
case EasysetupTypeBuds: {
|
||||
uint32_t model;
|
||||
if(cfg && cfg->data.buds.model != 0x000000) {
|
||||
model = cfg->data.buds.model;
|
||||
} else {
|
||||
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model = buds_models[rand() % buds_models_count].value;
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
model = cfg->data.buds.model;
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
model = cfg->data.buds.model = _cfg->bruteforce.value;
|
||||
break;
|
||||
}
|
||||
|
||||
packet[i++] = 27; // Size
|
||||
@@ -137,10 +148,17 @@ void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const Protoc
|
||||
}
|
||||
case EasysetupTypeWatch: {
|
||||
uint8_t model;
|
||||
if(cfg && cfg->data.watch.model != 0x00) {
|
||||
model = cfg->data.watch.model;
|
||||
} else {
|
||||
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model = watch_models[rand() % watch_models_count].value;
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
model = cfg->data.watch.model;
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
model = cfg->data.watch.model = _cfg->bruteforce.value;
|
||||
break;
|
||||
}
|
||||
|
||||
packet[i++] = 14; // Size
|
||||
@@ -181,7 +199,8 @@ enum {
|
||||
};
|
||||
static void config_callback(void* _ctx, uint32_t index) {
|
||||
Ctx* ctx = _ctx;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index);
|
||||
switch(cfg->type) {
|
||||
case EasysetupTypeBuds: {
|
||||
@@ -214,31 +233,36 @@ static void config_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
}
|
||||
static void buds_model_changed(VariableItem* item) {
|
||||
EasysetupCfg* cfg = variable_item_get_context(item);
|
||||
ProtocolCfg* _cfg = variable_item_get_context(item);
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
if(index) {
|
||||
index--;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.buds.model = buds_models[index].value;
|
||||
variable_item_set_current_value_text(item, buds_models[index].name);
|
||||
} else {
|
||||
cfg->data.buds.model = 0x000000;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
variable_item_set_current_value_text(item, "Random");
|
||||
}
|
||||
}
|
||||
static void watch_model_changed(VariableItem* item) {
|
||||
EasysetupCfg* cfg = variable_item_get_context(item);
|
||||
ProtocolCfg* _cfg = variable_item_get_context(item);
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
if(index) {
|
||||
index--;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.watch.model = watch_models[index].value;
|
||||
variable_item_set_current_value_text(item, watch_models[index].name);
|
||||
} else {
|
||||
cfg->data.watch.model = 0x00;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
variable_item_set_current_value_text(item, "Random");
|
||||
}
|
||||
}
|
||||
static void easysetup_extra_config(Ctx* ctx) {
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
static void extra_config(Ctx* ctx) {
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
VariableItemList* list = ctx->variable_item_list;
|
||||
VariableItem* item;
|
||||
size_t value_index;
|
||||
@@ -246,13 +270,16 @@ static void easysetup_extra_config(Ctx* ctx) {
|
||||
switch(cfg->type) {
|
||||
case EasysetupTypeBuds: {
|
||||
item = variable_item_list_add(
|
||||
list, "Model Code", buds_models_count + 1, buds_model_changed, cfg);
|
||||
list, "Model Code", buds_models_count + 1, buds_model_changed, _cfg);
|
||||
const char* model_name = NULL;
|
||||
char model_name_buf[9];
|
||||
if(cfg->data.buds.model == 0x000000) {
|
||||
switch(_cfg->mode) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model_name = "Random";
|
||||
value_index = 0;
|
||||
} else {
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
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;
|
||||
@@ -265,6 +292,11 @@ static void easysetup_extra_config(Ctx* ctx) {
|
||||
model_name = model_name_buf;
|
||||
value_index = buds_models_count + 1;
|
||||
}
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
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);
|
||||
@@ -274,13 +306,16 @@ static void easysetup_extra_config(Ctx* ctx) {
|
||||
}
|
||||
case EasysetupTypeWatch: {
|
||||
item = variable_item_list_add(
|
||||
list, "Model Code", watch_models_count + 1, watch_model_changed, cfg);
|
||||
list, "Model Code", watch_models_count + 1, watch_model_changed, _cfg);
|
||||
const char* model_name = NULL;
|
||||
char model_name_buf[3];
|
||||
if(cfg->data.watch.model == 0x00) {
|
||||
switch(_cfg->mode) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model_name = "Random";
|
||||
value_index = 0;
|
||||
} else {
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
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;
|
||||
@@ -293,6 +328,11 @@ static void easysetup_extra_config(Ctx* ctx) {
|
||||
model_name = model_name_buf;
|
||||
value_index = watch_models_count + 1;
|
||||
}
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
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);
|
||||
@@ -309,31 +349,40 @@ static uint8_t config_counts[EasysetupTypeCOUNT] = {
|
||||
[EasysetupTypeBuds] = ConfigBudsCOUNT - ConfigExtraStart - 1,
|
||||
[EasysetupTypeWatch] = ConfigWatchCOUNT - ConfigExtraStart - 1,
|
||||
};
|
||||
static uint8_t easysetup_config_count(const ProtocolCfg* _cfg) {
|
||||
const EasysetupCfg* cfg = &_cfg->easysetup;
|
||||
static uint8_t config_count(const ProtocolCfg* _cfg) {
|
||||
const EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
return config_counts[cfg->type];
|
||||
}
|
||||
|
||||
const Protocol protocol_easysetup = {
|
||||
.icon = &I_android,
|
||||
.get_name = easysetup_get_name,
|
||||
.make_packet = easysetup_make_packet,
|
||||
.extra_config = easysetup_extra_config,
|
||||
.config_count = easysetup_config_count,
|
||||
.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;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
switch(index) {
|
||||
case 0:
|
||||
cfg->data.buds.model = 0x000000;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
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:
|
||||
_cfg->mode = ProtocolModeBruteforce;
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value = cfg->data.buds.model;
|
||||
_cfg->bruteforce.size = 3;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
default:
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.buds.model = buds_models[index - 1].value;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
@@ -341,30 +390,36 @@ static void buds_model_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
void scene_easysetup_buds_model_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
Submenu* submenu = ctx->submenu;
|
||||
uint32_t selected = 0;
|
||||
bool found = false;
|
||||
submenu_reset(submenu);
|
||||
|
||||
submenu_add_item(submenu, "Random", 0, buds_model_callback, ctx);
|
||||
if(cfg->data.buds.model == 0x000000) {
|
||||
found = true;
|
||||
if(_cfg->mode == ProtocolModeRandom) {
|
||||
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 && cfg->data.buds.model == buds_models[i].value) {
|
||||
if(!found && _cfg->mode == ProtocolModeValue &&
|
||||
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) {
|
||||
found = true;
|
||||
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||
selected = buds_models_count + 1;
|
||||
}
|
||||
|
||||
submenu_add_item(submenu, "Bruteforce", buds_models_count + 2, buds_model_callback, ctx);
|
||||
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||
selected = buds_models_count + 2;
|
||||
}
|
||||
|
||||
submenu_set_selected_item(submenu, selected);
|
||||
|
||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||
@@ -380,12 +435,18 @@ void scene_easysetup_buds_model_on_exit(void* _ctx) {
|
||||
|
||||
static void buds_model_custom_callback(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
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;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
ByteInput* byte_input = ctx->byte_input;
|
||||
|
||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||
@@ -405,24 +466,30 @@ bool scene_easysetup_buds_model_custom_on_event(void* _ctx, SceneManagerEvent ev
|
||||
return false;
|
||||
}
|
||||
void scene_easysetup_buds_model_custom_on_exit(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
cfg->data.buds.model =
|
||||
(ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00);
|
||||
UNUSED(_ctx);
|
||||
}
|
||||
|
||||
static void watch_model_callback(void* _ctx, uint32_t index) {
|
||||
Ctx* ctx = _ctx;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
switch(index) {
|
||||
case 0:
|
||||
cfg->data.watch.model = 0x00;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
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:
|
||||
_cfg->mode = ProtocolModeBruteforce;
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value = cfg->data.watch.model;
|
||||
_cfg->bruteforce.size = 1;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
default:
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->data.watch.model = watch_models[index - 1].value;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
@@ -430,30 +497,36 @@ static void watch_model_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
void scene_easysetup_watch_model_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
Submenu* submenu = ctx->submenu;
|
||||
uint32_t selected = 0;
|
||||
bool found = false;
|
||||
submenu_reset(submenu);
|
||||
|
||||
submenu_add_item(submenu, "Random", 0, watch_model_callback, ctx);
|
||||
if(cfg->data.watch.model == 0x00) {
|
||||
found = true;
|
||||
if(_cfg->mode == ProtocolModeRandom) {
|
||||
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 && cfg->data.watch.model == watch_models[i].value) {
|
||||
if(!found && _cfg->mode == ProtocolModeValue &&
|
||||
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) {
|
||||
found = true;
|
||||
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||
selected = watch_models_count + 1;
|
||||
}
|
||||
|
||||
submenu_add_item(submenu, "Bruteforce", watch_models_count + 2, watch_model_callback, ctx);
|
||||
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||
selected = watch_models_count + 2;
|
||||
}
|
||||
|
||||
submenu_set_selected_item(submenu, selected);
|
||||
|
||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||
@@ -469,12 +542,17 @@ void scene_easysetup_watch_model_on_exit(void* _ctx) {
|
||||
|
||||
static void watch_model_custom_callback(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
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;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||
ByteInput* byte_input = ctx->byte_input;
|
||||
|
||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||
@@ -492,7 +570,5 @@ bool scene_easysetup_watch_model_custom_on_event(void* _ctx, SceneManagerEvent e
|
||||
return false;
|
||||
}
|
||||
void scene_easysetup_watch_model_custom_on_exit(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
||||
cfg->data.watch.model = (ctx->byte_store[0] << 0x00);
|
||||
UNUSED(_ctx);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// Research by @Spooks4576
|
||||
|
||||
typedef enum {
|
||||
EasysetupTypeBuds,
|
||||
EasysetupTypeBuds = 0x01, // Skip 0 as it means unset
|
||||
EasysetupTypeWatch,
|
||||
EasysetupTypeCOUNT,
|
||||
} EasysetupType;
|
||||
|
||||
127
applications/external/ble_spam/protocols/fastpair.c
vendored
127
applications/external/ble_spam/protocols/fastpair.c
vendored
@@ -8,17 +8,43 @@ const struct {
|
||||
uint32_t value;
|
||||
const char* name;
|
||||
} models[] = {
|
||||
// Genuine actions
|
||||
{0x00000C, "Set Up Device"},
|
||||
|
||||
// Genuine non-production/forgotten (good job Google)
|
||||
{0x0001F0, "Bisto CSR8670 Dev Board"},
|
||||
{0x000047, "Arduino 101"},
|
||||
{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"},
|
||||
{0x000048, "Fast Pair Headphones"},
|
||||
{0x000049, "Fast Pair Headphones 2"},
|
||||
|
||||
// Genuine devices
|
||||
{0xCD8256, "Bose NC 700"},
|
||||
{0x0000F0, "Bose QuietComfort 35 II"},
|
||||
{0x821F66, "JBL Flip 6"},
|
||||
{0xF52494, "JBL Buds Pro"},
|
||||
{0x718FA4, "JBL Live 300TWS"},
|
||||
{0x821F66, "JBL Flip 6"},
|
||||
{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"},
|
||||
|
||||
// Custom debug popups
|
||||
{0xD99CA1, "Flipper Zero"},
|
||||
@@ -39,19 +65,26 @@ const struct {
|
||||
};
|
||||
const uint8_t models_count = COUNT_OF(models);
|
||||
|
||||
static const char* fastpair_get_name(const ProtocolCfg* _cfg) {
|
||||
static const char* get_name(const ProtocolCfg* _cfg) {
|
||||
UNUSED(_cfg);
|
||||
return "FastPair";
|
||||
}
|
||||
|
||||
static void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) {
|
||||
const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL;
|
||||
static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) {
|
||||
FastpairCfg* cfg = _cfg ? &_cfg->specific.fastpair : NULL;
|
||||
|
||||
uint32_t model;
|
||||
if(cfg && cfg->model != 0x000000) {
|
||||
model = cfg->model;
|
||||
} else {
|
||||
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model = models[rand() % models_count].value;
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
model = cfg->model;
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
model = cfg->model = _cfg->bruteforce.value;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t size = 14;
|
||||
@@ -100,30 +133,36 @@ static void config_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
}
|
||||
static void model_changed(VariableItem* item) {
|
||||
FastpairCfg* cfg = variable_item_get_context(item);
|
||||
ProtocolCfg* _cfg = variable_item_get_context(item);
|
||||
FastpairCfg* cfg = &_cfg->specific.fastpair;
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
if(index) {
|
||||
index--;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->model = models[index].value;
|
||||
variable_item_set_current_value_text(item, models[index].name);
|
||||
} else {
|
||||
cfg->model = 0x000000;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
variable_item_set_current_value_text(item, "Random");
|
||||
}
|
||||
}
|
||||
static void fastpair_extra_config(Ctx* ctx) {
|
||||
FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
|
||||
static void extra_config(Ctx* ctx) {
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
FastpairCfg* cfg = &_cfg->specific.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, cfg);
|
||||
item = variable_item_list_add(list, "Model Code", models_count + 1, model_changed, _cfg);
|
||||
const char* model_name = NULL;
|
||||
char model_name_buf[9];
|
||||
if(cfg->model == 0x000000) {
|
||||
switch(_cfg->mode) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
model_name = "Random";
|
||||
value_index = 0;
|
||||
} else {
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
for(uint8_t i = 0; i < models_count; i++) {
|
||||
if(cfg->model == models[i].value) {
|
||||
model_name = models[i].name;
|
||||
@@ -136,6 +175,11 @@ static void fastpair_extra_config(Ctx* ctx) {
|
||||
model_name = model_name_buf;
|
||||
value_index = models_count + 1;
|
||||
}
|
||||
break;
|
||||
case ProtocolModeBruteforce:
|
||||
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);
|
||||
@@ -145,31 +189,40 @@ static void fastpair_extra_config(Ctx* ctx) {
|
||||
variable_item_list_set_enter_callback(list, config_callback, ctx);
|
||||
}
|
||||
|
||||
static uint8_t fastpair_config_count(const ProtocolCfg* _cfg) {
|
||||
static uint8_t config_count(const ProtocolCfg* _cfg) {
|
||||
UNUSED(_cfg);
|
||||
return ConfigCOUNT - ConfigExtraStart - 1;
|
||||
}
|
||||
|
||||
const Protocol protocol_fastpair = {
|
||||
.icon = &I_android,
|
||||
.get_name = fastpair_get_name,
|
||||
.make_packet = fastpair_make_packet,
|
||||
.extra_config = fastpair_extra_config,
|
||||
.config_count = fastpair_config_count,
|
||||
.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;
|
||||
FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
FastpairCfg* cfg = &_cfg->specific.fastpair;
|
||||
switch(index) {
|
||||
case 0:
|
||||
cfg->model = 0x000000;
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
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:
|
||||
_cfg->mode = ProtocolModeBruteforce;
|
||||
_cfg->bruteforce.counter = 0;
|
||||
_cfg->bruteforce.value = cfg->model;
|
||||
_cfg->bruteforce.size = 3;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
default:
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
cfg->model = models[index - 1].value;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
break;
|
||||
@@ -177,30 +230,35 @@ static void model_callback(void* _ctx, uint32_t index) {
|
||||
}
|
||||
void scene_fastpair_model_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
FastpairCfg* cfg = &_cfg->specific.fastpair;
|
||||
Submenu* submenu = ctx->submenu;
|
||||
uint32_t selected = 0;
|
||||
bool found = false;
|
||||
submenu_reset(submenu);
|
||||
|
||||
submenu_add_item(submenu, "Random", 0, model_callback, ctx);
|
||||
if(cfg->model == 0x000000) {
|
||||
found = true;
|
||||
if(_cfg->mode == ProtocolModeRandom) {
|
||||
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 && cfg->model == models[i].value) {
|
||||
if(!found && _cfg->mode == ProtocolModeValue && cfg->model == models[i].value) {
|
||||
found = true;
|
||||
selected = i + 1;
|
||||
}
|
||||
}
|
||||
submenu_add_item(submenu, "Custom", models_count + 1, model_callback, ctx);
|
||||
if(!found) {
|
||||
found = true;
|
||||
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||
selected = models_count + 1;
|
||||
}
|
||||
|
||||
submenu_add_item(submenu, "Bruteforce", models_count + 2, model_callback, ctx);
|
||||
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||
selected = models_count + 2;
|
||||
}
|
||||
|
||||
submenu_set_selected_item(submenu, selected);
|
||||
|
||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||
@@ -216,12 +274,18 @@ void scene_fastpair_model_on_exit(void* _ctx) {
|
||||
|
||||
static void model_custom_callback(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
FastpairCfg* cfg = &_cfg->specific.fastpair;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
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;
|
||||
FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
FastpairCfg* cfg = &_cfg->specific.fastpair;
|
||||
ByteInput* byte_input = ctx->byte_input;
|
||||
|
||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||
@@ -241,8 +305,5 @@ bool scene_fastpair_model_custom_on_event(void* _ctx, SceneManagerEvent event) {
|
||||
return false;
|
||||
}
|
||||
void scene_fastpair_model_custom_on_exit(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
|
||||
cfg->model =
|
||||
(ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00);
|
||||
UNUSED(_ctx);
|
||||
}
|
||||
|
||||
@@ -4,27 +4,33 @@
|
||||
// Hacked together by @Willy-JL and @Spooks4576
|
||||
// Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair
|
||||
|
||||
static const char* swiftpair_get_name(const ProtocolCfg* _cfg) {
|
||||
const char* names[] = {
|
||||
"Assquach💦",
|
||||
"Flipper 🐬",
|
||||
"iOS 17 🍎",
|
||||
"Kink💦",
|
||||
"👉👌",
|
||||
"🔵🦷",
|
||||
};
|
||||
const uint8_t names_count = COUNT_OF(names);
|
||||
|
||||
static const char* get_name(const ProtocolCfg* _cfg) {
|
||||
UNUSED(_cfg);
|
||||
return "SwiftPair";
|
||||
}
|
||||
|
||||
static void swiftpair_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) {
|
||||
const SwiftpairCfg* cfg = _cfg ? &_cfg->swiftpair : NULL;
|
||||
static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) {
|
||||
SwiftpairCfg* cfg = _cfg ? &_cfg->specific.swiftpair : NULL;
|
||||
|
||||
const char* name;
|
||||
if(cfg && cfg->name[0] != '\0') {
|
||||
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||
case ProtocolModeRandom:
|
||||
default:
|
||||
name = names[rand() % names_count];
|
||||
break;
|
||||
case ProtocolModeValue:
|
||||
name = cfg->name;
|
||||
} else {
|
||||
const char* names[] = {
|
||||
"Assquach💦",
|
||||
"Flipper 🐬",
|
||||
"iOS 17 🍎",
|
||||
"Kink💦",
|
||||
"👉👌",
|
||||
"🔵🦷",
|
||||
};
|
||||
name = names[rand() % COUNT_OF(names)];
|
||||
break;
|
||||
}
|
||||
uint8_t name_len = strlen(name);
|
||||
|
||||
@@ -66,43 +72,48 @@ static void config_callback(void* _ctx, uint32_t index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void swiftpair_extra_config(Ctx* ctx) {
|
||||
SwiftpairCfg* cfg = &ctx->attack->payload.cfg.swiftpair;
|
||||
static void extra_config(Ctx* ctx) {
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
SwiftpairCfg* cfg = &_cfg->specific.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, cfg->name[0] != '\0' ? cfg->name : "Random");
|
||||
variable_item_set_current_value_text(
|
||||
item, _cfg->mode == ProtocolModeRandom ? "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 swiftpair_config_count(const ProtocolCfg* _cfg) {
|
||||
static uint8_t config_count(const ProtocolCfg* _cfg) {
|
||||
UNUSED(_cfg);
|
||||
return ConfigCOUNT - ConfigExtraStart - 1;
|
||||
}
|
||||
|
||||
const Protocol protocol_swiftpair = {
|
||||
.icon = &I_windows,
|
||||
.get_name = swiftpair_get_name,
|
||||
.make_packet = swiftpair_make_packet,
|
||||
.extra_config = swiftpair_extra_config,
|
||||
.config_count = swiftpair_config_count,
|
||||
.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;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
_cfg->mode = ProtocolModeValue;
|
||||
scene_manager_previous_scene(ctx->scene_manager);
|
||||
}
|
||||
void scene_swiftpair_name_on_enter(void* _ctx) {
|
||||
Ctx* ctx = _ctx;
|
||||
SwiftpairCfg* cfg = &ctx->attack->payload.cfg.swiftpair;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
SwiftpairCfg* cfg = &_cfg->specific.swiftpair;
|
||||
TextInput* text_input = ctx->text_input;
|
||||
text_input_reset(text_input);
|
||||
|
||||
text_input_set_header_text(text_input, "Leave empty for random");
|
||||
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);
|
||||
@@ -112,8 +123,11 @@ void scene_swiftpair_name_on_enter(void* _ctx) {
|
||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewTextInput);
|
||||
}
|
||||
bool scene_swiftpair_name_on_event(void* _ctx, SceneManagerEvent event) {
|
||||
UNUSED(_ctx);
|
||||
UNUSED(event);
|
||||
Ctx* ctx = _ctx;
|
||||
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
_cfg->mode = ProtocolModeRandom;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void scene_swiftpair_name_on_exit(void* _ctx) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
11
fbt
11
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 "$@"
|
||||
|
||||
12
fbt.cmd
12
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
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -270,6 +270,11 @@ vars.AddVariables(
|
||||
"clangd",
|
||||
],
|
||||
),
|
||||
BoolVariable(
|
||||
"STRICT_FAP_IMPORT_CHECK",
|
||||
help="Enable strict import check for .faps",
|
||||
default=True,
|
||||
),
|
||||
)
|
||||
|
||||
Return("vars")
|
||||
|
||||
Reference in New Issue
Block a user