summaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/OVR_Linux_HIDDevice.cpp
diff options
context:
space:
mode:
authorBrad Davis <[email protected]>2013-10-13 20:28:58 -0700
committerBrad Davis <[email protected]>2013-10-13 20:28:58 -0700
commit672cdd0ef5455cd62a0d7f7eb6b9889f3ea35f21 (patch)
treef3454dc864242744aef1ea5474b5011556d0f388 /LibOVR/Src/OVR_Linux_HIDDevice.cpp
parent1408ed7b208c7a1cff1a2448fc890e9b8bd6dc4e (diff)
Updating to cmake, glew, xrandr
Diffstat (limited to 'LibOVR/Src/OVR_Linux_HIDDevice.cpp')
-rw-r--r--LibOVR/Src/OVR_Linux_HIDDevice.cpp109
1 files changed, 66 insertions, 43 deletions
diff --git a/LibOVR/Src/OVR_Linux_HIDDevice.cpp b/LibOVR/Src/OVR_Linux_HIDDevice.cpp
index c07c1ad..21d8ee5 100644
--- a/LibOVR/Src/OVR_Linux_HIDDevice.cpp
+++ b/LibOVR/Src/OVR_Linux_HIDDevice.cpp
@@ -3,9 +3,9 @@ Filename : OVR_Linux_HIDDevice.cpp
Content : Linux HID device implementation.
Created : February 26, 2013
Authors : Lee Cooper
-
+
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
+
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
@@ -23,7 +23,7 @@ otherwise accompanies this software in either electronic or hard copy form.
namespace OVR { namespace Linux {
static const UInt32 MAX_QUEUED_INPUT_REPORTS = 5;
-
+
//-------------------------------------------------------------------------------------
// **** Linux::DeviceManager
//-----------------------------------------------------------------------------
@@ -47,27 +47,34 @@ bool HIDDeviceManager::initializeManager()
return true;
}
+ OVR_DEBUG_LOG(("Attempting to initialize the HID Device Manager"));
// Create a udev_monitor handle to watch for device changes (hot-plug detection)
HIDMonitor = udev_monitor_new_from_netlink(UdevInstance, "udev");
if (HIDMonitor == NULL)
{
+ LogError("Unable to create udev monitor");
return false;
}
- udev_monitor_filter_add_match_subsystem_devtype(HIDMonitor, "hidraw", NULL); // filter for hidraw only
-
- int err = udev_monitor_enable_receiving(HIDMonitor);
+ int err = udev_monitor_filter_add_match_subsystem_devtype(HIDMonitor, "hidraw", NULL); // filter for hidraw only
+ if (err) {
+ LogError("Unable to add hidraw filter %d", err);
+ }
+
+ err = udev_monitor_enable_receiving(HIDMonitor);
if (err)
{
+ LogError("Unable to enable monitor receiving %d", err);
udev_monitor_unref(HIDMonitor);
HIDMonitor = NULL;
return false;
}
-
- // Get the file descriptor (fd) for the monitor.
+
+ // Get the file descriptor (fd) for the monitor.
HIDMonHandle = udev_monitor_get_fd(HIDMonitor);
if (HIDMonHandle < 0)
{
+ LogError("Unable to open monitor descriptor");
udev_monitor_unref(HIDMonitor);
HIDMonitor = NULL;
return false;
@@ -77,6 +84,7 @@ bool HIDDeviceManager::initializeManager()
// Add the handle to the polling list
if (!DevManager->pThread->AddSelectFd(this, HIDMonHandle))
{
+ LogError("Failed to add udev monitor fd to select list");
close(HIDMonHandle);
HIDMonHandle = -1;
@@ -116,7 +124,7 @@ void HIDDeviceManager::Shutdown()
}
udev_unref(UdevInstance); // release the library
-
+
LogText("OVR::Linux::HIDDeviceManager - shutting down.\n");
}
@@ -202,39 +210,49 @@ bool HIDDeviceManager::getStringProperty(udev_device* device,
//-----------------------------------------------------------------------------
bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
{
-
if (!initializeManager())
{
return false;
}
- // Get a list of hid devices
+ OVR_DEBUG_LOG_TEXT(("Attempting to enumerate the HID devices to find the Oculus Rift\n"));
+
+ // Get a list of hid devices
udev_enumerate* devices = udev_enumerate_new(UdevInstance);
- udev_enumerate_add_match_subsystem(devices, "hidraw");
- udev_enumerate_scan_devices(devices);
+ if (0 != udev_enumerate_add_match_subsystem(devices, "hidraw") ||
+ 0 != udev_enumerate_scan_devices(devices)) {
+ LogError("Unable to enumerate/scan hidraw devices");
+ return false;
+ }
udev_list_entry* entry = udev_enumerate_get_list_entry(devices);
-
// Search each device for the matching vid/pid
while (entry != NULL)
{
// Get the device file name
const char* sysfs_path = udev_list_entry_get_name(entry);
+
+ OVR_DEBUG_LOG(("Found udev path %s", sysfs_path));
udev_device* hid; // The device's HID udev node.
hid = udev_device_new_from_syspath(UdevInstance, sysfs_path);
const char* dev_path = udev_device_get_devnode(hid);
+ OVR_DEBUG_LOG(("Found udev device node %s", dev_path));
// Get the USB device
+ // FIXME possible descriptor leak... if this returns NULL, the old hid value is lost and never 'unrefed'
hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device");
if (hid)
{
+ OVR_DEBUG_LOG(("Found parent USB device %s", udev_device_get_devnode(hid)));
HIDDeviceDesc devDesc;
// Check the VID/PID for a match
+ OVR_DEBUG_LOG(("Matching product/vendor ID %d:%d", devDesc.VendorId, devDesc.ProductId));
if (dev_path &&
initVendorProductVersion(hid, &devDesc) &&
enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId))
{
+ OVR_DEBUG_LOG_TEXT(("Found Rift tracker at %s\n", dev_path));
devDesc.Path = dev_path;
getFullDesc(hid, &devDesc);
@@ -244,10 +262,13 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
// will fail; therefore, we just set Enumerated to 'true' and continue.
if (existingDevice && existingDevice->pDevice)
{
+ OVR_DEBUG_LOG(("Rift device already opened in Device Manager"));
existingDevice->Enumerated = true;
}
else
- { // open the device temporarily for startup communication
+ {
+ OVR_DEBUG_LOG(("Opening Rift tracker device"));
+ // open the device temporarily for startup communication
int device_handle = open(dev_path, O_RDWR);
if (device_handle >= 0)
{
@@ -256,6 +277,8 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
enumVisitor->Visit(device, devDesc);
close(device_handle); // close the file handle
+ } else {
+ LogError("Error %d opening Rift device at %s", errno, dev_path);
}
}
}
@@ -278,7 +301,7 @@ OVR::HIDDevice* HIDDeviceManager::Open(const String& path)
if (device->HIDInitialize(path))
{
- device->AddRef();
+ device->AddRef();
return device;
}
@@ -288,20 +311,20 @@ OVR::HIDDevice* HIDDeviceManager::Open(const String& path)
//-----------------------------------------------------------------------------
bool HIDDeviceManager::getFullDesc(udev_device* device, HIDDeviceDesc* desc)
{
-
+
if (!initVendorProductVersion(device, desc))
{
return false;
}
-
+
if (!getStringProperty(device, "serial", &(desc->SerialNumber)))
{
return false;
}
-
+
getStringProperty(device, "manufacturer", &(desc->Manufacturer));
getStringProperty(device, "product", &(desc->Product));
-
+
return true;
}
@@ -424,7 +447,7 @@ HIDDevice::HIDDevice(HIDDeviceManager* manager)
{
DeviceHandle = -1;
}
-
+
//-----------------------------------------------------------------------------
// This is a minimal constructor used during enumeration for us to pass
// a HIDDevice to the visit function (so that it can query feature reports).
@@ -451,7 +474,7 @@ bool HIDDevice::HIDInitialize(const String& path)
LogText("OVR::Linux::HIDDevice - Failed to open HIDDevice: %s", hid_path);
return false;
}
-
+
HIDManager->DevManager->pThread->AddTicksNotifier(this);
HIDManager->AddNotificationDevice(this);
@@ -460,7 +483,7 @@ bool HIDDevice::HIDInitialize(const String& path)
DevDesc.Path.ToCStr(),
DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(),
DevDesc.SerialNumber.ToCStr());
-
+
return true;
}
@@ -490,7 +513,7 @@ bool HIDDevice::initInfo()
OVR_ASSERT_LOG(false, ("Failed to get report descriptor."));
return false;
}
-
+
/*
// Get report lengths.
SInt32 bufferLength;
@@ -505,21 +528,21 @@ bool HIDDevice::initInfo()
getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength);
OVR_ASSERT(getResult);
FeatureReportBufferLength = (UInt16) bufferLength;
-
-
+
+
if (ReadBufferSize < InputReportBufferLength)
{
OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer."));
return false;
}
-
+
// Get device desc.
if (!HIDManager->getFullDesc(Device, &DevDesc))
{
OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device."));
return false;
}
-
+
return true;
*/
@@ -528,13 +551,13 @@ bool HIDDevice::initInfo()
InputReportBufferLength = 62;
OutputReportBufferLength = 0;
FeatureReportBufferLength = 69;
-
+
if (ReadBufferSize < InputReportBufferLength)
{
OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer."));
return false;
}
-
+
return true;
}
@@ -575,22 +598,22 @@ bool HIDDevice::openDevice(const char* device_path)
DeviceHandle = -1;
return false;
}
-
+
return true;
}
-
+
//-----------------------------------------------------------------------------
void HIDDevice::HIDShutdown()
{
HIDManager->DevManager->pThread->RemoveTicksNotifier(this);
HIDManager->RemoveNotificationDevice(this);
-
+
if (DeviceHandle >= 0) // Device may already have been closed if unplugged.
{
closeDevice(false);
}
-
+
LogText("OVR::Linux::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr());
}
@@ -598,13 +621,13 @@ void HIDDevice::HIDShutdown()
void HIDDevice::closeDevice(bool wasUnplugged)
{
OVR_ASSERT(DeviceHandle >= 0);
-
+
HIDManager->DevManager->pThread->RemoveSelectFd(this, DeviceHandle);
close(DeviceHandle); // close the file handle
DeviceHandle = -1;
-
+
LogText("OVR::Linux::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr());
}
@@ -618,10 +641,10 @@ void HIDDevice::closeDeviceOnIOError()
//-----------------------------------------------------------------------------
bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length)
{
-
+
if (DeviceHandle < 0)
return false;
-
+
UByte reportID = data[0];
if (reportID == 0)
@@ -652,7 +675,7 @@ UInt64 HIDDevice::OnTicks(UInt64 ticksMks)
{
return Handler->OnTicks(ticksMks);
}
-
+
return DeviceManagerThread::Notifier::OnTicks(ticksMks);
}
@@ -695,7 +718,7 @@ bool HIDDevice::OnDeviceNotification(MessageType messageType,
// A closed device has been re-added. Try to reopen.
if (!openDevice(device_path))
{
- LogError("OVR::Linux::HIDDevice - Failed to reopen a device '%s' that was re-added.\n",
+ LogError("OVR::Linux::HIDDevice - Failed to reopen a device '%s' that was re-added.\n",
device_path);
*error = true;
return true;
@@ -740,7 +763,7 @@ bool HIDDevice::OnDeviceNotification(MessageType messageType,
//-----------------------------------------------------------------------------
HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devManager)
{
-
+
if (!System::IsInitialized())
{
// Use custom message, since Log is not yet installed.
@@ -765,7 +788,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devMana
return manager.GetPtr();
}
-
+
} // namespace Linux
//-------------------------------------------------------------------------------------
@@ -775,7 +798,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devMana
HIDDeviceManager* HIDDeviceManager::Create()
{
OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet."));
-
+
if (!System::IsInitialized())
{
// Use custom message, since Log is not yet installed.