2024-11-25 23:10:11 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <libusb-1.0/libusb.h>
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
uint8_t cmd[64];
|
2024-11-26 19:56:30 +01:00
|
|
|
char tokbuf[1024];
|
2024-11-25 23:10:11 +01:00
|
|
|
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
|
|
|
|
//
|
2024-11-26 19:56:30 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-11-25 23:10:11 +01:00
|
|
|
}
|
|
|
|
for (uint8_t i = 0; i < 2; ++i) {
|
2024-11-26 19:56:30 +01:00
|
|
|
if (libusb_claim_interface(devh, i)) {
|
|
|
|
perror("failed to claim interface");
|
|
|
|
return 1;
|
2024-11-25 23:10:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-26 19:56:30 +01:00
|
|
|
|
2024-11-25 23:10:11 +01:00
|
|
|
//
|
|
|
|
// 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);
|
2024-11-26 19:56:30 +01:00
|
|
|
cmd[0] = 0xfd;
|
2024-11-25 23:10:11 +01:00
|
|
|
cmd[1] = strlen(argv[i])+3;
|
2024-11-26 19:56:30 +01:00
|
|
|
cmd[2] = 0x16;
|
|
|
|
cmd[3] = 0x4d;
|
|
|
|
cmd[4] = 0x0d;
|
2024-11-25 23:10:11 +01:00
|
|
|
memcpy(cmd+5, argv[i], strlen(argv[i]));
|
2024-11-26 19:56:30 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2024-11-25 23:10:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Cleanup
|
|
|
|
//
|
2024-11-26 19:56:30 +01:00
|
|
|
for (uint8_t i = 0; i < 2; ++i) {
|
|
|
|
if (libusb_release_interface(devh, i)) {
|
|
|
|
perror("failed to release interface");
|
|
|
|
}
|
|
|
|
}
|
2024-11-25 23:10:11 +01:00
|
|
|
libusb_close(devh);
|
|
|
|
libusb_exit(ctx);
|
|
|
|
}
|