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:
		
							parent
							
								
									6470aa8ff9
								
							
						
					
					
						commit
						d075e00ae1
					
				| @ -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; | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) { | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) { | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) { | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) { | ||||||
|  | |||||||
| @ -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
 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -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 */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikolay Minaylov
						Nikolay Minaylov