Example #1
0
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();
}
Example #6
0
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;
}