1
0
Fork 0

HID-input: don’t crash when open fails

Important since hidraw devices need special permissions on Linux.
This commit is contained in:
James Turner 2017-12-25 18:13:03 +00:00
parent 2538ab717a
commit 01f0f27c84
6 changed files with 50 additions and 20 deletions

View file

@ -410,8 +410,12 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
inputDevice->Configure( deviceNode ); inputDevice->Configure( deviceNode );
try { try {
inputDevice->Open(); bool ok = inputDevice->Open();
if (ok) {
input_devices[ deviceNode->getIndex() ] = inputDevice; input_devices[ deviceNode->getIndex() ] = inputDevice;
} else {
throw sg_exception("Opening input device failed");
}
} }
catch( ... ) { catch( ... ) {
delete inputDevice; delete inputDevice;

View file

@ -223,7 +223,7 @@ public:
virtual ~FGInputDevice(); virtual ~FGInputDevice();
virtual void Open() = 0; virtual bool Open() = 0;
virtual void Close() = 0; virtual void Close() = 0;
virtual void Send( const char * eventName, double value ) = 0; virtual void Send( const char * eventName, double value ) = 0;

View file

@ -219,7 +219,7 @@ public:
virtual ~FGHIDDevice(); virtual ~FGHIDDevice();
void Open() override; bool Open() override;
void Close() override; void Close() override;
void update(double dt) override; void update(double dt) override;
@ -322,15 +322,17 @@ FGHIDDevice::FGHIDDevice(hid_device_info *devInfo, FGHIDEventInput *)
FGHIDDevice::~FGHIDDevice() FGHIDDevice::~FGHIDDevice()
{ {
if (_device) {
hid_close(_device);
}
} }
void FGHIDDevice::Open() bool FGHIDDevice::Open()
{ {
_device = hid_open_path(_hidPath.c_str()); _device = hid_open_path(_hidPath.c_str());
if (_device == 0) { if (_device == nullptr) {
SG_LOG(SG_INPUT, SG_WARN, "Failed to open:" << _hidPath); SG_LOG(SG_INPUT, SG_WARN, "HID: Failed to open:" << _hidPath);
return; return false;
} }
unsigned char reportDescriptor[1024]; unsigned char reportDescriptor[1024];
@ -354,6 +356,8 @@ void FGHIDDevice::Open()
// SG_LOG(SG_INPUT, SG_INFO, "found item for event:" << v.first); // SG_LOG(SG_INPUT, SG_INFO, "found item for event:" << v.first);
reportItem.second->event = event; reportItem.second->event = event;
} }
return true;
} }
void FGHIDDevice::scanCollection(hid_item* c) void FGHIDDevice::scanCollection(hid_item* c)
@ -475,11 +479,18 @@ void FGHIDDevice::scanItem(hid_item* item)
void FGHIDDevice::Close() void FGHIDDevice::Close()
{ {
if (_device) {
hid_close(_device); hid_close(_device);
_device = nullptr;
}
} }
void FGHIDDevice::update(double dt) void FGHIDDevice::update(double dt)
{ {
if (!_device) {
return;
}
uint8_t reportBuf[65]; uint8_t reportBuf[65];
int readCount = 0; int readCount = 0;
while (true) { while (true) {
@ -528,6 +539,10 @@ void writeBits(uint8_t* bytes, size_t bitOffset, size_t bitSize, int value)
void FGHIDDevice::sendReport(Report* report) const void FGHIDDevice::sendReport(Report* report) const
{ {
if (!_device) {
return;
}
uint8_t reportBytes[65]; uint8_t reportBytes[65];
size_t reportLength = 0; size_t reportLength = 0;
memset(reportBytes, 0, sizeof(reportBytes)); memset(reportBytes, 0, sizeof(reportBytes));
@ -632,6 +647,10 @@ void FGHIDDevice::processInputReport(Report* report, unsigned char* data,
void FGHIDDevice::SendFeatureReport(unsigned int reportId, const std::string& data) void FGHIDDevice::SendFeatureReport(unsigned int reportId, const std::string& data)
{ {
if (!_device) {
return;
}
uint8_t buf[65]; uint8_t buf[65];
size_t len = std::min(data.length() + 1, sizeof(buf)); size_t len = std::min(data.length() + 1, sizeof(buf));
buf[0] = reportId; buf[0] = reportId;

View file

@ -286,9 +286,9 @@ static inline bool bitSet( unsigned char * buf, unsigned bit )
return (buf[bit/sizeof(unsigned char)/8] >> (bit%(sizeof(unsigned char)*8))) & 1; return (buf[bit/sizeof(unsigned char)/8] >> (bit%(sizeof(unsigned char)*8))) & 1;
} }
void FGLinuxInputDevice::Open() bool FGLinuxInputDevice::Open()
{ {
if( fd != -1 ) return; if( fd != -1 ) return true;
if( (fd = ::open( devname.c_str(), O_RDWR )) == -1 ) { if( (fd = ::open( devname.c_str(), O_RDWR )) == -1 ) {
throw std::exception(); throw std::exception();
} }
@ -371,6 +371,8 @@ void FGLinuxInputDevice::Open()
} }
} }
} }
return true;
} }
double FGLinuxInputDevice::Normalize( struct input_event & event ) double FGLinuxInputDevice::Normalize( struct input_event & event )

View file

@ -45,10 +45,10 @@ public:
FGLinuxInputDevice( std::string name, std::string devname, std::string aSerial ); FGLinuxInputDevice( std::string name, std::string devname, std::string aSerial );
virtual ~FGLinuxInputDevice(); virtual ~FGLinuxInputDevice();
virtual void Open(); bool Open() override;
virtual void Close(); void Close() override;
virtual void Send( const char * eventName, double value ); void Send( const char * eventName, double value ) override;
virtual const char * TranslateEventName( FGEventData & eventData ); const char * TranslateEventName( FGEventData & eventData ) override;
void SetDevname( const std::string & name ); void SetDevname( const std::string & name );
std::string GetDevname() const { return devname; } std::string GetDevname() const { return devname; }

View file

@ -153,7 +153,7 @@ public:
virtual ~FGMacOSXInputDevice(); virtual ~FGMacOSXInputDevice();
void Open() override; bool Open() override;
void Close() override; void Close() override;
virtual void update(double dt); virtual void update(double dt);
@ -344,16 +344,21 @@ FGMacOSXInputDevice::~FGMacOSXInputDevice()
CFRelease(_hid); CFRelease(_hid);
} }
void FGMacOSXInputDevice::Open() bool FGMacOSXInputDevice::Open()
{ {
IOReturn result = IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
if (result != kIOReturnSuccess) {
return false;
}
IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
// IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this); // IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOHIDQueueStart(_queue); IOHIDQueueStart(_queue);
return true;
} }
void FGMacOSXInputDevice::buildElementNameDictionary() void FGMacOSXInputDevice::buildElementNameDictionary()