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) {
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);
view_dispatcher_run(bad_usb_app->view_dispatcher);
furi_hal_usb_set_config(usb_mode_prev);
bad_usb_app_free(bad_usb_app);
return 0;
}

View File

@ -24,6 +24,7 @@ typedef enum {
} WorkerEvtFlags;
struct BadUsbScript {
FuriHalUsbHidConfig hid_cfg;
BadUsbState st;
string_t file_path;
uint32_t defdelay;
@ -101,6 +102,7 @@ static const DuckyKey ducky_keys[] = {
};
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_string[] = {"STRING "};
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
}
FURI_LOG_I(WORKER_TAG, "line:%s", line_tmp);
FURI_LOG_D(WORKER_TAG, "line:%s", line_tmp);
// General commands
if(strncmp(line_tmp, ducky_cmd_comment, strlen(ducky_cmd_comment)) == 0) {
// REM - comment line
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) {
// DELAY
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;
}
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) {
uint8_t ret = 0;
uint32_t line_len = 0;
string_reset(bad_usb->line);
do {
ret = storage_file_read(script_file, bad_usb->file_buf, FILE_BUFFER_LEN);
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++;
line_len = 0;
} else {
if(bad_usb->st.line_nb == 0) { // Save first line
string_push_back(bad_usb->line, bad_usb->file_buf[i]);
}
line_len++;
}
}
@ -324,7 +359,20 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
}
} 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);
string_reset(bad_usb->line);
return true;
}
@ -403,6 +451,8 @@ static int32_t bad_usb_worker(void* context) {
BadUsbWorkerState worker_state = BadUsbStateInit;
int32_t delay_val = 0;
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
FURI_LOG_I(WORKER_TAG, "Init");
File* script_file = storage_file_alloc(furi_record_open("storage"));
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_usb_set_config(usb_mode_prev, NULL);
storage_file_close(script_file);
storage_file_free(script_file);
string_clear(bad_usb->line);

View File

@ -42,7 +42,7 @@ int32_t usb_mouse_app(void* p) {
ViewPort* view_port = view_port_alloc();
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_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);
}
furi_hal_usb_set_config(usb_mode_prev);
furi_hal_usb_set_config(usb_mode_prev, NULL);
// remove & free all stuff created by app
gui_remove_view_port(gui, view_port);

View File

@ -10,6 +10,7 @@ typedef struct {
Gui* gui;
ViewDispatcher* view_dispatcher;
Submenu* submenu;
FuriHalUsbHidConfig hid_cfg;
} UsbTestApp;
typedef enum {
@ -19,12 +20,13 @@ typedef enum {
UsbTestSubmenuIndexVcpSingle,
UsbTestSubmenuIndexVcpDual,
UsbTestSubmenuIndexHid,
UsbTestSubmenuIndexHidWithParams,
UsbTestSubmenuIndexHidU2F,
} SubmenuIndex;
void usb_test_submenu_callback(void* context, uint32_t index) {
furi_assert(context);
//UsbTestApp* app = context;
UsbTestApp* app = context;
if(index == UsbTestSubmenuIndexEnable) {
furi_hal_usb_enable();
} else if(index == UsbTestSubmenuIndexDisable) {
@ -32,13 +34,19 @@ void usb_test_submenu_callback(void* context, uint32_t index) {
} else if(index == UsbTestSubmenuIndexRestart) {
furi_hal_usb_reinit();
} 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) {
furi_hal_usb_set_config(&usb_cdc_dual);
furi_hal_usb_set_config(&usb_cdc_dual, NULL);
} 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) {
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);
submenu_add_item(
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(
app->submenu, "HID U2F", UsbTestSubmenuIndexHidU2F, usb_test_submenu_callback, app);
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) {
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();
} 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);
}
@ -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_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) {
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);

View File

@ -191,7 +191,7 @@ static int32_t u2f_hid_worker(void* context) {
FURI_LOG_D(WORKER_TAG, "Init");
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);
@ -270,7 +270,7 @@ static int32_t u2f_hid_worker(void* context) {
osTimerDelete(u2f_hid->lock_timer);
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");
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 Open terminal window

View File

@ -18,6 +18,7 @@ typedef struct {
bool connected;
FuriHalUsbInterface* if_cur;
FuriHalUsbInterface* if_next;
void* if_ctx;
FuriHalUsbStateCallback callback;
void* cb_ctx;
} UsbSrv;
@ -88,8 +89,9 @@ void furi_hal_usb_init(void) {
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_ctx = ctx;
if(usb.thread == NULL) {
// Service thread hasn't started yet, so just save interface mode
return;
@ -246,7 +248,7 @@ static int32_t furi_hal_usb_thread(void* context) {
usb.if_cur->deinit(&udev);
}
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);
FURI_LOG_I(TAG, "USB Mode change done");
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 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_on_wakeup(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,
};
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
usb_dev = dev;
cdc_if_cur = intf;

View File

@ -21,6 +21,9 @@
#define HID_PAGE_CONSUMER 0x0C
#define HID_CONSUMER_CONTROL 0x01
#define HID_VID_DEFAULT 0x046D
#define HID_PID_DEFAULT 0xC529
struct HidIadDescriptor {
struct usb_iad_descriptor hid_iad;
struct usb_interface_descriptor hid;
@ -114,12 +117,8 @@ static const uint8_t hid_report_desc[] = {
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 */
static const struct usb_device_descriptor hid_device_desc = {
static struct usb_device_descriptor hid_device_desc = {
.bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = USB_DTYPE_DEVICE,
.bcdUSB = VERSION_BCD(2, 0, 0),
@ -127,12 +126,12 @@ static const struct usb_device_descriptor hid_device_desc = {
.bDeviceSubClass = USB_SUBCLASS_IAD,
.bDeviceProtocol = USB_PROTO_IAD,
.bMaxPacketSize0 = USB_EP0_SIZE,
.idVendor = 0x046d,
.idProduct = 0xc529,
.idVendor = HID_VID_DEFAULT,
.idProduct = HID_PID_DEFAULT,
.bcdDevice = VERSION_BCD(1, 0, 0),
.iManufacturer = UsbDevManuf,
.iProduct = UsbDevProduct,
.iSerialNumber = UsbDevSerial,
.iManufacturer = 0,
.iProduct = 0,
.iSerialNumber = 0,
.bNumConfigurations = 1,
};
@ -236,11 +235,26 @@ static struct HidReport {
struct HidReportConsumer consumer;
} __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_on_wakeup(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 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);
@ -348,28 +362,48 @@ bool furi_hal_hid_consumer_key_release(uint16_t button) {
return hid_send_report(ReportIdConsumer);
}
FuriHalUsbInterface usb_hid = {
.init = hid_init,
.deinit = hid_deinit,
.wakeup = hid_on_wakeup,
.suspend = hid_on_suspend,
static void* hid_set_string_descr(char* str) {
furi_assert(str);
.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,
.str_prod_descr = (void*)&dev_prod_desc,
.str_serial_descr = (void*)&dev_serial_desc,
return dev_str_desc;
}
.cfg_descr = (void*)&hid_cfg_desc,
};
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
FuriHalUsbHidConfig* cfg = (FuriHalUsbHidConfig*)ctx;
if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL);
usb_dev = dev;
hid_report.keyboard.report_id = ReportIdKeyboard;
hid_report.mouse.report_id = ReportIdMouse;
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_control(dev, hid_control);
@ -379,6 +413,9 @@ static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void hid_deinit(usbd_device* dev) {
usbd_reg_config(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) {

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_on_wakeup(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,
};
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);
usb_dev = dev;

View File

@ -79,7 +79,7 @@ static int32_t vcp_worker(void* context) {
size_t missed_rx = 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);
while(1) {

View File

@ -18,6 +18,7 @@ typedef struct {
bool connected;
FuriHalUsbInterface* if_cur;
FuriHalUsbInterface* if_next;
void* if_ctx;
FuriHalUsbStateCallback callback;
void* cb_ctx;
} UsbSrv;
@ -88,8 +89,9 @@ void furi_hal_usb_init(void) {
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_ctx = ctx;
if(usb.thread == NULL) {
// Service thread hasn't started yet, so just save interface mode
return;
@ -246,7 +248,7 @@ static int32_t furi_hal_usb_thread(void* context) {
usb.if_cur->deinit(&udev);
}
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);
FURI_LOG_I(TAG, "USB Mode change done");
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 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_on_wakeup(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,
};
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void cdc_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
usb_dev = dev;
cdc_if_cur = intf;

View File

@ -21,6 +21,9 @@
#define HID_PAGE_CONSUMER 0x0C
#define HID_CONSUMER_CONTROL 0x01
#define HID_VID_DEFAULT 0x046D
#define HID_PID_DEFAULT 0xC529
struct HidIadDescriptor {
struct usb_iad_descriptor hid_iad;
struct usb_interface_descriptor hid;
@ -114,12 +117,8 @@ static const uint8_t hid_report_desc[] = {
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 */
static const struct usb_device_descriptor hid_device_desc = {
static struct usb_device_descriptor hid_device_desc = {
.bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = USB_DTYPE_DEVICE,
.bcdUSB = VERSION_BCD(2, 0, 0),
@ -127,12 +126,12 @@ static const struct usb_device_descriptor hid_device_desc = {
.bDeviceSubClass = USB_SUBCLASS_IAD,
.bDeviceProtocol = USB_PROTO_IAD,
.bMaxPacketSize0 = USB_EP0_SIZE,
.idVendor = 0x046d,
.idProduct = 0xc529,
.idVendor = HID_VID_DEFAULT,
.idProduct = HID_PID_DEFAULT,
.bcdDevice = VERSION_BCD(1, 0, 0),
.iManufacturer = UsbDevManuf,
.iProduct = UsbDevProduct,
.iSerialNumber = UsbDevSerial,
.iManufacturer = 0,
.iProduct = 0,
.iSerialNumber = 0,
.bNumConfigurations = 1,
};
@ -236,11 +235,26 @@ static struct HidReport {
struct HidReportConsumer consumer;
} __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_on_wakeup(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 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);
@ -348,28 +362,48 @@ bool furi_hal_hid_consumer_key_release(uint16_t button) {
return hid_send_report(ReportIdConsumer);
}
FuriHalUsbInterface usb_hid = {
.init = hid_init,
.deinit = hid_deinit,
.wakeup = hid_on_wakeup,
.suspend = hid_on_suspend,
static void* hid_set_string_descr(char* str) {
furi_assert(str);
.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,
.str_prod_descr = (void*)&dev_prod_desc,
.str_serial_descr = (void*)&dev_serial_desc,
return dev_str_desc;
}
.cfg_descr = (void*)&hid_cfg_desc,
};
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
FuriHalUsbHidConfig* cfg = (FuriHalUsbHidConfig*)ctx;
if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL);
usb_dev = dev;
hid_report.keyboard.report_id = ReportIdKeyboard;
hid_report.mouse.report_id = ReportIdMouse;
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_control(dev, hid_control);
@ -379,6 +413,9 @@ static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf) {
static void hid_deinit(usbd_device* dev) {
usbd_reg_config(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) {

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_on_wakeup(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,
};
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);
usb_dev = dev;

View File

@ -79,7 +79,7 @@ static int32_t vcp_worker(void* context) {
size_t missed_rx = 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);
while(1) {

View File

@ -5,7 +5,7 @@
typedef struct FuriHalUsbInterface 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 (*wakeup)(usbd_device* dev);
void (*suspend)(usbd_device* dev);
@ -41,8 +41,9 @@ void furi_hal_usb_init();
/** Set USB device configuration
*
* @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
*

View File

@ -250,6 +250,13 @@ static const uint16_t hid_asciimap[] = {
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);
/** ASCII to keycode conversion macro */