ms-tools/gohid/gohid_linux.go
2021-09-07 15:15:52 +02:00

90 lines
1.4 KiB
Go

// +build linux
package gohid
import (
"errors"
"fmt"
"os"
"runtime"
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
type HIDRaw struct {
dev *os.File
}
func openHIDInternal(path string) (HIDDevice, error) {
dev, err := os.Open(path)
if err != nil {
return nil, err
}
return &HIDRaw{
dev: dev,
}, nil
}
var ErrorTooLong = errors.New("Transfer is too long")
/*
HIDIOCSFEATURE(0) = C0004806
HIDIOCSFEATURE(9) = C0094806
HIDIOCGFEATURE(0) = C0004807
HIDIOCGFEATURE(9) = C0094807
*/
func (h *HIDRaw) SendFeatureReport(b []byte) (int, error) {
var tmp [1024]byte
if len(b) > len(tmp) {
return 0, ErrorTooLong
}
copy(tmp[:], b)
_, _, errno := unix.Syscall(
syscall.SYS_IOCTL,
uintptr(h.dev.Fd()),
uintptr(uint32(0xC0004806)|uint32(len(b)<<16)),
uintptr(unsafe.Pointer(&tmp)),
)
runtime.KeepAlive(tmp)
if errno != 0 {
return 0, os.NewSyscallError("SendFeatureReport", fmt.Errorf("%d", int(errno)))
}
return len(b), nil
}
func (h *HIDRaw) GetFeatureReport(b []byte) (int, error) {
var tmp [256]byte
if len(b) > len(tmp) {
return 0, ErrorTooLong
}
_, _, errno := unix.Syscall(
syscall.SYS_IOCTL,
uintptr(h.dev.Fd()),
uintptr(uint32(0xC0004807)|uint32(len(b)<<16)),
uintptr(unsafe.Pointer(&tmp)),
)
if errno != 0 {
return 0, os.NewSyscallError("GetFeatureReport", fmt.Errorf("%d", int(errno)))
}
copy(b, tmp[:])
return len(b), nil
}
func (h *HIDRaw) Close() error {
return h.dev.Close()
}