bool Xbox360Peripheral::SendSwitch(bool sendOut) { IOUSBDevRequest controlReq; controlReq.bmRequestType = USBmakebmRequestType(sendOut ? kUSBOut : kUSBIn, kUSBVendor, kUSBDevice); controlReq.bRequest = 0xa1; controlReq.wValue = 0x0000; controlReq.wIndex = 0xe416; controlReq.wLength = sizeof(chatpadInit); controlReq.pData = chatpadInit; IOReturn err = device->DeviceRequest(&controlReq, 100, 100, NULL); if (err == kIOReturnSuccess) return true; const char *errStr = stringFromReturn(err); IOLog("start - failed to %s chatpad setting (%s)\n", sendOut ? "write" : "read", errStr); return false; }
IOReturn BrcmPatchRAM::bulkWrite(const void* data, UInt16 length) { IOReturn result; if (IOMemoryDescriptor* buffer = IOMemoryDescriptor::withAddress((void*)data, length, kIODirectionIn)) { if ((result = buffer->prepare()) == kIOReturnSuccess) { if ((result = mBulkPipe->Write(buffer, 0, 0, buffer->getLength(), (IOUSBCompletion*)NULL)) == kIOReturnSuccess) { //DEBUG_LOG("%s: Wrote %d bytes to bulk pipe.\n", getName(), length); } else AlwaysLog("[%04x:%04x]: Failed to write to bulk pipe (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); } else AlwaysLog("[%04x:%04x]: Failed to prepare bulk write memory buffer (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); if ((result = buffer->complete()) != kIOReturnSuccess) AlwaysLog("[%04x:%04x]: Failed to complete bulk write memory buffer (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); buffer->release(); } else { AlwaysLog("[%04x:%04x]: Unable to allocate bulk write buffer.\n", mVendorId, mProductId); result = kIOReturnNoMemory; } return result; }
IOReturn BrcmPatchRAM::hciCommand(void * command, UInt16 length) { IOReturn result; IOUSBDevRequest request = { .bmRequestType = USBmakebmRequestType(kUSBOut, kUSBClass, kUSBDevice), .bRequest = 0, .wValue = 0, .wIndex = 0, .wLength = length, .pData = command }; if ((result = mInterface->DeviceRequest(&request)) != kIOReturnSuccess) AlwaysLog("[%04x:%04x]: device request failed (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return result; } IOReturn BrcmPatchRAM::hciParseResponse(void* response, UInt16 length, void* output, UInt8* outputLength) { HCI_RESPONSE* header = (HCI_RESPONSE*)response; IOReturn result = kIOReturnSuccess; switch (header->eventCode) { case HCI_EVENT_COMMAND_COMPLETE: { HCI_COMMAND_COMPLETE* event = (HCI_COMMAND_COMPLETE*)response; switch (event->opcode) { case HCI_OPCODE_READ_VERBOSE_CONFIG: DebugLog("[%04x:%04x]: READ VERBOSE CONFIG complete (status: 0x%02x, length: %d bytes).\n", mVendorId, mProductId, event->status, header->length); mFirmareVersion = *(UInt16*)(((char*)response) + 10); DebugLog("[%04x:%04x]: Firmware version: v%d.\n", mVendorId, mProductId, mFirmareVersion + 0x1000); // Device does not require a firmware patch at this time if (mFirmareVersion > 0) mDeviceState = kUpdateComplete; else mDeviceState = kFirmwareVersion; break; case HCI_OPCODE_DOWNLOAD_MINIDRIVER: DebugLog("[%04x:%04x]: DOWNLOAD MINIDRIVER complete (status: 0x%02x, length: %d bytes).\n", mVendorId, mProductId, event->status, header->length); mDeviceState = kMiniDriverComplete; break; case HCI_OPCODE_LAUNCH_RAM: //DebugLog("[%04x:%04x]: LAUNCH RAM complete (status: 0x%02x, length: %d bytes).\n", // mVendorId, mProductId, event->status, header->length); mDeviceState = kInstructionWritten; break; case HCI_OPCODE_END_OF_RECORD: DebugLog("[%04x:%04x]: END OF RECORD complete (status: 0x%02x, length: %d bytes).\n", mVendorId, mProductId, event->status, header->length); mDeviceState = kFirmwareWritten; break; case HCI_OPCODE_RESET: DebugLog("[%04x:%04x]: RESET complete (status: 0x%02x, length: %d bytes).\n", mVendorId, mProductId, event->status, header->length); mDeviceState = kResetComplete; break; default: DebugLog("[%04x:%04x]: Event COMMAND COMPLETE (opcode 0x%04x, status: 0x%02x, length: %d bytes).\n", mVendorId, mProductId, event->opcode, event->status, header->length); break; } if (output && outputLength) { bzero(output, *outputLength); // Return the received data if (*outputLength >= length) { DebugLog("[%04x:%04x]: Returning output data %d bytes.\n", mVendorId, mProductId, length); *outputLength = length; memcpy(output, response, length); } else // Not enough buffer space for data result = kIOReturnMessageTooLarge; } break; } case HCI_EVENT_NUM_COMPLETED_PACKETS: DebugLog("[%04x:%04x]: Number of completed packets.\n", mVendorId, mProductId); break; case HCI_EVENT_CONN_COMPLETE: DebugLog("[%04x:%04x]: Connection complete event.\n", mVendorId, mProductId); break; case HCI_EVENT_DISCONN_COMPLETE: DebugLog("[%04x:%04x]: Disconnection complete. event\n", mVendorId, mProductId); break; case HCI_EVENT_HARDWARE_ERROR: DebugLog("[%04x:%04x]: Hardware error\n", mVendorId, mProductId); break; case HCI_EVENT_MODE_CHANGE: DebugLog("[%04x:%04x]: Mode change event.\n", mVendorId, mProductId); break; case HCI_EVENT_LE_META: DebugLog("[%04x:%04x]: Low-Energy meta event.\n", mVendorId, mProductId); break; default: DebugLog("[%04x:%04x]: Unknown event code (0x%02x).\n", mVendorId, mProductId, header->eventCode); break; } return result; }
bool BrcmPatchRAM::setConfiguration(int configurationIndex) { IOReturn result; const IOUSBConfigurationDescriptor* configurationDescriptor; UInt8 currentConfiguration = 0xFF; // Find the first config/interface UInt8 numconf = 0; if ((numconf = mDevice->GetNumConfigurations()) < (configurationIndex + 1)) { AlwaysLog("[%04x:%04x]: Composite configuration index %d is not available, %d total composite configurations.\n", mVendorId, mProductId, configurationIndex, numconf); return false; } else DebugLog("[%04x:%04x]: Available composite configurations: %d.\n", mVendorId, mProductId, numconf); configurationDescriptor = mDevice->GetFullConfigurationDescriptor(configurationIndex); // Set the configuration to the requested configuration index if (!configurationDescriptor) { AlwaysLog("[%04x:%04x]: No configuration descriptor for configuration index: %d.\n", mVendorId, mProductId, configurationIndex); return false; } if ((result = mDevice->GetConfiguration(¤tConfiguration)) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Unable to retrieve active configuration (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return false; } // Device is already configured if (currentConfiguration != 0) { DebugLog("[%04x:%04x]: Device configuration is already set to configuration index %d.\n", mVendorId, mProductId, configurationIndex); return true; } // Set the configuration to the first configuration if ((result = mDevice->SetConfiguration(this, configurationDescriptor->bConfigurationValue, true)) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Unable to (re-)configure device (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return false; } DebugLog("[%04x:%04x]: Set device configuration to configuration index %d successfully.\n", mVendorId, mProductId, configurationIndex); return true; }
bool BrcmPatchRAM::resetDevice() { IOReturn result; if ((result = mDevice->ResetDevice()) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Failed to reset the device (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return false; } else DebugLog("[%04x:%04x]: Device reset.\n", mVendorId, mProductId); return true; }
int BrcmPatchRAM::getDeviceStatus() { IOReturn result; USBStatus status; if ((result = mDevice->GetDeviceStatus(&status)) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Unable to get device status (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return 0; } else DebugLog("[%04x:%04x]: Device status 0x%08x.\n", mVendorId, mProductId, (int)status); return (int)status; }
IOReturn BrcmPatchRAM::hciCommand(void * command, UInt16 length) { IOReturn result; if ((result = mInterface.hciCommand(command, length)) != kIOReturnSuccess) AlwaysLog("[%04x:%04x]: device request failed (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return result; }