diff --git a/usb/config.go b/usb/config.go index 7ee8844..da36aeb 100644 --- a/usb/config.go +++ b/usb/config.go @@ -17,37 +17,31 @@ package usb import ( "fmt" + "strings" + "time" ) type EndpointInfo struct { - Address uint8 - Attributes uint8 - MaxPacketSize uint16 - MaxIsoPacket uint32 - PollInterval uint8 - RefreshRate uint8 - SynchAddress uint8 -} - -func (e EndpointInfo) Number() int { - return int(e.Address & EndpointNumMask) -} - -func (e EndpointInfo) TransferType() TransferType { - return TransferType(e.Attributes & TransferTypeMask) -} - -func (e EndpointInfo) Direction() EndpointDirection { - return EndpointDirection(e.Address & EndpointDirectionMask) + Number uint8 + Direction EndpointDirection + MaxPacketSize uint32 + TransferType TransferType + PollInterval time.Duration + IsoSyncType IsoSyncType + UsageType UsageType } func (e EndpointInfo) String() string { - return fmt.Sprintf("Endpoint #%d %-3s %s - %s %s [%d %d]", - e.Number(), e.Direction(), e.TransferType(), - IsoSyncType(e.Attributes)&IsoSyncTypeMask, - IsoUsageType(e.Attributes)&IsoUsageTypeMask, - e.MaxPacketSize, e.MaxIsoPacket, - ) + ret := make([]string, 0, 3) + ret = append(ret, fmt.Sprintf("Endpoint #%d %s (address 0x%02x) %s", e.Number, e.Direction, uint8(e.Number)|uint8(e.Direction), e.TransferType)) + switch e.TransferType { + case TransferTypeIsochronous: + ret = append(ret, fmt.Sprintf("- %s %s", e.IsoSyncType, e.UsageType)) + case TransferTypeInterrupt: + ret = append(ret, fmt.Sprintf("- %s", e.UsageType)) + } + ret = append(ret, fmt.Sprintf("[%d bytes]", e.MaxPacketSize)) + return strings.Join(ret, " ") } type InterfaceInfo struct { diff --git a/usb/config_test.go b/usb/config_test.go index f4cbbcf..288eee7 100644 --- a/usb/config_test.go +++ b/usb/config_test.go @@ -9,20 +9,23 @@ func TestEndpointInfo(t *testing.T) { }{ { ep: EndpointInfo{ - Address: 0x86, - Attributes: 0x02, + Number: 6, + Direction: EndpointDirectionIn, + TransferType: TransferTypeBulk, MaxPacketSize: 512, }, - want: "Endpoint #6 IN bulk - unsynchronized data [512 0]", + want: "Endpoint #6 IN (address 0x86) bulk [512 bytes]", }, { ep: EndpointInfo{ - Address: 0x02, - Attributes: 0x05, + Number: 2, + Direction: EndpointDirectionOut, + TransferType: TransferTypeIsochronous, MaxPacketSize: 512, - MaxIsoPacket: 512, + IsoSyncType: IsoSyncTypeAsync, + UsageType: IsoUsageTypeData, }, - want: "Endpoint #2 OUT isochronous - asynchronous data [512 512]", + want: "Endpoint #2 OUT (address 0x02) isochronous - asynchronous data [512 bytes]", }, } { if got := tc.ep.String(); got != tc.want { diff --git a/usb/constants.go b/usb/constants.go index b6ee82f..d1d1d02 100644 --- a/usb/constants.go +++ b/usb/constants.go @@ -144,23 +144,32 @@ func (ist IsoSyncType) String() string { return isoSyncTypeDescription[ist] } -type IsoUsageType uint8 +type UsageType uint8 const ( - IsoUsageTypeData IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_DATA << 4 - IsoUsageTypeFeedback IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_FEEDBACK << 4 - IsoUsageTypeImplicit IsoUsageType = C.LIBUSB_ISO_USAGE_TYPE_IMPLICIT << 4 - IsoUsageTypeMask = 0x30 + // Note: USB3.0 defines usage type for both isochronous and interrupt + // endpoints, with the same constants representing different usage types. + // UsageType constants do not correspond to bmAttribute values. + UsageTypeMask = 0x30 + UsageTypeUndefined UsageType = iota + IsoUsageTypeData + IsoUsageTypeFeedback + IsoUsageTypeImplicit + InterruptUsageTypePeriodic + InterruptUsageTypeNotification ) -var isoUsageTypeDescription = map[IsoUsageType]string{ - IsoUsageTypeData: "data", - IsoUsageTypeFeedback: "feedback", - IsoUsageTypeImplicit: "implicit data", +var usageTypeDescription = map[UsageType]string{ + UsageTypeUndefined: "undefined usage", + IsoUsageTypeData: "data", + IsoUsageTypeFeedback: "feedback", + IsoUsageTypeImplicit: "implicit data", + InterruptUsageTypePeriodic: "periodic", + InterruptUsageTypeNotification: "notification", } -func (iut IsoUsageType) String() string { - return isoUsageTypeDescription[iut] +func (ut UsageType) String() string { + return usageTypeDescription[ut] } type RequestType uint8 diff --git a/usb/device.go b/usb/device.go index 46ff63f..5937dde 100644 --- a/usb/device.go +++ b/usb/device.go @@ -92,7 +92,7 @@ func (d *Device) Close() error { return nil } -func (d *Device) OpenEndpoint(cfgNum, ifNum, setNum, epNum uint8) (*Endpoint, error) { +func (d *Device) OpenEndpoint(epNum, cfgNum, ifNum, setNum uint8) (*Endpoint, error) { var cfg *ConfigInfo for _, c := range d.Configs { if c.Config == cfgNum { @@ -132,7 +132,7 @@ func (d *Device) OpenEndpoint(cfgNum, ifNum, setNum, epNum uint8) (*Endpoint, er var ep *EndpointInfo for _, e := range ifs.Endpoints { - if e.Address == epNum { + if e.Number == epNum { debug.Printf("found ep %02x in %#v\n", epNum, *ifs) ep = &e } diff --git a/usb/endpoint.go b/usb/endpoint.go index 1a75804..0827b6f 100644 --- a/usb/endpoint.go +++ b/usb/endpoint.go @@ -24,14 +24,14 @@ type Endpoint struct { h *libusbDevHandle InterfaceSetup - EndpointInfo + Info EndpointInfo readTimeout time.Duration writeTimeout time.Duration } func (e *Endpoint) Read(buf []byte) (int, error) { - if EndpointDirection(e.Address)&EndpointDirectionMask != EndpointDirectionIn { + if e.Info.Direction != EndpointDirectionIn { return 0, fmt.Errorf("usb: read: not an IN endpoint") } @@ -39,22 +39,19 @@ func (e *Endpoint) Read(buf []byte) (int, error) { } func (e *Endpoint) Write(buf []byte) (int, error) { - if EndpointDirection(e.Address)&EndpointDirectionMask != EndpointDirectionOut { + if e.Info.Direction != EndpointDirectionOut { return 0, fmt.Errorf("usb: write: not an OUT endpoint") } return e.transfer(buf, e.writeTimeout) } -func (e *Endpoint) Interface() InterfaceSetup { return e.InterfaceSetup } -func (e *Endpoint) Info() EndpointInfo { return e.EndpointInfo } - func (e *Endpoint) transfer(buf []byte, timeout time.Duration) (int, error) { if len(buf) == 0 { return 0, nil } - t, err := newUSBTransfer(e.h, e.EndpointInfo, buf, timeout) + t, err := newUSBTransfer(e.h, &e.Info, buf, timeout) if err != nil { return 0, err } @@ -74,7 +71,7 @@ func (e *Endpoint) transfer(buf []byte, timeout time.Duration) (int, error) { func newEndpoint(h *libusbDevHandle, s InterfaceSetup, e EndpointInfo, rt, wt time.Duration) *Endpoint { return &Endpoint{ InterfaceSetup: s, - EndpointInfo: e, + Info: e, h: h, readTimeout: rt, writeTimeout: wt, diff --git a/usb/endpoint_info_test.go b/usb/endpoint_info_test.go index 45f6f0d..c7159f7 100644 --- a/usb/endpoint_info_test.go +++ b/usb/endpoint_info_test.go @@ -14,12 +14,14 @@ package usb +import "time" + // IN bulk endpoint var testBulkInEP = EndpointInfo{ - Address: 0x82, - Attributes: uint8(TransferTypeBulk), + Number: 2, + Direction: EndpointDirectionIn, MaxPacketSize: 512, - PollInterval: 1, + TransferType: TransferTypeBulk, } var testBulkInSetup = InterfaceSetup{ @@ -31,11 +33,11 @@ var testBulkInSetup = InterfaceSetup{ // OUT iso endpoint var testIsoOutEP = EndpointInfo{ - Address: 0x06, - Attributes: uint8(TransferTypeIsochronous), - MaxPacketSize: 3<<11 + 1024, - MaxIsoPacket: 3 * 1024, - PollInterval: 1, + Number: 6, + MaxPacketSize: 3 * 1024, + TransferType: TransferTypeIsochronous, + PollInterval: 125 * time.Microsecond, + UsageType: IsoUsageTypeData, } var testIsoOutSetup = InterfaceSetup{ diff --git a/usb/endpoint_test.go b/usb/endpoint_test.go index 9a3ffea..bda4115 100644 --- a/usb/endpoint_test.go +++ b/usb/endpoint_test.go @@ -90,7 +90,7 @@ func TestEndpoint(t *testing.T) { func TestEndpointWrongDirection(t *testing.T) { ep := &Endpoint{ InterfaceSetup: testBulkInSetup, - EndpointInfo: testBulkInEP, + Info: testBulkInEP, } _, err := ep.Write([]byte{1, 2, 3}) if err == nil { @@ -98,7 +98,7 @@ func TestEndpointWrongDirection(t *testing.T) { } ep = &Endpoint{ InterfaceSetup: testIsoOutSetup, - EndpointInfo: testIsoOutEP, + Info: testIsoOutEP, } _, err = ep.Read(make([]byte, 64)) if err == nil { @@ -120,15 +120,11 @@ func TestOpenEndpoint(t *testing.T) { if err != nil { t.Fatalf("OpenDeviceWithVidPid(0x8888, 0x0002): got error %v, want nil", err) } - ep, err := dev.OpenEndpoint(1, 1, 2, 0x86) + got, err := dev.OpenEndpoint(6, 1, 1, 2) if err != nil { - t.Errorf("OpenEndpoint(cfg=1, if=1, alt=2, ep=0x86): got error %v, want nil", err) + t.Fatalf("OpenEndpoint(cfg=1, if=1, alt=2, ep=0x86): got error %v, want nil", err) } - i := ep.Info() - if got, want := i.Address, uint8(0x86); got != want { - t.Errorf("OpenEndpoint(cfg=1, if=1, alt=2, ep=0x86): ep.Info.Address = %x, want %x", got, want) - } - if got, want := i.MaxIsoPacket, uint32(1024); got != want { - t.Errorf("OpenEndpoint(cfg=1, if=1, alt=2, ep=0x86): ep.Info.MaxIsoPacket = %d, want %d", got, want) + if want := fakeDevices[1].Configs[0].Interfaces[1].Setups[2].Endpoints[1]; !reflect.DeepEqual(got.Info, want) { + t.Errorf("OpenEndpoint(cfg=1, if=1, alt=2, ep=0x86): got %+v, want %+v", got, want) } } diff --git a/usb/fakelibusb_test.go b/usb/fakelibusb_test.go index e251bd1..dab5eee 100644 --- a/usb/fakelibusb_test.go +++ b/usb/fakelibusb_test.go @@ -46,13 +46,15 @@ var ( Alternate: 0, IfClass: uint8(ClassVendorSpec), Endpoints: []EndpointInfo{{ - Address: uint8(0x01 | EndpointDirectionOut), - Attributes: uint8(TransferTypeBulk), + Number: 1, + Direction: EndpointDirectionOut, MaxPacketSize: 512, + TransferType: TransferTypeBulk, }, { - Address: uint8(0x02 | EndpointDirectionIn), - Attributes: uint8(TransferTypeBulk), + Number: 2, + Direction: EndpointDirectionIn, MaxPacketSize: 512, + TransferType: TransferTypeBulk, }}, }}, }}, @@ -87,45 +89,47 @@ var ( Alternate: 0, IfClass: uint8(ClassVendorSpec), Endpoints: []EndpointInfo{{ - Address: uint8(0x05 | EndpointDirectionOut), - Attributes: uint8(TransferTypeIsochronous), - MaxPacketSize: 2<<11 | 1024, - MaxIsoPacket: 3 * 1024, + Number: 5, + Direction: EndpointDirectionOut, + MaxPacketSize: 3 * 1024, + TransferType: TransferTypeIsochronous, + UsageType: IsoUsageTypeData, }, { - Address: uint8(0x06 | EndpointDirectionIn), - Attributes: uint8(TransferTypeIsochronous), - MaxPacketSize: 2<<11 | 1024, - MaxIsoPacket: 3 * 1024, + Number: 6, + Direction: EndpointDirectionIn, + MaxPacketSize: 3 * 1024, + TransferType: TransferTypeIsochronous, + UsageType: IsoUsageTypeData, }}, }, { Number: 1, Alternate: 1, IfClass: uint8(ClassVendorSpec), Endpoints: []EndpointInfo{{ - Address: uint8(0x05 | EndpointDirectionOut), - Attributes: uint8(TransferTypeIsochronous), - MaxPacketSize: 1<<11 | 1024, - MaxIsoPacket: 2 * 1024, + Number: 5, + Direction: EndpointDirectionOut, + MaxPacketSize: 2 * 1024, + TransferType: TransferTypeIsochronous, }, { - Address: uint8(0x06 | EndpointDirectionIn), - Attributes: uint8(TransferTypeIsochronous), - MaxPacketSize: 1<<11 | 1024, - MaxIsoPacket: 2 * 1024, + Number: 6, + Direction: EndpointDirectionIn, + MaxPacketSize: 2 * 1024, + TransferType: TransferTypeIsochronous, }}, }, { Number: 1, Alternate: 2, IfClass: uint8(ClassVendorSpec), Endpoints: []EndpointInfo{{ - Address: uint8(0x05 | EndpointDirectionOut), - Attributes: uint8(TransferTypeIsochronous), + Number: 5, + Direction: EndpointDirectionIn, MaxPacketSize: 1024, - MaxIsoPacket: 1024, + TransferType: TransferTypeIsochronous, }, { - Address: uint8(0x06 | EndpointDirectionIn), - Attributes: uint8(TransferTypeIsochronous), + Number: 6, + Direction: EndpointDirectionIn, MaxPacketSize: 1024, - MaxIsoPacket: 1024, + TransferType: TransferTypeIsochronous, }}, }}, }}, @@ -256,7 +260,7 @@ func (f *fakeLibusb) setAlt(d *libusbDevHandle, intf, alt uint8) error { return nil } -func (f *fakeLibusb) alloc(_ *libusbDevHandle, _ uint8, _ TransferType, _ time.Duration, _ int, buf []byte) (*libusbTransfer, error) { +func (f *fakeLibusb) alloc(_ *libusbDevHandle, _ *EndpointInfo, _ time.Duration, _ int, buf []byte) (*libusbTransfer, error) { f.mu.Lock() defer f.mu.Unlock() t := new(libusbTransfer) diff --git a/usb/libusb.go b/usb/libusb.go index f88f079..efa0c9a 100644 --- a/usb/libusb.go +++ b/usb/libusb.go @@ -36,6 +36,74 @@ type libusbDevice C.libusb_device type libusbDevHandle C.libusb_device_handle type libusbTransfer C.struct_libusb_transfer type libusbIso C.struct_libusb_iso_packet_descriptor +type libusbEndpoint C.struct_libusb_endpoint_descriptor + +func (ep libusbEndpoint) endpointInfo(dev *Descriptor) EndpointInfo { + ei := EndpointInfo{ + Number: uint8(ep.bEndpointAddress & EndpointNumMask), + Direction: EndpointDirection(ep.bEndpointAddress & EndpointDirectionMask), + TransferType: TransferType(ep.bmAttributes & TransferTypeMask), + MaxPacketSize: uint32(ep.wMaxPacketSize), + } + if ei.TransferType == TransferTypeIsochronous { + // bits 0-10 identify the packet size, bits 11-12 are the number of additional transactions per microframe. + // Don't use libusb_get_max_iso_packet_size, as it has a bug where it returns the same value + // regardless of alternative setting used, where different alternative settings might define different + // max packet sizes. + // See http://libusb.org/ticket/77 for more background. + ei.MaxPacketSize = uint32(ep.wMaxPacketSize) & 0x07ff * (uint32(ep.wMaxPacketSize)>>11&3 + 1) + ei.IsoSyncType = IsoSyncType(ep.bmAttributes & IsoSyncTypeMask) + switch ep.bmAttributes & UsageTypeMask { + case C.LIBUSB_ISO_USAGE_TYPE_DATA: + ei.UsageType = IsoUsageTypeData + case C.LIBUSB_ISO_USAGE_TYPE_FEEDBACK: + ei.UsageType = IsoUsageTypeFeedback + case C.LIBUSB_ISO_USAGE_TYPE_IMPLICIT: + ei.UsageType = IsoUsageTypeImplicit + } + } + // TODO(sebek): PollInterval does not work yet. The meaning of bInterval + // in the descriptor varies depending on the device and USB version: + // - if the device conforms to USB1.x: + // Interval for polling endpoint for data transfers. Expressed in + // milliseconds. + // This field is ignored for bulk and control endpoints. For + // isochronous endpoints this field must be set to 1. For interrupt + // endpoints, this field may range from 1 to 255. + // - if the device conforms to USB[23].x and the device is in low speed + // of full speed mode: + // Interval for polling endpoint for data transfers. Expressed in + // frames or microframes depending on the device operating speed + // (i.e., either 1 millisecond or 125 µs units). + // For full-/high-speed isochronous endpoints, this value must be in + // the range from 1 to 16. The bInterval value is used as the exponent + // for a 2bInterval-1 value; e.g., a bInterval of 4 means a period + // of 8 (24-1). + // For full-/low-speed interrupt endpoints, the value of this field may + // be from 1 to 255. + // For high-speed interrupt endpoints, the bInterval value is used as + // the exponent for a 2bInterval-1 value; e.g., a bInterval of 4 means + // a period of 8 (24-1). This value must be from 1 to 16. + // For high-speed bulk/control OUT endpoints, the bInterval must + // specify the maximum NAK rate of the endpoint. A value of 0 indicates + // the endpoint never NAKs. Other values indicate at most 1 NAK each + // bInterval number of microframes. This value must be in the range + // from 0 to 255. + // - if the device conforms to USB3.x and the device is in SuperSpeed mode: + // Interval for servicing the endpoint for data transfers. Expressed in + // 125-µs units. + // For Enhanced SuperSpeed isochronous and interrupt endpoints, this + // value shall be in the range from 1 to 16. However, the valid ranges + // are 8 to 16 for Notification type Interrupt endpoints. The bInterval + // value is used as the exponent for a 2(bInterval-1) value; e.g., a + // bInterval of 4 means a period of 8 (2(4-1) → 23 → 8). + // This field is reserved and shall not be used for Enhanced SuperSpeed + // bulk or control endpoints. + // + // Note: in low-speed mode, isochronous transfers are not supported. + ei.PollInterval = 0 + return ei +} // libusbIntf is a set of trivial idiomatic Go wrappers around libusb C functions. // The underlying code is generally not testable or difficult to test, @@ -70,7 +138,7 @@ type libusbIntf interface { setAlt(*libusbDevHandle, uint8, uint8) error // transfer - alloc(*libusbDevHandle, uint8, TransferType, time.Duration, int, []byte) (*libusbTransfer, error) + alloc(*libusbDevHandle, *EndpointInfo, time.Duration, int, []byte) (*libusbTransfer, error) cancel(*libusbTransfer) error submit(*libusbTransfer, chan struct{}) error data(*libusbTransfer) (int, TransferStatus) @@ -184,24 +252,9 @@ func (libusbImpl) getDeviceDesc(d *libusbDevice) (*Descriptor, error) { Cap: int(alt.bNumEndpoints), } i.Endpoints = make([]EndpointInfo, 0, len(ends)) - for _, end := range ends { - ei := EndpointInfo{ - Address: uint8(end.bEndpointAddress), - Attributes: uint8(end.bmAttributes), - MaxPacketSize: uint16(end.wMaxPacketSize), - PollInterval: uint8(end.bInterval), - RefreshRate: uint8(end.bRefresh), - SynchAddress: uint8(end.bSynchAddress), - } - if ei.TransferType() == TransferTypeIsochronous { - // bits 0-10 identify the packet size, bits 11-12 are the number of additional transactions per microframe. - // Don't use libusb_get_max_iso_packet_size, as it has a bug where it returns the same value - // regardless of alternative setting used, where different alternative settings might define different - // max packet sizes. - // See http://libusb.org/ticket/77 for more background. - ei.MaxIsoPacket = uint32(end.wMaxPacketSize) & 0x07ff * (uint32(end.wMaxPacketSize)>>11&3 + 1) - } - i.Endpoints = append(i.Endpoints, ei) + for n, end := range ends { + // TODO(sebek): pass the device descriptor too. + i.Endpoints[n] = libusbEndpoint(end).endpointInfo(nil) } descs = append(descs, i) } @@ -313,15 +366,15 @@ func (libusbImpl) setAlt(d *libusbDevHandle, iface, setup uint8) error { return fromUSBError(C.libusb_set_interface_alt_setting((*C.libusb_device_handle)(d), C.int(iface), C.int(setup))) } -func (libusbImpl) alloc(d *libusbDevHandle, addr uint8, tt TransferType, timeout time.Duration, isoPackets int, buf []byte) (*libusbTransfer, error) { +func (libusbImpl) alloc(d *libusbDevHandle, ep *EndpointInfo, timeout time.Duration, isoPackets int, buf []byte) (*libusbTransfer, error) { xfer := C.libusb_alloc_transfer(C.int(isoPackets)) if xfer == nil { return nil, fmt.Errorf("libusb_alloc_transfer(%d) failed", isoPackets) } xfer.dev_handle = (*C.libusb_device_handle)(d) - xfer.endpoint = C.uchar(addr) + xfer.endpoint = C.uchar(uint8(ep.Number&EndpointNumMask) | uint8(ep.Direction&EndpointDirectionMask)) xfer.timeout = C.uint(timeout / time.Millisecond) - xfer._type = C.uchar(tt) + xfer._type = C.uchar(ep.TransferType) xfer.num_iso_packets = C.int(isoPackets) xfer.buffer = (*C.uchar)((unsafe.Pointer)(&buf[0])) xfer.length = C.int(len(buf)) diff --git a/usb/transfer.go b/usb/transfer.go index cd42048..9dff4d7 100644 --- a/usb/transfer.go +++ b/usb/transfer.go @@ -112,23 +112,22 @@ func (t *usbTransfer) free() error { // newUSBTransfer allocates a new transfer structure for communication with a // given device/endpoint, with buf as the underlying transfer buffer. -func newUSBTransfer(dev *libusbDevHandle, ei EndpointInfo, buf []byte, timeout time.Duration) (*usbTransfer, error) { +func newUSBTransfer(dev *libusbDevHandle, ei *EndpointInfo, buf []byte, timeout time.Duration) (*usbTransfer, error) { var isoPackets int - tt := ei.TransferType() - if tt == TransferTypeIsochronous { - isoPackets = len(buf) / int(ei.MaxIsoPacket) - if int(ei.MaxIsoPacket)*isoPackets < len(buf) { + if ei.TransferType == TransferTypeIsochronous { + isoPackets = len(buf) / int(ei.MaxPacketSize) + if int(ei.MaxPacketSize)*isoPackets < len(buf) { isoPackets++ } } - xfer, err := libusb.alloc(dev, ei.Address, tt, timeout, isoPackets, buf) + xfer, err := libusb.alloc(dev, ei, timeout, isoPackets, buf) if err != nil { return nil, err } - if tt == TransferTypeIsochronous { - libusb.setIsoPacketLengths(xfer, ei.MaxIsoPacket) + if ei.TransferType == TransferTypeIsochronous { + libusb.setIsoPacketLengths(xfer, ei.MaxPacketSize) } t := &usbTransfer{ diff --git a/usb/transfer_test.go b/usb/transfer_test.go index 6e13ae6..887aef0 100644 --- a/usb/transfer_test.go +++ b/usb/transfer_test.go @@ -27,8 +27,7 @@ func TestNewTransfer(t *testing.T) { desc string dir EndpointDirection tt TransferType - maxPkt uint16 - maxIso uint32 + maxPkt uint32 buf int timeout time.Duration wantIso int @@ -48,18 +47,16 @@ func TestNewTransfer(t *testing.T) { desc: "iso out transfer, 3 * 1024B packets", dir: EndpointDirectionOut, tt: TransferTypeIsochronous, - maxPkt: 2<<11 + 1024, - maxIso: 3 * 1024, + maxPkt: 3 * 1024, buf: 10000, wantLength: 10000, }, } { - xfer, err := newUSBTransfer(nil, EndpointInfo{ - Address: uint8(tc.dir) | 0x02, - Attributes: uint8(tc.tt), + xfer, err := newUSBTransfer(nil, &EndpointInfo{ + Number: 2, + Direction: tc.dir, + TransferType: tc.tt, MaxPacketSize: tc.maxPkt, - MaxIsoPacket: tc.maxIso, - PollInterval: 1, }, make([]byte, tc.buf), tc.timeout) if err != nil { @@ -80,11 +77,11 @@ func TestTransferProtocol(t *testing.T) { xfers := make([]*usbTransfer, 2) var err error for i := 0; i < 2; i++ { - xfers[i], err = newUSBTransfer(nil, EndpointInfo{ - Address: 0x86, - Attributes: uint8(TransferTypeBulk), + xfers[i], err = newUSBTransfer(nil, &EndpointInfo{ + Number: 6, + Direction: EndpointDirectionIn, + TransferType: TransferTypeBulk, MaxPacketSize: 512, - PollInterval: 1, }, make([]byte, 10240), time.Second) if err != nil { t.Fatalf("newUSBTransfer: %v", err)