Initial NetBSD/UHID native backend implementation #612
No reviewers
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi!612
Loading…
Reference in a new issue
No description provided.
Delete branch "netbsd"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This is the culmination of the research I did for
uhidon NetBSD. It should be as complete as a native backend can be given the limitations of NetBSD's kernel anduhidas a whole. See related issue, #608.@ -42,6 +42,9 @@ elseif(NOT WIN32)option(HIDAPI_WITH_HIDRAW "Build HIDRAW-based implementation of HIDAPI" ON)option(HIDAPI_WITH_LIBUSB "Build LIBUSB-based implementation of HIDAPI" ON)endif()if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")Just to double-check: is
uhidbackend specific to NetBSD or is it available on other BSD systems?@ -42,6 +42,9 @@ elseif(NOT WIN32)option(HIDAPI_WITH_HIDRAW "Build HIDRAW-based implementation of HIDAPI" ON)option(HIDAPI_WITH_LIBUSB "Build LIBUSB-based implementation of HIDAPI" ON)endif()if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")Technically it is available to other BSD systems since it has existed since sometime in 1990. But they have diverged heavily over the years so they are all at varying levels of compatibility not to mention differences in internal kernel behavior. The compatible subset I found is extremely limited and would not make for a very useful generic approach. I thought it best to combine
uhidwith platform specific support code to help workaround its limitations. NetBSD probably has the most advanceduhidimplementation in terms of overall features.@ -42,6 +42,9 @@ elseif(NOT WIN32)option(HIDAPI_WITH_HIDRAW "Build HIDRAW-based implementation of HIDAPI" ON)option(HIDAPI_WITH_LIBUSB "Build LIBUSB-based implementation of HIDAPI" ON)endif()if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")Thanks, this is helpfull.
I agree, better keep it for NetBSD only.
Minor code cleanup. I noticed some improvements I could make when reusing some of the code for another project of mine.
Nice, the first simple test seems to work fine. I need to modify hidapitester to test this more.
I am using NetBSD 9.3 VM running under Proxmox and I attach a generic HID device to the VM.
Feel free to refine it further but I have reached the limit of what I can see to do. I am considering writing a FreeBSD backend after NetBSD has been merged. It is probably the last native BSD backend that has enough kernel API functionality to work with the current library abstraction. I may end up creating two versions for FreeBSD due to it having the option of using a
hidrawcompatibility layer as well as the olderuhidone.That would be wonderful. I tend to think the 1hidraw` backend is the way to go for FreeBSD.
Preliminary investigation suggests this has its own problems due to how new this backend is. It isn't enabled by default on fresh installations. Of the two,
uhidandhidraw, only one can be attached to any particular device.uhidis the default ifhw.usb.usbhid.enableis set to 0.hidrawcan only be used ifhw.usb.usbhid.enableis set to 1 and thehidrawmodule is loaded explicitly. Ifhw.usb.usbhid.enableis set to 1 buthidrawis not available, there won't be anything setup to provide userspace HID access.Any solution would probably have to be prepared to use whichever API the FreeBSD environment is configured to use as I don't think it would be a good practice to forcefully enable
hidrawagainst the wishes of the end user.I agree. I'd say that even if we will get the
hidrawbackend implementation for FreeBSD - that is absolutely fine that it will be functional only if user explicitly enables thehidrawsubsystem/driver in his environmnet on his own.Thanks for the analysis.
However, for the FreeBSD OS, there is already a libusb backend which will be the default as it already works fine (other than common libusb issues: https://github.com/libusb/hidapi/issues?q=is%3Aopen+is%3Aissue+label%3Alibusb). So libusb backend will be the preferred backend in the foreseeable future.
I believe ugen driver is also attached to generic USB HID device along with uhid (or hidraw). That is why it works.
I see this as similar to Linux side last time -- libusb was the preferred and hidraw was secondary as there was too many limitations previously. Now hidraw is the preferred.
But of course you can develop uhid backend first as it is more common for now. However, I tend to believe hidraw may be the future for FreeBSD as well (and maybe NetBSD/OpenBSD).
@Youw
This PR does not support the existing auto-tools build system. Do we want to keep the auto-tools support?
I left it out because I found comments saying that it was deprecated so I assumed it was going to be removed in the near future.
No.
This is exactly why.
BTW: I've reviewed all CMake changes - very consistent with what we already have. Very nice, thanks.
Overall very consistent implementation.
I didn't check all of the implementation/logic (specially what consernes the
uhidAPI/usage) but overall looks very good.Just a few comments/improvements to consider.
@ -0,0 +1,1173 @@/*******************************************************this is just me being pedantic:
in all other backends the
device_handleis the very first member in astructlets have it as a first here too
I've just merged additional change to linux/hidraw to master that changes this function
lets update here as well
this is probably a copy-paste (or not), but since technically we're writing this from scratch - I'd prefer reading such conditionas as:
generally speaking, having a negation (
!) automatically triggers human brain to look for a failed call (even if often not the case in unix world)lets have a (global) named constant/define for 256 (
HIDAPI_MAX_SUPPORTED_DEVICES)?how about:
is this
256is same as above or not?(use same or different named constant accordingly)
can you confirm this is required for this backend and not just a copy-paste?
I'm seeing
16and32magic numbers often - lets have a named constant for that tooin all places
@ -0,0 +3,4 @@communication with HID devices.James Burenlibusb/hidapi Team@braewoods add your name here as well - you made it happen
@ -0,0 +772,4 @@hid_free_enumeration(devs);if (*path == '\0') {register_global_error("Device with requested VID/PID/(SerialNumber) not found");NOTE: global error never clears
if the previous call has failed, and the next one didn't - the global error still going to point to the previous failure
@ -0,0 +779,4 @@return hid_open_path(path);}HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)global error not cleared
@ -0,0 +826,4 @@strlcpy(devpath, "/dev/", sizeof(devpath));strlcat(devpath, child_dev, sizeof(devpath));uhid = open(devpath, O_RDWR | O_CLOEXEC);so we always open all report handles
lets havea a
README.mdundernetbsd/and describe important details like thatRe-based on latest
masterbranch.@ -0,0 +1,1173 @@/*******************************************************As you wish. This is just the result of me trying to order struct fields in terms of size to reduce the need for compiler added padding for data alignment.
@ -0,0 +1,1173 @@/*******************************************************These are tied to an implementation defined size. I'll find a suitable macro they already defined to use.
@ -0,0 +1,1173 @@/*******************************************************It is written this way for a reason. If the caller doesn't provide enough space, NetBSD instead says how much it would have used. There's nothing to iterate over if this happens. The array would be full of garbage data.
@ -0,0 +1,1173 @@/*******************************************************The reason it exists is to be a failsafe if my assumptions somehow end up being wrong on some NetBSD system that has a very large number of child devices on a given parent device.
@ -0,0 +1,1173 @@/*******************************************************I can do this. But seeing as this is related to the other comment, what do you prefer? I was using stack-based fixed size allocations to not have to deal with dynamic memory within a recursive function. This is faster overall than the other approach I could use to retrieve the size before doing the actual data request. I figured that it is very unlikely that any given device node will have more than 256 child devices. This really is about how many child nodes you can expect to encounter in any given parent node in the NetBSD device tree.
@ -0,0 +1,1173 @@/*******************************************************It is identical to the others. I am reusing the device tree walker function because the system call approach is the same, it just starts with a specific parent device instead of the empty string (which is the root of the device tree here).
@ -0,0 +772,4 @@hid_free_enumeration(devs);if (*path == '\0') {register_global_error("Device with requested VID/PID/(SerialNumber) not found");Resolved by clearing global error before
hid_open_pathreturns success. All other exit points set a new error.@ -0,0 +779,4 @@return hid_open_path(path);}HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)Resolved by clearing global error before
hid_open_pathreturns success. All other exit points set a new error.@ -0,0 +1,1173 @@/*******************************************************Apparently it isn't. I kept it originally because I was assuming it was required for the multi-byte functions to work correctly on utf8 input like it is with
glibc.Ok. That should handle the requested changes. Anything else?
@ -0,0 +1,1173 @@/*******************************************************I'm perfectly fine with pre-allocated stack memory
my only point is to have a single name/definition for the magic number
thanks
@ -0,0 +1,1173 @@/*******************************************************then lets have an explicit comment about that
I might not be the only one who may thing about an "optimisation" like that
just one last comment
There. That comment should cover it.