Tidy up interfaces and pretty printing
This commit is contained in:
@@ -5,6 +5,7 @@ package usb
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"runtime"
|
||||
@@ -13,38 +14,64 @@ import (
|
||||
|
||||
type Endpoint struct {
|
||||
Type DescriptorType
|
||||
Address ID
|
||||
Address uint8
|
||||
Attributes uint8
|
||||
MaxPacketSize uint16
|
||||
PollInterval uint8
|
||||
RefreshRate uint8
|
||||
SynchAddress ID
|
||||
SynchAddress uint8
|
||||
}
|
||||
|
||||
func (e Endpoint) Number() int {
|
||||
return int(e.Address) & ENDPOINT_NUM_MASK
|
||||
}
|
||||
|
||||
func (e Endpoint) Direction() EndpointDirection {
|
||||
return EndpointDirection(e.Address) & ENDPOINT_DIR_MASK
|
||||
}
|
||||
|
||||
func (e Endpoint) String() string {
|
||||
return fmt.Sprintf("Endpoint %d %-3s %s - %s %s",
|
||||
e.Number(), e.Direction(),
|
||||
TransferType(e.Attributes) & TRANSFER_TYPE_MASK,
|
||||
IsoSyncType(e.Attributes) & ISO_SYNC_TYPE_MASK,
|
||||
IsoUsageType(e.Attributes) & ISO_USAGE_TYPE_MASK,
|
||||
)
|
||||
}
|
||||
|
||||
type Interface struct {
|
||||
Type DescriptorType
|
||||
Number ID
|
||||
Alternate ID
|
||||
IfClass Class
|
||||
Number uint8
|
||||
Alternate uint8
|
||||
IfClass uint8
|
||||
IfSubClass uint8
|
||||
IfProtocol uint8
|
||||
Endpoints []*Endpoint
|
||||
}
|
||||
|
||||
func (i Interface) String() string {
|
||||
return fmt.Sprintf("Interface %02x (config %02x)", i.Number, i.Alternate)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
cfg *C.struct_libusb_config_descriptor
|
||||
|
||||
Type DescriptorType
|
||||
Config ID
|
||||
Config uint8
|
||||
Attributes uint8
|
||||
MaxPower uint8
|
||||
Interfaces [][]*Interface
|
||||
}
|
||||
|
||||
func (c Config) String() string {
|
||||
return fmt.Sprintf("Config %02x", c.Config)
|
||||
}
|
||||
|
||||
func newConfig(cfg *C.struct_libusb_config_descriptor) *Config {
|
||||
c := &Config{
|
||||
cfg: cfg,
|
||||
Type: DescriptorType(cfg.bDescriptorType),
|
||||
Config: ID(cfg.bConfigurationValue),
|
||||
Config: uint8(cfg.bConfigurationValue),
|
||||
Attributes: uint8(cfg.bmAttributes),
|
||||
MaxPower: uint8(cfg.MaxPower),
|
||||
}
|
||||
@@ -67,9 +94,9 @@ func newConfig(cfg *C.struct_libusb_config_descriptor) *Config {
|
||||
for _, alt := range alts {
|
||||
i := &Interface{
|
||||
Type: DescriptorType(alt.bDescriptorType),
|
||||
Number: ID(alt.bInterfaceNumber),
|
||||
Alternate: ID(alt.bAlternateSetting),
|
||||
IfClass: Class(alt.bInterfaceClass),
|
||||
Number: uint8(alt.bInterfaceNumber),
|
||||
Alternate: uint8(alt.bAlternateSetting),
|
||||
IfClass: uint8(alt.bInterfaceClass),
|
||||
IfSubClass: uint8(alt.bInterfaceSubClass),
|
||||
IfProtocol: uint8(alt.bInterfaceProtocol),
|
||||
}
|
||||
@@ -83,11 +110,12 @@ func newConfig(cfg *C.struct_libusb_config_descriptor) *Config {
|
||||
for _, end := range ends {
|
||||
i.Endpoints = append(i.Endpoints, &Endpoint{
|
||||
Type: DescriptorType(end.bDescriptorType),
|
||||
Address: ID(end.bEndpointAddress),
|
||||
Address: uint8(end.bEndpointAddress),
|
||||
Attributes: uint8(end.bmAttributes),
|
||||
MaxPacketSize: uint16(end.wMaxPacketSize),
|
||||
PollInterval: uint8(end.bInterval),
|
||||
RefreshRate: uint8(end.bRefresh),
|
||||
SynchAddress: ID(end.bSynchAddress),
|
||||
SynchAddress: uint8(end.bSynchAddress),
|
||||
})
|
||||
}
|
||||
descs = append(descs, i)
|
||||
|
@@ -9,9 +9,9 @@ type Descriptor struct {
|
||||
|
||||
Type DescriptorType // The type of this descriptor
|
||||
Spec BCD // USB Specification Release Number
|
||||
Class Class // The class of this device
|
||||
SubClass uint8 // The sub-class (within the class) of this device
|
||||
Protocol uint8 // The protocol (within the sub-class) of this device
|
||||
Class uint8 // The class of this device
|
||||
SubClass uint8 // The sub-class (within the class) of this device
|
||||
Protocol uint8 // The protocol (within the sub-class) of this device
|
||||
Vendor ID // The 8-bit Vendor identifer
|
||||
Product ID // The 8-bit Product identifier
|
||||
Device BCD // The device version
|
||||
@@ -26,7 +26,7 @@ func newDescriptor(dev *C.libusb_device) (*Descriptor, error) {
|
||||
desc: &desc,
|
||||
Type: DescriptorType(desc.bDescriptorType),
|
||||
Spec: BCD(desc.bcdUSB),
|
||||
Class: Class(desc.bDeviceClass),
|
||||
Class: uint8(desc.bDeviceClass),
|
||||
SubClass: uint8(desc.bDeviceSubClass),
|
||||
Protocol: uint8(desc.bDeviceProtocol),
|
||||
Vendor: ID(desc.idVendor),
|
||||
@@ -147,13 +147,15 @@ func (dt DescriptorType) String() string {
|
||||
type EndpointDirection int
|
||||
|
||||
const (
|
||||
ENDPOINT_IN EndpointDirection = C.LIBUSB_ENDPOINT_IN
|
||||
ENDPOINT_OUT EndpointDirection = C.LIBUSB_ENDPOINT_OUT
|
||||
ENDPOINT_NUM_MASK = 0x03
|
||||
ENDPOINT_DIR_IN EndpointDirection = C.LIBUSB_ENDPOINT_IN
|
||||
ENDPOINT_DIR_OUT EndpointDirection = C.LIBUSB_ENDPOINT_OUT
|
||||
ENDPOINT_DIR_MASK EndpointDirection = 0x80
|
||||
)
|
||||
|
||||
var endpointDirectionDescription = map[EndpointDirection]string{
|
||||
ENDPOINT_IN: "device-to-host",
|
||||
ENDPOINT_OUT: "host-to-device",
|
||||
ENDPOINT_DIR_IN: "IN",
|
||||
ENDPOINT_DIR_OUT: "OUT",
|
||||
}
|
||||
|
||||
func (ed EndpointDirection) String() string {
|
||||
@@ -167,6 +169,7 @@ const (
|
||||
TRANSFER_TYPE_ISOCHRONOUS TransferType = C.LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
|
||||
TRANSFER_TYPE_BULK TransferType = C.LIBUSB_TRANSFER_TYPE_BULK
|
||||
TRANSFER_TYPE_INTERRUPT TransferType = C.LIBUSB_TRANSFER_TYPE_INTERRUPT
|
||||
TRANSFER_TYPE_MASK TransferType = 0x03
|
||||
)
|
||||
|
||||
var transferTypeDescription = map[TransferType]string{
|
||||
@@ -183,14 +186,15 @@ func (tt TransferType) String() string {
|
||||
type IsoSyncType int
|
||||
|
||||
const (
|
||||
ISO_SYNC_TYPE_NONE IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_NONE
|
||||
ISO_SYNC_TYPE_ASYNC IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_ASYNC
|
||||
ISO_SYNC_TYPE_ADAPTIVE IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_ADAPTIVE
|
||||
ISO_SYNC_TYPE_SYNC IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_SYNC
|
||||
ISO_SYNC_TYPE_NONE IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_NONE << 2
|
||||
ISO_SYNC_TYPE_ASYNC IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_ASYNC << 2
|
||||
ISO_SYNC_TYPE_ADAPTIVE IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_ADAPTIVE << 2
|
||||
ISO_SYNC_TYPE_SYNC IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_SYNC << 2
|
||||
ISO_SYNC_TYPE_MASK IsoSyncType = 0x0C
|
||||
)
|
||||
|
||||
var isoSyncTypeDescription = map[IsoSyncType]string{
|
||||
ISO_SYNC_TYPE_NONE: "no synchronization",
|
||||
ISO_SYNC_TYPE_NONE: "unsynchronized",
|
||||
ISO_SYNC_TYPE_ASYNC: "asynchronous",
|
||||
ISO_SYNC_TYPE_ADAPTIVE: "adaptive",
|
||||
ISO_SYNC_TYPE_SYNC: "synchronous",
|
||||
@@ -203,9 +207,10 @@ func (ist IsoSyncType) String() string {
|
||||
type IsoUsageType int
|
||||
|
||||
const (
|
||||
ISO_USAGE_TYPE_DATA IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_DATA
|
||||
ISO_USAGE_TYPE_FEEDBACK IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_FEEDBACK
|
||||
ISO_USAGE_TYPE_IMPLICIT IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_IMPLICIT
|
||||
ISO_USAGE_TYPE_DATA IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_DATA << 4
|
||||
ISO_USAGE_TYPE_FEEDBACK IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_FEEDBACK << 4
|
||||
ISO_USAGE_TYPE_IMPLICIT IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_IMPLICIT << 4
|
||||
ISO_USAGE_TYPE_MASK IsoUsageType = 0x30
|
||||
)
|
||||
|
||||
var isoUsageTypeDescription = map[IsoUsageType]string{
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"log"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -89,6 +90,7 @@ func (d *Device) Reset() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var ControlTimeout = 5*time.Second
|
||||
func (d *Device) Control(rType, request uint8, val, idx uint16, data []byte) (int, error) {
|
||||
dataSlice := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
||||
n := C.libusb_control_transfer(
|
||||
@@ -99,13 +101,28 @@ func (d *Device) Control(rType, request uint8, val, idx uint16, data []byte) (in
|
||||
C.uint16_t(idx),
|
||||
(*C.uchar)(unsafe.Pointer(dataSlice.Data)),
|
||||
C.uint16_t(len(data)),
|
||||
0)
|
||||
C.uint(ControlTimeout/time.Millisecond))
|
||||
if n < 0 {
|
||||
return int(n), usbError(n)
|
||||
}
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
func (d *Device) ActiveConfig() (int, error) {
|
||||
var cfg C.int
|
||||
if errno := C.libusb_get_configuration(d.handle, &cfg); errno < 0 {
|
||||
return 0, usbError(errno)
|
||||
}
|
||||
return int(cfg), nil
|
||||
}
|
||||
|
||||
func (d *Device) SetConfig(cfg int) error {
|
||||
if errno := C.libusb_set_configuration(d.handle, C.int(cfg)); errno < 0 {
|
||||
return usbError(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Device) Close() error {
|
||||
if d.handle != nil {
|
||||
log.Printf("device %p closed", d.handle)
|
||||
|
@@ -45,14 +45,8 @@ func TestEnum(t *testing.T) {
|
||||
bus := dev.BusNumber()
|
||||
addr := dev.Address()
|
||||
|
||||
t.Logf("%03d:%03d %+v", bus, addr, desc)
|
||||
if v, ok := usbid.Vendors[desc.Vendor]; ok {
|
||||
if p, ok := v.Devices[desc.Product]; ok {
|
||||
t.Logf(" - %s (%s) %s (%s)", v, desc.Vendor, p, desc.Product)
|
||||
} else {
|
||||
t.Logf(" - %s (%s) Unknown", v, desc.Vendor)
|
||||
}
|
||||
}
|
||||
t.Logf("%03d:%03d %s", bus, addr, usbid.Describe(desc))
|
||||
t.Logf("- Protocol: %s", usbid.Classify(desc))
|
||||
|
||||
cfgs, err := dev.Configurations()
|
||||
defer func() {
|
||||
@@ -61,21 +55,23 @@ func TestEnum(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
t.Errorf(" - configs: %s", err)
|
||||
t.Errorf(" - configs: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, cfg := range cfgs {
|
||||
t.Logf(" - %#v", cfg)
|
||||
t.Logf("- %s:", cfg)
|
||||
for _, alt := range cfg.Interfaces {
|
||||
t.Logf(" --------------")
|
||||
for _, iface := range alt {
|
||||
t.Logf(" - %#v", iface)
|
||||
t.Logf(" - %s", iface)
|
||||
t.Logf(" - %s", usbid.Classify(iface))
|
||||
for _, end := range iface.Endpoints {
|
||||
t.Logf(" - %#v", end)
|
||||
t.Logf(" - %s", end)
|
||||
}
|
||||
}
|
||||
t.Logf(" -----")
|
||||
}
|
||||
t.Logf(" --------------")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user