receiver: use dictionary for expected message length checking; ignore messages with unknown report ids
This commit is contained in:
parent
1740a9a8c4
commit
7c6bd4202d
|
@ -44,6 +44,15 @@ _LONG_MESSAGE_SIZE = 20
|
||||||
_MEDIUM_MESSAGE_SIZE = 15
|
_MEDIUM_MESSAGE_SIZE = 15
|
||||||
_MAX_READ_SIZE = 32
|
_MAX_READ_SIZE = 32
|
||||||
|
|
||||||
|
# mapping from report_id to message length
|
||||||
|
report_lengths = {
|
||||||
|
0x10: _SHORT_MESSAGE_SIZE,
|
||||||
|
0x11: _LONG_MESSAGE_SIZE,
|
||||||
|
0x20: _MEDIUM_MESSAGE_SIZE,
|
||||||
|
0x21: _MAX_READ_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
"""Default timeout on read (in seconds)."""
|
"""Default timeout on read (in seconds)."""
|
||||||
DEFAULT_TIMEOUT = 4
|
DEFAULT_TIMEOUT = 4
|
||||||
# the receiver itself should reply very fast, within 500ms
|
# the receiver itself should reply very fast, within 500ms
|
||||||
|
@ -189,15 +198,16 @@ def read(handle, timeout=DEFAULT_TIMEOUT):
|
||||||
return reply[1:]
|
return reply[1:]
|
||||||
|
|
||||||
|
|
||||||
# sanity checks on message and report incorrect sizes when debugging
|
# sanity checks on message report id and size
|
||||||
def debug_message(data) :
|
def check_message(data) :
|
||||||
assert isinstance(data, bytes), (repr(data), type(data))
|
assert isinstance(data, bytes), (repr(data), type(data))
|
||||||
report_id = ord(data[:1])
|
report_id = ord(data[:1])
|
||||||
assert ((report_id & 0xF0 == 0) or
|
if report_id in report_lengths: # is this an HID++ or DJ message?
|
||||||
(report_id == 0x10 and len(data) == _SHORT_MESSAGE_SIZE) or
|
if report_lengths.get(report_id) == len(data):
|
||||||
(report_id == 0x11 and len(data) == _LONG_MESSAGE_SIZE) or
|
return True
|
||||||
(report_id == 0x20 and len(data) == _MEDIUM_MESSAGE_SIZE)), \
|
else:
|
||||||
"unexpected message size: report_id %02X message %s" % (report_id, _strhex(data))
|
_log.warn("unexpected message size: report_id %02X message %s" % (report_id, _strhex(data)))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _read(handle, timeout):
|
def _read(handle, timeout):
|
||||||
|
@ -218,13 +228,8 @@ def _read(handle, timeout):
|
||||||
close(handle)
|
close(handle)
|
||||||
raise NoReceiver(reason=reason)
|
raise NoReceiver(reason=reason)
|
||||||
|
|
||||||
if data:
|
if data and check_message(data): # ignore messages that fail check
|
||||||
debug_message(data)
|
|
||||||
report_id = ord(data[:1])
|
report_id = ord(data[:1])
|
||||||
if report_id & 0xF0 == 0x00:
|
|
||||||
if _log.isEnabledFor(_DEBUG):
|
|
||||||
_log.debug("(%s) => r[%02X %s] ignoring unknown report", handle, report_id, _strhex(data[1:]))
|
|
||||||
return
|
|
||||||
devnumber = ord(data[1:2])
|
devnumber = ord(data[1:2])
|
||||||
|
|
||||||
if _log.isEnabledFor(_DEBUG):
|
if _log.isEnabledFor(_DEBUG):
|
||||||
|
@ -252,9 +257,9 @@ def _skip_incoming(handle, ihandle, notifications_hook):
|
||||||
raise NoReceiver(reason=reason)
|
raise NoReceiver(reason=reason)
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
debug_message(data)
|
if check_message(data): # only process messages that pass check
|
||||||
report_id = ord(data[:1])
|
report_id = ord(data[:1])
|
||||||
if notifications_hook and report_id & 0xF0:
|
if notifications_hook:
|
||||||
n = make_notification(ord(data[1:2]), data[2:])
|
n = make_notification(ord(data[1:2]), data[2:])
|
||||||
if n:
|
if n:
|
||||||
notifications_hook(n)
|
notifications_hook(n)
|
||||||
|
@ -274,7 +279,7 @@ def make_notification(devnumber, data):
|
||||||
|
|
||||||
# regular keyboard key press reports and mouse movement reports are not notifications
|
# regular keyboard key press reports and mouse movement reports are not notifications
|
||||||
# it would be better to check for report_id 0x20 but that information is not sent here
|
# it would be better to check for report_id 0x20 but that information is not sent here
|
||||||
if ( len(data) == _MEDIUM_MESSAGE_SIZE-2 and ( sub_id==0x02 or sub_id==0x01 ) ) :
|
if len(data) == _MEDIUM_MESSAGE_SIZE-2 and (sub_id==0x02 or sub_id==0x01):
|
||||||
return
|
return
|
||||||
|
|
||||||
address = ord(data[1:2])
|
address = ord(data[1:2])
|
||||||
|
|
Loading…
Reference in New Issue