Releases: nemarpuc/libaoahid
Release list
v4.0.1
libaoahid 4.0.1
No library code changed. Hardware-verified on a Samsung Galaxy Tab S11 and a
POCO F6 Pro (Windows 10 x64 and Arch Linux): the profiles and paths marked
Verified in docs/TARGET_MATRIX.md; every other row is still unverified.
Documentation
- README: a Demo section with a video of aoahid_player, an app built on this
library. docs/TARGET_MATRIX.md: rows 1, 2, 3 and 6 of the accessory mode and Bulk
Channel table are verified on hardware (Samsung Galaxy Tab S11 and POCO F6
Pro, on Windows 10 x64 and Arch Linux).docs/TARGET_MATRIX.md: Keyboard, Mouse, Consumer Toggle, all three
Gamepad D-pad forms, and fixed-MT Touchscreen took effect on the same
hardware (Application API column).docs/PORTING.md: the Samsung-on-Windows driver note is a hardware
observation, not a user report.
v4.0.0
libaoahid 4.0.0
Changed (breaking)
aoahid_device_opensends no AOA request. It no longer sends request 51 to
re-check the version, so it no longer returnsAOAHID_ERR_NOT_AOAor a
version error. A device without AOA 2.0 HID opens and then fails at
aoahid_node_openwithAOAHID_ERR_STALL.- The library applies no AOA version policy.
aoahid_discoverstill sends
request 51 to each device and lists those with a nonzero version; the new
aoahid_device_info.protocol_versionreports that version, and the caller
decides what to open. A caller that fillsaoahid_device_infoitself sends
no request 51 at all, which also avoids Android's accessory-handshake
broadcast (SOURCE_CONFLICTS.mdT-12). aoahid_device_infogainsprotocol_version. It fits in existing padding,
so the size and the offsets ofserialandproductare unchanged.aoahid_device_optionsdrops every member that did nothing:
startup_mode,accept_future_protocol_versions,
reenumeration_timeout_ms,first_report_attempts,
first_report_backoff_us,accessory_strings, and
enable_deprecated_audio_mode.validate_reportsmoves to the end so the
structure has no interior padding. Rebuild every caller against this header.- Removed:
aoahid_device_protocol_version(),aoahid_startup_mode,
AOAHID_START_CURRENT_USB_MODE,AOAHID_START_ACCESSORY_MODE, and
AOAHID_ERR_VERSION(code 5 is now unassigned; no other code changes). Use
aoahid_accessory_startto switch a device to accessory mode. - The shared library is
libaoahid.so.4with theAOAHID_4.0symbol node. - The Python, C#, and Rust bindings follow the new layouts and drop the
removed names. The C#, Python, Rust, and C examples print each device's AOA
version and refuse a version below 2 themselves.
Documentation
- The guide, API, design, and example documents describe probe-free open and
caller-side version checks, and no longer describe ABI placeholders. The
guide's first-report policy now matches the library, which has never retried
since 2.0.0.
Verification status
Fake-backend tests only (the dev, TSan, and ASan/UBSan configurations).
Nothing is hardware-verified.
v3.0.5
libaoahid 3.0.5
Changed
- Reports are serialized a byte at a time instead of a bit at a time, about
2.9 times faster for a 16-contact touchscreen report (766 ns to 267 ns on
one x86-64 machine). The bytes on the wire are unchanged; the new encoder
was checked against the old one over 2,000,000 random fields. - Internal cleanups with no behavior change: unused parameters, a duplicated
protocol-version check, and setup-packet fields rewritten on every submit
although acquiring the transfer slot had already written them.
Fixed
examples/c/verify: a failure could print "no field" and "no reason"
instead of the failing call's diagnostic, becauseaoahid_result_name()
clears the last-error record and C leaves argument evaluation order
unspecified. The record is now read first.- On Linux, the shared library now relinks when
cmake/aoahid.mapchanges,
as the Apple build already did for its export list. - The integration tests compile with Clang 22: the replacement
operator deleteoverloads intests/integration/test_transport.cppno
longer take top-levelconstparameters.
Documentation
- README: the ADB section no longer suggests
adb connect localhost:5555, a
port the adb server scans for emulators, and describes how
aoahid_adb_proxy works (a Channel on the application's own USB handle). - QUICKSTART:
AOAHID_USE_FAKE_LIBUSBisOFFunless a test configuration
turns it on, andaoahid_verify_allis listed with the other verify
programs.examples/README.mdliststouchpad.c.
Verification status
Fake-backend tests only (the dev, TSan, and ASan/UBSan configurations, and a
Clang build). Nothing is hardware-verified.
v3.0.4
libaoahid 3.0.4
Changed
- The repository is renamed from
nemarpuc/Libaoa_hidto
nemarpuc/libaoahid, matching the library (libaoahid), header
(aoahid.h), and CMake package (aoahid) names. Package metadata, release
validation (AOAHID_EXPECTED_REPOSITORY), and documentation links use the
new name. GitHub redirects the old URLs; the Pages URL is now
https://nemarpuc.github.io/libaoahid/. The library is unchanged. - 3.0.3 was tagged, but its release did not publish because the repository
was renamed while the release job ran. 3.0.4 contains all of 3.0.3.
Verification status
No library code changed. Nothing is hardware-verified.
v3.0.2
libaoahid 3.0.2
Fixed
- On Windows, a Channel on the interface that libusb's WinUSB backend
auto-claims for control transfers (typically ADB) could lose its claim when
a HID report transfer in flight duringaoahid_channel_opencompleted.
aoahid_channel_opennow waits, within the Device'sclose_drain_timeout_ms,
until no report transfer is in flight before it claims the interface, and
returnsAOAHID_ERR_TIMEOUTif one still is.aoahid_channel_closewaits
the same way (best effort) before releasing it. SeeFACT_AUDIT.mdA-25.
Verification status
Fake-backend tests only. Nothing is hardware-verified.
v3.0.1
libaoahid 3.0.1
Packaging
- Linux archives record how the bundled libusb was built from the bundled
source (libusb_buildinshare/doc/libaoahid/build-metadata.json), and
THIRD_PARTY_NOTICES.mdpoints to it. The library itself is unchanged.
Verification status
No library code changed. Nothing is hardware-verified.
v3.0.0
libaoahid 3.0.0
Added
aoahid_channel_options.read_modeandaoahid_channel_read_mode.
AOAHID_CHANNEL_READ_STREAM(zero) keeps the read-ahead byte stream.
AOAHID_CHANNEL_READ_REQUESTsubmits no read-ahead. Instead, a read with
nothing buffered submits one IN transfer of its capacity, rounded up to
wMaxPacketSizeand capped attransfer_bytes, the way host adb reads a
length-prefixed payload. A request completes as soon as it is full, so a
packet-aligned message with no zero-length packet no longer waits for more
data. A timeout leaves the request pending for the next read, so no byte is
lost.- The Python, C#, and Rust bindings expose the new field and constants.
Changed (breaking)
aoahid_channel_optionsgrows by one 32-bit field, so itsstruct_size
changes. Rebuild every caller against this header. Zero keeps the 2.x
behavior.
Documentation
docs/API.mdexplains when a stream-mode read waits (a Bulk IN transfer
completes only when full or on a short packet), with AOSP adb references.
Verification status
Verified with fake-libusb tests (request sizing, pending timeout, buffered
remainder, zero-length packet, unplug), plus ASan/UBSan and ThreadSanitizer.
Nothing is hardware-verified.
v2.0.1
libaoahid 2.0.1
Removed
docs/ARCHITECTURE_USB_HUB.md, which still described a rejected automatic
design and an unimplemented ADB-server plan.docs/API.mdnow cites the
Android 10-second accessory-request timeout directly from AOSP
UsbDeviceManager.java.- An unused internal Channel query and two fake-libusb test helpers left over
from that rejected design. No public function, structure, value, or behavior
changes; the ABI is identical to 2.0.0.
Verification status
Documentation and dead-code removal only. Nothing is hardware-verified; the
accessory-mode and Channel hypotheses in docs/TARGET_MATRIX.md remain
[unverified on hardware], and every profile remains not hardware-verified.
v2.0.0
libaoahid 2.0.0
Changed (breaking)
- The library never retries a transfer. The first report after
aoahid_node_openused to be resent automatically after a STALL (default 20
attempts, 1 ms apart); it is now sent once andAOAHID_ERR_STALLis returned.
A STALL means the target refused request 57 (f_accessorystalls while the
HID ID is not yet registered), so the refused state now stays pending and the
caller's next submit resends it; timeouts, cancellations, and I/O errors still
consume the submitted state because delivery is unknown.
first_report_attemptsandfirst_report_backoff_usstay in
aoahid_device_optionsfor layout compatibility and are ignored.
examples/c/verify/verify_common.hshows a bounded caller-side resend. - SOVERSION 2 (
libaoahid.so.2) with the ELF symbol-version node
AOAHID_2.0, because the change above alters documented behavior.
Added
aoahid_accessory_startwithaoahid_accessory_options: sends AOA requests
51, 52 (the caller'saoahid_aoa_strings; a nonempty manufacturer and model
are required, each at most 256 bytes including its NUL as AOA 1.0 specifies,
checked before any request), and 53 to a device in its current USB mode, then
closes it and returns. It never waits for re-enumeration and never retries. The
application rediscovers the accessory-mode device (VID0x18D1, PID
0x2D00-0x2D05) and opens it with the unchangedaoahid_device_open. A
device already in accessory mode receives no request. There is no call that
leaves accessory mode.- Bulk Channels on a Device:
aoahid_channel_open,aoahid_channel_read,
aoahid_channel_write,aoahid_channel_close, andaoahid_channel_options.
A Channel selects configuration 1 only on an unconfigured device (AOA 1.0),
claims the first interface with the requested class triple (for example ADB
0xFF/0x42/0x01) on the Device's own USB handle, keeps IN
transfers submitted ahead of the reader, uses a transfer pool separate from
HID, reads as a byte stream, back-pressures writes, and can end a write with
an explicit zero-length packet that behaves the same on every backend. Read
and write take no lock and allocate nothing. Channels follow the Node close
rules, andaoahid_device_closealso closes them. examples/c/verify/verify_accessory.c: switches the first phone to
accessory mode, types one letter, and opens an ADB Channel when USB debugging
is on.- C, Python, C#, and Rust declarations for every new function and structure.
Changed
- Every USB handle is owned by one internal Port shared by the Device and its
Channels.aoahid_discoverprobes a device that an open Device already holds
through that handle instead of opening it a second time (WinUSB refuses a
second open).aoahid_accessory_startlikewise borrows an open Device's
handle. docs/API.mdnow describes theaoahid_togglerelease rule introduced in
1.0.0 (usagemust be0or the pressed Usage).udev/51-aoahid.rulescomments describe the accessory-mode VID/PID range
thataoahid_accessory_startproduces; the rules themselves are unchanged.
Verification status
The new accessory start and Bulk Channels are tested only against the
deterministic fake libusb backend (including ThreadSanitizer runs and an
allocation probe of Channel read/write). None of it is hardware-verified: the
ten accessory-mode and Channel hypotheses in docs/TARGET_MATRIX.md,
including re-enumeration, HID in accessory mode, ADB next to HID on one handle
on Linux and Windows, and the first-report STALL behavior without library
retry, are recorded as [unverified on hardware]. No profile's status in
TARGET_MATRIX.md changes: every profile remains not hardware-verified.
v1.0.0
libaoahid 1.0.0
Added
examples/c/verify/verify_toggle.candverify_battery.c, joining
verify_keyboard/verify_touch/verify_mouse/verify_allas
human-observable real-device verification programs (see
docs/QUICKSTART.md).verify_togglefires four Consumer Control Usages
in turn (Play/Pause, Volume Increment, Mute, "AC New") for a media app to
react to, deliberately excluding System Control Usages that could suspend
or power off the phone mid-test.verify_batterysends a low/mid/high
Battery Strength sequence and the explicit unknown (Null) state; unlike
every other program here it produces nogeteventoutput by design, so
confirming it means checkingadb shell dumpsys batteryand
/sys/class/power_supplyinstead.
Fixed
aoahid_toggle(node, usage, 0)(release) silently ignoredusage
entirely, always releasing whichever Usage was currently pressed
regardless of what was passed. A caller that lost track of which Usage it
had pressed could release the wrong one -- or release nothing, if nothing
was pressed -- with no indication anything was wrong.usageon release
must now be either0(release whichever Usage is pressed, for a caller
that never tracked it -- the prior behavior, kept as an explicit opt-in)
or the Usage actually pressed; a different nonzero Usage is rejected with
AOAHID_ERR_PARAMinstead of silently doing the wrong thing.examples/c/verify/verify_toggle.cdid not set
aoahid_toggle_options.expected_linux_event_types/expected_linux_codes,
two of the four required parallel arrays (seeexamples/c/profiles/toggle.c
for the reference shape), soaoahid_spec_create_togglealways failed with
AOAHID_ERR_UNSET_FIELDand the program could never run.
Verification status
verify_toggle and verify_battery were each run once against one physical
Samsung Android target after the fixes above, confirming both now run to
completion without error; verify_toggle's Play/Pause, Volume Increment, and
Mute were also each observed changing that target's foreground media app.
This falls well short of TARGET_MATRIX.md's "Minimum per-profile cases" for
either profile (every allowed Usage under foreground/background/screen-off,
zero re-arm, and -- for Battery -- the declared minimum/midpoint/maximum plus
power_supply/application-API association), so this release changes no
profile's status in TARGET_MATRIX.md: Toggle and Battery Strength remain
not hardware-verified, same as every other profile. The usage-on-release
fix and both new example programs touch neither the wire format nor the
generated descriptor of any profile.