BLE Spam refactor namespace and use viewdispatcher

This commit is contained in:
Willy-JL
2023-10-18 05:13:43 +01:00
parent 9abe7cf3d2
commit dfc2309a3a
10 changed files with 99 additions and 79 deletions

View File

@@ -1,6 +1,7 @@
#include <gui/gui.h> #include <gui/gui.h>
#include <furi_hal_bt.h> #include <furi_hal_bt.h>
#include <gui/elements.h> #include <gui/elements.h>
#include <gui/view_dispatcher.h>
#include "protocols/_registry.h" #include "protocols/_registry.h"
@@ -14,8 +15,8 @@
typedef struct { typedef struct {
const char* title; const char* title;
const char* text; const char* text;
const BleSpamProtocol* protocol; const Protocol* protocol;
BleSpamPayload payload; Payload payload;
} Attack; } Attack;
static Attack attacks[] = { static Attack attacks[] = {
@@ -32,7 +33,7 @@ static Attack attacks[] = {
{ {
.title = "iOS 17 Lockup Crash", .title = "iOS 17 Lockup Crash",
.text = "Newer iPhones, long range", .text = "Newer iPhones, long range",
.protocol = &ble_spam_protocol_continuity, .protocol = &protocol_continuity,
.payload = .payload =
{ {
.random_mac = false, .random_mac = false,
@@ -49,7 +50,7 @@ static Attack attacks[] = {
{ {
.title = "Apple Action Modal", .title = "Apple Action Modal",
.text = "Lock cooldown, long range", .text = "Lock cooldown, long range",
.protocol = &ble_spam_protocol_continuity, .protocol = &protocol_continuity,
.payload = .payload =
{ {
.random_mac = false, .random_mac = false,
@@ -66,7 +67,7 @@ static Attack attacks[] = {
{ {
.title = "Apple Device Popup", .title = "Apple Device Popup",
.text = "No cooldown, close range", .text = "No cooldown, close range",
.protocol = &ble_spam_protocol_continuity, .protocol = &protocol_continuity,
.payload = .payload =
{ {
.random_mac = false, .random_mac = false,
@@ -83,7 +84,7 @@ static Attack attacks[] = {
{ {
.title = "Android Device Pair", .title = "Android Device Pair",
.text = "Reboot cooldown, long range", .text = "Reboot cooldown, long range",
.protocol = &ble_spam_protocol_fastpair, .protocol = &protocol_fastpair,
.payload = .payload =
{ {
.random_mac = true, .random_mac = true,
@@ -96,7 +97,7 @@ static Attack attacks[] = {
{ {
.title = "Windows Device Found", .title = "Windows Device Found",
.text = "Requires enabling SwiftPair", .text = "Requires enabling SwiftPair",
.protocol = &ble_spam_protocol_swiftpair, .protocol = &protocol_swiftpair,
.payload = .payload =
{ {
.random_mac = true, .random_mac = true,
@@ -108,7 +109,7 @@ static Attack attacks[] = {
}, },
}; };
#define ATTACK_COUNT ((signed)COUNT_OF(attacks)) #define ATTACKS_COUNT ((signed)COUNT_OF(attacks))
uint16_t delays[] = {20, 50, 100, 200}; uint16_t delays[] = {20, 50, 100, 200};
@@ -126,16 +127,15 @@ static int32_t adv_thread(void* ctx) {
uint16_t delay; uint16_t delay;
uint8_t* packet; uint8_t* packet;
uint8_t mac[GAP_MAC_ADDR_SIZE]; uint8_t mac[GAP_MAC_ADDR_SIZE];
BleSpamPayload* payload = &attacks[state->index].payload; Payload* payload = &attacks[state->index].payload;
const BleSpamProtocol* protocol = attacks[state->index].protocol; const Protocol* protocol = attacks[state->index].protocol;
if(!payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac)); if(!payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac));
while(state->advertising) { while(state->advertising) {
if(protocol) { if(protocol) {
protocol->make_packet(&size, &packet, &payload->cfg); protocol->make_packet(&size, &packet, &payload->cfg);
} else { } else {
ble_spam_protocols[rand() % ble_spam_protocols_count]->make_packet( protocols[rand() % protocols_count]->make_packet(&size, &packet, NULL);
&size, &packet, NULL);
} }
furi_hal_bt_custom_adv_set(packet, size); furi_hal_bt_custom_adv_set(packet, size);
free(packet); free(packet);
@@ -164,19 +164,23 @@ static void toggle_adv(State* state) {
} }
} }
enum {
ViewMain,
};
#define PAGE_MIN (-3) #define PAGE_MIN (-3)
#define PAGE_MAX ATTACK_COUNT #define PAGE_MAX ATTACKS_COUNT
enum { enum {
PageHelpApps = PAGE_MIN, PageHelpApps = PAGE_MIN,
PageHelpDelay, PageHelpDelay,
PageHelpDistance, PageHelpDistance,
PageStart = 0, PageStart = 0,
PageEnd = ATTACK_COUNT - 1, PageEnd = ATTACKS_COUNT - 1,
PageAboutCredits = PAGE_MAX, PageAboutCredits = PAGE_MAX,
}; };
static void draw_callback(Canvas* canvas, void* ctx) { static void draw_callback(Canvas* canvas, void* ctx) {
State* state = ctx; State* state = *(State**)ctx;
const char* back = "Back"; const char* back = "Back";
const char* next = "Next"; const char* next = "Next";
switch(state->index) { switch(state->index) {
@@ -195,9 +199,9 @@ static void draw_callback(Canvas* canvas, void* ctx) {
} }
const Attack* attack = const Attack* attack =
(state->index >= 0 && state->index <= ATTACK_COUNT - 1) ? &attacks[state->index] : NULL; (state->index >= 0 && state->index <= ATTACKS_COUNT - 1) ? &attacks[state->index] : NULL;
const BleSpamPayload* payload = attack ? &attack->payload : NULL; const Payload* payload = attack ? &attack->payload : NULL;
const BleSpamProtocol* protocol = attack ? attack->protocol : NULL; const Protocol* protocol = attack ? attack->protocol : NULL;
canvas_set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas_draw_icon(canvas, 4, 3, protocol ? protocol->icon : &I_ble); canvas_draw_icon(canvas, 4, 3, protocol ? protocol->icon : &I_ble);
@@ -285,7 +289,7 @@ static void draw_callback(Canvas* canvas, void* ctx) {
sizeof(str), sizeof(str),
"%02i/%02i: %s", "%02i/%02i: %s",
state->index + 1, state->index + 1,
ATTACK_COUNT, ATTACKS_COUNT,
protocol ? protocol->get_name(&payload->cfg) : "Everything"); protocol ? protocol->get_name(&payload->cfg) : "Everything");
canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 21, str); canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 21, str);
@@ -308,37 +312,19 @@ static void draw_callback(Canvas* canvas, void* ctx) {
} }
} }
static void input_callback(InputEvent* input, void* ctx) { static bool input_callback(InputEvent* input, void* ctx) {
FuriMessageQueue* input_queue = ctx; View* view = ctx;
State* state = *(State**)view_get_model(view);
bool consumed = false;
if(input->type == InputTypeShort || input->type == InputTypeLong || if(input->type == InputTypeShort || input->type == InputTypeLong ||
input->type == InputTypeRepeat) { input->type == InputTypeRepeat) {
furi_message_queue_put(input_queue, input, 0); consumed = true;
}
}
int32_t ble_spam(void* p) { bool is_attack = state->index >= 0 && state->index <= ATTACKS_COUNT - 1;
UNUSED(p);
State* state = malloc(sizeof(State));
state->thread = furi_thread_alloc();
furi_thread_set_callback(state->thread, adv_thread);
furi_thread_set_context(state->thread, state);
furi_thread_set_stack_size(state->thread, 4096);
FuriMessageQueue* input_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
ViewPort* view_port = view_port_alloc();
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);
bool running = true;
while(running) {
InputEvent input;
furi_check(furi_message_queue_get(input_queue, &input, FuriWaitForever) == FuriStatusOk);
bool is_attack = state->index >= 0 && state->index <= ATTACK_COUNT - 1;
bool advertising = state->advertising; bool advertising = state->advertising;
switch(input.key) {
switch(input->key) {
case InputKeyOk: case InputKeyOk:
if(is_attack) toggle_adv(state); if(is_attack) toggle_adv(state);
break; break;
@@ -366,19 +352,53 @@ int32_t ble_spam(void* p) {
break; break;
case InputKeyBack: case InputKeyBack:
if(advertising) toggle_adv(state); if(advertising) toggle_adv(state);
running = false; consumed = false;
break; break;
default: default:
continue; break;
}
} }
view_port_update(view_port); view_commit_model(view, consumed);
return consumed;
} }
gui_remove_view_port(gui, view_port); static uint32_t exit_callback(void* ctx) {
UNUSED(ctx);
return VIEW_NONE;
}
int32_t ble_spam(void* p) {
UNUSED(p);
State* state = malloc(sizeof(State));
state->thread = furi_thread_alloc();
furi_thread_set_callback(state->thread, adv_thread);
furi_thread_set_context(state->thread, state);
furi_thread_set_stack_size(state->thread, 4096);
Gui* gui = furi_record_open(RECORD_GUI);
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(view_dispatcher);
view_dispatcher_set_event_callback_context(view_dispatcher, state);
View* view = view_alloc();
view_allocate_model(view, ViewModelTypeLockFree, sizeof(State*));
with_view_model(
view, State * *model, { *model = state; }, false);
view_set_context(view, view);
view_set_draw_callback(view, draw_callback);
view_set_input_callback(view, input_callback);
view_set_previous_callback(view, exit_callback);
view_dispatcher_add_view(view_dispatcher, ViewMain, view);
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
view_dispatcher_switch_to_view(view_dispatcher, ViewMain);
view_dispatcher_run(view_dispatcher);
view_dispatcher_remove_view(view_dispatcher, ViewMain);
view_free(view);
view_dispatcher_free(view_dispatcher);
furi_record_close(RECORD_GUI); furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(input_queue);
furi_thread_free(state->thread); furi_thread_free(state->thread);
free(state); free(state);

View File

@@ -9,10 +9,10 @@
#include <furi_hal_random.h> #include <furi_hal_random.h>
#include <core/core_defines.h> #include <core/core_defines.h>
typedef union BleSpamProtocolCfg BleSpamProtocolCfg; typedef union ProtocolCfg ProtocolCfg;
typedef struct { typedef struct {
const Icon* icon; const Icon* icon;
const char* (*get_name)(const BleSpamProtocolCfg* _cfg); const char* (*get_name)(const ProtocolCfg* _cfg);
void (*make_packet)(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg); void (*make_packet)(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg);
} BleSpamProtocol; } Protocol;

View File

@@ -1,9 +1,9 @@
#include "_registry.h" #include "_registry.h"
const BleSpamProtocol* ble_spam_protocols[] = { const Protocol* protocols[] = {
&ble_spam_protocol_continuity, &protocol_continuity,
&ble_spam_protocol_fastpair, &protocol_fastpair,
&ble_spam_protocol_swiftpair, &protocol_swiftpair,
}; };
const size_t ble_spam_protocols_count = COUNT_OF(ble_spam_protocols); const size_t protocols_count = COUNT_OF(protocols);

View File

@@ -4,17 +4,17 @@
#include "fastpair.h" #include "fastpair.h"
#include "swiftpair.h" #include "swiftpair.h"
union BleSpamProtocolCfg { union ProtocolCfg {
ContinuityCfg continuity; ContinuityCfg continuity;
FastpairCfg fastpair; FastpairCfg fastpair;
SwiftpairCfg swiftpair; SwiftpairCfg swiftpair;
}; };
extern const BleSpamProtocol* ble_spam_protocols[]; extern const Protocol* protocols[];
extern const size_t ble_spam_protocols_count; extern const size_t protocols_count;
typedef struct { typedef struct {
bool random_mac; bool random_mac;
BleSpamProtocolCfg cfg; ProtocolCfg cfg;
} BleSpamPayload; } Payload;

View File

@@ -16,7 +16,7 @@ static const char* type_names[ContinuityTypeCount] = {
[ContinuityTypeNearbyInfo] = "Nearby Info", [ContinuityTypeNearbyInfo] = "Nearby Info",
[ContinuityTypeCustomCrash] = "Custom Packet", [ContinuityTypeCustomCrash] = "Custom Packet",
}; };
const char* continuity_get_name(const BleSpamProtocolCfg* _cfg) { const char* continuity_get_name(const ProtocolCfg* _cfg) {
const ContinuityCfg* cfg = &_cfg->continuity; const ContinuityCfg* cfg = &_cfg->continuity;
return type_names[cfg->type]; return type_names[cfg->type];
} }
@@ -33,7 +33,7 @@ static uint8_t packet_sizes[ContinuityTypeCount] = {
[ContinuityTypeCustomCrash] = HEADER_LEN + 11, [ContinuityTypeCustomCrash] = HEADER_LEN + 11,
}; };
void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg) { void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) {
const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL; const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL;
ContinuityType type; ContinuityType type;
@@ -269,7 +269,7 @@ void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProt
*_packet = packet; *_packet = packet;
} }
const BleSpamProtocol ble_spam_protocol_continuity = { const Protocol protocol_continuity = {
.icon = &I_apple, .icon = &I_apple,
.get_name = continuity_get_name, .get_name = continuity_get_name,
.make_packet = continuity_make_packet, .make_packet = continuity_make_packet,

View File

@@ -33,4 +33,4 @@ typedef struct {
} data; } data;
} ContinuityCfg; } ContinuityCfg;
extern const BleSpamProtocol ble_spam_protocol_continuity; extern const Protocol protocol_continuity;

View File

@@ -4,13 +4,13 @@
// Hacked together by @Willy-JL and @Spooks4576 // Hacked together by @Willy-JL and @Spooks4576
// Documentation at https://developers.google.com/nearby/fast-pair/specifications/introduction // Documentation at https://developers.google.com/nearby/fast-pair/specifications/introduction
const char* fastpair_get_name(const BleSpamProtocolCfg* _cfg) { const char* fastpair_get_name(const ProtocolCfg* _cfg) {
const FastpairCfg* cfg = &_cfg->fastpair; const FastpairCfg* cfg = &_cfg->fastpair;
UNUSED(cfg); UNUSED(cfg);
return "FastPair"; return "FastPair";
} }
void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg) { void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) {
const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL; const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL;
uint32_t model_id; uint32_t model_id;
@@ -67,7 +67,7 @@ void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtoc
*_packet = packet; *_packet = packet;
} }
const BleSpamProtocol ble_spam_protocol_fastpair = { const Protocol protocol_fastpair = {
.icon = &I_android, .icon = &I_android,
.get_name = fastpair_get_name, .get_name = fastpair_get_name,
.make_packet = fastpair_make_packet, .make_packet = fastpair_make_packet,

View File

@@ -8,4 +8,4 @@ typedef struct {
uint32_t model_id; uint32_t model_id;
} FastpairCfg; } FastpairCfg;
extern const BleSpamProtocol ble_spam_protocol_fastpair; extern const Protocol protocol_fastpair;

View File

@@ -4,13 +4,13 @@
// Hacked together by @Willy-JL and @Spooks4576 // Hacked together by @Willy-JL and @Spooks4576
// Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair // 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 char* swiftpair_get_name(const ProtocolCfg* _cfg) {
const SwiftpairCfg* cfg = &_cfg->swiftpair; const SwiftpairCfg* cfg = &_cfg->swiftpair;
UNUSED(cfg); UNUSED(cfg);
return "SwiftPair"; return "SwiftPair";
} }
void swiftpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProtocolCfg* _cfg) { void swiftpair_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) {
const SwiftpairCfg* cfg = _cfg ? &_cfg->swiftpair : NULL; const SwiftpairCfg* cfg = _cfg ? &_cfg->swiftpair : NULL;
const char* display_name; const char* display_name;
@@ -47,7 +47,7 @@ void swiftpair_make_packet(uint8_t* _size, uint8_t** _packet, const BleSpamProto
*_packet = packet; *_packet = packet;
} }
const BleSpamProtocol ble_spam_protocol_swiftpair = { const Protocol protocol_swiftpair = {
.icon = &I_windows, .icon = &I_windows,
.get_name = swiftpair_get_name, .get_name = swiftpair_get_name,
.make_packet = swiftpair_make_packet, .make_packet = swiftpair_make_packet,

View File

@@ -8,4 +8,4 @@ typedef struct {
char display_name[25]; char display_name[25];
} SwiftpairCfg; } SwiftpairCfg;
extern const BleSpamProtocol ble_spam_protocol_swiftpair; extern const Protocol protocol_swiftpair;