karalabe / hid Goto Github PK
View Code? Open in Web Editor NEWGopher Interface Devices (USB HID)
License: Other
Gopher Interface Devices (USB HID)
License: Other
Hi
Thank you for this amazing package.
Would you know if this library can be used together with gomobile bind
to access usb devices on android/ios?
I am trying it, it compiles fine, but I get zero results from the Enumerate(0,0)
call.
Thanks.
OS: Windows 10 Version 1709
For my device, hid_read is not working but hid_get_feature_report is. I can't figure out the reason but after wrapping hid_get_feature_report in your package. My program can read data from device. I am not a driver developer so I don't have much experience on how to debug this problem.
Write
on Windows reports one more byte written than asked for.
Internally, this is because a 0x00
byte is prepended to the data.
However:
I'm trying to build a Go program for my LinkSys MR8300 V1.1 router, which has armv7l
processor (uname -a
output), which is ARM v7, 32-bit CPU. I have OpenWrt operating system installed on the router.
The idea of the app is to connect USB coin acceptor, and enable internet for 30 minutes when you drop a coin. I have working app on the Ubuntu desktop which understands the device, and on desktop everything's fine.
However, the router is 32 bit, and ARM, so things are little bit different and more complicated.
cat /proc/cpuinfo
on my router gives something like this:
processor : 0
model name : ARMv7 Processor rev 5 (v7l)
BogoMIPS : 26.81
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc07
CPU revision : 5
I'm using cross-compilation, since the router has only 19MB of disk space (and not all of the development packages are available).
For cross-compilation I'm using x86_64 Ubuntu desktop, and toolchain provided by OpenWrt. I'm already past the point when you need to configure and make the toolchain. I was able to compile and execute the basic C programs on my router, like:
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
And even Go programs like:
package main
func main() {
println("Coin acceptor device control program")
}
When I upload binaries to the router they work, there is no any problem with that.
Problems start when I try to use USB library inside the router. Since it's cross-compilation, I should mention environment variables I have:
STAGING_DIR=/home/ro/work/openwrt/staging_dir
TOOLCHAIN_DIR=/home/ro/work/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-11.3.0_musl_eabi
LDCFLAGS=/home/ro/work/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-11.3.0_musl_eabi/usr/lib
LD_LIBRARY_PATH=/home/ro/work/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-11.3.0_musl_eabi/usr/lib
LDFLAGS=-L/home/ro/work/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-11.3.0_musl_eabi/usr/lib
CGO_LDFLAGS=-L/home/ro/work/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-11.3.0_musl_eabi/usr/lib
CFLAGS=-I/home/ro/work/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-11.3.0_musl_eabi/include
CC=arm-openwrt-linux-gcc
GOARCH=arm
CROSS_COMPILE=arm-openwrt-linux-gcc
CGO_ENABLED=1
GOOS=linux
GOARM=7
With these environment variables go get github.com/karalabe/hid
command works as expected (there is hid.a
binary in my /home/ro/go/pkg/linux_arm/github.com/karalabe
folder).
However, this library has dependencies on some C libraries... So here is where GOC comes into play I guess.
As I mentioned before, I can compile simple apps on my Desktop and upload them to the router, and these apps work! However, when I try to use the library, things go little bit off the script.
Here is the app I have:
main.go
package main
import (
"fmt"
)
func main() {
println("Hello")
devices := FindAll(0x0079)
if len(devices) == 0 {
fmt.Println("No coin acceptor found")
return
}
println("Found coin acceptor")
}
device.go
package main
import (
"errors"
"github.com/karalabe/hid"
)
type Device struct {
info hid.DeviceInfo
dev *hid.Device
Name string
PID uint16
}
func (device *Device) Open() error {
if device.dev != nil {
return errors.New("device: Device handle is not null, but Open() called")
}
var err error
device.dev, err = device.info.Open()
return err
}
func (device *Device) Close() error {
if device.dev == nil {
return errors.New("device: Close() called for Device with null handle")
}
err := device.dev.Close()
device.dev = nil
return err
}
// Find all products with the given product ID.
func FindAll(product uint16) []Device {
deviceInfo := hid.Enumerate(0x1e7d, product)
if len(deviceInfo) == 0 {
return []Device{}
}
devices := make([]Device, len(deviceInfo))
for i, info := range deviceInfo {
devices[i] = Device{
info: info,
Name: info.Product,
PID: product,
}
}
return devices
}
Command I use to build a thing:
go build ./main.go ./device.go
The binary gets produced, and things look normal. Until the point when I upload and run the binary on the router. It pretty much says:
Error relocating ./main: __pthread_cond_timedwait_time64: symbol not found
Error relocating ./main: __nanosleep_time64: symbol not found
Error relocating ./main: __stat_time64: symbol not found
Error relocating ./main: __clock_gettime64: symbol not found
And that's it. It doesn't even print "Hello".
One thing to notice is that it has references to (and complains about) 64-bit functions for some reason. So, to sum this up:
I'm wondering what am I missing? What flags should I specify to the compiler(s) so there is no 64-bit functions usage? Maybe there is something inside these USB libraries written in C? I kinda ran out of any ideas and pretty much stuck at this point, since I cannot use my USB device with embedded OpenWrt device.
$ go get github.com/dh1tw/streamdeck
# github.com/karalabe/hid
In file included from ..\..\karalabe\hid\hid_enabled.go:40:
..\..\karalabe\hid/hidapi/windows/hid.c: In function 'hid_enumerate':
..\..\karalabe\hid/hidapi/windows/hid.c:431:5: warning: 'strncpy' specified bound depends on the length of the source argument [-Wstringop-overflow=]
strncpy(cur_dev->path, str, len+1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
..\..\karalabe\hid/hidapi/windows/hid.c:429:11: note: length computed here
len = strlen(str);
^~~~~~~~~~~
Mingw64 version:
$ choco info mingw
Chocolatey v0.10.8
mingw 8.1.0 [Approved] Downloads cached for licensed users
Title: MinGW-w64 | Published: 30/10/2018
Package approved by gep13 on Jun 30 2019 14:22:35.
Package testing status: Passing on Oct 30 2018 18:40:10.
Number of Downloads: 154896 | Downloads for this version: 24259
Package url
Chocolatey Package Source: n/a
Package Checksum: 'ObzK15CYC2pW0gGFTFYMQWPSEYV8ono//ozdORZ23GBNY6XHUBFB5EN6gJl3gABZqD8ltzG8zdlGiEvaJ7zjLQ==' (SHA512)
Tags: compiler gcc mingw mingw-w64
Software Site: https://mingw-w64.org/
Software License: n/a
Summary: GCC for Windows 64 & 32 bits.
Description: Mingw-w64 is an advancement of the original mingw.org project, created to support the GCC compiler on Windows systems. It has forked it in 2007 in order
to provide support for 64 bits and new APIs. It has since then gained widespread use and distribution.
this a simple demo code:
package main
import (
"fmt"
"time"
"github.com/karalabe/hid"
)
func main() {
vid, pid := uint16(0x16C0), uint16(0x05DF)
devices := hid.Enumerate(vid, pid)
if len(devices) == 0 {
fmt.Println("未找到设备")
return
}
device, err := devices[0].Open()
if err != nil {
fmt.Println("无法打开设备:", err)
return
}
defer device.Close()
channel := byte(1)
state := byte(1)
buf := []byte{0x00, 0x00, 0xFF, channel, state}
_, err = device.Write(buf)
if err != nil {
fmt.Println("无法写入数据:", err)
return
}
time.Sleep(1 * time.Second)
}
linux cross compile for window:
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 GOARM= go build -ldflags "-s -w" -o build/relay cmd/relay/main.go
runtime/cgo
gcc: error: unrecognized command line option ‘-mthreads’; did you mean ‘-pthread’?
make: *** [Makefile:10: relay] Error 1
windows cross compile for window:
C:\Users\lau\code\demo>mingw32-make.exe
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 GOARM= go build -ldflags "-s -w" -o build/relay cmd/relay/main.gogithub.com/karalabe/hid
In file included from ........\go\pkg\mod\github.com\karalabe\[email protected]\hid_enabled.go:40:
........\go\pkg\mod\github.com\karalabe\[email protected]/hidapi/windows/hid.c: In function 'hid_enumerate':
........\go\pkg\mod\github.com\karalabe\[email protected]/hidapi/windows/hid.c:431:5: warning: 'strncpy' specified bound depends on the length of the source argument [-Wstringop-overflow=]
strncpy(cur_dev->path, str, len+1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
........\go\pkg\mod\github.com\karalabe\[email protected]/hidapi/windows/hid.c:429:11: note: length computed here
len = strlen(str);
^~~~~~~~~~~
How to resolve ? think you
your LICENSE.md
and README.md
files state that libusb is under GPL 2.1, which is wrong. the COPYING
file states
GNU LESSER GENERAL PUBLIC LICENSE
# github.com/zondax/hid
../../../../pkg/mod/github.com/zondax/[email protected]/hid_enabled.go:22:11: fatal error: sys/poll.h: No such file or directory
#include <sys/poll.h>
^~~~~~~~~~~~
compilation terminated.
Makefile:94: recipe for target 'install' failed
Ubuntu 18.04.1, x64 hardware, and go version go1.12.4 linux/amd64
. While trying to make tools install
https://github.com/cosmos/cosmos-sdk
I'm playing around with an elgato streamdeck on windows and I had to remove the report ID to get it to work. Not sure if an underlying library is acting differently or what.
https://github.com/karalabe/hid/blob/master/hid_enabled.go#L168
Hello,
When go-getting this module, it will by default download the latest tagged version (v1.0.0
, 2019) which seems not to work on some platforms (tested on macOS 14.2.1, arm64), but works when getting the latest commit.
Could a newer version tag be created so the module works without having to point to a specific commit?
Thanks a lot! :)
Hello! I'm using hid
in an upcoming project, and noticed that Device.Close
has no return value. Since almost all Close
functions in Go return an error, would it be acceptable to add an error return value to this method as well?
This would enable *hid.Device
to easily implement io.Closer
and io.ReadWriteCloser
, and ensure that if any error return value is needed in the future, it can be easily adjusted.
Let me know what you think, and thank you for this package.
$ go build
In file included from .\hid_enabled.go:40:
./hidapi/windows/hid.c: In function 'hid_enumerate':
./hidapi/windows/hid.c:431:5: warning: 'strncpy' specified bound depends on the length of the source argument [-Wstringop-overflow=]
strncpy(cur_dev->path, str, len+1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./hidapi/windows/hid.c:429:11: note: length computed here
len = strlen(str);
^~~~~~~~~~~
# github.com/karalabe/hid
vendor/github.com/karalabe/hid/hid_enabled.go:23:11: fatal error: os/threads_posix.c: No such file or directory
#include "os/threads_posix.c"
^~~~~~~~~~~~~~~~~~~~
Have been getting this on ubuntu18. CGO_ENABLED=1. libusb 1.0.0 + libusb1.0.0-dev installed.
Wondering what I'm missing
Is there any other way to send bin file content? Please help me, thanks.
C:\Users\Frank>go install github.com/karalabe/hid
d:\go\src\github.com\karalabe\hid\hid_enabled.go:133:10: could not determine kind of name for C.hid_device
d:\go\src\github.com\karalabe\hid\hid_enabled.go:174:61: could not determine kind of name for C.size_t
d:\go\src\github.com\karalabe\hid\hid_enabled.go:174:39: could not determine kind of name for C.uchar
d:\go\src\github.com\karalabe\hid\hid_enabled.go:82:26: could not determine kind of name for C.ushort
`
C:\Users\Frank>go get github.com/karalabe/hid
d:\go\src\github.com\karalabe\hid\hid_enabled.go:133:10: could not determine kind of name for C.hid_device
d:\go\src\github.com\karalabe\hid\hid_enabled.go:174:61: could not determine kind of name for C.size_t
d:\go\src\github.com\karalabe\hid\hid_enabled.go:174:39: could not determine kind of name for C.uchar
d:\go\src\github.com\karalabe\hid\hid_enabled.go:82:26: could not determine kind of name for C.ushort
I'm trying to change the LED on my keyboard.
This is the snippet: https://pastebin.com/Xzr1X9P5
When I try to write more than 8btyes, I get an error: hidapi: unknown failure
I don't really know how to debug this.
I didn't really find any examples online, and I'm quite new to this stuff.
Any help is appreciated!
When running go tests or vet, warnings pop up similar to those described here: karalabe/usb#25
# github.com/karalabe/hid
In file included from vendor/github.com/karalabe/hid/hid_enabled.go:38:
vendor/github.com/karalabe/hid/hidapi/mac/hid.c:693:34: warning: 'kIOMasterPortDefault' is deprecated: first deprecated in macOS 12.0 [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/IOKit.framework/Headers/IOKitLib.h:123:19: note: 'kIOMasterPortDefault' has been explicitly marked deprecated here
Thanks for this nice golang package. I use it to connect to a second usb keyboard. I receive the bytes from the connected keyboard representing the scancodes. (like 4 for "a").
Do u know an easy way to map/convert the incoming scancodes to runes or characters to receive a string in the end (even using the current operating system keyboard layout). I have a loop reading all inputs only from the second keyboard, which works fine, until enter is pressed. But now i have only the "scancodes" but need to get an ascii string.
Thanks in advance.
Just asking - why does this use libusb instead of hidraw backend? Hidraw seems like less of a hassle (no need to package all libusb), but I have not tried it.
Hi,
I am trying to use go-streamdeck, which internal uses karalabe/hid.
Its a library to control the elgato Stream Deck.
It works under linux, but fails under windows with:
panic: hidapi: Falscher Parameter.
Which is german for "wrong Parameter".
Without known much about USB, and HID: At one point tried the following:
I removed the windows specificas in these lines:
if runtime.GOOS == "windows" {
report = append([]byte{0x00}, b...)
} else {
report = b
}
with
report = b
At these lines: https://github.com/karalabe/hid/blob/master/hid_enabled.go#L167
Now it works!
I have no Idea why.
Should this be fixed? Or is my device strange?
What would be a good way to write a patch so I can used the unmodifed HID library?
Hello,
this is not an issue, just a thanks/letting you know that we will use this library (and xgo library) in trezord, which we are now rewriting from c++ to go. (it seems you are working on geth, so you know what is trezor :D)
See
(if you are interested - we need both libusb directly and hidapi, because we will switch from hidapi to webusb soon-ish and we want to support both)
There doesn't seem to be a sensible way to do a read that doesn't then block forever (and lock!)
Hi. I am building the latest release of geth which depends on hid. Unfortunately, I have the topic error, more of it below. Probably, it is a build environment problem (I'm using NixOS linux distro which is quite unusual).
My go is version 1.7.1.
Could you please suggest a hint regarding the error?
# github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:44:8: error: enumerator value for '__cgo_enum__0' is not an integer constant
return stringToWchar4(s) // Unix
^
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:52:8: error: enumerator value for '__cgo_enum__7' is not an integer constant
case 2:
^
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:60:2: error: initializer element is not constant
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:60:2: note: (near initialization for '__cgodebug_data[0]')
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:67:2: error: initializer element is not constant
default:
^
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:67:2: note: (near initialization for '__cgodebug_data[7]')
github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid
# github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:44:8: error: enumerator value for '__cgo_enum__0' is not an integer constant
return stringToWchar4(s) // Unix
^
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:52:8: error: enumerator value for '__cgo_enum__7' is not an integer constant
case 2:
^
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:60:2: error: initializer element is not constant
go/src/github.com/ethereum/go-ethereum/vendor/github.com/karalabe/hid/wchar.go:60:2: note: (near initialization for '__cgodebug_data[0]')
I tried with this minimal test program:
package main
import (
"fmt"
"github.com/karalabe/hid"
)
func main() {
// Ledger Nano S Vendor ID and Product ID
vendorID := uint16(0x2c97)
productID := uint16(0x1015)
// Enumerate devices to find the Ledger
devices := hid.Enumerate(vendorID, productID)
if len(devices) == 0 {
fmt.Println("No Ledger Nano S found.")
return
}
// Open the first found Ledger device
device, err := devices[0].Open()
if err != nil {
fmt.Printf("Failed to open device: %v\n", err)
return
}
defer device.Close()
fmt.Println("Device successfully opened.")
}
Output:
Failed to open device: hidapi: failed to open device
While it is possible to open/connect using homebrew's hidapi like this:
package main
/*
#cgo CFLAGS: -I/opt/homebrew/Cellar/hidapi/0.14.0/include/hidapi
#cgo LDFLAGS: -L/opt/homebrew/Cellar/hidapi/0.14.0/lib -lhidapi
#include <hidapi.h>
*/
import "C"
import (
"fmt"
)
func main() {
// Initialize the HIDAPI library
res := C.hid_init()
if res != 0 {
fmt.Println("Failed to initialize HIDAPI")
return
}
defer C.hid_exit()
// Open the device using Vendor ID and Product ID
vendorID := C.ushort(0x2c97)
productID := C.ushort(0x1015)
device := C.hid_open(vendorID, productID, nil)
if device == nil {
fmt.Println("Failed to open device")
return
}
defer C.hid_close(device)
// Your HID interaction code here
fmt.Println("Device opened successfully")
}
Output:
Device opened successfully
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.