Пользовательский режим Изохронный перенос USB с устройства на хост
В настоящее время я пытаюсь подключиться к USB-аудиоустройству с пользовательской земли. В настоящее время у меня есть полное перечисление устройства, и я установил интерфейс и установил альтернативный интерфейс для альтернативного интерфейса без ненулевой полосы пропускания.
Во-первых, я должен сказать, что не могу использовать ничего подобного libusb. Я сделал это через файловую систему Linux USB.
Итак, насколько я могу судить, я готов начать получать изохронные данные. Однако я могу найти очень мало информации о том, как сделать изохронную передачу.
Из того, что я могу сказать, мне нужно заполнить структуру usbdevfs_urb, но я совершенно не уверен, как именно заполнить эту структуру.
Кроме того, как только я заполнил эту структуру, я правильно понял, что мне нужно вызвать следующее:
int retSubmit = ioctl( fd, USBDEVFS_SUBMITURB, &usbRequest );
а затем после отправки я могу дождаться завершения запроса с помощью
USBDEVFS_REAPURBNDELAY
В случае REAPURBNDELAY, какой именно параметр мне нужно передать?
Я даже лаю по правильному дереву?
Любая информация будет широко оценена.
Спасибо заранее!
Edit:
Я пытаюсь выполнить изохронную передачу следующим образом:
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;
Несчастливо это дает мне ошибку -28 (ENOSPC).
<7>[ 3184.243163] usb 1-1: usbfs: usb_submit_urb returned -28
Я не понимаю, почему пропускной способности шины USB не хватит. Существует только 1 USB-порт, и мое устройство является единственным устройством, подключенным к нему.
Любые мысли?
Ответы
Ответ 1
Хорошо, поэтому выясняется, что проблема связана с тем, что ОС Android установила HID-драйвер для управления элементами HID. Это, похоже, блокирует пропускную способность. Отключение этих драйверов от интерфейсов HID освобождает полосу пропускания, позволяющую продолжить изохронную передачу.
Вы отсоединяете драйвер ядра, выполняя следующие действия:
usbdevfs_ioctl command;
command.ifno = mpInterface->GetInterfaceNumber();
command.ioctl_code = USBDEVFS_DISCONNECT;
command.data = NULL;
int ret = ioctl( fd, USBDEVFS_IOCTL, &command );
В противном случае то, что я сделал, является правильным.
Ответ 2
Я понимаю, что единственная причина, по которой вы не используете libusb, заключается в том, что вы не можете самостоятельно открыть устройство USB, но у вас есть файловый дескриптор, указывающий на него.
Если это все правильно, почему вы пытаетесь повторно реализовать все, что есть в libusb, вместо того, чтобы просто повторно использовать функцию usb_open(), которая принимает файловый дескриптор в качестве аргумента и вашу структуру usb_device *. Вы можете взять большую часть кода из исходного кода libusb usb_open() и использовать libusb для остальных.
Ответ 3
Я написал класс Java для пользовательского режима USB изохронной передачи: UsbIso
Он использует JNA для доступа к USBFS API через вызовы IOCTL.