BadUSB ID change (#1046)

* badusb: vid/pid/strings change
* demo script update
* removed vid/pid values

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Nikolay Minaylov 2022-03-23 16:35:25 +03:00 committed by GitHub
parent 6470aa8ff9
commit d075e00ae1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 233 additions and 82 deletions

View File

@ -115,15 +115,10 @@ void bad_usb_app_free(BadUsbApp* app) {
} }
int32_t bad_usb_app(void* p) { int32_t bad_usb_app(void* p) {
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
furi_hal_usb_set_config(&usb_hid);
BadUsbApp* bad_usb_app = bad_usb_app_alloc((char*)p); BadUsbApp* bad_usb_app = bad_usb_app_alloc((char*)p);
view_dispatcher_run(bad_usb_app->view_dispatcher); view_dispatcher_run(bad_usb_app->view_dispatcher);
furi_hal_usb_set_config(usb_mode_prev);
bad_usb_app_free(bad_usb_app); bad_usb_app_free(bad_usb_app);
return 0; return 0;
} }

View File

@ -24,6 +24,7 @@ typedef enum {
} WorkerEvtFlags; } WorkerEvtFlags;
struct BadUsbScript { struct BadUsbScript {
FuriHalUsbHidConfig hid_cfg;
BadUsbState st; BadUsbState st;
string_t file_path; string_t file_path;
uint32_t defdelay; uint32_t defdelay;
@ -101,6 +102,7 @@ static const DuckyKey ducky_keys[] = {
}; };
static const char ducky_cmd_comment[] = {"REM"}; static const char ducky_cmd_comment[] = {"REM"};
static const char ducky_cmd_id[] = {"ID"};
static const char ducky_cmd_delay[] = {"DELAY "}; static const char ducky_cmd_delay[] = {"DELAY "};
static const char ducky_cmd_string[] = {"STRING "}; static const char ducky_cmd_string[] = {"STRING "};
static const char ducky_cmd_defdelay_1[] = {"DEFAULT_DELAY "}; static const char ducky_cmd_defdelay_1[] = {"DEFAULT_DELAY "};
@ -240,12 +242,15 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
if(i == line_len - 1) return SCRIPT_STATE_NEXT_LINE; // Skip empty lines if(i == line_len - 1) return SCRIPT_STATE_NEXT_LINE; // Skip empty lines
} }
FURI_LOG_I(WORKER_TAG, "line:%s", line_tmp); FURI_LOG_D(WORKER_TAG, "line:%s", line_tmp);
// General commands // General commands
if(strncmp(line_tmp, ducky_cmd_comment, strlen(ducky_cmd_comment)) == 0) { if(strncmp(line_tmp, ducky_cmd_comment, strlen(ducky_cmd_comment)) == 0) {
// REM - comment line // REM - comment line
return (0); return (0);
} else if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) {
// ID - executed in ducky_script_preload
return (0);
} else if(strncmp(line_tmp, ducky_cmd_delay, strlen(ducky_cmd_delay)) == 0) { } else if(strncmp(line_tmp, ducky_cmd_delay, strlen(ducky_cmd_delay)) == 0) {
// DELAY // DELAY
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
@ -302,10 +307,37 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
return SCRIPT_STATE_ERROR; return SCRIPT_STATE_ERROR;
} }
static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) {
if(sscanf(line, "%lX:%lX", &bad_usb->hid_cfg.vid, &bad_usb->hid_cfg.pid) == 2) {
bad_usb->hid_cfg.manuf[0] = '\0';
bad_usb->hid_cfg.product[0] = '\0';
uint8_t id_len = ducky_get_command_len(line);
if(!ducky_is_line_end(line[id_len + 1])) {
sscanf(
&line[id_len + 1],
"%31[^\r\n:]:%31[^\r\n]",
bad_usb->hid_cfg.manuf,
bad_usb->hid_cfg.product);
}
FURI_LOG_D(
WORKER_TAG,
"set id: %04X:%04X mfr:%s product:%s",
bad_usb->hid_cfg.vid,
bad_usb->hid_cfg.pid,
bad_usb->hid_cfg.manuf,
bad_usb->hid_cfg.product);
return true;
}
return false;
}
static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
uint8_t ret = 0; uint8_t ret = 0;
uint32_t line_len = 0; uint32_t line_len = 0;
string_reset(bad_usb->line);
do { do {
ret = storage_file_read(script_file, bad_usb->file_buf, FILE_BUFFER_LEN); ret = storage_file_read(script_file, bad_usb->file_buf, FILE_BUFFER_LEN);
for(uint16_t i = 0; i < ret; i++) { for(uint16_t i = 0; i < ret; i++) {
@ -313,6 +345,9 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
bad_usb->st.line_nb++; bad_usb->st.line_nb++;
line_len = 0; line_len = 0;
} else { } else {
if(bad_usb->st.line_nb == 0) { // Save first line
string_push_back(bad_usb->line, bad_usb->file_buf[i]);
}
line_len++; line_len++;
} }
} }
@ -324,7 +359,20 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
} }
} while(ret > 0); } while(ret > 0);
const char* line_tmp = string_get_cstr(bad_usb->line);
bool id_set = false; // Looking for ID command at first line
if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) {
id_set = ducky_set_usb_id(bad_usb, &line_tmp[strlen(ducky_cmd_id) + 1]);
}
if(id_set) {
furi_hal_usb_set_config(&usb_hid, &bad_usb->hid_cfg);
} else {
furi_hal_usb_set_config(&usb_hid, NULL);
}
storage_file_seek(script_file, 0, true); storage_file_seek(script_file, 0, true);
string_reset(bad_usb->line);
return true; return true;
} }
@ -403,6 +451,8 @@ static int32_t bad_usb_worker(void* context) {
BadUsbWorkerState worker_state = BadUsbStateInit; BadUsbWorkerState worker_state = BadUsbStateInit;
int32_t delay_val = 0; int32_t delay_val = 0;
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
FURI_LOG_I(WORKER_TAG, "Init"); FURI_LOG_I(WORKER_TAG, "Init");
File* script_file = storage_file_alloc(furi_record_open("storage")); File* script_file = storage_file_alloc(furi_record_open("storage"));
string_init(bad_usb->line); string_init(bad_usb->line);
@ -522,6 +572,8 @@ static int32_t bad_usb_worker(void* context) {
furi_hal_hid_set_state_callback(NULL, NULL); furi_hal_hid_set_state_callback(NULL, NULL);
furi_hal_usb_set_config(usb_mode_prev, NULL);
storage_file_close(script_file); storage_file_close(script_file);
storage_file_free(script_file); storage_file_free(script_file);
string_clear(bad_usb->line); string_clear(bad_usb->line);

View File

@ -42,7 +42,7 @@ int32_t usb_mouse_app(void* p) {
ViewPort* view_port = view_port_alloc(); ViewPort* view_port = view_port_alloc();
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
furi_hal_usb_set_config(&usb_hid); furi_hal_usb_set_config(&usb_hid, NULL);
view_port_draw_callback_set(view_port, usb_mouse_render_callback, NULL); view_port_draw_callback_set(view_port, usb_mouse_render_callback, NULL);
view_port_input_callback_set(view_port, usb_mouse_input_callback, event_queue); view_port_input_callback_set(view_port, usb_mouse_input_callback, event_queue);
@ -110,7 +110,7 @@ int32_t usb_mouse_app(void* p) {
view_port_update(view_port); view_port_update(view_port);
} }
furi_hal_usb_set_config(usb_mode_prev); furi_hal_usb_set_config(usb_mode_prev, NULL);
// remove & free all stuff created by app // remove & free all stuff created by app
gui_remove_view_port(gui, view_port); gui_remove_view_port(gui, view_port);

View File

@ -10,6 +10,7 @@ typedef struct {
Gui* gui; Gui* gui;
ViewDispatcher* view_dispatcher; ViewDispatcher* view_dispatcher;
Submenu* submenu; Submenu* submenu;
FuriHalUsbHidConfig hid_cfg;
} UsbTestApp; } UsbTestApp;
typedef enum { typedef enum {
@ -19,12 +20,13 @@ typedef enum {
UsbTestSubmenuIndexVcpSingle, UsbTestSubmenuIndexVcpSingle,
UsbTestSubmenuIndexVcpDual, UsbTestSubmenuIndexVcpDual,
UsbTestSubmenuIndexHid, UsbTestSubmenuIndexHid,
UsbTestSubmenuIndexHidWithParams,
UsbTestSubmenuIndexHidU2F, UsbTestSubmenuIndexHidU2F,
} SubmenuIndex; } SubmenuIndex;
void usb_test_submenu_callback(void* context, uint32_t index) { void usb_test_submenu_callback(void* context, uint32_t index) {
furi_assert(context); furi_assert(context);
//UsbTestApp* app = context; UsbTestApp* app = context;
if(index == UsbTestSubmenuIndexEnable) { if(index == UsbTestSubmenuIndexEnable) {
furi_hal_usb_enable(); furi_hal_usb_enable();
} else if(index == UsbTestSubmenuIndexDisable) { } else if(index == UsbTestSubmenuIndexDisable) {
@ -32,13 +34,19 @@ void usb_test_submenu_callback(void* context, uint32_t index) {
} else if(index == UsbTestSubmenuIndexRestart) { } else if(index == UsbTestSubmenuIndexRestart) {
furi_hal_usb_reinit(); furi_hal_usb_reinit();
} else if(index == UsbTestSubmenuIndexVcpSingle) { } else if(index == UsbTestSubmenuIndexVcpSingle) {
furi_hal_usb_set_config(&usb_cdc_single); furi_hal_usb_set_config(&usb_cdc_single, NULL);
} else if(index == UsbTestSubmenuIndexVcpDual) { } else if(index == UsbTestSubmenuIndexVcpDual) {
furi_hal_usb_set_config(&usb_cdc_dual); furi_hal_usb_set_config(&usb_cdc_dual, NULL);
} else if(index == UsbTestSubmenuIndexHid) { } else if(index == UsbTestSubmenuIndexHid) {
furi_hal_usb_set_config(&usb_hid); furi_hal_usb_set_config(&usb_hid, NULL);
} else if(index == UsbTestSubmenuIndexHidWithParams) {
app->hid_cfg.vid = 0x1234;
app->hid_cfg.pid = 0xabcd;
strncpy(app->hid_cfg.manuf, "WEN", sizeof(app->hid_cfg.manuf));
strncpy(app->hid_cfg.product, "FLIP", sizeof(app->hid_cfg.product));
furi_hal_usb_set_config(&usb_hid, &app->hid_cfg);
} else if(index == UsbTestSubmenuIndexHidU2F) { } else if(index == UsbTestSubmenuIndexHidU2F) {
furi_hal_usb_set_config(&usb_hid_u2f); furi_hal_usb_set_config(&usb_hid_u2f, NULL);
} }
} }
@ -71,6 +79,12 @@ UsbTestApp* usb_test_app_alloc() {
app->submenu, "Dual VCP", UsbTestSubmenuIndexVcpDual, usb_test_submenu_callback, app); app->submenu, "Dual VCP", UsbTestSubmenuIndexVcpDual, usb_test_submenu_callback, app);
submenu_add_item( submenu_add_item(
app->submenu, "HID KB+Mouse", UsbTestSubmenuIndexHid, usb_test_submenu_callback, app); app->submenu, "HID KB+Mouse", UsbTestSubmenuIndexHid, usb_test_submenu_callback, app);
submenu_add_item(
app->submenu,
"HID KB+Mouse custom ID",
UsbTestSubmenuIndexHidWithParams,
usb_test_submenu_callback,
app);
submenu_add_item( submenu_add_item(
app->submenu, "HID U2F", UsbTestSubmenuIndexHidU2F, usb_test_submenu_callback, app); app->submenu, "HID U2F", UsbTestSubmenuIndexHidU2F, usb_test_submenu_callback, app);
view_set_previous_callback(submenu_get_view(app->submenu), usb_test_exit); view_set_previous_callback(submenu_get_view(app->submenu), usb_test_exit);

View File

@ -84,10 +84,10 @@ static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) { static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) {
if(vcp_ch == 0) { if(vcp_ch == 0) {
furi_hal_usb_set_config(&usb_cdc_single); furi_hal_usb_set_config(&usb_cdc_single, NULL);
furi_hal_vcp_disable(); furi_hal_vcp_disable();
} else { } else {
furi_hal_usb_set_config(&usb_cdc_dual); furi_hal_usb_set_config(&usb_cdc_dual, NULL);
} }
furi_hal_cdc_set_callbacks(vcp_ch, (CdcCallbacks*)&cdc_cb, usb_uart); furi_hal_cdc_set_callbacks(vcp_ch, (CdcCallbacks*)&cdc_cb, usb_uart);
} }
@ -247,7 +247,7 @@ static int32_t usb_uart_worker(void* context) {
usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch); usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch);
usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch); usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch);
furi_hal_usb_set_config(usb_mode_prev); furi_hal_usb_set_config(usb_mode_prev, NULL);
if(usb_uart->cfg.flow_pins != 0) { if(usb_uart->cfg.flow_pins != 0) {
hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog);
hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog);

View File

@ -191,7 +191,7 @@ static int32_t u2f_hid_worker(void* context) {
FURI_LOG_D(WORKER_TAG, "Init"); FURI_LOG_D(WORKER_TAG, "Init");
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
furi_hal_usb_set_config(&usb_hid_u2f); furi_hal_usb_set_config(&usb_hid_u2f, NULL);
u2f_hid->lock_timer = osTimerNew(u2f_hid_lock_timeout_callback, osTimerOnce, u2f_hid, NULL); u2f_hid->lock_timer = osTimerNew(u2f_hid_lock_timeout_callback, osTimerOnce, u2f_hid, NULL);
@ -270,7 +270,7 @@ static int32_t u2f_hid_worker(void* context) {
osTimerDelete(u2f_hid->lock_timer); osTimerDelete(u2f_hid->lock_timer);
furi_hal_hid_u2f_set_callback(NULL, NULL); furi_hal_hid_u2f_set_callback(NULL, NULL);
furi_hal_usb_set_config(usb_mode_prev); furi_hal_usb_set_config(usb_mode_prev, NULL);
FURI_LOG_D(WORKER_TAG, "End"); FURI_LOG_D(WORKER_TAG, "End");
return 0; return 0;

View File

@ -1,3 +1,7 @@
ID 1234:5678 Apple:Keyboard
REM You can change these values to VID/PID of original Apple keyboard
REM to bypass Keyboard Setup Assistant
REM This is BadUSB demo script for macOS REM This is BadUSB demo script for macOS
REM Open terminal window REM Open terminal window

View File

@ -18,6 +18,7 @@ typedef struct {
bool connected; bool connected;
FuriHalUsbInterface* if_cur; FuriHalUsbInterface* if_cur;
FuriHalUsbInterface* if_next; FuriHalUsbInterface* if_next;
void* if_ctx;
FuriHalUsbStateCallback callback; FuriHalUsbStateCallback callback;
void* cb_ctx; void* cb_ctx;
} UsbSrv; } UsbSrv;
@ -88,8 +89,9 @@ void furi_hal_usb_init(void) {
FURI_LOG_I(TAG, "Init OK"); FURI_LOG_I(TAG, "Init OK");
} }
void furi_hal_usb_set_config(FuriHalUsbInterface* new_if) { void furi_hal_usb_set_config(FuriHalUsbInterface* new_if, void* ctx) {
usb.if_next = new_if; usb.if_next = new_if;
usb.if_ctx = ctx;
if(usb.thread == NULL) { if(usb.thread == NULL) {
// Service thread hasn't started yet, so just save interface mode // Service thread hasn't started yet, so just save interface mode
return; return;
@ -246,7 +248,7 @@ static int32_t furi_hal_usb_thread(void* context) {
usb.if_cur->deinit(&udev); usb.if_cur->deinit(&udev);
} }
if(usb.if_next != NULL) { if(usb.if_next != NULL) {
usb.if_next->init(&udev, usb.if_next); usb.if_next->init(&udev, usb.if_next, usb.if_ctx);
usbd_reg_event(&udev, usbd_evt_reset, reset_evt); usbd_reg_event(&udev, usbd_evt_reset, reset_evt);
FURI_LOG_I(TAG, "USB Mode change done"); FURI_LOG_I(TAG, "USB Mode change done");
usb.enabled = true; usb.enabled = true;

View File

@ -385,7 +385,7 @@ static const struct CdcConfigDescriptorDual
static struct usb_cdc_line_coding cdc_config[IF_NUM_MAX] = {}; static struct usb_cdc_line_coding cdc_config[IF_NUM_MAX] = {};
static uint8_t cdc_ctrl_line_state[IF_NUM_MAX]; static uint8_t cdc_ctrl_line_state[IF_NUM_MAX];
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf); static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
static void cdc_deinit(usbd_device* dev); static void cdc_deinit(usbd_device* dev);
static void cdc_on_wakeup(usbd_device* dev); static void cdc_on_wakeup(usbd_device* dev);
static void cdc_on_suspend(usbd_device* dev); static void cdc_on_suspend(usbd_device* dev);
@ -428,7 +428,7 @@ FuriHalUsbInterface usb_cdc_dual = {
.cfg_descr = (void*)&cdc_cfg_desc_dual, .cfg_descr = (void*)&cdc_cfg_desc_dual,
}; };
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf) { static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
usb_dev = dev; usb_dev = dev;
cdc_if_cur = intf; cdc_if_cur = intf;

View File

@ -21,6 +21,9 @@
#define HID_PAGE_CONSUMER 0x0C #define HID_PAGE_CONSUMER 0x0C
#define HID_CONSUMER_CONTROL 0x01 #define HID_CONSUMER_CONTROL 0x01
#define HID_VID_DEFAULT 0x046D
#define HID_PID_DEFAULT 0xC529
struct HidIadDescriptor { struct HidIadDescriptor {
struct usb_iad_descriptor hid_iad; struct usb_iad_descriptor hid_iad;
struct usb_interface_descriptor hid; struct usb_interface_descriptor hid;
@ -114,12 +117,8 @@ static const uint8_t hid_report_desc[] = {
HID_END_COLLECTION, HID_END_COLLECTION,
}; };
static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Logitech");
static const struct usb_string_descriptor dev_prod_desc = USB_STRING_DESC("USB Receiver");
static const struct usb_string_descriptor dev_serial_desc = USB_STRING_DESC("1234567890");
/* Device descriptor */ /* Device descriptor */
static const struct usb_device_descriptor hid_device_desc = { static struct usb_device_descriptor hid_device_desc = {
.bLength = sizeof(struct usb_device_descriptor), .bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = USB_DTYPE_DEVICE, .bDescriptorType = USB_DTYPE_DEVICE,
.bcdUSB = VERSION_BCD(2, 0, 0), .bcdUSB = VERSION_BCD(2, 0, 0),
@ -127,12 +126,12 @@ static const struct usb_device_descriptor hid_device_desc = {
.bDeviceSubClass = USB_SUBCLASS_IAD, .bDeviceSubClass = USB_SUBCLASS_IAD,
.bDeviceProtocol = USB_PROTO_IAD, .bDeviceProtocol = USB_PROTO_IAD,
.bMaxPacketSize0 = USB_EP0_SIZE, .bMaxPacketSize0 = USB_EP0_SIZE,
.idVendor = 0x046d, .idVendor = HID_VID_DEFAULT,
.idProduct = 0xc529, .idProduct = HID_PID_DEFAULT,
.bcdDevice = VERSION_BCD(1, 0, 0), .bcdDevice = VERSION_BCD(1, 0, 0),
.iManufacturer = UsbDevManuf, .iManufacturer = 0,
.iProduct = UsbDevProduct, .iProduct = 0,
.iSerialNumber = UsbDevSerial, .iSerialNumber = 0,
.bNumConfigurations = 1, .bNumConfigurations = 1,
}; };
@ -236,11 +235,26 @@ static struct HidReport {
struct HidReportConsumer consumer; struct HidReportConsumer consumer;
} __attribute__((packed)) hid_report; } __attribute__((packed)) hid_report;
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf); static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
static void hid_deinit(usbd_device* dev); static void hid_deinit(usbd_device* dev);
static void hid_on_wakeup(usbd_device* dev); static void hid_on_wakeup(usbd_device* dev);
static void hid_on_suspend(usbd_device* dev); static void hid_on_suspend(usbd_device* dev);
FuriHalUsbInterface usb_hid = {
.init = hid_init,
.deinit = hid_deinit,
.wakeup = hid_on_wakeup,
.suspend = hid_on_suspend,
.dev_descr = (struct usb_device_descriptor*)&hid_device_desc,
.str_manuf_descr = NULL,
.str_prod_descr = NULL,
.str_serial_descr = NULL,
.cfg_descr = (void*)&hid_cfg_desc,
};
static bool hid_send_report(uint8_t report_id); static bool hid_send_report(uint8_t report_id);
static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg); static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg);
static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback);
@ -348,28 +362,48 @@ bool furi_hal_hid_consumer_key_release(uint16_t button) {
return hid_send_report(ReportIdConsumer); return hid_send_report(ReportIdConsumer);
} }
FuriHalUsbInterface usb_hid = { static void* hid_set_string_descr(char* str) {
.init = hid_init, furi_assert(str);
.deinit = hid_deinit,
.wakeup = hid_on_wakeup,
.suspend = hid_on_suspend,
.dev_descr = (struct usb_device_descriptor*)&hid_device_desc, uint8_t len = strlen(str);
struct usb_string_descriptor* dev_str_desc = malloc(len * 2 + 2);
dev_str_desc->bLength = len * 2 + 2;
dev_str_desc->bDescriptorType = USB_DTYPE_STRING;
for(uint8_t i = 0; i < len; i++) dev_str_desc->wString[i] = str[i];
.str_manuf_descr = (void*)&dev_manuf_desc, return dev_str_desc;
.str_prod_descr = (void*)&dev_prod_desc, }
.str_serial_descr = (void*)&dev_serial_desc,
.cfg_descr = (void*)&hid_cfg_desc, static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
}; FuriHalUsbHidConfig* cfg = (FuriHalUsbHidConfig*)ctx;
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL); if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL);
usb_dev = dev; usb_dev = dev;
hid_report.keyboard.report_id = ReportIdKeyboard; hid_report.keyboard.report_id = ReportIdKeyboard;
hid_report.mouse.report_id = ReportIdMouse; hid_report.mouse.report_id = ReportIdMouse;
hid_report.consumer.report_id = ReportIdConsumer; hid_report.consumer.report_id = ReportIdConsumer;
usb_hid.dev_descr->iManufacturer = 0;
usb_hid.dev_descr->iProduct = 0;
usb_hid.str_manuf_descr = NULL;
usb_hid.str_prod_descr = NULL;
usb_hid.dev_descr->idVendor = HID_VID_DEFAULT;
usb_hid.dev_descr->idProduct = HID_PID_DEFAULT;
if(cfg != NULL) {
usb_hid.dev_descr->idVendor = cfg->vid;
usb_hid.dev_descr->idProduct = cfg->pid;
if(cfg->manuf[0] != '\0') {
usb_hid.str_manuf_descr = hid_set_string_descr(cfg->manuf);
usb_hid.dev_descr->iManufacturer = UsbDevManuf;
}
if(cfg->product[0] != '\0') {
usb_hid.str_prod_descr = hid_set_string_descr(cfg->product);
usb_hid.dev_descr->iProduct = UsbDevProduct;
}
}
usbd_reg_config(dev, hid_ep_config); usbd_reg_config(dev, hid_ep_config);
usbd_reg_control(dev, hid_control); usbd_reg_control(dev, hid_control);
@ -379,6 +413,9 @@ static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void hid_deinit(usbd_device* dev) { static void hid_deinit(usbd_device* dev) {
usbd_reg_config(dev, NULL); usbd_reg_config(dev, NULL);
usbd_reg_control(dev, NULL); usbd_reg_control(dev, NULL);
free(usb_hid.str_manuf_descr);
free(usb_hid.str_prod_descr);
} }
static void hid_on_wakeup(usbd_device* dev) { static void hid_on_wakeup(usbd_device* dev) {

View File

@ -137,7 +137,7 @@ static const struct HidConfigDescriptor hid_u2f_cfg_desc = {
}, },
}; };
static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf); static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
static void hid_u2f_deinit(usbd_device* dev); static void hid_u2f_deinit(usbd_device* dev);
static void hid_u2f_on_wakeup(usbd_device* dev); static void hid_u2f_on_wakeup(usbd_device* dev);
static void hid_u2f_on_suspend(usbd_device* dev); static void hid_u2f_on_suspend(usbd_device* dev);
@ -185,7 +185,7 @@ FuriHalUsbInterface usb_hid_u2f = {
.cfg_descr = (void*)&hid_u2f_cfg_desc, .cfg_descr = (void*)&hid_u2f_cfg_desc,
}; };
static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf) { static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
if(hid_u2f_semaphore == NULL) hid_u2f_semaphore = osSemaphoreNew(1, 1, NULL); if(hid_u2f_semaphore == NULL) hid_u2f_semaphore = osSemaphoreNew(1, 1, NULL);
usb_dev = dev; usb_dev = dev;

View File

@ -79,7 +79,7 @@ static int32_t vcp_worker(void* context) {
size_t missed_rx = 0; size_t missed_rx = 0;
uint8_t last_tx_pkt_len = 0; uint8_t last_tx_pkt_len = 0;
furi_hal_usb_set_config(&usb_cdc_single); furi_hal_usb_set_config(&usb_cdc_single, NULL);
furi_hal_cdc_set_callbacks(VCP_IF_NUM, &cdc_cb, NULL); furi_hal_cdc_set_callbacks(VCP_IF_NUM, &cdc_cb, NULL);
while(1) { while(1) {

View File

@ -18,6 +18,7 @@ typedef struct {
bool connected; bool connected;
FuriHalUsbInterface* if_cur; FuriHalUsbInterface* if_cur;
FuriHalUsbInterface* if_next; FuriHalUsbInterface* if_next;
void* if_ctx;
FuriHalUsbStateCallback callback; FuriHalUsbStateCallback callback;
void* cb_ctx; void* cb_ctx;
} UsbSrv; } UsbSrv;
@ -88,8 +89,9 @@ void furi_hal_usb_init(void) {
FURI_LOG_I(TAG, "Init OK"); FURI_LOG_I(TAG, "Init OK");
} }
void furi_hal_usb_set_config(FuriHalUsbInterface* new_if) { void furi_hal_usb_set_config(FuriHalUsbInterface* new_if, void* ctx) {
usb.if_next = new_if; usb.if_next = new_if;
usb.if_ctx = ctx;
if(usb.thread == NULL) { if(usb.thread == NULL) {
// Service thread hasn't started yet, so just save interface mode // Service thread hasn't started yet, so just save interface mode
return; return;
@ -246,7 +248,7 @@ static int32_t furi_hal_usb_thread(void* context) {
usb.if_cur->deinit(&udev); usb.if_cur->deinit(&udev);
} }
if(usb.if_next != NULL) { if(usb.if_next != NULL) {
usb.if_next->init(&udev, usb.if_next); usb.if_next->init(&udev, usb.if_next, usb.if_ctx);
usbd_reg_event(&udev, usbd_evt_reset, reset_evt); usbd_reg_event(&udev, usbd_evt_reset, reset_evt);
FURI_LOG_I(TAG, "USB Mode change done"); FURI_LOG_I(TAG, "USB Mode change done");
usb.enabled = true; usb.enabled = true;

View File

@ -385,7 +385,7 @@ static const struct CdcConfigDescriptorDual
static struct usb_cdc_line_coding cdc_config[IF_NUM_MAX] = {}; static struct usb_cdc_line_coding cdc_config[IF_NUM_MAX] = {};
static uint8_t cdc_ctrl_line_state[IF_NUM_MAX]; static uint8_t cdc_ctrl_line_state[IF_NUM_MAX];
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf); static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
static void cdc_deinit(usbd_device* dev); static void cdc_deinit(usbd_device* dev);
static void cdc_on_wakeup(usbd_device* dev); static void cdc_on_wakeup(usbd_device* dev);
static void cdc_on_suspend(usbd_device* dev); static void cdc_on_suspend(usbd_device* dev);
@ -428,7 +428,7 @@ FuriHalUsbInterface usb_cdc_dual = {
.cfg_descr = (void*)&cdc_cfg_desc_dual, .cfg_descr = (void*)&cdc_cfg_desc_dual,
}; };
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf) { static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
usb_dev = dev; usb_dev = dev;
cdc_if_cur = intf; cdc_if_cur = intf;

View File

@ -21,6 +21,9 @@
#define HID_PAGE_CONSUMER 0x0C #define HID_PAGE_CONSUMER 0x0C
#define HID_CONSUMER_CONTROL 0x01 #define HID_CONSUMER_CONTROL 0x01
#define HID_VID_DEFAULT 0x046D
#define HID_PID_DEFAULT 0xC529
struct HidIadDescriptor { struct HidIadDescriptor {
struct usb_iad_descriptor hid_iad; struct usb_iad_descriptor hid_iad;
struct usb_interface_descriptor hid; struct usb_interface_descriptor hid;
@ -114,12 +117,8 @@ static const uint8_t hid_report_desc[] = {
HID_END_COLLECTION, HID_END_COLLECTION,
}; };
static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Logitech");
static const struct usb_string_descriptor dev_prod_desc = USB_STRING_DESC("USB Receiver");
static const struct usb_string_descriptor dev_serial_desc = USB_STRING_DESC("1234567890");
/* Device descriptor */ /* Device descriptor */
static const struct usb_device_descriptor hid_device_desc = { static struct usb_device_descriptor hid_device_desc = {
.bLength = sizeof(struct usb_device_descriptor), .bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = USB_DTYPE_DEVICE, .bDescriptorType = USB_DTYPE_DEVICE,
.bcdUSB = VERSION_BCD(2, 0, 0), .bcdUSB = VERSION_BCD(2, 0, 0),
@ -127,12 +126,12 @@ static const struct usb_device_descriptor hid_device_desc = {
.bDeviceSubClass = USB_SUBCLASS_IAD, .bDeviceSubClass = USB_SUBCLASS_IAD,
.bDeviceProtocol = USB_PROTO_IAD, .bDeviceProtocol = USB_PROTO_IAD,
.bMaxPacketSize0 = USB_EP0_SIZE, .bMaxPacketSize0 = USB_EP0_SIZE,
.idVendor = 0x046d, .idVendor = HID_VID_DEFAULT,
.idProduct = 0xc529, .idProduct = HID_PID_DEFAULT,
.bcdDevice = VERSION_BCD(1, 0, 0), .bcdDevice = VERSION_BCD(1, 0, 0),
.iManufacturer = UsbDevManuf, .iManufacturer = 0,
.iProduct = UsbDevProduct, .iProduct = 0,
.iSerialNumber = UsbDevSerial, .iSerialNumber = 0,
.bNumConfigurations = 1, .bNumConfigurations = 1,
}; };
@ -236,11 +235,26 @@ static struct HidReport {
struct HidReportConsumer consumer; struct HidReportConsumer consumer;
} __attribute__((packed)) hid_report; } __attribute__((packed)) hid_report;
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf); static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
static void hid_deinit(usbd_device* dev); static void hid_deinit(usbd_device* dev);
static void hid_on_wakeup(usbd_device* dev); static void hid_on_wakeup(usbd_device* dev);
static void hid_on_suspend(usbd_device* dev); static void hid_on_suspend(usbd_device* dev);
FuriHalUsbInterface usb_hid = {
.init = hid_init,
.deinit = hid_deinit,
.wakeup = hid_on_wakeup,
.suspend = hid_on_suspend,
.dev_descr = (struct usb_device_descriptor*)&hid_device_desc,
.str_manuf_descr = NULL,
.str_prod_descr = NULL,
.str_serial_descr = NULL,
.cfg_descr = (void*)&hid_cfg_desc,
};
static bool hid_send_report(uint8_t report_id); static bool hid_send_report(uint8_t report_id);
static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg); static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg);
static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback);
@ -348,28 +362,48 @@ bool furi_hal_hid_consumer_key_release(uint16_t button) {
return hid_send_report(ReportIdConsumer); return hid_send_report(ReportIdConsumer);
} }
FuriHalUsbInterface usb_hid = { static void* hid_set_string_descr(char* str) {
.init = hid_init, furi_assert(str);
.deinit = hid_deinit,
.wakeup = hid_on_wakeup,
.suspend = hid_on_suspend,
.dev_descr = (struct usb_device_descriptor*)&hid_device_desc, uint8_t len = strlen(str);
struct usb_string_descriptor* dev_str_desc = malloc(len * 2 + 2);
dev_str_desc->bLength = len * 2 + 2;
dev_str_desc->bDescriptorType = USB_DTYPE_STRING;
for(uint8_t i = 0; i < len; i++) dev_str_desc->wString[i] = str[i];
.str_manuf_descr = (void*)&dev_manuf_desc, return dev_str_desc;
.str_prod_descr = (void*)&dev_prod_desc, }
.str_serial_descr = (void*)&dev_serial_desc,
.cfg_descr = (void*)&hid_cfg_desc, static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
}; FuriHalUsbHidConfig* cfg = (FuriHalUsbHidConfig*)ctx;
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL); if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL);
usb_dev = dev; usb_dev = dev;
hid_report.keyboard.report_id = ReportIdKeyboard; hid_report.keyboard.report_id = ReportIdKeyboard;
hid_report.mouse.report_id = ReportIdMouse; hid_report.mouse.report_id = ReportIdMouse;
hid_report.consumer.report_id = ReportIdConsumer; hid_report.consumer.report_id = ReportIdConsumer;
usb_hid.dev_descr->iManufacturer = 0;
usb_hid.dev_descr->iProduct = 0;
usb_hid.str_manuf_descr = NULL;
usb_hid.str_prod_descr = NULL;
usb_hid.dev_descr->idVendor = HID_VID_DEFAULT;
usb_hid.dev_descr->idProduct = HID_PID_DEFAULT;
if(cfg != NULL) {
usb_hid.dev_descr->idVendor = cfg->vid;
usb_hid.dev_descr->idProduct = cfg->pid;
if(cfg->manuf[0] != '\0') {
usb_hid.str_manuf_descr = hid_set_string_descr(cfg->manuf);
usb_hid.dev_descr->iManufacturer = UsbDevManuf;
}
if(cfg->product[0] != '\0') {
usb_hid.str_prod_descr = hid_set_string_descr(cfg->product);
usb_hid.dev_descr->iProduct = UsbDevProduct;
}
}
usbd_reg_config(dev, hid_ep_config); usbd_reg_config(dev, hid_ep_config);
usbd_reg_control(dev, hid_control); usbd_reg_control(dev, hid_control);
@ -379,6 +413,9 @@ static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void hid_deinit(usbd_device* dev) { static void hid_deinit(usbd_device* dev) {
usbd_reg_config(dev, NULL); usbd_reg_config(dev, NULL);
usbd_reg_control(dev, NULL); usbd_reg_control(dev, NULL);
free(usb_hid.str_manuf_descr);
free(usb_hid.str_prod_descr);
} }
static void hid_on_wakeup(usbd_device* dev) { static void hid_on_wakeup(usbd_device* dev) {

View File

@ -137,7 +137,7 @@ static const struct HidConfigDescriptor hid_u2f_cfg_desc = {
}, },
}; };
static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf); static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
static void hid_u2f_deinit(usbd_device* dev); static void hid_u2f_deinit(usbd_device* dev);
static void hid_u2f_on_wakeup(usbd_device* dev); static void hid_u2f_on_wakeup(usbd_device* dev);
static void hid_u2f_on_suspend(usbd_device* dev); static void hid_u2f_on_suspend(usbd_device* dev);
@ -185,7 +185,7 @@ FuriHalUsbInterface usb_hid_u2f = {
.cfg_descr = (void*)&hid_u2f_cfg_desc, .cfg_descr = (void*)&hid_u2f_cfg_desc,
}; };
static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf) { static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
if(hid_u2f_semaphore == NULL) hid_u2f_semaphore = osSemaphoreNew(1, 1, NULL); if(hid_u2f_semaphore == NULL) hid_u2f_semaphore = osSemaphoreNew(1, 1, NULL);
usb_dev = dev; usb_dev = dev;

View File

@ -79,7 +79,7 @@ static int32_t vcp_worker(void* context) {
size_t missed_rx = 0; size_t missed_rx = 0;
uint8_t last_tx_pkt_len = 0; uint8_t last_tx_pkt_len = 0;
furi_hal_usb_set_config(&usb_cdc_single); furi_hal_usb_set_config(&usb_cdc_single, NULL);
furi_hal_cdc_set_callbacks(VCP_IF_NUM, &cdc_cb, NULL); furi_hal_cdc_set_callbacks(VCP_IF_NUM, &cdc_cb, NULL);
while(1) { while(1) {

View File

@ -5,7 +5,7 @@
typedef struct FuriHalUsbInterface FuriHalUsbInterface; typedef struct FuriHalUsbInterface FuriHalUsbInterface;
struct FuriHalUsbInterface { struct FuriHalUsbInterface {
void (*init)(usbd_device* dev, FuriHalUsbInterface* intf); void (*init)(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
void (*deinit)(usbd_device* dev); void (*deinit)(usbd_device* dev);
void (*wakeup)(usbd_device* dev); void (*wakeup)(usbd_device* dev);
void (*suspend)(usbd_device* dev); void (*suspend)(usbd_device* dev);
@ -41,8 +41,9 @@ void furi_hal_usb_init();
/** Set USB device configuration /** Set USB device configuration
* *
* @param mode new USB device mode * @param mode new USB device mode
* @param ctx context passed to device mode init function
*/ */
void furi_hal_usb_set_config(FuriHalUsbInterface* new_if); void furi_hal_usb_set_config(FuriHalUsbInterface* new_if, void* ctx);
/** Get USB device configuration /** Get USB device configuration
* *

View File

@ -250,6 +250,13 @@ static const uint16_t hid_asciimap[] = {
KEY_NONE, // DEL KEY_NONE, // DEL
}; };
typedef struct {
uint32_t vid;
uint32_t pid;
char manuf[32];
char product[32];
} FuriHalUsbHidConfig;
typedef void (*HidStateCallback)(bool state, void* context); typedef void (*HidStateCallback)(bool state, void* context);
/** ASCII to keycode conversion macro */ /** ASCII to keycode conversion macro */