#include #include #include #include #include #include #include #include #include // Template for control messages, obtained through packet capture unsigned char *CMD = "\xfd\x00\x16M\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; int main(int argc, char **argv) { uint8_t cmd[64]; memcpy(cmd, CMD, 64); struct usbdevfs_ioctl command; libusb_context *ctx = NULL; // // Find and open the device // libusb_init(&ctx); if (!ctx) { perror("failed to initialize libusb"); return 1; } libusb_device_handle *devh = libusb_open_device_with_vid_pid(ctx, 0x0c2e, 0x0b07); if (!devh) { devh = libusb_open_device_with_vid_pid(ctx, 0x0c2e, 0x0b01); if (!devh) { perror("failed to open device"); return 1; } } libusb_device *dev = libusb_get_device(devh); if (!dev) { perror("failed to get device info"); return 1; } // // Disconnect usbhid driver from both device interfaces // char usbdevfs[32]; snprintf(usbdevfs, 32, "/dev/bus/usb/%03d/%03d", libusb_get_bus_number(dev), libusb_get_device_address(dev)); // usbdevfs/ioctl inspired from // https://www.linuxquestions.org/questions/linux-hardware-18/how-to-unclaim-usb-device-558138/#post3406986 int fd = open(usbdevfs,O_RDWR); if (fd < 1) { perror("failed to open usbdevfs file"); return 1; } for (uint8_t i = 0; i < 2; ++i) { command.ifno = i; command.ioctl_code = USBDEVFS_DISCONNECT; command.data = NULL; int ret = ioctl(fd, USBDEVFS_IOCTL, &command); if (ret < 0) { perror("failed to unclaim USB interface from usbhid"); } } // // Prepare and send a message on the control channel for each config argument // for (int i = 1; i < argc; ++i) { memset(cmd+5, 0, 59); cmd[1] = strlen(argv[i])+3; memcpy(cmd+5, argv[i], strlen(argv[i])); libusb_control_transfer(devh, 0x21, 0x09, 0x02fd, 1, cmd, 64, 0); } // // Cleanup // libusb_release_interface(devh, 1); libusb_close(devh); libusb_exit(ctx); }