Use a map to store endpoint descriptors. Allows easy access to a

particular endpoint number.
This commit is contained in:
Sebastian Zagrodzki
2017-04-29 12:19:34 +02:00
parent 77c176cd4c
commit 6d81ca37d3
4 changed files with 79 additions and 64 deletions

View File

@@ -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 { for _, tc := range []struct {
desc string desc string
buf []byte buf []byte

View File

@@ -44,17 +44,20 @@ var (
Number: 0, Number: 0,
Alternate: 0, Alternate: 0,
Class: ClassVendorSpec, Class: ClassVendorSpec,
Endpoints: []EndpointInfo{{ Endpoints: map[int]EndpointInfo{
Number: 1, 1: {
Direction: EndpointDirectionOut, Number: 1,
MaxPacketSize: 512, Direction: EndpointDirectionOut,
TransferType: TransferTypeBulk, MaxPacketSize: 512,
}, { TransferType: TransferTypeBulk,
Number: 2, },
Direction: EndpointDirectionIn, 2: {
MaxPacketSize: 512, Number: 2,
TransferType: TransferTypeBulk, Direction: EndpointDirectionIn,
}}, MaxPacketSize: 512,
TransferType: TransferTypeBulk,
},
},
}}, }},
}}, }},
}}, }},
@@ -87,49 +90,58 @@ var (
Number: 1, Number: 1,
Alternate: 0, Alternate: 0,
Class: ClassVendorSpec, Class: ClassVendorSpec,
Endpoints: []EndpointInfo{{ Endpoints: map[int]EndpointInfo{
Number: 5, 5: {
Direction: EndpointDirectionOut, Number: 5,
MaxPacketSize: 3 * 1024, Direction: EndpointDirectionOut,
TransferType: TransferTypeIsochronous, MaxPacketSize: 3 * 1024,
UsageType: IsoUsageTypeData, TransferType: TransferTypeIsochronous,
}, { UsageType: IsoUsageTypeData,
Number: 6, },
Direction: EndpointDirectionIn, 6: {
MaxPacketSize: 3 * 1024, Number: 6,
TransferType: TransferTypeIsochronous, Direction: EndpointDirectionIn,
UsageType: IsoUsageTypeData, MaxPacketSize: 3 * 1024,
}}, TransferType: TransferTypeIsochronous,
UsageType: IsoUsageTypeData,
},
},
}, { }, {
Number: 1, Number: 1,
Alternate: 1, Alternate: 1,
Class: ClassVendorSpec, Class: ClassVendorSpec,
Endpoints: []EndpointInfo{{ Endpoints: map[int]EndpointInfo{
Number: 5, 5: {
Direction: EndpointDirectionOut, Number: 5,
MaxPacketSize: 2 * 1024, Direction: EndpointDirectionOut,
TransferType: TransferTypeIsochronous, MaxPacketSize: 2 * 1024,
}, { TransferType: TransferTypeIsochronous,
Number: 6, },
Direction: EndpointDirectionIn, 6: {
MaxPacketSize: 2 * 1024, Number: 6,
TransferType: TransferTypeIsochronous, Direction: EndpointDirectionIn,
}}, MaxPacketSize: 2 * 1024,
TransferType: TransferTypeIsochronous,
},
},
}, { }, {
Number: 1, Number: 1,
Alternate: 2, Alternate: 2,
Class: ClassVendorSpec, Class: ClassVendorSpec,
Endpoints: []EndpointInfo{{ Endpoints: map[int]EndpointInfo{
Number: 5, 5: {
Direction: EndpointDirectionIn, Number: 5,
MaxPacketSize: 1024, Direction: EndpointDirectionIn,
TransferType: TransferTypeIsochronous, MaxPacketSize: 1024,
}, { TransferType: TransferTypeIsochronous,
Number: 6, },
Direction: EndpointDirectionIn, 6: {
MaxPacketSize: 1024, Number: 6,
TransferType: TransferTypeIsochronous, Direction: EndpointDirectionIn,
}}, MaxPacketSize: 1024,
TransferType: TransferTypeIsochronous,
},
},
}}, }},
}}, }},
}}, }},

View File

@@ -17,6 +17,7 @@ package usb
import ( import (
"fmt" "fmt"
"sort"
) )
// InterfaceInfo contains information about a USB interface, extracted from // InterfaceInfo contains information about a USB interface, extracted from
@@ -48,15 +49,24 @@ type InterfaceSetting struct {
SubClass Class SubClass Class
// Protocol is USB protocol code, as defined by the USB spe.c // Protocol is USB protocol code, as defined by the USB spe.c
Protocol Protocol 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. // 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 // String returns a human-readable descripton of the particular
// alternate setting of an interface. // alternate setting of an interface.
func (a InterfaceSetting) String() string { 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 { type Interface struct {
@@ -83,17 +93,9 @@ func (i *Interface) Close() {
func (i *Interface) openEndpoint(epNum int) (*endpoint, error) { func (i *Interface) openEndpoint(epNum int) (*endpoint, error) {
var ep EndpointInfo var ep EndpointInfo
var found bool ep, ok := i.Setting.Endpoints[epNum]
for _, e := range i.Setting.Endpoints { if !ok {
if e.Number == epNum { return nil, fmt.Errorf("%s does not have endpoint number %d. Available endpoints: %v", i, epNum, i.Setting.sortedEndpointIds())
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)
} }
return &endpoint{ return &endpoint{
InterfaceSetting: i.Setting, InterfaceSetting: i.Setting,

View File

@@ -260,10 +260,11 @@ func (libusbImpl) getDeviceDesc(d *libusbDevice) (*Descriptor, error) {
Len: int(alt.bNumEndpoints), Len: int(alt.bNumEndpoints),
Cap: int(alt.bNumEndpoints), Cap: int(alt.bNumEndpoints),
} }
i.Endpoints = make([]EndpointInfo, len(ends)) i.Endpoints = make(map[int]EndpointInfo, len(ends))
for n, end := range ends { for _, end := range ends {
// TODO(sebek): pass the device descriptor too. // 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) descs = append(descs, i)
} }