// Queue a read on a controller bool WirelessGamingReceiver::QueueRead(int index) { IOUSBCompletion complete; IOReturn err; WGRREAD *data; data = (WGRREAD*)IOMalloc(sizeof(WGRREAD)); if (data == NULL) return false; data->index = index; data->buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(connections[index].controllerIn)); if (data->buffer == NULL) { IOFree(data, sizeof(WGRREAD)); return false; } complete.target = this; complete.action = _ReadComplete; complete.parameter = data; err = connections[index].controllerIn->Read(data->buffer, 0, 0, data->buffer->getLength(), &complete); if (err == kIOReturnSuccess) return true; data->buffer->release(); IOFree(data, sizeof(WGRREAD)); // IOLog("read - failed to start (0x%.8x)\n", err); return false; }
PacketStatisticDescriptor PacketStatistic::GetPacketStatistic() { PacketStatisticDescriptor tStat; tStat.Outgoing = IsOutgoingStream(); tStat.MinPacketSize = GetMinPacketSize(); tStat.MaxPacketSize = GetMaxPacketSize(); tStat.PacketCount = GetPacketCount(); tStat.ByteCount = GetByteCount(); tStat.LostPacketCount = GetLostPacketCount(); tStat.AvgPacketSize = GetAvgPacketSize(); tStat.AvgDataRate = GetAvgDataRate(); tStat.MomentAvgDataRate = GetMomentAvgDataRate(); return tStat; }
bool Xbox360Peripheral::start(IOService *provider) { const IOUSBConfigurationDescriptor *cd; IOUSBFindInterfaceRequest intf; IOUSBFindEndpointRequest pipe; XBOX360_OUT_LED led; IOWorkLoop *workloop = NULL; /* * Xbox One controller init packets. * The Rock Candy Xbox One controller requires more than just 0x05 * Minimum required packets unknown. */ UInt8 xoneInitFirst[] = { 0x02, 0x20, 0x01, 0x1C, 0x7E, 0xED, 0x8B, 0x11, 0x0F, 0xA8, 0x00, 0x00, 0x5E, 0x04, 0xD1, 0x02, 0x01, 0x00, 0x01, 0x00, 0x17, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; UInt8 xoneInitSecond[] = { 0x05, 0x20, 0x00, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53 }; UInt8 xoneInitThird[] = { 0x05, 0x20, 0x01, 0x01, 0x00 }; UInt8 xoneInitFourth[] = { 0x0A, 0x20, 0x02, 0x03, 0x00, 0x01, 0x14 }; if (!super::start(provider)) return false; // Get device device=OSDynamicCast(IOUSBDevice,provider); if(device==NULL) { IOLog("start - invalid provider\n"); goto fail; } // Check for configurations if(device->GetNumConfigurations()<1) { device=NULL; IOLog("start - device has no configurations!\n"); goto fail; } // Set configuration cd=device->GetFullConfigurationDescriptor(0); if(cd==NULL) { device=NULL; IOLog("start - couldn't get configuration descriptor\n"); goto fail; } // Open if(!device->open(this)) { device=NULL; IOLog("start - unable to open device\n"); goto fail; } if(device->SetConfiguration(this,cd->bConfigurationValue,true)!=kIOReturnSuccess) { IOLog("start - unable to set configuration\n"); goto fail; } // Get release { UInt16 release = device->GetDeviceRelease(); switch (release) { default: IOLog("Unknown device release %.4x\n", release); // fall through case 0x0110: chatpadInit[0] = 0x01; chatpadInit[1] = 0x02; break; case 0x0114: chatpadInit[0] = 0x09; chatpadInit[1] = 0x00; break; } } // Find correct interface controllerType = Xbox360; intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=93; intf.bInterfaceProtocol=1; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox original intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=66; intf.bInterfaceProtocol=0; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox One intf.bInterfaceClass=255; intf.bInterfaceSubClass=71; intf.bInterfaceProtocol=208; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL, &intf); if(interface==NULL) { IOLog("start - unable to find the interface\n"); goto fail; } controllerType = XboxOne; goto interfacefound; } controllerType = XboxOriginal; goto interfacefound; } interfacefound: interface->open(this); // Find pipes pipe.direction=kUSBIn; pipe.interval=0; pipe.type=kUSBInterrupt; pipe.maxPacketSize=0; inPipe=interface->FindNextPipe(NULL,&pipe); if(inPipe==NULL) { IOLog("start - unable to find in pipe\n"); goto fail; } inPipe->retain(); pipe.direction=kUSBOut; outPipe=interface->FindNextPipe(NULL,&pipe); if(outPipe==NULL) { IOLog("start - unable to find out pipe\n"); goto fail; } outPipe->retain(); // Get a buffer inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,GetMaxPacketSize(inPipe)); if(inBuffer==NULL) { IOLog("start - failed to allocate input buffer\n"); goto fail; } // Find chatpad interface intf.bInterfaceClass = kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass = 93; intf.bInterfaceProtocol = 2; intf.bAlternateSetting = kIOUSBFindInterfaceDontCare; serialIn = device->FindNextInterface(NULL, &intf); if (serialIn == NULL) { IOLog("start - unable to find chatpad interface\n"); goto nochat; } serialIn->open(this); // Find chatpad pipe pipe.direction = kUSBIn; pipe.interval = 0; pipe.type = kUSBInterrupt; pipe.maxPacketSize = 0; serialInPipe = serialIn->FindNextPipe(NULL, &pipe); if (serialInPipe == NULL) { IOLog("start - unable to find chatpad in pipe\n"); goto fail; } serialInPipe->retain(); // Get a buffer for the chatpad serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(serialInPipe)); if (serialInBuffer == NULL) { IOLog("start - failed to allocate input buffer for chatpad\n"); goto fail; } // Create timer for chatpad serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); if (serialTimer == NULL) { IOLog("start - failed to create timer for chatpad\n"); goto fail; } workloop = getWorkLoop(); if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) { IOLog("start - failed to connect timer for chatpad\n"); goto fail; } // Configure ChatPad // Send 'configuration' SendInit(0xa30c, 0x4423); SendInit(0x2344, 0x7f03); SendInit(0x5839, 0x6832); // Set 'switch' if ((!SendSwitch(false)) || (!SendSwitch(true)) || (!SendSwitch(false))) { // Commenting goto fail fixes the driver for the Hori Real Arcade Pro EX //goto fail; } // Begin toggle serialHeard = false; serialActive = false; serialToggle = false; serialResetCount = 0; serialTimerState = tsToggle; serialTimer->setTimeoutMS(1000); // Begin reading if (!QueueSerialRead()) goto fail; nochat: if (!QueueRead()) goto fail; if (controllerType == XboxOne) { QueueWrite(&xoneInitFirst, sizeof(xoneInitFirst)); QueueWrite(&xoneInitSecond, sizeof(xoneInitSecond)); QueueWrite(&xoneInitThird, sizeof(xoneInitThird)); QueueWrite(&xoneInitFourth, sizeof(xoneInitFourth)); } else { // Disable LED Xbox360_Prepare(led,outLed); led.pattern=ledOff; QueueWrite(&led,sizeof(led)); } // Done PadConnect(); registerService(); return true; fail: ReleaseAll(); return false; }
void BaseTransport::ReadPackets() { assert( m_allocator ); assert( m_packetFactory ); assert( m_packetProcessor ); const int maxPacketSize = GetMaxPacketSize(); uint8_t * packetBuffer = (uint8_t*) alloca( maxPacketSize ); while ( true ) { Address address; int packetBytes = InternalReceivePacket( address, packetBuffer, maxPacketSize ); if ( !packetBytes ) break; assert( packetBytes > 0 ); if ( m_receiveQueue.IsFull() ) { debug_printf( "base transport receive queue overflow\n" ); m_counters[TRANSPORT_COUNTER_RECEIVE_QUEUE_OVERFLOW]++; break; } uint64_t sequence = 0; const uint8_t * key = m_encryptionManager.GetReceiveKey( address, GetTime() ); bool encrypted = false; const uint8_t * encryptedPacketTypes = m_packetTypeIsEncrypted; const uint8_t * unencryptedPacketTypes = m_packetTypeIsUnencrypted; #if YOJIMBO_INSECURE_CONNECT if ( GetFlags() & TRANSPORT_FLAG_INSECURE_MODE ) { encryptedPacketTypes = m_allPacketTypes; unencryptedPacketTypes = m_allPacketTypes; } #endif // #if YOJIMBO_INSECURE_CONNECT Packet * packet = m_packetProcessor->ReadPacket( packetBuffer, sequence, packetBytes, encrypted, key, encryptedPacketTypes, unencryptedPacketTypes ); if ( !packet ) { switch ( m_packetProcessor->GetError() ) { case PACKET_PROCESSOR_ERROR_KEY_IS_NULL: { printf( "base transport key is null (read packet)\n" ); m_counters[TRANSPORT_COUNTER_ENCRYPTION_MAPPING_FAILURES]++; } break; case PACKET_PROCESSOR_ERROR_DECRYPT_FAILED: { printf( "base transport decrypt failed (read packet)\n" ); m_counters[TRANSPORT_COUNTER_ENCRYPT_PACKET_FAILURES]++; } break; case PACKET_PROCESSOR_ERROR_PACKET_TOO_SMALL: { printf( "base transport packet too small (read packet)\n" ); m_counters[TRANSPORT_COUNTER_DECRYPT_PACKET_FAILURES]++; } break; case PACKET_PROCESSOR_ERROR_READ_PACKET_FAILED: { printf( "base transport read packet failed (read packet)\n" ); m_counters[TRANSPORT_COUNTER_READ_PACKET_FAILURES]++; } break; default: break; } continue; } PacketEntry entry; entry.sequence = sequence; entry.packet = packet; entry.address = address; m_receiveQueue.Push( entry ); m_counters[TRANSPORT_COUNTER_PACKETS_READ]++; if ( encrypted ) m_counters[TRANSPORT_COUNTER_ENCRYPTED_PACKETS_READ]++; else m_counters[TRANSPORT_COUNTER_UNENCRYPTED_PACKETS_READ]++; } }