IOKit:没有从蓝牙

时间:2015-06-12 00:56:52

标签: macos iokit gamepad

简介

我正致力于使用PlayStation 4 Controller中的HID界面全面支持IOKit。控制器通过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)。

1 个答案:

答案 0 :(得分:3)

问题是IOHIDDeviceGetReport kIOHIDReportTypeOutput通过中断端点发送输出报告; DS4通过控制端点期望它。 AFAIK在OS X上没有任何办法通过ctrl端点输出GetReport(没有写一个kext来覆盖它)。