From 6d81ca37d33ece13b9edfc102c2c9fb71d7c887a Mon Sep 17 00:00:00 2001 From: Sebastian Zagrodzki Date: Sat, 29 Apr 2017 12:19:34 +0200 Subject: [PATCH] Use a map to store endpoint descriptors. Allows easy access to a particular endpoint number. --- usb/endpoint_test.go | 2 +- usb/fakelibusb_test.go | 104 +++++++++++++++++++++++------------------ usb/interface.go | 30 ++++++------ usb/libusb.go | 7 +-- 4 files changed, 79 insertions(+), 64 deletions(-) diff --git a/usb/endpoint_test.go b/usb/endpoint_test.go index bbac9d0..10b4292 100644 --- a/usb/endpoint_test.go +++ b/usb/endpoint_test.go @@ -55,7 +55,7 @@ func TestEndpoint(t *testing.T) { }, }, } { - epData.intf.Endpoints = []EndpointInfo{epData.ei} + epData.intf.Endpoints = map[int]EndpointInfo{epData.ei.Number: epData.ei} for _, tc := range []struct { desc string buf []byte diff --git a/usb/fakelibusb_test.go b/usb/fakelibusb_test.go index 9bc424c..25ecac7 100644 --- a/usb/fakelibusb_test.go +++ b/usb/fakelibusb_test.go @@ -44,17 +44,20 @@ var ( Number: 0, Alternate: 0, Class: ClassVendorSpec, - Endpoints: []EndpointInfo{{ - Number: 1, - Direction: EndpointDirectionOut, - MaxPacketSize: 512, - TransferType: TransferTypeBulk, - }, { - Number: 2, - Direction: EndpointDirectionIn, - MaxPacketSize: 512, - TransferType: TransferTypeBulk, - }}, + Endpoints: map[int]EndpointInfo{ + 1: { + Number: 1, + Direction: EndpointDirectionOut, + MaxPacketSize: 512, + TransferType: TransferTypeBulk, + }, + 2: { + Number: 2, + Direction: EndpointDirectionIn, + MaxPacketSize: 512, + TransferType: TransferTypeBulk, + }, + }, }}, }}, }}, @@ -87,49 +90,58 @@ var ( Number: 1, Alternate: 0, Class: ClassVendorSpec, - Endpoints: []EndpointInfo{{ - Number: 5, - Direction: EndpointDirectionOut, - MaxPacketSize: 3 * 1024, - TransferType: TransferTypeIsochronous, - UsageType: IsoUsageTypeData, - }, { - Number: 6, - Direction: EndpointDirectionIn, - MaxPacketSize: 3 * 1024, - TransferType: TransferTypeIsochronous, - UsageType: IsoUsageTypeData, - }}, + Endpoints: map[int]EndpointInfo{ + 5: { + Number: 5, + Direction: EndpointDirectionOut, + MaxPacketSize: 3 * 1024, + TransferType: TransferTypeIsochronous, + UsageType: IsoUsageTypeData, + }, + 6: { + Number: 6, + Direction: EndpointDirectionIn, + MaxPacketSize: 3 * 1024, + TransferType: TransferTypeIsochronous, + UsageType: IsoUsageTypeData, + }, + }, }, { Number: 1, Alternate: 1, Class: ClassVendorSpec, - Endpoints: []EndpointInfo{{ - Number: 5, - Direction: EndpointDirectionOut, - MaxPacketSize: 2 * 1024, - TransferType: TransferTypeIsochronous, - }, { - Number: 6, - Direction: EndpointDirectionIn, - MaxPacketSize: 2 * 1024, - TransferType: TransferTypeIsochronous, - }}, + Endpoints: map[int]EndpointInfo{ + 5: { + Number: 5, + Direction: EndpointDirectionOut, + MaxPacketSize: 2 * 1024, + TransferType: TransferTypeIsochronous, + }, + 6: { + Number: 6, + Direction: EndpointDirectionIn, + MaxPacketSize: 2 * 1024, + TransferType: TransferTypeIsochronous, + }, + }, }, { Number: 1, Alternate: 2, Class: ClassVendorSpec, - Endpoints: []EndpointInfo{{ - Number: 5, - Direction: EndpointDirectionIn, - MaxPacketSize: 1024, - TransferType: TransferTypeIsochronous, - }, { - Number: 6, - Direction: EndpointDirectionIn, - MaxPacketSize: 1024, - TransferType: TransferTypeIsochronous, - }}, + Endpoints: map[int]EndpointInfo{ + 5: { + Number: 5, + Direction: EndpointDirectionIn, + MaxPacketSize: 1024, + TransferType: TransferTypeIsochronous, + }, + 6: { + Number: 6, + Direction: EndpointDirectionIn, + MaxPacketSize: 1024, + TransferType: TransferTypeIsochronous, + }, + }, }}, }}, }}, diff --git a/usb/interface.go b/usb/interface.go index b926e84..a4643fc 100644 --- a/usb/interface.go +++ b/usb/interface.go @@ -17,6 +17,7 @@ package usb import ( "fmt" + "sort" ) // InterfaceInfo contains information about a USB interface, extracted from @@ -48,15 +49,24 @@ type InterfaceSetting struct { SubClass Class // Protocol is USB protocol code, as defined by the USB spe.c Protocol Protocol - // Endpoints has the list of endpoints available on this interface with + // Endpoints enumerates the endpoints available on this interface with // this alternate setting. - Endpoints []EndpointInfo + Endpoints map[int]EndpointInfo +} + +func (a InterfaceSetting) sortedEndpointIds() []string { + var eps []string + for _, ei := range a.Endpoints { + eps = append(eps, fmt.Sprintf("%d(%s)", ei.Number, ei.Direction)) + } + sort.Strings(eps) + return eps } // String returns a human-readable descripton of the particular // alternate setting of an interface. func (a InterfaceSetting) String() string { - return fmt.Sprintf("Interface %d alternate setting %d", a.Number, a.Alternate) + return fmt.Sprintf("Interface %d alternate setting %d (available endpoints: %v)", a.Number, a.Alternate, a.sortedEndpointIds()) } type Interface struct { @@ -83,17 +93,9 @@ func (i *Interface) Close() { func (i *Interface) openEndpoint(epNum int) (*endpoint, error) { var ep EndpointInfo - var found bool - for _, e := range i.Setting.Endpoints { - if e.Number == epNum { - debug.Printf("found ep %s in %s\n", e, i) - ep = e - found = true - break - } - } - if !found { - return nil, fmt.Errorf("%s does not have endpoint number %d. Available endpoints: %v", i, epNum, i.Setting.Endpoints) + ep, ok := i.Setting.Endpoints[epNum] + if !ok { + return nil, fmt.Errorf("%s does not have endpoint number %d. Available endpoints: %v", i, epNum, i.Setting.sortedEndpointIds()) } return &endpoint{ InterfaceSetting: i.Setting, diff --git a/usb/libusb.go b/usb/libusb.go index 45b26db..9f73873 100644 --- a/usb/libusb.go +++ b/usb/libusb.go @@ -260,10 +260,11 @@ func (libusbImpl) getDeviceDesc(d *libusbDevice) (*Descriptor, error) { Len: int(alt.bNumEndpoints), Cap: int(alt.bNumEndpoints), } - i.Endpoints = make([]EndpointInfo, len(ends)) - for n, end := range ends { + i.Endpoints = make(map[int]EndpointInfo, len(ends)) + for _, end := range ends { // TODO(sebek): pass the device descriptor too. - i.Endpoints[n] = libusbEndpoint(end).endpointInfo(nil) + epi := libusbEndpoint(end).endpointInfo(nil) + i.Endpoints[epi.Number] = epi } descs = append(descs, i) }