I am currently trying to interface with a USB audio device from user land. I currently have the device fully enumerated and I've set the interface and set the alternative interface to the interface non-zero-bandwidth alternative interface.
Firstly I have to say I can't use anything like libusb. I ned to do this via Linux's USB device file system.
So as far as I can tell I'm ready to begin receiving isochronous data. However I can find very little information on how to do an isochronous transfer.
From what I can tell I need to populate a usbdevfs_urb structure but I'm completely unsure of how exactly to fill this structure.
Also, once I have filled this structure am I right in thinking I need to call the following:
int retSubmit = ioctl( fd, USBDEVFS_SUBMITURB, &usbRequest );
and then once submitted I can wait for the request to complete using
USBDEVFS_REAPURBNDELAY
In the case of REAPURBNDELAY what exactly is the parameter I need to pass?
Am I even barking up the right tree?
Any information would be massively appreciated.
Thanks in advance!
Edit:
I attempt to do the isochronous transfer as follows:
usbdevfs_urb& urbRequest = *(usbdevfs_urb*)malloc( 384 );
urbRequest.type = USBDEVFS_URB_TYPE_ISO;
urbRequest.endpoint = mpEndpoint->GetEndpointAddress();//mpEndpoint->GetEndpointIndex();
urbRequest.status = 0;
urbRequest.flags = USBDEVFS_URB_ISO_ASAP;
urbRequest.buffer = pData;
urbRequest.buffer_length = 0;
urbRequest.actual_length = 0;
urbRequest.start_frame = 0;
urbRequest.number_of_packets = 1;
urbRequest.error_count = 0;
urbRequest.signr = 0;
urbRequest.usercontext = pData;
usbdevfs_iso_packet_desc* pIsoPacketDesc = &urbRequest.iso_frame_desc[0];
pIsoPacketDesc->length = 384;
pIsoPacketDesc->actual_length = 0;
pIsoPacketDesc->status = 0;
Unfgortunately this gives me an error of -28 (ENOSPC).
<7>[ 3184.243163] usb 1-1: usbfs: usb_submit_urb returned -28
I can't understand why there wouldn't be enough usb bus bandwidth. There is only 1 usb port and my device is the only device plugged into it.
Any thoughts?
Ok so it turns out that the problem is due to the fact that the android OS has placed an HID driver to handle the HID controls. This seems to block up the bandwidth. Detaching these drivers from the HID interfaces releases the bandwidth allowing the isochronous transfer to proceed.
You detach the kernel driver by doing the following:
usbdevfs_ioctl command;
command.ifno = mpInterface->GetInterfaceNumber();
command.ioctl_code = USBDEVFS_DISCONNECT;
command.data = NULL;
int ret = ioctl( fd, USBDEVFS_IOCTL, &command );
Otherwise what I have done is correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With