This commit is contained in:
Kyle Lemons
2012-03-27 20:30:16 -07:00
parent 5fef64fd78
commit c8d19d2d0f
5 changed files with 48 additions and 17 deletions

View File

@@ -38,7 +38,7 @@ func main() {
fmt.Printf(" %s:\n", cfg) fmt.Printf(" %s:\n", cfg)
for _, alt := range cfg.Interfaces { for _, alt := range cfg.Interfaces {
fmt.Printf(" --------------\n") fmt.Printf(" --------------\n")
for _, iface := range alt { for _, iface := range alt.Setups {
fmt.Printf(" %s\n", iface) fmt.Printf(" %s\n", iface)
fmt.Printf(" %s\n", usbid.Classify(iface)) fmt.Printf(" %s\n", usbid.Classify(iface))
for _, end := range iface.Endpoints { for _, end := range iface.Endpoints {

View File

@@ -11,7 +11,6 @@ import (
) )
type EndpointInfo struct { type EndpointInfo struct {
Type DescriptorType
Address uint8 Address uint8
Attributes uint8 Attributes uint8
MaxPacketSize uint16 MaxPacketSize uint16
@@ -38,7 +37,15 @@ func (e EndpointInfo) String() string {
} }
type InterfaceInfo struct { type InterfaceInfo struct {
Type DescriptorType Number uint8
Setups []InterfaceSetup
}
func (i InterfaceInfo) String() string {
return fmt.Sprintf("Interface %02x (%d setups)", i.Number, len(i.Setups))
}
type InterfaceSetup struct {
Number uint8 Number uint8
Alternate uint8 Alternate uint8
IfClass uint8 IfClass uint8
@@ -47,16 +54,15 @@ type InterfaceInfo struct {
Endpoints []EndpointInfo Endpoints []EndpointInfo
} }
func (i InterfaceInfo) String() string { func (a InterfaceSetup) String() string {
return fmt.Sprintf("Interface %02x (config %02x)", i.Number, i.Alternate) return fmt.Sprintf("Interface %02x Setup %02x", a.Number, a.Alternate)
} }
type ConfigInfo struct { type ConfigInfo struct {
Type DescriptorType
Config uint8 Config uint8
Attributes uint8 Attributes uint8
MaxPower uint8 MaxPower uint8
Interfaces [][]InterfaceInfo Interfaces []InterfaceInfo
} }
func (c ConfigInfo) String() string { func (c ConfigInfo) String() string {
@@ -65,7 +71,6 @@ func (c ConfigInfo) String() string {
func newConfig(cfg *C.struct_libusb_config_descriptor) ConfigInfo { func newConfig(cfg *C.struct_libusb_config_descriptor) ConfigInfo {
c := ConfigInfo{ c := ConfigInfo{
Type: DescriptorType(cfg.bDescriptorType),
Config: uint8(cfg.bConfigurationValue), Config: uint8(cfg.bConfigurationValue),
Attributes: uint8(cfg.bmAttributes), Attributes: uint8(cfg.bmAttributes),
MaxPower: uint8(cfg.MaxPower), MaxPower: uint8(cfg.MaxPower),
@@ -77,18 +82,21 @@ func newConfig(cfg *C.struct_libusb_config_descriptor) ConfigInfo {
Len: int(cfg.bNumInterfaces), Len: int(cfg.bNumInterfaces),
Cap: int(cfg.bNumInterfaces), Cap: int(cfg.bNumInterfaces),
} }
c.Interfaces = make([][]InterfaceInfo, 0, len(ifaces)) c.Interfaces = make([]InterfaceInfo, 0, len(ifaces))
for _, iface := range ifaces { for _, iface := range ifaces {
if iface.num_altsetting == 0 {
continue
}
var alts []C.struct_libusb_interface_descriptor var alts []C.struct_libusb_interface_descriptor
*(*reflect.SliceHeader)(unsafe.Pointer(&alts)) = reflect.SliceHeader{ *(*reflect.SliceHeader)(unsafe.Pointer(&alts)) = reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(iface.altsetting)), Data: uintptr(unsafe.Pointer(iface.altsetting)),
Len: int(iface.num_altsetting), Len: int(iface.num_altsetting),
Cap: int(iface.num_altsetting), Cap: int(iface.num_altsetting),
} }
descs := make([]InterfaceInfo, 0, len(alts)) descs := make([]InterfaceSetup, 0, len(alts))
for _, alt := range alts { for _, alt := range alts {
i := InterfaceInfo{ i := InterfaceSetup{
Type: DescriptorType(alt.bDescriptorType),
Number: uint8(alt.bInterfaceNumber), Number: uint8(alt.bInterfaceNumber),
Alternate: uint8(alt.bAlternateSetting), Alternate: uint8(alt.bAlternateSetting),
IfClass: uint8(alt.bInterfaceClass), IfClass: uint8(alt.bInterfaceClass),
@@ -104,7 +112,6 @@ func newConfig(cfg *C.struct_libusb_config_descriptor) ConfigInfo {
i.Endpoints = make([]EndpointInfo, 0, len(ends)) i.Endpoints = make([]EndpointInfo, 0, len(ends))
for _, end := range ends { for _, end := range ends {
i.Endpoints = append(i.Endpoints, EndpointInfo{ i.Endpoints = append(i.Endpoints, EndpointInfo{
Type: DescriptorType(end.bDescriptorType),
Address: uint8(end.bEndpointAddress), Address: uint8(end.bEndpointAddress),
Attributes: uint8(end.bmAttributes), Attributes: uint8(end.bmAttributes),
MaxPacketSize: uint16(end.wMaxPacketSize), MaxPacketSize: uint16(end.wMaxPacketSize),
@@ -115,7 +122,10 @@ func newConfig(cfg *C.struct_libusb_config_descriptor) ConfigInfo {
} }
descs = append(descs, i) descs = append(descs, i)
} }
c.Interfaces = append(c.Interfaces, descs) c.Interfaces = append(c.Interfaces, InterfaceInfo{
Number: descs[0].Number,
Setups: descs,
})
} }
return c return c
} }

View File

@@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"runtime" "runtime"
"sync"
"time" "time"
"unsafe" "unsafe"
) )
@@ -22,13 +23,20 @@ type Device struct {
// Timeouts // Timeouts
ControlTimeout time.Duration ControlTimeout time.Duration
// Claimed interfaces
lock *sync.Mutex
claimed map[uint8]int
} }
func newDevice(handle *C.libusb_device_handle, desc *Descriptor) *Device { func newDevice(handle *C.libusb_device_handle, desc *Descriptor) *Device {
ifaces := 0
d := &Device{ d := &Device{
handle: handle, handle: handle,
Descriptor: desc, Descriptor: desc,
ControlTimeout: DefaultControlTimeout, ControlTimeout: DefaultControlTimeout,
lock: new(sync.Mutex),
claimed: make(map[uint8]int, ifaces),
} }
// This doesn't seem to actually get called // This doesn't seem to actually get called
@@ -86,7 +94,20 @@ func (d *Device) Close() error {
if d.handle == nil { if d.handle == nil {
return fmt.Errorf("usb: double close on device") return fmt.Errorf("usb: double close on device")
} }
for iface := range d.claimed {
C.libusb_release_interface(d.handle, C.int(iface))
}
C.libusb_close(d.handle) C.libusb_close(d.handle)
d.handle = nil d.handle = nil
return nil return nil
} }
type Interface struct {
}
func (d *Device) OpenInterface(id uint8) (*Interface, error) {
if errno := C.libusb_claim_interface(d.handle, C.int(id)); errno < 0 {
return nil, usbError(errno)
}
return &Interface{}, nil
}

View File

@@ -26,7 +26,7 @@ func TestEnum(t *testing.T) {
t.Logf("- %s:", cfg) t.Logf("- %s:", cfg)
for _, alt := range cfg.Interfaces { for _, alt := range cfg.Interfaces {
t.Logf(" --------------") t.Logf(" --------------")
for _, iface := range alt { for _, iface := range alt.Setups {
t.Logf(" - %s", iface) t.Logf(" - %s", iface)
t.Logf(" - %s", usbid.Classify(iface)) t.Logf(" - %s", usbid.Classify(iface))
for _, end := range iface.Endpoints { for _, end := range iface.Endpoints {

View File

@@ -39,13 +39,13 @@ func Describe(val interface{}) string {
// //
// The given val must be one of the following: // The given val must be one of the following:
// - *usb.Descriptor "Class (SubClass) Protocol" // - *usb.Descriptor "Class (SubClass) Protocol"
// - *usb.InterfaceInfo "IfClass (IfSubClass) IfProtocol" // - *usb.InterfaceSetup "IfClass (IfSubClass) IfProtocol"
func Classify(val interface{}) string { func Classify(val interface{}) string {
var class, sub, proto uint8 var class, sub, proto uint8
switch val := val.(type) { switch val := val.(type) {
case *usb.Descriptor: case *usb.Descriptor:
class, sub, proto = val.Class, val.SubClass, val.Protocol class, sub, proto = val.Class, val.SubClass, val.Protocol
case *usb.InterfaceInfo: case *usb.InterfaceSetup:
class, sub, proto = val.IfClass, val.IfSubClass, val.IfProtocol class, sub, proto = val.IfClass, val.IfSubClass, val.IfProtocol
default: default:
return fmt.Sprintf("Unknown (%T)", val) return fmt.Sprintf("Unknown (%T)", val)