Skip to content

Commit

Permalink
[FL-3914] BackUSB (#3951)
Browse files Browse the repository at this point in the history
* Revert "[FL-3896] Split BadUSB into BadUSB and BadBLE (#3931)"
  This reverts commit 0eaad8b.
* Better USB-BLE switch UX
* Format sources
* Format images

Co-authored-by: あく <[email protected]>
  • Loading branch information
Astrrra and skotopes authored Oct 15, 2024
1 parent a6cf085 commit a34e090
Show file tree
Hide file tree
Showing 40 changed files with 349 additions and 2,415 deletions.
2 changes: 1 addition & 1 deletion applications/main/bad_usb/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ App(
icon="A_BadUsb_14",
order=70,
resources="resources",
fap_libs=["assets"],
fap_libs=["assets", "ble_profile"],
fap_icon="icon.png",
fap_category="USB",
)
25 changes: 23 additions & 2 deletions applications/main/bad_usb/bad_usb_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static void bad_usb_load_settings(BadUsbApp* app) {

FuriString* temp_str = furi_string_alloc();
uint32_t version = 0;
uint32_t interface = 0;

if(flipper_format_file_open_existing(fff, BAD_USB_SETTINGS_PATH)) {
do {
Expand All @@ -44,6 +45,8 @@ static void bad_usb_load_settings(BadUsbApp* app) {
break;

if(!flipper_format_read_string(fff, "layout", temp_str)) break;
if(!flipper_format_read_uint32(fff, "interface", &interface, 1)) break;
if(interface > BadUsbHidInterfaceBle) break;

state = true;
} while(0);
Expand All @@ -53,6 +56,7 @@ static void bad_usb_load_settings(BadUsbApp* app) {

if(state) {
furi_string_set(app->keyboard_layout, temp_str);
app->interface = interface;

Storage* fs_api = furi_record_open(RECORD_STORAGE);
FileInfo layout_file_info;
Expand All @@ -64,6 +68,7 @@ static void bad_usb_load_settings(BadUsbApp* app) {
}
} else {
furi_string_set(app->keyboard_layout, BAD_USB_SETTINGS_DEFAULT_LAYOUT);
app->interface = BadUsbHidInterfaceUsb;
}

furi_string_free(temp_str);
Expand All @@ -79,13 +84,21 @@ static void bad_usb_save_settings(BadUsbApp* app) {
fff, BAD_USB_SETTINGS_FILE_TYPE, BAD_USB_SETTINGS_VERSION))
break;
if(!flipper_format_write_string(fff, "layout", app->keyboard_layout)) break;
uint32_t interface_id = app->interface;
if(!flipper_format_write_uint32(fff, "interface", (const uint32_t*)&interface_id, 1))
break;
} while(0);
}

flipper_format_free(fff);
furi_record_close(RECORD_STORAGE);
}

void bad_usb_set_interface(BadUsbApp* app, BadUsbHidInterface interface) {
app->interface = interface;
bad_usb_view_set_interface(app->bad_usb_view, interface);
}

BadUsbApp* bad_usb_app_alloc(char* arg) {
BadUsbApp* app = malloc(sizeof(BadUsbApp));

Expand Down Expand Up @@ -117,7 +130,11 @@ BadUsbApp* bad_usb_app_alloc(char* arg) {
// Custom Widget
app->widget = widget_alloc();
view_dispatcher_add_view(
app->view_dispatcher, BadUsbAppViewError, widget_get_view(app->widget));
app->view_dispatcher, BadUsbAppViewWidget, widget_get_view(app->widget));

// Popup
app->popup = popup_alloc();
view_dispatcher_add_view(app->view_dispatcher, BadUsbAppViewPopup, popup_get_view(app->popup));

app->var_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
Expand Down Expand Up @@ -163,9 +180,13 @@ void bad_usb_app_free(BadUsbApp* app) {
bad_usb_view_free(app->bad_usb_view);

// Custom Widget
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewError);
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewWidget);
widget_free(app->widget);

// Popup
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewPopup);
popup_free(app->popup);

// Config menu
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewConfig);
variable_item_list_free(app->var_item_list);
Expand Down
8 changes: 7 additions & 1 deletion applications/main/bad_usb/bad_usb_app_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <notification/notification_messages.h>
#include <gui/modules/variable_item_list.h>
#include <gui/modules/widget.h>
#include <gui/modules/popup.h>
#include "views/bad_usb_view.h"
#include <furi_hal_usb.h>

Expand All @@ -33,6 +34,7 @@ struct BadUsbApp {
NotificationApp* notifications;
DialogsApp* dialogs;
Widget* widget;
Popup* popup;
VariableItemList* var_item_list;

BadUsbAppError error;
Expand All @@ -41,11 +43,15 @@ struct BadUsbApp {
BadUsb* bad_usb_view;
BadUsbScript* bad_usb_script;

BadUsbHidInterface interface;
FuriHalUsbInterface* usb_if_prev;
};

typedef enum {
BadUsbAppViewError,
BadUsbAppViewWidget,
BadUsbAppViewPopup,
BadUsbAppViewWork,
BadUsbAppViewConfig,
} BadUsbAppView;

void bad_usb_set_interface(BadUsbApp* app, BadUsbHidInterface interface);
156 changes: 154 additions & 2 deletions applications/main/bad_usb/helpers/bad_usb_hid.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "bad_usb_hid.h"
#include <extra_profiles/hid_profile.h>
#include <bt/bt_service/bt.h>
#include <storage/storage.h>

#define TAG "BadUSB HID"

#define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys"

void* hid_usb_init(FuriHalUsbHidConfig* hid_cfg) {
furi_check(furi_hal_usb_set_config(&usb_hid, hid_cfg));
return NULL;
Expand Down Expand Up @@ -69,6 +72,155 @@ static const BadUsbHidApi hid_api_usb = {
.release_all = hid_usb_release_all,
.get_led_state = hid_usb_get_led_state,
};
const BadUsbHidApi* bad_usb_hid_get_interface() {
return &hid_api_usb;

typedef struct {
Bt* bt;
FuriHalBleProfileBase* profile;
HidStateCallback state_callback;
void* callback_context;
bool is_connected;
} BleHidInstance;

static const BleProfileHidParams ble_hid_params = {
.device_name_prefix = "BadUSB",
.mac_xor = 0x0002,
};

static void hid_ble_connection_status_callback(BtStatus status, void* context) {
furi_assert(context);
BleHidInstance* ble_hid = context;
ble_hid->is_connected = (status == BtStatusConnected);
if(ble_hid->state_callback) {
ble_hid->state_callback(ble_hid->is_connected, ble_hid->callback_context);
}
}

void* hid_ble_init(FuriHalUsbHidConfig* hid_cfg) {
UNUSED(hid_cfg);
BleHidInstance* ble_hid = malloc(sizeof(BleHidInstance));
ble_hid->bt = furi_record_open(RECORD_BT);
bt_disconnect(ble_hid->bt);

// Wait 2nd core to update nvm storage
furi_delay_ms(200);

bt_keys_storage_set_storage_path(ble_hid->bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME));

ble_hid->profile = bt_profile_start(ble_hid->bt, ble_profile_hid, (void*)&ble_hid_params);
furi_check(ble_hid->profile);

furi_hal_bt_start_advertising();

bt_set_status_changed_callback(ble_hid->bt, hid_ble_connection_status_callback, ble_hid);

return ble_hid;
}

void hid_ble_deinit(void* inst) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);

bt_set_status_changed_callback(ble_hid->bt, NULL, NULL);
bt_disconnect(ble_hid->bt);

// Wait 2nd core to update nvm storage
furi_delay_ms(200);
bt_keys_storage_set_default_path(ble_hid->bt);

furi_check(bt_profile_restore_default(ble_hid->bt));
furi_record_close(RECORD_BT);
free(ble_hid);
}

void hid_ble_set_state_callback(void* inst, HidStateCallback cb, void* context) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);
ble_hid->state_callback = cb;
ble_hid->callback_context = context;
}

bool hid_ble_is_connected(void* inst) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);
return ble_hid->is_connected;
}

bool hid_ble_kb_press(void* inst, uint16_t button) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);
return ble_profile_hid_kb_press(ble_hid->profile, button);
}

bool hid_ble_kb_release(void* inst, uint16_t button) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);
return ble_profile_hid_kb_release(ble_hid->profile, button);
}

bool hid_ble_consumer_press(void* inst, uint16_t button) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);
return ble_profile_hid_consumer_key_press(ble_hid->profile, button);
}

bool hid_ble_consumer_release(void* inst, uint16_t button) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);
return ble_profile_hid_consumer_key_release(ble_hid->profile, button);
}

bool hid_ble_release_all(void* inst) {
BleHidInstance* ble_hid = inst;
furi_assert(ble_hid);
bool state = ble_profile_hid_kb_release_all(ble_hid->profile);
state &= ble_profile_hid_consumer_key_release_all(ble_hid->profile);
return state;
}

uint8_t hid_ble_get_led_state(void* inst) {
UNUSED(inst);
FURI_LOG_W(TAG, "hid_ble_get_led_state not implemented");
return 0;
}

static const BadUsbHidApi hid_api_ble = {
.init = hid_ble_init,
.deinit = hid_ble_deinit,
.set_state_callback = hid_ble_set_state_callback,
.is_connected = hid_ble_is_connected,

.kb_press = hid_ble_kb_press,
.kb_release = hid_ble_kb_release,
.consumer_press = hid_ble_consumer_press,
.consumer_release = hid_ble_consumer_release,
.release_all = hid_ble_release_all,
.get_led_state = hid_ble_get_led_state,
};

const BadUsbHidApi* bad_usb_hid_get_interface(BadUsbHidInterface interface) {
if(interface == BadUsbHidInterfaceUsb) {
return &hid_api_usb;
} else {
return &hid_api_ble;
}
}

void bad_usb_hid_ble_remove_pairing(void) {
Bt* bt = furi_record_open(RECORD_BT);
bt_disconnect(bt);

// Wait 2nd core to update nvm storage
furi_delay_ms(200);

furi_hal_bt_stop_advertising();

bt_keys_storage_set_storage_path(bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME));
bt_forget_bonded_devices(bt);

// Wait 2nd core to update nvm storage
furi_delay_ms(200);
bt_keys_storage_set_default_path(bt);

furi_check(bt_profile_restore_default(bt));
furi_record_close(RECORD_BT);
}
7 changes: 6 additions & 1 deletion applications/main/bad_usb/helpers/bad_usb_hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ extern "C" {
#include <furi.h>
#include <furi_hal.h>

typedef enum {
BadUsbHidInterfaceUsb,
BadUsbHidInterfaceBle,
} BadUsbHidInterface;

typedef struct {
void* (*init)(FuriHalUsbHidConfig* hid_cfg);
void (*deinit)(void* inst);
Expand All @@ -21,7 +26,7 @@ typedef struct {
uint8_t (*get_led_state)(void* inst);
} BadUsbHidApi;

const BadUsbHidApi* bad_usb_hid_get_interface();
const BadUsbHidApi* bad_usb_hid_get_interface(BadUsbHidInterface interface);

void bad_usb_hid_ble_remove_pairing(void);

Expand Down
4 changes: 2 additions & 2 deletions applications/main/bad_usb/helpers/ducky_script.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ static void bad_usb_script_set_default_keyboard_layout(BadUsbScript* bad_usb) {
memcpy(bad_usb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), sizeof(bad_usb->layout)));
}

BadUsbScript* bad_usb_script_open(FuriString* file_path) {
BadUsbScript* bad_usb_script_open(FuriString* file_path, BadUsbHidInterface interface) {
furi_assert(file_path);

BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript));
Expand All @@ -660,7 +660,7 @@ BadUsbScript* bad_usb_script_open(FuriString* file_path) {

bad_usb->st.state = BadUsbStateInit;
bad_usb->st.error[0] = '\0';
bad_usb->hid = bad_usb_hid_get_interface();
bad_usb->hid = bad_usb_hid_get_interface(interface);

bad_usb->thread = furi_thread_alloc_ex("BadUsbWorker", 2048, bad_usb_worker, bad_usb);
furi_thread_start(bad_usb->thread);
Expand Down
2 changes: 1 addition & 1 deletion applications/main/bad_usb/helpers/ducky_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef struct {

typedef struct BadUsbScript BadUsbScript;

BadUsbScript* bad_usb_script_open(FuriString* file_path);
BadUsbScript* bad_usb_script_open(FuriString* file_path, BadUsbHidInterface interface);

void bad_usb_script_close(BadUsbScript* bad_usb);

Expand Down
Loading

0 comments on commit a34e090

Please sign in to comment.