Как получить доступ к IOMemoryBufferDescriptor в CompleteAsyncIO, который отправляется через AsyncIO при прерывании EP - PullRequest
1 голос
/ 19 июня 2020
• 1000 Для этого завершения запроса (CompleteAsyncIO) вызывается с помощью action-> GetReference (). Я получил структуру ivars, я ожидал, что данные о завершении прерывания получены с USB-устройства, к сожалению, я не вижу связанных данных. В wirehark я попытался отладить полученные данные размером 16 байт, а фактических байтов CompleteAsyncIO также 16.

Каков правильный способ получить данные прерывания, полученные с устройства с помощью IOMemoryBufferDescriptor?

OSAction Create for CompleteAsyncIO

ret = OSAction::Create(this,
                       Data_interruptComplete_ID,
                       IOUSBHostPipe_CompleteAsyncIO_ID,
                       sizeof(IntActRef),
                       &ivars->interruptComplete);

Распределение дескриптора IOMemoryBufferDescriptor для EP прерывания USB:

IOBufferMemoryDescriptor*       fCommPipeMDP; 

ivars->fCommPipeMDP->Create(kIOMemoryDirectionIn,
                            ivars->fcomBuffSize,
                            0,
                            &ivars->fCommPipeMDP);

    ivars->fCommPipeMDP->SetLength(ivars->fcomBuffSize); 
    ivars->fCommPipeMDP->GetAddressRange(&aRange);
    ivars->fCommPipeBuffer = (uint8_t*)&aRange.address;

Отправить запрос AsyncIO на EP прерывания

ret = ivars->fCommPipe->AsyncIO(ivars->fCommPipeMDP,
                                ivars->fcomBuffSize,
                                ivars->interruptComplete,
                                0);

CompleteAsyncIO, вызываемого фреймворком

void
IMPL (ClassData,interruptComplete)
{
struct interruptActionRef *actionref = (struct interruptActionRef*)action->GetReference();
Data_IVars * livars = actionref->interruptactionref;

  for(tmp = 0; tmp < actualByteCount; tmp++)
  os_log(OS_LOG_DEFAULT, "%x",livars->fCommPipeBuffer[tmp]); 
  //TRYING PRINT DATA RECEIVED FROM USB DEVICE IN INTERRUPT COMPLETION(CompleteAsyncIO)
  //UNFORTUNATELY DATA IS NOT MATCHING
}

Как получить фактические данные, полученные с USB-устройства для завершения прерывания с помощью IOBufferMemoryDescriptor, которые я отправил с помощью AsyncIO? Нужен ли мне адрес MAP для текущего адресного пространства процесса?

который я вижу wirehark с фильтром USB, соответствует только фактическая длина данных.

Журналы Wireshark a1 20 00 00 01 00 02 00 03 00 00 00 00 00 00 00 (16 байтов данных) «3029», «32.105745», «64.16.4 «,« хост »,« USB »,« 40 »,« URB_INTERRUPT в (отправлено) »« 3030 »,« 32.169565 »,« 64.16.4 »,« хост »,« USB »,« 56 »,« URB_INTERRUPT в (завершено) "

0000   01 01 28 01 10 00 00 00 00 00 00 00 00 00 00 00   ..(.............
0010   31 d8 05 00 00 00 00 00 00 00 40 14 02 10 84 03   1.........@.....
0020   ff 02 01 00 04 10 3e 63 a1 20 00 00 01 00 02 00   ......>c. ......
0030   03 00 00 00 00 00 00 00 

1 Ответ

1 голос
/ 19 июня 2020

Проблема находится в этой строке:

ivars->fCommPipeBuffer = (uint8_t*)&aRange.address;

Это сохраняет указатель на поле адреса переменной структуры IOAddressSegment, а не указатель на сам буфер. Вы хотите:

ivars->fCommPipeBuffer = (uint8_t*)aRange.address;

или, менее подверженных ошибкам и более идиоматических c C ++:

ivars->fCommPipeBuffer = reinterpret_cast<uint8_t*>(aRange.address);

(Хотя, честно говоря, средство проверки типов все равно не обнаружило бы ошибку ; stati c, однако, может иметь место анализ.)

При правильном указателе буфера он должен начать вывод правильных данных.

...