Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
4799b5ab
Unverified
Commit
4799b5ab
authored
May 16, 2019
by
Guillaume Ballet
Committed by
Péter Szilágyi
Jun 03, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
accounts/usbwallet: support webusb for Trezor wallets
parent
7a22da98
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
443 additions
and
34 deletions
+443
-34
hub.go
accounts/usbwallet/hub.go
+19
-3
trezor.go
accounts/usbwallet/trezor.go
+2
-0
wallet.go
accounts/usbwallet/wallet.go
+1
-1
config.go
node/config.go
+6
-0
api.go
signer/core/api.go
+7
-0
generic.go
vendor/github.com/karalabe/hid/generic.go
+54
-0
hid.go
vendor/github.com/karalabe/hid/hid.go
+17
-2
hid_disabled.go
vendor/github.com/karalabe/hid/hid_disabled.go
+33
-8
hid_enabled.go
vendor/github.com/karalabe/hid/hid_enabled.go
+247
-16
usb.go
vendor/github.com/karalabe/hid/usb.go
+53
-0
wchar.go
vendor/github.com/karalabe/hid/wchar.go
+1
-1
vendor.json
vendor/vendor.json
+3
-3
No files found.
accounts/usbwallet/hub.go
View file @
4799b5ab
...
...
@@ -89,6 +89,12 @@ func NewTrezorHub() (*Hub, error) {
return
newHub
(
TrezorScheme
,
0x534c
,
[]
uint16
{
0x0001
/* Trezor 1 */
},
0xff00
,
0
,
newTrezorDriver
)
}
// NewWebUSBTrezorHub creates a new hardware wallet manager for Trezor devices with
// firmware version > 1.8.0
func
NewWebUSBTrezorHub
()
(
*
Hub
,
error
)
{
return
newHub
(
TrezorScheme
,
0x1209
,
[]
uint16
{
0x53c1
/* Trezor 1 WebUSB */
},
0
,
0
,
newTrezorDriver
)
}
// newHub creates a new hardware wallet manager for generic USB devices.
func
newHub
(
scheme
string
,
vendorID
uint16
,
productIDs
[]
uint16
,
usageID
uint16
,
endpointID
int
,
makeDriver
func
(
log
.
Logger
)
driver
)
(
*
Hub
,
error
)
{
if
!
hid
.
Supported
()
{
...
...
@@ -148,9 +154,19 @@ func (hub *Hub) refreshWallets() {
return
}
}
for
_
,
info
:=
range
hid
.
Enumerate
(
hub
.
vendorID
,
0
)
{
infos
,
err
:=
hid
.
Enumerate
(
hub
.
vendorID
,
0
)
if
err
!=
nil
{
if
runtime
.
GOOS
==
"linux"
{
// See rationale before the enumeration why this is needed and only on Linux.
hub
.
commsLock
.
Unlock
()
}
log
.
Error
(
"error enumerating USB enumeration: "
,
"code"
,
err
)
return
}
for
_
,
info
:=
range
infos
{
for
_
,
id
:=
range
hub
.
productIDs
{
if
info
.
ProductID
==
id
&&
(
info
.
UsagePage
==
hub
.
usageID
||
info
.
Interface
==
hub
.
endpointID
)
{
_
,
pid
,
endpoint
,
_
/* FIXME usageID */
:=
info
.
IDs
()
if
pid
==
id
&&
(
/* FIXME usageID == hub.usageID || */
endpoint
==
hub
.
endpointID
)
{
devices
=
append
(
devices
,
info
)
break
}
...
...
@@ -169,7 +185,7 @@ func (hub *Hub) refreshWallets() {
)
for
_
,
device
:=
range
devices
{
url
:=
accounts
.
URL
{
Scheme
:
hub
.
scheme
,
Path
:
device
.
Path
}
url
:=
accounts
.
URL
{
Scheme
:
hub
.
scheme
,
Path
:
device
.
GetPath
()
}
// Drop wallets in front of the next device or those that failed for some reason
for
len
(
hub
.
wallets
)
>
0
{
...
...
accounts/usbwallet/trezor.go
View file @
4799b5ab
...
...
@@ -36,6 +36,8 @@ import (
"github.com/golang/protobuf/proto"
)
var
ErrInvalidDeviceType
=
errors
.
New
(
"trezor: invalid device type"
)
// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In
// this case, the calling application should display a pinpad and send back the
// encoded passphrase.
...
...
accounts/usbwallet/wallet.go
View file @
4799b5ab
...
...
@@ -78,7 +78,7 @@ type wallet struct {
url
*
accounts
.
URL
// Textual URL uniquely identifying this wallet
info
hid
.
DeviceInfo
// Known USB device infos about the wallet
device
*
hid
.
Device
// USB device advertising itself as a hardware wallet
device
hid
.
Device
// USB device advertising itself as a hardware wallet
accounts
[]
accounts
.
Account
// List of derive accounts pinned on the hardware wallet
paths
map
[
common
.
Address
]
accounts
.
DerivationPath
// Known derivation paths for signing operations
...
...
node/config.go
View file @
4799b5ab
...
...
@@ -507,6 +507,12 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) {
}
else
{
backends
=
append
(
backends
,
trezorhub
)
}
// Start a USB hub for Trezor hardware wallets (WebUSB version)
if
trezorhub
,
err
:=
usbwallet
.
NewWebUSBTrezorHub
();
err
!=
nil
{
log
.
Warn
(
fmt
.
Sprintf
(
"Failed to start Trezor hub, disabling: %v"
,
err
))
}
else
{
backends
=
append
(
backends
,
trezorhub
)
}
}
if
len
(
conf
.
SmartCardDaemonPath
)
>
0
{
// Start a smart card hub
...
...
signer/core/api.go
View file @
4799b5ab
...
...
@@ -151,6 +151,13 @@ func StartClefAccountManager(ksLocation string, nousb, lightKDF bool) *accounts.
backends
=
append
(
backends
,
trezorhub
)
log
.
Debug
(
"Trezor support enabled"
)
}
// Start a USB hub for Trezor hardware wallets (WebUSB version)
if
trezorhub
,
err
:=
usbwallet
.
NewWebUSBTrezorHub
();
err
!=
nil
{
log
.
Warn
(
fmt
.
Sprintf
(
"Failed to start Trezor hub, disabling: %v"
,
err
))
}
else
{
backends
=
append
(
backends
,
trezorhub
)
log
.
Debug
(
"Trezor support enabled"
)
}
}
// Clef doesn't allow insecure http account unlock.
return
accounts
.
NewManager
(
&
accounts
.
Config
{
InsecureUnlockAllowed
:
false
},
backends
...
)
...
...
vendor/github.com/karalabe/hid/generic.go
0 → 100644
View file @
4799b5ab
// hid - Gopher Interface Devices (USB HID)
// Copyright (c) 2019 Péter Szilágyi, Guillaume Ballet. All rights reserved.
package
hid
import
(
"C"
)
type
GenericEndpointDirection
uint8
// List of endpoint direction types
const
(
GenericEndpointDirectionOut
=
0x00
GenericEndpointDirectionIn
=
0x80
)
// List of endpoint attributes
const
(
GenericEndpointAttributeInterrupt
=
3
)
// GenericEndpoint represents a USB endpoint
type
GenericEndpoint
struct
{
Address
uint8
Direction
GenericEndpointDirection
Attributes
uint8
}
type
GenericDeviceInfo
struct
{
Path
string
// Platform-specific device path
VendorID
uint16
// Device Vendor ID
ProductID
uint16
// Device Product ID
device
*
GenericDevice
Interface
int
Endpoints
[]
GenericEndpoint
}
func
(
gdi
*
GenericDeviceInfo
)
Type
()
DeviceType
{
return
DeviceTypeGeneric
}
// Platform-specific device path
func
(
gdi
*
GenericDeviceInfo
)
GetPath
()
string
{
return
gdi
.
Path
}
// IDs returns the vendor and product IDs for the device
func
(
gdi
*
GenericDeviceInfo
)
IDs
()
(
uint16
,
uint16
,
int
,
uint16
)
{
return
gdi
.
VendorID
,
gdi
.
ProductID
,
gdi
.
Interface
,
0
}
vendor/github.com/karalabe/hid/hid.go
View file @
4799b5ab
...
...
@@ -17,8 +17,8 @@ var ErrDeviceClosed = errors.New("hid: device closed")
// operating system is not supported by the library.
var
ErrUnsupportedPlatform
=
errors
.
New
(
"hid: unsupported platform"
)
// DeviceInfo is a hidapi info structure.
type
DeviceInfo
struct
{
//
Hid
DeviceInfo is a hidapi info structure.
type
Hid
DeviceInfo
struct
{
Path
string
// Platform-specific device path
VendorID
uint16
// Device Vendor ID
ProductID
uint16
// Device Product ID
...
...
@@ -35,3 +35,18 @@ type DeviceInfo struct {
// only if the device contains more than one interface.
Interface
int
}
// GetPath returns the system-dependent path to the device
func
(
hdi
*
HidDeviceInfo
)
GetPath
()
string
{
return
hdi
.
Path
}
// IDs returns the vendor and product id of the device
func
(
hdi
*
HidDeviceInfo
)
IDs
()
(
uint16
,
uint16
,
int
,
uint16
)
{
return
hdi
.
VendorID
,
hdi
.
ProductID
,
hdi
.
Interface
,
hdi
.
UsagePage
}
// Type returns the type of the device (HID or generic)
func
(
hdi
*
HidDeviceInfo
)
Type
()
DeviceType
{
return
DeviceTypeHID
}
vendor/github.com/karalabe/hid/hid_disabled.go
View file @
4799b5ab
...
...
@@ -4,7 +4,7 @@
// This file is released under the 3-clause BSD license. Note however that Linux
// support depends on libusb, released under GNU LGPL 2.1 or later.
// +build !linux,!darwin,!windows ios !cgo
// +build !
freebsd,!
linux,!darwin,!windows ios !cgo
package
hid
...
...
@@ -22,30 +22,55 @@ func Enumerate(vendorID uint16, productID uint16) []DeviceInfo {
return
nil
}
// Device is a live HID USB connected device handle. On platforms that this file
//
Hid
Device is a live HID USB connected device handle. On platforms that this file
// implements the type lacks the actual HID device and all methods are noop.
type
Device
struct
{
DeviceInfo
// Embed the infos for easier access
type
Hid
Device
struct
{
Hid
DeviceInfo
// Embed the infos for easier access
}
// Open connects to an HID device by its path name. On platforms that this file
// implements the method just returns an error.
func
(
info
DeviceInfo
)
Open
()
(
*
Device
,
error
)
{
func
(
info
Hid
DeviceInfo
)
Open
()
(
*
Device
,
error
)
{
return
nil
,
ErrUnsupportedPlatform
}
// Close releases the HID USB device handle. On platforms that this file implements
// the method is just a noop.
func
(
dev
*
Device
)
Close
()
error
{
return
nil
}
func
(
dev
*
HidDevice
)
Close
()
error
{
return
ErrUnsupportedPlatform
}
// Write sends an output report to a HID device. On platforms that this file
// implements the method just returns an error.
func
(
dev
*
Device
)
Write
(
b
[]
byte
)
(
int
,
error
)
{
func
(
dev
*
Hid
Device
)
Write
(
b
[]
byte
)
(
int
,
error
)
{
return
0
,
ErrUnsupportedPlatform
}
// Read retrieves an input report from a HID device. On platforms that this file
// implements the method just returns an error.
func
(
dev
*
Device
)
Read
(
b
[]
byte
)
(
int
,
error
)
{
func
(
dev
*
Hid
Device
)
Read
(
b
[]
byte
)
(
int
,
error
)
{
return
0
,
ErrUnsupportedPlatform
}
// Open tries to open the USB device represented by the current DeviceInfo
func
(
gdi
*
GenericDeviceInfo
)
Open
()
(
Device
,
error
)
{
return
nil
,
ErrUnsupportedPlatform
}
// GenericDevice represents a generic USB device
type
GenericDevice
struct
{
*
GenericDeviceInfo
// Embed the infos for easier access
}
// Write implements io.ReaderWriter
func
(
gd
*
GenericDevice
)
Write
(
b
[]
byte
)
(
int
,
error
)
{
return
0
,
ErrUnsupportedPlatform
}
// Read implements io.ReaderWriter
func
(
gd
*
GenericDevice
)
Read
(
b
[]
byte
)
(
int
,
error
)
{
return
0
,
ErrUnsupportedPlatform
}
// Close a previously opened generic USB device
func
(
gd
*
GenericDevice
)
Close
()
error
{
return
ErrUnsupportedPlatform
}
vendor/github.com/karalabe/hid/hid_enabled.go
View file @
4799b5ab
...
...
@@ -4,7 +4,7 @@
// This file is released under the 3-clause BSD license. Note however that Linux
// support depends on libusb, released under LGNU GPL 2.1 or later.
// +build linux,cgo darwin,!ios,cgo windows,cgo
// +build
freebsd,cgo
linux,cgo darwin,!ios,cgo windows,cgo
package
hid
...
...
@@ -13,13 +13,15 @@ package hid
#cgo linux CFLAGS: -I./libusb/libusb -DDEFAULT_VISIBILITY="" -DOS_LINUX -D_GNU_SOURCE -DPOLL_NFDS_TYPE=int
#cgo linux,!android LDFLAGS: -lrt
#cgo darwin CFLAGS: -DOS_DARWIN
#cgo darwin LDFLAGS: -framework CoreFoundation -framework IOKit
#cgo darwin CFLAGS: -DOS_DARWIN
-I./libusb/libusb
#cgo darwin LDFLAGS: -framework CoreFoundation -framework IOKit
-lusb-1.0.0
#cgo windows CFLAGS: -DOS_WINDOWS
#cgo windows LDFLAGS: -lsetupapi
#cgo freebsd CFLAGS: -DOS_FREEBSD
#cgo freebsd LDFLAGS: -lusb
#ifdef OS_LINUX
#include <
sys/
poll.h>
#include <poll.h>
#include "os/threads_posix.c"
#include "os/poll_posix.c"
...
...
@@ -35,15 +37,50 @@ package hid
#include "hidapi/libusb/hid.c"
#elif OS_DARWIN
#include <libusb.h>
#include "hidapi/mac/hid.c"
#elif OS_WINDOWS
#include "hidapi/windows/hid.c"
#elif OS_FREEBSD
#include <stdlib.h>
#include <libusb.h>
#include "hidapi/libusb/hid.c"
#endif
#if defined(OS_LINUX) || defined(OS_WINDOWS)
void copy_device_list_to_slice(struct libusb_device **data, struct libusb_device **list, int count)
{
int i;
struct libusb_device *current = *list;
for (i=0; i<count; i++)
{
data[i] = current;
current = list_entry(current->list.next, struct libusb_device, list);
}
}
#elif defined(OS_DARWIN) || defined(OS_FREEBSD)
void copy_device_list_to_slice(struct libusb_device **data, struct libusb_device **list, int count)
{
int i;
// No memcopy because the struct size isn't available for a sizeof()
for (i=0; i<count; i++)
{
data[i] = list[i];
}
}
#endif
const char *usb_strerror(int err)
{
return libusb_strerror(err);
}
*/
import
"C"
import
(
"errors"
"fmt"
"reflect"
"runtime"
"sync"
"unsafe"
...
...
@@ -65,26 +102,132 @@ func Supported() bool {
return
true
}
// genericEnumerate performs generic USB device enumeration
func
genericEnumerate
(
vendorID
uint16
,
productID
uint16
)
([]
DeviceInfo
,
error
)
{
var
infos
[]
DeviceInfo
var
ctx
*
C
.
struct_libusb_context
errCode
:=
int
(
C
.
libusb_init
((
**
C
.
struct_libusb_context
)(
&
ctx
)))
if
errCode
<
0
{
return
nil
,
fmt
.
Errorf
(
"Error while initializing libusb: %d"
,
errCode
)
}
var
deviceListPtr
**
C
.
struct_libusb_device
count
:=
C
.
libusb_get_device_list
(
ctx
,
(
***
C
.
struct_libusb_device
)(
&
deviceListPtr
))
if
count
<
0
{
return
nil
,
fmt
.
Errorf
(
"Error code listing devices: %d"
,
count
)
}
defer
C
.
libusb_free_device_list
(
deviceListPtr
,
C
.
int
(
count
))
deviceList
:=
make
([]
*
C
.
struct_libusb_device
,
count
)
dlhdr
:=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
deviceList
))
C
.
copy_device_list_to_slice
((
**
C
.
struct_libusb_device
)(
unsafe
.
Pointer
(
dlhdr
.
Data
)),
deviceListPtr
,
C
.
int
(
count
))
for
devnum
,
dev
:=
range
deviceList
{
var
desc
C
.
struct_libusb_device_descriptor
errCode
:=
int
(
C
.
libusb_get_device_descriptor
(
dev
,
&
desc
))
if
errCode
<
0
{
return
nil
,
fmt
.
Errorf
(
"Error getting device descriptor for generic device %d: %d"
,
devnum
,
errCode
)
}
// Start by checking the vendor id and the product id if necessary
if
uint16
(
desc
.
idVendor
)
!=
vendorID
||
!
(
productID
==
0
||
uint16
(
desc
.
idProduct
)
==
productID
)
{
continue
}
// Skip HID devices, they will be handled later
switch
desc
.
bDeviceClass
{
case
0
:
/* Device class is specified at interface level */
for
cfgnum
:=
0
;
cfgnum
<
int
(
desc
.
bNumConfigurations
);
cfgnum
++
{
var
cfgdesc
*
C
.
struct_libusb_config_descriptor
errCode
=
int
(
C
.
libusb_get_config_descriptor
(
dev
,
C
.
uint8_t
(
cfgnum
),
&
cfgdesc
))
if
errCode
!=
0
{
return
nil
,
fmt
.
Errorf
(
"Error getting device configuration #%d for generic device %d: %d"
,
cfgnum
,
devnum
,
errCode
)
}
var
ifs
[]
C
.
struct_libusb_interface
ifshdr
:=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
ifs
))
ifshdr
.
Cap
=
int
(
cfgdesc
.
bNumInterfaces
)
ifshdr
.
Len
=
int
(
cfgdesc
.
bNumInterfaces
)
ifshdr
.
Data
=
uintptr
(
unsafe
.
Pointer
(
cfgdesc
.
_interface
))
for
ifnum
,
ifc
:=
range
ifs
{
var
ifdescs
[]
C
.
struct_libusb_interface_descriptor
ifdshdr
:=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
ifdescs
))
ifdshdr
.
Cap
=
int
(
ifc
.
num_altsetting
)
ifdshdr
.
Len
=
int
(
ifc
.
num_altsetting
)
ifdshdr
.
Data
=
uintptr
(
unsafe
.
Pointer
(
ifc
.
altsetting
))
for
_
,
alt
:=
range
ifdescs
{
if
alt
.
bInterfaceClass
!=
3
{
// Device isn't a HID interface, add them to the device list.
var
endps
[]
C
.
struct_libusb_endpoint_descriptor
endpshdr
:=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
endps
))
endpshdr
.
Cap
=
int
(
alt
.
bNumEndpoints
)
endpshdr
.
Len
=
int
(
alt
.
bNumEndpoints
)
endpshdr
.
Data
=
uintptr
(
unsafe
.
Pointer
(
alt
.
endpoint
))
endpoints
:=
make
([]
GenericEndpoint
,
alt
.
bNumEndpoints
)
for
ne
,
endpoint
:=
range
endps
{
endpoints
[
ne
]
=
GenericEndpoint
{
Direction
:
GenericEndpointDirection
(
endpoint
.
bEndpointAddress
)
&
GenericEndpointDirectionIn
,
Address
:
uint8
(
endpoint
.
bEndpointAddress
),
Attributes
:
uint8
(
endpoint
.
bmAttributes
),
}
}
info
:=
&
GenericDeviceInfo
{
Path
:
fmt
.
Sprintf
(
"%x:%x:%d"
,
vendorID
,
uint16
(
desc
.
idProduct
),
uint8
(
C
.
libusb_get_port_number
(
dev
))),
VendorID
:
uint16
(
desc
.
idVendor
),
ProductID
:
uint16
(
desc
.
idProduct
),
device
:
&
GenericDevice
{
device
:
dev
,
},
Endpoints
:
endpoints
,
Interface
:
ifnum
,
}
info
.
device
.
GenericDeviceInfo
=
info
infos
=
append
(
infos
,
info
)
}
}
}
}
case
3
:
// Device class is HID, skip it
continue
}
}
return
infos
,
nil
}
// Enumerate returns a list of all the HID devices attached to the system which
// match the vendor and product id:
// - If the vendor id is set to 0 then any vendor matches.
// - If the product id is set to 0 then any product matches.
// - If the vendor and product id are both 0, all HID devices are returned.
func
Enumerate
(
vendorID
uint16
,
productID
uint16
)
[]
DeviceInfo
{
func
Enumerate
(
vendorID
uint16
,
productID
uint16
)
([]
DeviceInfo
,
error
)
{
enumerateLock
.
Lock
()
defer
enumerateLock
.
Unlock
()
infos
,
err
:=
genericEnumerate
(
vendorID
,
productID
)
if
err
!=
nil
{
return
nil
,
err
}
// Gather all device infos and ensure they are freed before returning
head
:=
C
.
hid_enumerate
(
C
.
ushort
(
vendorID
),
C
.
ushort
(
productID
))
if
head
==
nil
{
return
nil
return
nil
,
nil
}
defer
C
.
hid_free_enumeration
(
head
)
// Iterate the list and retrieve the device details
var
infos
[]
DeviceInfo
for
;
head
!=
nil
;
head
=
head
.
next
{
info
:=
DeviceInfo
{
info
:=
&
Hid
DeviceInfo
{
Path
:
C
.
GoString
(
head
.
path
),
VendorID
:
uint16
(
head
.
vendor_id
),
ProductID
:
uint16
(
head
.
product_id
),
...
...
@@ -104,11 +247,11 @@ func Enumerate(vendorID uint16, productID uint16) []DeviceInfo {
}
infos
=
append
(
infos
,
info
)
}
return
infos
return
infos
,
nil
}
// Open connects to an HID device by its path name.
func
(
info
DeviceInfo
)
Open
()
(
*
Device
,
error
)
{
func
(
info
*
HidDeviceInfo
)
Open
()
(
Device
,
error
)
{
enumerateLock
.
Lock
()
defer
enumerateLock
.
Unlock
()
...
...
@@ -119,14 +262,14 @@ func (info DeviceInfo) Open() (*Device, error) {
if
device
==
nil
{
return
nil
,
errors
.
New
(
"hidapi: failed to open device"
)
}
return
&
Device
{
return
&
Hid
Device
{
DeviceInfo
:
info
,
device
:
device
,
},
nil
}
// Device is a live HID USB connected device handle.
type
Device
struct
{
//
Hid
Device is a live HID USB connected device handle.
type
Hid
Device
struct
{
DeviceInfo
// Embed the infos for easier access
device
*
C
.
hid_device
// Low level HID device to communicate through
...
...
@@ -134,7 +277,7 @@ type Device struct {
}
// Close releases the HID USB device handle.
func
(
dev
*
Device
)
Close
()
error
{
func
(
dev
*
Hid
Device
)
Close
()
error
{
dev
.
lock
.
Lock
()
defer
dev
.
lock
.
Unlock
()
...
...
@@ -149,7 +292,7 @@ func (dev *Device) Close() error {
//
// Write will send the data on the first OUT endpoint, if one exists. If it does
// not, it will send the data through the Control Endpoint (Endpoint 0).
func
(
dev
*
Device
)
Write
(
b
[]
byte
)
(
int
,
error
)
{
func
(
dev
*
Hid
Device
)
Write
(
b
[]
byte
)
(
int
,
error
)
{
// Abort if nothing to write
if
len
(
b
)
==
0
{
return
0
,
nil
...
...
@@ -192,7 +335,7 @@ func (dev *Device) Write(b []byte) (int, error) {
}
// Read retrieves an input report from a HID device.
func
(
dev
*
Device
)
Read
(
b
[]
byte
)
(
int
,
error
)
{
func
(
dev
*
Hid
Device
)
Read
(
b
[]
byte
)
(
int
,
error
)
{
// Aborth if nothing to read
if
len
(
b
)
==
0
{
return
0
,
nil
...
...
@@ -226,3 +369,91 @@ func (dev *Device) Read(b []byte) (int, error) {
}
return
read
,
nil
}
// Type identify the device as a HID device
func
(
dev
*
HidDevice
)
Type
()
DeviceType
{
return
dev
.
DeviceInfo
.
Type
()
}
// Open tries to open the USB device represented by the current DeviceInfo
func
(
gdi
*
GenericDeviceInfo
)
Open
()
(
Device
,
error
)
{
var
handle
*
C
.
struct_libusb_device_handle
errCode
:=
int
(
C
.
libusb_open
(
gdi
.
device
.
device
,
(
**
C
.
struct_libusb_device_handle
)(
&
handle
)))
if
errCode
<
0
{
return
nil
,
fmt
.
Errorf
(
"Error opening generic USB device %v, code %d"
,
gdi
.
device
.
handle
,
errCode
)
}
gdi
.
device
.
handle
=
handle
// QUESTION: ai-je deja initialie le GDI ?
// GenericDeviceInfo: gdi,
// handle: handle,
// }
for
_
,
endpoint
:=
range
gdi
.
Endpoints
{
switch
{
case
endpoint
.
Direction
==
GenericEndpointDirectionOut
&&
endpoint
.
Attributes
==
GenericEndpointAttributeInterrupt
:
gdi
.
device
.
WEndpoint
=
endpoint
.
Address
case
endpoint
.
Direction
==
GenericEndpointDirectionIn
&&
endpoint
.
Attributes
==
GenericEndpointAttributeInterrupt
:
gdi
.
device
.
REndpoint
=
endpoint
.
Address
}
}
if
gdi
.
device
.
REndpoint
==
0
||
gdi
.
device
.
WEndpoint
==
0
{
return
nil
,
fmt
.
Errorf
(
"Missing endpoint in device %#x:%#x:%d"
,
gdi
.
VendorID
,
gdi
.
ProductID
,
gdi
.
Interface
)
}
return
gdi
.
device
,
nil
}
// GenericDevice represents a generic USB device
type
GenericDevice
struct
{
*
GenericDeviceInfo
// Embed the infos for easier access
REndpoint
uint8
WEndpoint
uint8
device
*
C
.
struct_libusb_device
handle
*
C
.
struct_libusb_device_handle
lock
sync
.
Mutex
}
// Write implements io.ReaderWriter
func
(
gd
*
GenericDevice
)
Write
(
b
[]
byte
)
(
int
,
error
)
{
gd
.
lock
.
Lock
()
defer
gd
.
lock
.
Unlock
()
out
,
err
:=
interruptTransfer
(
gd
.
handle
,
gd
.
WEndpoint
,
b
)
return
len
(
out
),
err
}
// Read implements io.ReaderWriter
func
(
gd
*
GenericDevice
)
Read
(
b
[]
byte
)
(
int
,
error
)
{
gd
.
lock
.
Lock
()
defer
gd
.
lock
.
Unlock
()
out
,
err
:=
interruptTransfer
(
gd
.
handle
,
gd
.
REndpoint
,
b
)
return
len
(
out
),
err
}
// Close a previously opened generic USB device
func
(
gd
*
GenericDevice
)
Close
()
error
{
gd
.
lock
.
Lock
()
defer
gd
.
lock
.
Unlock
()
if
gd
.
handle
!=
nil
{
C
.
libusb_close
(
gd
.
handle
)
gd
.
handle
=
nil
}
return
nil
}
// interruptTransfer is a helpler function for libusb's interrupt transfer function
func
interruptTransfer
(
handle
*
C
.
struct_libusb_device_handle
,
endpoint
uint8
,
data
[]
byte
)
([]
byte
,
error
)
{
var
transferred
C
.
int
errCode
:=
int
(
C
.
libusb_interrupt_transfer
(
handle
,
(
C
.
uchar
)(
endpoint
),
(
*
C
.
uchar
)(
&
data
[
0
]),
(
C
.
int
)(
len
(
data
)),
&
transferred
,
(
C
.
uint
)(
0
)))
if
errCode
!=
0
{
return
nil
,
fmt
.
Errorf
(
"Interrupt transfer error: %s"
,
C
.
GoString
(
C
.
usb_strerror
(
C
.
int
(
errCode
))))
}
return
data
[
:
int
(
transferred
)],
nil
}
vendor/github.com/karalabe/hid/usb.go
0 → 100644
View file @
4799b5ab
// hid - Gopher Interface Devices (USB HID)
// Copyright (c) 2019 Péter Szilágyi, Guillaume Ballet. All rights reserved.
//
// This file is released under the 3-clause BSD license. Note however that Linux
// support depends on libusb, released under GNU LGPL 2.1 or later.
// Package usb provide interfaces for generic USB devices.
package
hid
// DeviceType represents the type of a USB device (generic or HID)
type
DeviceType
int
// List of supported device types
const
(
DeviceTypeGeneric
DeviceType
=
0
DeviceTypeHID
DeviceType
=
1
)
// Enumerate returns a list of all the HID devices attached to the system which
// match the vendor and product id:
// - If the vendor id is set to 0 then any vendor matches.
// - If the product id is set to 0 then any product matches.
// - If the vendor and product id are both 0, all HID devices are returned.
// func Enumerate(vendorID uint16, productID uint16) []DeviceInfo {
// }
// DeviceInfo is a generic libusb info interface
type
DeviceInfo
interface
{
// Type returns the type of the device (generic or HID)
Type
()
DeviceType
// Platform-specific device path
GetPath
()
string
// IDs returns the vendor and product IDs for the device,
// as well as the endpoint id and the usage page.
IDs
()
(
uint16
,
uint16
,
int
,
uint16
)
// Open tries to open the USB device represented by the current DeviceInfo
Open
()
(
Device
,
error
)
}
// Device is a generic libusb device interface
type
Device
interface
{
Close
()
error
Write
(
b
[]
byte
)
(
int
,
error
)
Read
(
b
[]
byte
)
(
int
,
error
)
// Type returns the type of the device (generic or HID)
Type
()
DeviceType
}
vendor/github.com/karalabe/hid/wchar.go
View file @
4799b5ab
...
...
@@ -7,7 +7,7 @@
// https://github.com/orofarne/gowchar/blob/master/LICENSE
// +build !ios
// +build linux darwin windows
// +build
freebsd
linux darwin windows
package
hid
...
...
vendor/vendor.json
View file @
4799b5ab
...
...
@@ -267,10 +267,10 @@
"revisionTime"
:
"2017-04-30T22:20:11Z"
},
{
"checksumSHA1"
:
"
6XsjAARQFvlW6dS15al0ibTFPOQ
="
,
"checksumSHA1"
:
"
p6UjFsx/1ACWAhsdEOWrXAHptGY
="
,
"path"
:
"github.com/karalabe/hid"
,
"revision"
:
"
d815e0c1a2e2082a287a2806bc90bc8fc7b276a9
"
,
"revisionTime"
:
"201
8-11-28T19:21:57
Z"
,
"revision"
:
"
e40407cce1c217644c09da5415bbfb07d330ea5e
"
,
"revisionTime"
:
"201
9-05-28T15:16:06
Z"
,
"tree"
:
true
},
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment