|
whiskers 0.2.0
RP2350 BadUSB Tool
|
HAL USB functions.
Here is all of the code for using USB. Typically, the underlying stack for USB is TinyUSB, although all of the TinyUSB functions are hidden away via the HAL it is still worth knowing the USB protocol and some of how TinyUSB works.
The proper setup/structure for bare minimum USB functionality goes as follows:
Currently the USB stack only supports one HID device (being a keyboard).
#include "shared.h"Go to the source code of this file.
Data Structures | |
| struct | usb_mods |
| USB Modifiers. More... | |
| struct | usb_callbacks |
| Struct holding callback functions for internal USB events. More... | |
Typedefs | |
| typedef struct usb_mods | w_usb_mods |
| typedef struct usb_callbacks | w_usb_cbs |
Functions | |
| void | usb_setup_msc (char vendor_string[8], char product_string[16], _DISK_INFO *di) |
| Sets up the MSC Class USB interface. | |
| void | usb_initialize_defaults (w_usb_cbs *cbs) |
| Starts the internal USB stack with default values. | |
| void | usb_initialize_custom (w_usb_cbs *cbs, w_usb_mods *mods) |
| Starts the internal USB stack with custom descriptors. | |
| void | usb_keyboard_send_report (const uint8_t rep[8]) |
| Sends a standard HID keyboard report. | |
| void | usb_loop () |
| For TinyUSB based systems, this refreshes tud_task(). This must be called at least once every millisecond, peferably as fast as possible. | |
| void | usb_remote_wakeup_host () |
| If the host allows us, this function will wake it up. | |
| void usb_initialize_custom | ( | w_usb_cbs * | cbs, |
| w_usb_mods * | mods ) |
Starts the internal USB stack with custom descriptors.
| cbs | Callback struct for the internal functions. |
| mods | USB modifiers struct. |
| void usb_initialize_defaults | ( | w_usb_cbs * | cbs | ) |
Starts the internal USB stack with default values.
| cbs | Callback struct for the internal functions. |
| void usb_keyboard_send_report | ( | const uint8_t | rep[8] | ) |
Sends a standard HID keyboard report.
| rep | The 8 byte report to be sent. |
Some information about the report structure for the uninitiated. This report structure follows the standard USB protocol as follows:
| Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 |
| This is the modifier codes bitmask. See below table for this. | Reserved. Set to zero. | First keyboard scancode. | Second keyboard scancode. | Third keyboard scancode. | Fourth keyboard scancode. | Fifth keyboard scancode. | Sixth keyboard scancode. |
Now for the modifier bitmask. This is the first byte of the report and each bit must be set to one for the modifier's effect.
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
| Right Meta (Windows Key). | Right Alt. | Right Shift. | Right Control. | Left Meta (Windows Key). | Left Alt. | Left Shift. | Left Control. |
For a list of all scancodes (eventually a static array will be added for fast lookups/parsing) visit this list.
For an example, a report that contains the following:
[ 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x0, 0x0 ]
Would output the following string to the host computer: "ABCD". However, if we never reset after sending this report, the host will think we are holding down that last scancode (being D in this case). So after every report you send you must send a "NULL" report that consists of all zeros. However, if you need to hold the key for a certain amount of time (ie. you need to emulate holding down A for 10 seconds) then only send the NULL report after you've waited for how long you want to hold the key for.
| void usb_setup_msc | ( | char | vendor_string[8], |
| char | product_string[16], | ||
| _DISK_INFO * | di ) |
Sets up the MSC Class USB interface.
| vendor_string | 8 byte string for vendor name. |
| product_string | 16 byte string for product name. |
| di | _DISK_INFO pointer to valid disk. |
Note that the _DISK_INFO input can be any valid disk. This can be something like an SD card (which is setup when you mount the SD card through the disk.h functions) or even something like a ramdisk or file. This allows you to expose any medium you want to the host. For example, if you want the host to "see" the disk (but not your own files) you can make a large continous file (1-2gb) and format that chunk of disk as a seperate FAT filesystem then expose it to the host. To the host it looks like it's just a 1-2gb medium while not exposing the other files or allowing the host to "pierce the veil" in a sense and see what else is on the disk.