mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 13:28:36 -07:00
BLE Spam refactor namespace and use viewdispatcher
This commit is contained in:
124
applications/external/ble_spam/ble_spam.c
vendored
124
applications/external/ble_spam/ble_spam.c
vendored
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -33,4 +33,4 @@ typedef struct {
|
|||||||
} data;
|
} data;
|
||||||
} ContinuityCfg;
|
} ContinuityCfg;
|
||||||
|
|
||||||
extern const BleSpamProtocol ble_spam_protocol_continuity;
|
extern const Protocol protocol_continuity;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user