Implement initial profile reading and writing with little-endian offsets and CLI tool

This commit is contained in:
Aodhan Collins
2026-02-22 17:53:05 +00:00
parent 224271e639
commit db5c3505da
72 changed files with 7090 additions and 126 deletions

View File

@@ -10,6 +10,8 @@
#include <libusb-1.0/libusb.h>
#include <string.h>
#define AZERON_CONFIG_INTERFACE 4
/* Claim device interfaces */
int azeron_device_claim(struct azeron_device *device)
{
@@ -25,26 +27,34 @@ int azeron_device_claim(struct azeron_device *device)
pthread_mutex_lock(&device->mutex);
/* Claim all interfaces - the device has 5 interfaces (0-4) */
for (int i = 0; i <= 4; i++) {
ret = libusb_claim_interface(device->handle, i);
if (ret < 0) {
AZERON_ERROR("Failed to claim interface %d: %s", i, azeron_usb_error_string(ret));
/* Release already claimed interfaces */
for (int j = 0; j < i; j++) {
libusb_release_interface(device->handle, j);
}
/*
* The device has 5 interfaces (0-4).
* Interfaces 1, 2, and 3 are handled by the kernel for input (HID).
* Interface 4 is the configuration interface we need.
*/
/* Detach kernel driver if active on Interface 4 */
if (libusb_kernel_driver_active(device->handle, AZERON_CONFIG_INTERFACE) == 1) {
ret = libusb_detach_kernel_driver(device->handle, AZERON_CONFIG_INTERFACE);
if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) {
AZERON_ERROR("Failed to detach kernel driver: %s", azeron_usb_error_string(ret));
pthread_mutex_unlock(&device->mutex);
return azeron_libusb_to_azeron_error(ret);
}
}
/* Claim configuration interface */
ret = libusb_claim_interface(device->handle, AZERON_CONFIG_INTERFACE);
if (ret < 0) {
AZERON_ERROR("Failed to claim interface %d: %s", AZERON_CONFIG_INTERFACE, azeron_usb_error_string(ret));
pthread_mutex_unlock(&device->mutex);
return azeron_libusb_to_azeron_error(ret);
}
device->claimed = true;
pthread_mutex_unlock(&device->mutex);
AZERON_LOG("Device interfaces claimed");
AZERON_LOG("Device configuration interface claimed");
return AZERON_SUCCESS;
}
@@ -53,7 +63,6 @@ int azeron_device_claim(struct azeron_device *device)
int azeron_device_release(struct azeron_device *device)
{
int ret;
int overall_ret = AZERON_SUCCESS;
if (!device || !device->handle) {
return AZERON_ERROR_INVALID_PARAM;
@@ -65,21 +74,20 @@ int azeron_device_release(struct azeron_device *device)
pthread_mutex_lock(&device->mutex);
/* Release all interfaces */
for (int i = 0; i <= 4; i++) {
ret = libusb_release_interface(device->handle, i);
if (ret < 0) {
AZERON_ERROR("Failed to release interface %d: %s", i, azeron_usb_error_string(ret));
overall_ret = azeron_libusb_to_azeron_error(ret);
}
ret = libusb_release_interface(device->handle, AZERON_CONFIG_INTERFACE);
if (ret < 0) {
AZERON_ERROR("Failed to release interface %d: %s", AZERON_CONFIG_INTERFACE, azeron_usb_error_string(ret));
}
/* Re-attach kernel driver */
libusb_attach_kernel_driver(device->handle, AZERON_CONFIG_INTERFACE);
device->claimed = false;
pthread_mutex_unlock(&device->mutex);
AZERON_LOG("Device interfaces released");
AZERON_LOG("Device interface released");
return overall_ret;
return (ret < 0) ? azeron_libusb_to_azeron_error(ret) : AZERON_SUCCESS;
}
/* Read data from endpoint */
@@ -180,39 +188,3 @@ int azeron_device_control_transfer(struct azeron_device *device, uint8_t request
return ret;
}
/* Get button type string */
const char *azeron_button_type_string(enum azeron_button_type type)
{
switch (type) {
case AZERON_BTN_KEYBOARD:
return "keyboard";
case AZERON_BTN_MOUSE:
return "mouse";
case AZERON_BTN_GAMEPAD:
return "gamepad";
case AZERON_BTN_MACRO:
return "macro";
case AZERON_BTN_LAYER_SWITCH:
return "layer_switch";
default:
return "unknown";
}
}
/* Get stick mode string */
const char *azeron_stick_mode_string(enum azeron_stick_mode mode)
{
switch (mode) {
case AZERON_STICK_ANALOG:
return "analog";
case AZERON_STICK_DIGITAL_4:
return "digital_4";
case AZERON_STICK_DIGITAL_8:
return "digital_8";
case AZERON_STICK_MOUSE:
return "mouse";
default:
return "unknown";
}
}