#include #include #include int main(int argc, char **argv) { uint8_t cmd[64]; char tokbuf[1024]; 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; } } // // Disconnect usbhid driver from both device interfaces // if (libusb_set_auto_detach_kernel_driver(devh, 1)) { perror("auto-attaching kernel driver not possible; please replug USB when done"); for (uint8_t i = 0; i < 2; ++i) { int ret = libusb_kernel_driver_active(devh, i); if (ret < 0) { perror("failed to query kernel driver state"); return 1; } if (ret > 0) { ret = libusb_detach_kernel_driver(devh, i); if (ret) { perror("failed to detach kernel driver"); return 1; } } } } for (uint8_t i = 0; i < 2; ++i) { if (libusb_claim_interface(devh, i)) { perror("failed to claim interface"); return 1; } } // // 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[0] = 0xfd; cmd[1] = strlen(argv[i])+3; cmd[2] = 0x16; cmd[3] = 0x4d; cmd[4] = 0x0d; memcpy(cmd+5, argv[i], strlen(argv[i])); int ret = libusb_control_transfer(devh, 0x21, 0x09, 0x02fd, 1, cmd, 64, 0); if (ret < 0) { perror("failed to send control message"); } else { printf("> %s\n", argv[i]); } int tx; tokbuf[64] = 0; char *start, *end, *tok = tokbuf; uint8_t eot = 0; // Repeat until a "." (EOT) is encountered in the response. while (!eot) { ret = libusb_interrupt_transfer(devh, 0x83, cmd, 64, &tx, 0); if (ret) { perror("failed to receive response"); break; } // strip 2-byte header and AIMID start = cmd+5; while (1) { // non-final tokens: terminated by ; end = strchr(start, ';'); if (end) { if (end > start) { memcpy(tok, start, end-start-1); tok += end-start-1; } *tok = 0; printf("< %s.\n", tokbuf); tok = tokbuf; *tok = 0; start = end + 1; continue; } // last token: terminated by . end = strchr(start, '.'); if (end) { eot = 1; if (end > start) { memcpy(tok, start, end-start-1); tok += end-start-1; } *tok = 0; printf("< %s.\n", tokbuf); tok = tokbuf; *tok = 0; break; } // incomplete tokens continued in the next message end = strchr(start, '?'); if (end) { *end = 0; } strcpy(tok, start); tok += strlen(start); break; } } } // // Cleanup // for (uint8_t i = 0; i < 2; ++i) { if (libusb_release_interface(devh, i)) { perror("failed to release interface"); } } libusb_close(devh); libusb_exit(ctx); }