2015-06-12 25 views
4

介紹由於IOKit:不接受HID中斷從DUALSHOCK 4控制器帶有藍牙

我正在使用HID接口IOKit得到了PlayStation 4 Controller全力支持連接報告。控制器通過Bluetooth連接。我可以打開與控制器的連接並開始接收報告,但是,一旦我發送報告,它會突然停止。

爲了完全控制PS4控制器(隆隆聲,觸控板,LED),我一直在參考the eleccelerator.com DualShock 4 page,其中包含有關可在PS4和DS4之間發送的報告的信息。

代碼

首先,我創建一個IOHIDManager,其負責檢測控制器。

self.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); 
// Make sure we detect ANY type of 'game controller' 
NSArray *criteria = [NSArray arrayWithObjects: 
     CreateCriterion(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick), 
     CreateCriterion(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad), 
     CreateCriterion(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController), 
    nil]; 

IOHIDManagerSetDeviceMatchingMultiple(self.hidManager, (__bridge CFArrayRef)criteria); 

IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 
IOHIDManagerOpen(self.hidManager, kIOHIDOptionsTypeNone); 

// Register callbacks 
IOHIDManagerRegisterDeviceMatchingCallback(self.hidManager, ControllerConnected, (__bridge void *)self); 
IOHIDManagerRegisterDeviceRemovalCallback(self.hidManager, ControllerDisconnected, (__bridge void *)self); 

然後得到一個呼叫ControllerConnected後,我創建了一個搖桿類,初始化IOHIDDeviceRef的一個實例。

- (void)registerDevice:(IOHIDDeviceRef)device { 
    self.device = device; 

    // Initialize the buffer 
    self.receivedPacketMaxSize = 552; // When using Bluetooth 
    self.receivedReport = (uint8_t *)calloc(self.receivedPacketMaxSize, sizeof(uint8_t)); 

    // Register the device report callback 
    IOHIDDeviceScheduleWithRunLoop(self.device, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); 
    IOHIDDeviceRegisterInputReportCallback(self.device, self.receivedReport, self.receivedPacketMaxSize, ControllerReport, (__bridge void *)self); 

    self.isValid = YES; 
} 

我現在去ControllerReport電話,但是我收到的0x01型這是在它們所包含的有限的報道(中沒有觸控板或加速計數據),但我想收到的報文鍵入0x11,其中包含來自控制器的所有數據。

爲了切換哪個分組控制器發送,網站狀態This report is sent once the GET REPORT FEATURE 0x02 is received.所以我將請求發送:

CFIndex len = self.receivedPacketMaxSize; 
IOReturn featureMode2RequestError = IOHIDDeviceGetReport(self.device, kIOHIDReportTypeFeature, 0x02, self.receivedReport, &len); 
if (featureMode2RequestError != kIOReturnSuccess) { 
    NSLog(@"Could switch the controller to mode 2 :("); 
} 

在這一點上,ControllerReport停止被從控制器新報告呼籲。

我知道我可以發送數據到控制器,因爲我可以發送更改LED顏色的數據包,或設置隆隆聲速度。

問題

?我怎樣才能從PS4控制器的時間越長爲0x11報告?

我已經試過

我使用IOHIDDeviceGetReportWithCallbackIOHIDDeviceGetReport試過,但我總是得到kIOReturnUnsupported回來。

我也發現了一些對... it starts sending input reports in report 17. Since report 17 is undefined ...形式的控制器的linux驅動程序源代碼內部引用這個問題,但是我不知道如何告訴IOKit處理報告17(0x11)。

+0

我不能告訴你爲什麼你看到那個特定的問題以及如何解決它,但如果我正在調試這個,我會檢查[IOKit HID家族](http://www.opensource.apple 。com/source/IOHIDFamily/IOHIDFamily-606.1.7 /)和[IOKit userlib HID](http://www.opensource.apple.com/source/IOKitUser/IOKitUser-1050.1.21/hid.subproj/)源代碼和追蹤設備報告的路徑。一旦你找到了被忽略的地方,解決它不應該太難。 – pmdj

+0

我現在還沒有解決方案。由於這似乎是由框架中的一個錯誤引起的,我將在macOS發佈的秋季再次嘗試。但是,我懷疑如果它仍然存在,我將有資源來尋找和解決問題。 –

回答

3

問題是IOHIDDeviceGetReport kIOHIDReportTypeOutput通過中斷端點發送輸出報告; DS4期望通過控制端點。 AFAIK在OS X上沒有任何方法可以通過ctrl端點執行輸出GetReport(短寫一個kext來覆蓋它)。