// Queue an asynchronous write on a controller
bool WirelessGamingReceiver::QueueWrite(int index, const void *bytes, UInt32 length)
{
    IOBufferMemoryDescriptor *outBuffer;
    IOUSBCompletion complete;
    IOReturn err;
    
    outBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, length);
    if (outBuffer == NULL)
    {
//        IOLog("send - unable to allocate buffer\n");
        return false;
    }
    outBuffer->writeBytes(0, bytes, length);
    
    complete.target = this;
    complete.action = _WriteComplete;
    complete.parameter = outBuffer;
    
    err = connections[index].controllerOut->Write(outBuffer, 0, 0, length, &complete);
    if (err == kIOReturnSuccess)
        return true;
    else
    {
//        IOLog("send - failed to start (0x%.8x)\n",err);
        return false;
    }
}
Пример #2
0
// Returns the HID descriptor for this device
IOReturn Xbox360ControllerClass::newReportDescriptor(IOMemoryDescriptor **descriptor) const
{
    IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,sizeof(HID_360::ReportDescriptor));

    if (buffer == NULL) return kIOReturnNoResources;
    buffer->writeBytes(0,HID_360::ReportDescriptor,sizeof(HID_360::ReportDescriptor));
    *descriptor=buffer;
    return kIOReturnSuccess;
}
Пример #3
0
IOReturn it_unbit_foohid_device::newReportDescriptor(IOMemoryDescriptor **descriptor) const {
    IOLog("it_unbit_foohid_device::newReportDescriptor()\n");
    IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, reportDescriptor_len);
    if (buffer == NULL) {
        IOLog("OOOOPS");
        return kIOReturnNoResources;
    }
    
    buffer->writeBytes(0, reportDescriptor, reportDescriptor_len);
    *descriptor = buffer;
    
    IOLog("all fine\n");
    
    return kIOReturnSuccess;
}
Пример #4
0
void VoodooI2CHIDDevice::i2c_hid_get_input(OSObject* owner, IOTimerEventSource* sender) {
//    IOLog("getting input\n");
    if (hid_device->reading)
        return;

    UInt rsize;
    int ret;

    rsize = UInt16(ihid->hdesc.wMaxInputLength);
    
    unsigned char* rdesc = (unsigned char *)IOMalloc(rsize);
    
    ret = i2c_hid_command(ihid, &hid_input_cmd, rdesc, rsize);

//    IOLog("===Input (%d)===\n", rsize);
//    for (int i = 0; i < rsize; i++)
//        IOLog("0x%02x ", (UInt8) rdesc[i]);
//    IOLog("\n");

    int return_size = rdesc[0] | rdesc[1] << 8;
    if (return_size == 0) {
        /* host or device initiated RESET completed */
        // test/clear bit?
        hid_device->timerSource->setTimeoutMS(10);
        return;
    }

    if (return_size > rsize) {
        IOLog("%s: Incomplete report %d/%d\n", __func__, rsize, return_size);
    }

    IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, return_size);
    buffer->writeBytes(0, rdesc + 2, return_size - 2);

    IOReturn err = _wrapper->handleReport(buffer, kIOHIDReportTypeInput);
    if (err != kIOReturnSuccess)
        IOLog("Error handling report: 0x%.8x\n", err);

    buffer->release();

    IOFree(rdesc, rsize);
    
    hid_device->timerSource->setTimeoutMS(10);
}
Пример #5
0
// Set up an asynchronous write
bool Xbox360Peripheral::QueueWrite(const void *bytes,UInt32 length)
{
    IOBufferMemoryDescriptor *outBuffer;
    IOUSBCompletion complete;
    IOReturn err;
    
    outBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,length);
    if(outBuffer==NULL) {
        IOLog("send - unable to allocate buffer\n");
        return false;
    }
    outBuffer->writeBytes(0,bytes,length);
    complete.target=this;
    complete.action=WriteCompleteInternal;
    complete.parameter=outBuffer;
    err=outPipe->Write(outBuffer,0,0,length,&complete);
    if(err==kIOReturnSuccess) return true;
    else {
        IOLog("send - failed to start (0x%.8x)\n",err);
        return false;
    }
}
void VoodooI2CHIDDevice::i2c_hid_get_input(OSObject* owner, IOTimerEventSource* sender) {
//    IOLog("getting input\n");
    UInt rsize;
    int ret;
    static unsigned char* rdesc_prev = NULL;
    static UInt rsize_prev = 0;
    bool new_report = true;
    
    rsize = UInt16(ihid->hdesc.wMaxInputLength);
    
    unsigned char* rdesc = (unsigned char *)IOMalloc(rsize);
    
    ret = i2c_hid_command(ihid, &hid_input_cmd, rdesc, rsize);

//    IOLog("===Input (%d)===\n", rsize);
//    for (int i = 0; i < rsize; i++)
//        IOLog("0x%02x ", (UInt8) rdesc[i]);
//    IOLog("\n");

    int return_size = rdesc[0] | rdesc[1] << 8;
    if (return_size == 0) {
        /* host or device initiated RESET completed */
        // test/clear bit?
        hid_device->timerSource->setTimeoutMS(10);
        return;
    }

    if (return_size > rsize) {
        IOLog("%s: Incomplete report %d/%d\n", __func__, rsize, return_size);
    }

    IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, return_size);
    buffer->writeBytes(0, rdesc + 2, return_size - 2);

#define FILTER_REPEATED_REPORTS /* Needed on my ASUS/Skylake ELAN1000 */

#ifdef FILTER_REPEATED_REPORTS
    /* Compare to previous report */
    if (rdesc_prev)
    {
        /* See if they're different! */
        if (rsize == rsize_prev)
        {
            if (memcmp(rdesc_prev, rdesc, rsize))
            {
                new_report = true;
            } else {
                new_report = false;
            }
        } else {
            new_report = true;
        }

        /* We don't need the previous report anymore */
        IOFree(rdesc_prev, rsize_prev);
    }
    else
    {
        new_report = true;
    }

    /* Keep for next comparison */
    rdesc_prev = rdesc;
    rsize_prev = rsize;

    if (new_report)
    {
        IOReturn err = _wrapper->handleReport(buffer, kIOHIDReportTypeInput);
        if (err != kIOReturnSuccess)
            IOLog("Error handling report: 0x%.8x\n", err);
    }

#else /* non filtered for repeating reports */
    IOReturn err = _wrapper->handleReport(buffer, kIOHIDReportTypeInput);
    if (err != kIOReturnSuccess)
        IOLog("Error handling report: 0x%.8x\n", err);
#endif

    buffer->release();

#ifndef FILTER_REPEATED_REPORTS
    IOFree(rdesc, rsize);
#endif

    hid_device->timerSource->setTimeoutMS(10);
}