Two API calls have been specifically created to cater for HID Get and Set feature requests.
These are available in UPDD V7 on macOS 10.14 and above, from build 07.01.224. Equivalent calls existed in UPDD V5 but were not carried forward into V6.
These calls are intended for use by programmers familiar with direct HID API calls, as a replacement for such a call in cases where one is not possible because UPDD is in control of the device.
This is the case on macOS, where UPDD opens the USB device exclusively: a direct call fails, with IOUSBDeviceOpen returning kIOReturnExclusiveAccess (0xe00002c5) and ioreg -p IOUSB -l reporting "UsbExclusiveOwner" = "pid <n>, updd". These two calls pass the request to the driver, which performs it while retaining its exclusive open. The same restriction applies on Linux, but these calls are not implemented there, so a HID feature request cannot be issued while UPDD is in control of the device. On Windows UPDD binds using a HID filter driver and the device remains available to applications, so a direct HidD_GetFeature / HidD_SetFeature call works while UPDD is running — these APIs are neither required nor implemented there.
As such a detailed description of the HID report format is not given here.
The document here describes this in the context of the native Windows API.
TBApiHidGetFeature
This API is used to issue an HID get feature request to a UPDD controlled device.
Definition
TBBOOL TBAPI TBApiHidGetFeature(
HTBDEVICE aDevice,
int aInterface,
void* aReportBuffer,
uint32_t aReportBufferLength
);
Parameters
Device: the UPDD device handle representing the device instance to be queried.
aInterface: the interface number to be queried
aReportBuffer:
A block of memory allocated by the caller
When calling the API the caller sets up the HID feature report data to be sent to the device.
Typically this is simply the report id of the feature in byte zero.
aReportBufferLength: The length of the allocated block. This should be long enough to contain the expected response from the controller including the leading report id byte.
Notes: in normal HID mode a programmer will use an open handle to an HID collection.
Using the UPDD API; use standard UPDD APIs to derive the device handle and consult with the hardware supplier and / or examine USB traffic in HID mode to derive the interface number. The interface number is defined in the USB report descriptors and as such is constant for a given device in most cases. In many cases this value is simply zero.
TBApiHidSetFeature
This API is used to issue an HID set feature request to a UPDD controlled device.
Definition
TBBOOL TBAPI TBApiHidSetFeature(
HTBDEVICE aDevice,
int aInterface,
const void* aReportBuffer,
uint32_t aReportBufferLength
);
Parameters
aDevice: the UPDD device handle representing the device instance to be queried.
aInterface: the interface number to be queried
aReportBuffer:
A block of memory allocated by the caller
When calling the API the caller sets up the HID feature report data to be sent to the device.
Typically this is simply the report id of the feature in byte zero followed by the feature data.
aReportBufferLength: The length of the allocated block.
Notes: In normal HID mode a programmer will use an open handle to an HID collection.
Using the UPDD API; use standard UPDD APIs to derive the device handle and consult with the hardware supplier and / or examine USB traffic in HID mode to derive the interface number. The interface number is defined in the USB report descriptors and as such is constant for a given device in most cases. In many cases this value is simply zero.
Identifying the device
Both calls take an HTBDEVICE handle identifying the UPDD device to address. Obtain it by walking UPDD's device list; there is no need for an OS-level device path:
HTBDEVICE device = TBApiGetRelativeDevice(0);
for (int i = 0; device != TB_INVALID_HANDLE_VALUE; )
{
TBBOOL connected = 0;
TBApiIsDeviceConnected(device, &connected);
// 'device' is the handle to pass to TBApiHidGetFeature / TBApiHidSetFeature
device = TBApiGetRelativeDevice(++i);
}
To identify which physical device each handle refers to, read its connection_key setting:
TBCHAR conn[256];
TBApiGetSetting(device, "connection_key", conn, sizeof(conn));
// e.g. usb:337641472::vid=0x2575;pid=0xc300
The format is <location>::<hardware id>. On macOS location is usb: followed by the IOKit LocationID in decimal, identifying the physical USB port. The hardware id carries the vid= and pid= UPDD bound to. The command upddutils connections lists the same information for every connected device.
Return values and errors
Both calls return TBBOOL — non-zero on success, zero on failure. Call TBApiGetLastError for the error text.
TBApiHidGetFeature additionally fails if the device's response is longer than aReportBufferLength. The driver applies a two second timeout to the transfer.
Test interface for these APIs.
The UPDD Command Line Interface has two options which can be used to test the use of these APIs with a device under test
These are intended for use by programmers familiar with making direct API calls and as such a detailed description of formulating an HID feature get / set request is not be given here.
HidGetFeature
Syntax
upddutils hidgetfeature <interface> <report_id> <length>
Example
In this example get feature report 0A is send to the device.
For this device feature 0x0a is the max count HID feature.
The report ID must be entered as a 2 character ASCII representation of the hex value.
The report length is 2 bytes.
The response indicates that feature 0x0a has a value of 0x0a.
HidSetFeature
Syntax
upddutils hidsetfeature <interface> <reportdata>
Example

In this example set feature report 05 is sent to the device with report data of 0x02,00
For this device feature 0x05 is the device mode feature
The data must be entered as a series 2 character ASCII representations of the hex values, with no spaces.
Example API program
A documented C++ example API program hidfeature can be downloaded here. This opens the driver, selects the device and calls TBApiHidGetFeature / TBApiHidSetFeature.