IOReturn SoftU2FUserClient::sendFrame(U2FHID_FRAME *frame, size_t frameSize) { SoftU2FDevice *device = nullptr; IOMemoryDescriptor *report = nullptr; if (isInactive()) return kIOReturnOffline; if (frameSize != HID_RPT_SIZE) return kIOReturnBadArgument; device = OSDynamicCast(SoftU2FDevice, getClient()); if (!device) return kIOReturnNotAttached; report = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, HID_RPT_SIZE); if (!report) return kIOReturnNoResources; report->writeBytes(0, frame, frameSize); if (device->handleReport(report) != kIOReturnSuccess) { report->release(); return kIOReturnError; } report->release(); return kIOReturnSuccess; }
void IOVideoSampleStream::postFreeInputBuffer(UInt64 vbiTime, UInt64 outputTime, UInt64 totalFrameCount, UInt64 droppedFrameCount,UInt64 lastDisplayedSequenceNumber) { IOStreamBuffer* buf = OSDynamicCast(IOStreamBuffer, _freeBuffers->getObject(0)); if (NULL == buf) { USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - no free buffers\n"); if ((getOutputQueue())->entryCount > 0) { //all the free buffers are in the queue already so just alert the host (void) sendOutputNotification(); } return; } _freeBuffers->removeObject(0); IOMemoryDescriptor *ctrlDescriptor = OSDynamicCast(IOMemoryDescriptor, buf->getControlBuffer()); if (NULL != ctrlDescriptor) { USBLog(1, "IOVideoSampleStream got control buffer descriptor\n"); SampleVideoDeviceControlBuffer theBuffControl, readBackControl; USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - passed in vbiTime = %lld outputTime = %lld framecount = %lld droppedframecount = %lld lastDisplayedSequenceNumber = %lld \n", vbiTime, outputTime, totalFrameCount, droppedFrameCount, lastDisplayedSequenceNumber); theBuffControl.vbiTime = vbiTime; theBuffControl.outputTime = outputTime; theBuffControl.totalFrameCount = totalFrameCount; theBuffControl.droppedFrameCount = droppedFrameCount; theBuffControl.firstVBITime = 0; theBuffControl.sequenceNumber = lastDisplayedSequenceNumber; theBuffControl.discontinuityFlags = 0; (void) ctrlDescriptor->prepare(); ctrlDescriptor->writeBytes(0, &theBuffControl, buf->getControlBuffer()->getLength()); ctrlDescriptor->readBytes(0, &readBackControl, buf->getControlBuffer()->getLength()); USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - control buffer info vbiTime = %lld outputTime = %lld framecount = %lld droppedframecount = %lld sequencenumber = %lld\n", readBackControl.vbiTime, readBackControl.outputTime, readBackControl.totalFrameCount, readBackControl.droppedFrameCount,readBackControl.sequenceNumber); (void) ctrlDescriptor->complete(); } IOReturn result = enqueueOutputBuffer(buf, 0, buf->getDataBuffer()->getLength(), 0, buf->getControlBuffer()->getLength()); if (result != kIOReturnSuccess) { USBLog(1, "IOVideoSampleStream::postFreeInputBuffer help enqueueOutputBuffer failed! (%x)\n", result); return; } result = sendOutputNotification(); if (result != kIOReturnSuccess) { USBLog(1, "IOVideoSampleStream::postFreeInputBuffer help sendOutputNotification failed! (%x)\n", result); return; } }
IOReturn XboxOneControllerDriver::sendHello() { IOReturn ior = kIOReturnSuccess; IOMemoryDescriptor* hello = nullptr; IOByteCount bytesWritten = 0; constexpr size_t helloSize = sizeof XboxOneControllerHelloMessage; if (_interruptPipe == nullptr) // paranoid check { IO_LOG_DEBUG("_interruptPipe is null"); ior = kIOReturnInternalError; goto cleanup; } // Create the hello message that we're about to send to the controller. hello = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, helloSize); if (hello == nullptr) { IO_LOG_DEBUG("Could not allocate buffer for hello message."); ior = kIOReturnNoMemory; goto cleanup; } bytesWritten = hello->writeBytes(0, XboxOneControllerHelloMessage, helloSize); if (bytesWritten != helloSize) // paranoid check { ior = kIOReturnOverrun; goto cleanup; } // Now send the message ior = _interruptPipe->Write(hello, 0, 0, hello->getLength()); if (ior != kIOReturnSuccess) { IO_LOG_DEBUG("Couldn't send hello message to controller: %08x\n", ior); goto cleanup; } cleanup: if (hello != nullptr) { hello->release(); } return ior; }
IOReturn XboxOneControllerDriver::newReportDescriptor(IOMemoryDescriptor **descriptor) const { if (descriptor == nullptr) { return kIOReturnBadArgument; } constexpr size_t descriptorSize = sizeof XboxOneControllerReportDescriptor; IOMemoryDescriptor* buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, descriptorSize); if (buffer == nullptr) { return kIOReturnNoMemory; } IOByteCount written = buffer->writeBytes(0, XboxOneControllerReportDescriptor, descriptorSize); if (written != sizeof XboxOneControllerReportDescriptor) // paranoid check { buffer->release(); return kIOReturnNoSpace; } *descriptor = buffer; return kIOReturnSuccess; }
// Processes a message for a controller void WirelessGamingReceiver::ProcessMessage(int index, const unsigned char *data, int length) { /* char s[1024]; int i; for (i = 0; i < length; i++) { s[(i * 2) + 0] = "0123456789ABCDEF"[(data[i] & 0xF0) >> 4]; s[(i * 2) + 1] = "0123456789ABCDEF"[data[i] & 0x0F]; } s[i * 2] = '\0'; IOLog("Got data (%d, %d bytes): %s\n", index, length, s); */ // Handle device connections if ((length == 2) && (data[0] == 0x08)) { if (data[1] == 0x00) { // Device disconnected // IOLog("process: Device detached\n"); if (connections[index].service != NULL) { connections[index].service->SetIndex(-1); if (connections[index].controllerStarted) connections[index].service->terminate(kIOServiceRequired | kIOServiceSynchronous); connections[index].service->detach(this); connections[index].service->release(); connections[index].service = NULL; connections[index].controllerStarted = false; } } else { // Device connected // IOLog("process: Attempting to add new device\n"); if (connections[index].service == NULL) { bool ready; int i, j; IOMemoryDescriptor *data; char c; ready = false; j = connections[index].inputArray->getCount(); for (i = 0; !ready && (i < j); i++) { data = OSDynamicCast(IOMemoryDescriptor, connections[index].inputArray->getObject(i)); data->readBytes(1, &c, 1); if (c == 0x0f) ready = true; } InstantiateService(index); if (ready) { // IOLog("Registering wireless device"); connections[index].controllerStarted = true; connections[index].service->registerService(); } } } return; } // Add anything else to the queue IOMemoryDescriptor *copy = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, length); copy->writeBytes(0, data, length); connections[index].inputArray->setObject(copy); if (connections[index].service == NULL) InstantiateService(index); if (connections[index].service != NULL) { connections[index].service->NewData(); if (!connections[index].controllerStarted) { char c; copy->readBytes(1, &c, 1); if (c == 0x0f) { // IOLog("Registering wireless device"); connections[index].controllerStarted = true; connections[index].service->registerService(); } } } copy->release(); }
IOReturn IrDAUserClient::getIrDALog(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *outPutSize) { #if (hasTracing > 0) IOMemoryDescriptor *md; // make a memory descriptor for the client's big buffer unsigned char *input = (unsigned char *)pIn; mach_vm_address_t bigaddr; IOByteCount biglen; IrDALogInfo *info; require(inputSize == 9, Fail); require(outPutSize, Fail); require(*outPutSize == sizeof(IrDALogInfo), Fail); //bigaddr = input[1] << 24 | input[2] << 16 | input[3] << 8 | input[4]; //biglen = input[5] << 24 | input[6] << 16 | input[7] << 8 | input[8]; bcopy(&input[1], &bigaddr, sizeof(bigaddr)); bcopy(&input[5], &biglen, sizeof(biglen)); //IOLog("biglen is %d\n", biglen); // create and init the memory descriptor //md = IOMemoryDescriptor::withAddress(bigaddr, biglen, kIODirectionOutIn, fTask); // REVIEW direction //use withAddressRange() and prepare() instead md = IOMemoryDescriptor::withAddressRange(bigaddr, biglen, kIODirectionOutIn, fTask); // REVIEW direction md->prepare(kIODirectionOutIn); require(md, Fail); info = IrDALogGetInfo(); // get the info block //ELG(info->hdr, info->hdrSize, 'irda', "info hdr"); //ELG(info->eventLog, info->eventLogSize, 'irda', "info events"); //ELG(info->msgBuffer, info->msgBufferSize, 'irda', "info msg buf"); bcopy(info, pOut, sizeof(*info)); // copy the info record back to the client *outPutSize = sizeof(*info); // set the output size (nop, it already is) // copy the buffer over now if there is room if (biglen >= info->hdrSize + info->eventLogSize + info->msgBufferSize) { IOByteCount ct; IOReturn rc; rc = md->prepare(kIODirectionNone); if (rc) {ELG(-1, rc, 'irda', "prepare failed"); } ct = md->writeBytes(0, info->hdr, info->hdrSize); if (ct != info->hdrSize) ELG(-1, rc, 'irda', "write of hdr failed"); ct = md->writeBytes(info->hdrSize, info->eventLog, info->eventLogSize); if (ct != info->eventLogSize) ELG(-1, rc, 'irda', "write of events failed"); ct = md->writeBytes(info->hdrSize+info->eventLogSize, info->msgBuffer, info->msgBufferSize); if (ct != info->msgBufferSize) ELG(-1, rc, 'irda', "write of msgs failed"); ELG(0, info->hdrSize+info->eventLogSize, 'irda', "wrote msgs at offset"); rc = md->complete(kIODirectionNone); if (!rc) { ELG(0, 0, 'irda', "complete worked"); } else { ELG(-1, rc, 'irda', "complete failed"); } // todo check return code of above before resetting the buffer IrDALogReset(); // reset the buffer now } md->release(); // free it return kIOReturnSuccess; Fail: #endif // hasTracing > 0 return kIOReturnBadArgument; }