honeywell-config/honeywell-config.c

139 lines
3 KiB
C
Raw Normal View History

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];
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
//
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) {
if (libusb_claim_interface(devh, i)) {
perror("failed to claim interface");
return 1;
2024-11-25 23:10:11 +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);
cmd[0] = 0xfd;
2024-11-25 23:10:11 +01:00
cmd[1] = strlen(argv[i])+3;
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]));
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
//
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);
}