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 );
try {
inputDevice->Open();
input_devices[ deviceNode->getIndex() ] = inputDevice;
bool ok = inputDevice->Open();
if (ok) {
input_devices[ deviceNode->getIndex() ] = inputDevice;
} else {
throw sg_exception("Opening input device failed");
}
}
catch( ... ) {
delete inputDevice;

View file

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

View file

@ -219,7 +219,7 @@ public:
virtual ~FGHIDDevice();
void Open() override;
bool Open() override;
void Close() override;
void update(double dt) override;
@ -322,15 +322,17 @@ FGHIDDevice::FGHIDDevice(hid_device_info *devInfo, FGHIDEventInput *)
FGHIDDevice::~FGHIDDevice()
{
if (_device) {
hid_close(_device);
}
}
void FGHIDDevice::Open()
bool FGHIDDevice::Open()
{
_device = hid_open_path(_hidPath.c_str());
if (_device == 0) {
SG_LOG(SG_INPUT, SG_WARN, "Failed to open:" << _hidPath);
return;
if (_device == nullptr) {
SG_LOG(SG_INPUT, SG_WARN, "HID: Failed to open:" << _hidPath);
return false;
}
unsigned char reportDescriptor[1024];
@ -354,6 +356,8 @@ void FGHIDDevice::Open()
// SG_LOG(SG_INPUT, SG_INFO, "found item for event:" << v.first);
reportItem.second->event = event;
}
return true;
}
void FGHIDDevice::scanCollection(hid_item* c)
@ -475,11 +479,18 @@ void FGHIDDevice::scanItem(hid_item* item)
void FGHIDDevice::Close()
{
hid_close(_device);
if (_device) {
hid_close(_device);
_device = nullptr;
}
}
void FGHIDDevice::update(double dt)
{
if (!_device) {
return;
}
uint8_t reportBuf[65];
int readCount = 0;
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
{
if (!_device) {
return;
}
uint8_t reportBytes[65];
size_t reportLength = 0;
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)
{
if (!_device) {
return;
}
uint8_t buf[65];
size_t len = std::min(data.length() + 1, sizeof(buf));
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;
}
void FGLinuxInputDevice::Open()
bool FGLinuxInputDevice::Open()
{
if( fd != -1 ) return;
if( fd != -1 ) return true;
if( (fd = ::open( devname.c_str(), O_RDWR )) == -1 ) {
throw std::exception();
}
@ -371,6 +371,8 @@ void FGLinuxInputDevice::Open()
}
}
}
return true;
}
double FGLinuxInputDevice::Normalize( struct input_event & event )

View file

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

View file

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