From c27a77b547eac14996ea51e7ee3ca3a8a57308ed Mon Sep 17 00:00:00 2001 From: Sebastian Zagrodzki Date: Wed, 8 Feb 2017 23:02:08 +0100 Subject: [PATCH] Pass the max buffer size down to the alloc_transfer. Use the number of iso packets matching the buffer size. This guarantees that the transfer size is smaller or equal to the buffer. Device will transfer less data if iso transfer response does not utilize the maximum available number of iso packets per microframe or doesn't fill the packets entirely. --- usb/iso.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/usb/iso.go b/usb/iso.go index 517a126..a62df3a 100644 --- a/usb/iso.go +++ b/usb/iso.go @@ -37,18 +37,25 @@ func iso_callback(cptr unsafe.Pointer) { close(ch) } -func (end *endpoint) allocTransfer() *Transfer { - const ( - iso_packets = 8 // 128 // 242 - ) - - xfer := C.libusb_alloc_transfer(C.int(iso_packets)) +func (end *endpoint) allocTransfer(maxLen int) *Transfer { + isoPacketSize := end.EndpointInfo.MaxIsoPacket + // the larget the input buffer, the more packets we use in a single + // transfer. + numIsoPackets := maxLen / int(isoPacketSize) + if numIsoPackets*int(isoPacketSize) < maxLen { + numIsoPackets++ + } + // arbitrary limit + if numIsoPackets > 200 { + numIsoPackets = 200 + } + xfer := C.libusb_alloc_transfer(C.int(numIsoPackets)) if xfer == nil { log.Printf("usb: transfer allocation failed?!") return nil } - buf := make([]byte, iso_packets*end.EndpointInfo.MaxIsoPacket) + buf := make([]byte, numIsoPackets*int(end.EndpointInfo.MaxIsoPacket)) done := make(chan struct{}, 1) xfer.dev_handle = end.Device.handle @@ -57,7 +64,7 @@ func (end *endpoint) allocTransfer() *Transfer { xfer.buffer = (*C.uchar)((unsafe.Pointer)(&buf[0])) xfer.length = C.int(len(buf)) - xfer.num_iso_packets = iso_packets + xfer.num_iso_packets = C.int(numIsoPackets) C.libusb_set_iso_packet_lengths(xfer, C.uint(end.EndpointInfo.MaxIsoPacket)) /* @@ -130,7 +137,7 @@ func (t *Transfer) Close() error { } func isochronous_xfer(e *endpoint, buf []byte, timeout time.Duration) (int, error) { - t := e.allocTransfer() + t := e.allocTransfer(len(buf)) defer t.Close() if err := t.Submit(timeout); err != nil {