blob: 1ad003ea930c85d0cb89509f6810b0dd48f099c5 [file] [log] [blame] [edit]
/*
* BRLTTY - A background process providing access to the console screen (when in
* text mode) for a blind person using a refreshable braille display.
*
* Copyright (C) 1995-2023 by The BRLTTY Developers.
*
* BRLTTY comes with ABSOLUTELY NO WARRANTY.
*
* This is free software, placed under the terms of the
* GNU Lesser General Public License, as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any
* later version. Please see the file LICENSE-LGPL for details.
*
* Web Page: http://brltty.app/
*
* This software is maintained by Dave Mielke <dave@mielke.cc>.
*/
#include "prologue.h"
#include <string.h>
#include <errno.h>
#include "log.h"
#include "io_usb.h"
#include "usb_hid.h"
#include "bitfield.h"
const UsbHidDescriptor *
usbHidDescriptor (UsbDevice *device) {
const UsbDescriptor *descriptor = NULL;
while (usbNextDescriptor(device, &descriptor)) {
if (descriptor->header.bDescriptorType == UsbDescriptorType_HID) {
return &descriptor->hid;
}
}
logMessage(LOG_WARNING, "USB: HID descriptor not found");
errno = ENOENT;
return NULL;
}
HidItemsDescriptor *
usbHidGetItems (
UsbDevice *device,
unsigned char interface,
unsigned char number,
int timeout
) {
const UsbHidDescriptor *hid = usbHidDescriptor(device);
if (hid) {
if (number < hid->bNumDescriptors) {
const UsbClassDescriptor *descriptor = &hid->descriptors[number];
uint16_t length = getLittleEndian16(descriptor->wDescriptorLength);
HidItemsDescriptor *items;
size_t size = sizeof(*items);
size += length;
if ((items = malloc(size))) {
ssize_t result = usbControlRead(
device, UsbControlRecipient_Interface, UsbControlType_Standard,
UsbStandardRequest_GetDescriptor,
(descriptor->bDescriptorType << 8) | interface,
number, items->bytes, length, timeout
);
if (result != -1) {
memset(items, 0, sizeof(*items));
items->count = result;
return items;
}
free(items);
} else {
logMallocError();
}
} else {
logMessage(LOG_WARNING,
"USB report descriptor not found: %u[%u]",
interface, number
);
}
}
return NULL;
}
ssize_t
usbHidGetReport (
UsbDevice *device,
unsigned char interface,
HidReportIdentifier identifier,
unsigned char *buffer,
uint16_t size,
int timeout
) {
return usbControlRead(device,
UsbControlRecipient_Interface, UsbControlType_Class,
UsbHidRequest_GetReport,
(UsbHidReportType_Input << 8) | identifier, interface,
buffer, size, timeout
);
}
ssize_t
usbHidSetReport (
UsbDevice *device,
unsigned char interface,
HidReportIdentifier identifier,
const unsigned char *data,
uint16_t length,
int timeout
) {
return usbControlWrite(device,
UsbControlRecipient_Interface, UsbControlType_Class,
UsbHidRequest_SetReport,
(UsbHidReportType_Output << 8) | identifier, interface,
data, length, timeout
);
}
ssize_t
usbHidGetFeature (
UsbDevice *device,
unsigned char interface,
HidReportIdentifier identifier,
unsigned char *buffer,
uint16_t size,
int timeout
) {
return usbControlRead(device,
UsbControlRecipient_Interface, UsbControlType_Class,
UsbHidRequest_GetReport,
(UsbHidReportType_Feature << 8) | identifier, interface,
buffer, size, timeout
);
}
ssize_t
usbHidSetFeature (
UsbDevice *device,
unsigned char interface,
HidReportIdentifier identifier,
const unsigned char *data,
uint16_t length,
int timeout
) {
return usbControlWrite(device,
UsbControlRecipient_Interface, UsbControlType_Class,
UsbHidRequest_SetReport,
(UsbHidReportType_Feature << 8) | identifier, interface,
data, length, timeout
);
}