Skip to content

Commit 0b72b1b

Browse files
committed
src/usb_libusb10.c: slightly smarter isoc error handling.
Unless we get LIBUSB_TRANSFER_NO_DEVICE or LIBUSB_TRANSFER_CANCELLED, we really should resubmit unsucessful transfers, or eventually all of them will error and we won't stream any transfers anymore. We should also correctly track the number of dead transfers if we fail to submit a transfer. Fixes OpenKinect#227. Signed-off-by: Drew Fisher <[email protected]>
1 parent 02b55b3 commit 0b72b1b

File tree

1 file changed

+42
-11
lines changed

1 file changed

+42
-11
lines changed

src/usb_libusb10.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -273,17 +273,46 @@ static void iso_callback(struct libusb_transfer *xfer)
273273
return;
274274
}
275275

276-
if(xfer->status == LIBUSB_TRANSFER_COMPLETED) {
277-
uint8_t *buf = (uint8_t*)xfer->buffer;
278-
for (i=0; i<strm->pkts; i++) {
279-
strm->cb(strm->parent->parent, buf, xfer->iso_packet_desc[i].actual_length);
280-
buf += strm->len;
276+
switch(xfer->status) {
277+
case LIBUSB_TRANSFER_COMPLETED: // Normal operation.
278+
{
279+
uint8_t *buf = (uint8_t*)xfer->buffer;
280+
for (i=0; i<strm->pkts; i++) {
281+
strm->cb(strm->parent->parent, buf, xfer->iso_packet_desc[i].actual_length);
282+
buf += strm->len;
283+
}
284+
libusb_submit_transfer(xfer);
285+
break;
286+
}
287+
case LIBUSB_TRANSFER_NO_DEVICE:
288+
{
289+
// We lost the device we were talking to. This is a large problem,
290+
// and one that we should eventually come up with a way to
291+
// properly propagate up to the caller.
292+
freenect_context *ctx = strm->parent->parent->parent;
293+
FN_ERROR("USB device disappeared, cancelling stream :(\n");
294+
strm->dead_xfers++;
295+
fnusb_stop_iso(strm->parent, strm);
296+
break;
297+
}
298+
case LIBUSB_TRANSFER_CANCELLED:
299+
{
300+
freenect_context *ctx = strm->parent->parent->parent;
301+
FN_SPEW("EP %02x transfer cancelled\n", xfer->endpoint);
302+
strm->dead_xfers++;
303+
break;
304+
}
305+
default:
306+
{
307+
// On other errors, resubmit the transfer - in particular, libusb
308+
// on OSX tends to hit random errors a lot. If we don't resubmit
309+
// the transfers, eventually all of them die and then we don't get
310+
// any more data from the Kinect.
311+
freenect_context *ctx = strm->parent->parent->parent;
312+
FN_WARNING("Isochronous transfer error: %d\n", xfer->status);
313+
libusb_submit_transfer(xfer);
314+
break;
281315
}
282-
libusb_submit_transfer(xfer);
283-
} else {
284-
freenect_context *ctx = strm->parent->parent->parent;
285-
FN_WARNING("Isochronous transfer error: %d\n", xfer->status);
286-
strm->dead_xfers++;
287316
}
288317
}
289318

@@ -313,8 +342,10 @@ int fnusb_start_iso(fnusb_dev *dev, fnusb_isoc_stream *strm, fnusb_iso_cb cb, in
313342
libusb_set_iso_packet_lengths(strm->xfers[i], len);
314343

315344
ret = libusb_submit_transfer(strm->xfers[i]);
316-
if (ret < 0)
345+
if (ret < 0) {
317346
FN_WARNING("Failed to submit isochronous transfer %d: %d\n", i, ret);
347+
strm->dead_xfers++;
348+
}
318349

319350
bufp += pkts*len;
320351
}

0 commit comments

Comments
 (0)