Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3914] BackUSB #3951

Merged
merged 5 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading