Как получить доступ к IOMemoryBufferDescriptor в CompleteAsyncIO, который отправляется через AsyncIO при прерывании EP
Я пытаюсь отправить запрос с помощью AsyncIO для прерывания EP, для AsyncIO я создал IOMemoryBufferDescriptor, как только IOMemoryBufferDescriptor, Create - это успех, я использовал GetAddressRange и сохранил адрес в структуре dext ivars. Для этого запроса завершение (CompleteAsyncIO) вызывается с использованием action-> GetReference(). Я получил структуру ivars, я ожидал, что данные о завершении прерывания получены с USB-устройства, к сожалению, я не вижу связанных данных. В wirehark я попытался отладить полученные данные размером 16 байт, а фактические байты CompleteAsyncIO также 16.
Как правильно получать данные прерывания от устройства с помощью IOMemoryBufferDescriptor?
OSAction Create для 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 ответ
Проблема в этой строке:
ivars->fCommPipeBuffer = (uint8_t*)&aRange.address;
Это сохраняет указатель на адресное поле IOAddressSegment
struct переменная, а не указатель на сам буфер. Вы хотите:
ivars->fCommPipeBuffer = (uint8_t*)aRange.address;
или, менее подверженный ошибкам и более идиоматический C++:
ivars->fCommPipeBuffer = reinterpret_cast<uint8_t*>(aRange.address);
(Хотя, честно говоря, средство проверки типов все равно не обнаружило бы ошибку; однако статический анализ мог ее обнаружить.)
При правильном указателе буфера он должен начать вывод правильных данных.