honeywell-config/honeywell-config.c
2024-11-25 23:10:11 +01:00

82 lines
2.3 KiB
C

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/usbdevice_fs.h>
#include <libusb-1.0/libusb.h>
// 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);
}