device: be defensive when getting device id

This commit is contained in:
Peter F. Patel-Schneider 2020-11-01 15:11:46 -05:00
parent 73ddb12d8e
commit 1162ccb897
3 changed files with 26 additions and 17 deletions

View File

@ -218,23 +218,29 @@ class Device(object):
def unitId(self):
if not self._unitId:
if self.online and self.protocol >= 2.0:
self._unitId, self._modelId, self._tid_map = _hidpp20.get_ids(self)
if _log.isEnabledFor(_INFO) and self._serial and self._serial != self._unitId:
_log.info('%s: unitId %s does not match serial %s', self, self._unitId, self._serial)
ids = _hidpp20.get_ids(self)
if ids:
self._unitId, self._modelId, self._tid_map = ids
if _log.isEnabledFor(_INFO) and self._serial and self._serial != self._unitId:
_log.info('%s: unitId %s does not match serial %s', self, self._unitId, self._serial)
return self._unitId
@property
def modelId(self):
if not self._modelId:
if self.online and self.protocol >= 2.0:
self._unitId, self._modelId, self._tid_map = _hidpp20.get_ids(self)
ids = _hidpp20.get_ids(self)
if ids:
self._unitId, self._modelId, self._tid_map = _hidpp20.get_ids(self)
return self._modelId
@property
def tid_map(self):
if not self._tid_map:
if self.online and self.protocol >= 2.0:
self._unitId, self._modelId, self._tid_map = _hidpp20.get_ids(self)
ids = _hidpp20.get_ids(self)
if ids:
self._unitId, self._modelId, self._tid_map = _hidpp20.get_ids(self)
return self._tid_map
@property

View File

@ -1054,16 +1054,17 @@ def get_firmware(device):
def get_ids(device):
"""Reads a device's ids (unit and model numbers)"""
ids = feature_request(device, FEATURE.DEVICE_FW_VERSION)
unitId = ids[1:5]
modelId = ids[7:13]
transport_bits = ord(ids[6:7])
offset = 0
tid_map = {}
for transport, flag in [('btid', 0x1), ('btleid', 0x02), ('wpid', 0x04), ('usbid', 0x08)]:
if transport_bits & flag:
tid_map[transport] = modelId[offset:offset + 2].hex().upper()
offset = offset + 2
return (unitId.hex().upper(), modelId.hex().upper(), tid_map)
if ids:
unitId = ids[1:5]
modelId = ids[7:13]
transport_bits = ord(ids[6:7])
offset = 0
tid_map = {}
for transport, flag in [('btid', 0x1), ('btleid', 0x02), ('wpid', 0x04), ('usbid', 0x08)]:
if transport_bits & flag:
tid_map[transport] = modelId[offset:offset + 2].hex().upper()
offset = offset + 2
return (unitId.hex().upper(), modelId.hex().upper(), tid_map)
def get_kind(device):

View File

@ -208,8 +208,10 @@ def _print_device(dev, num=None):
for fw in _hidpp20.get_firmware(dev):
extras = _strhex(fw.extras) if fw.extras else ''
print(' Firmware: %s %s %s %s' % (fw.kind, fw.name, fw.version, extras))
unitId, modelId, tid_map = _hidpp20.get_ids(dev)
print(' Unit ID: %s Model ID: %s Transport IDs: %s' % (unitId, modelId, tid_map))
ids = _hidpp20.get_ids(dev)
if ids:
unitId, modelId, tid_map = ids
print(' Unit ID: %s Model ID: %s Transport IDs: %s' % (unitId, modelId, tid_map))
elif feature == _hidpp20.FEATURE.REPORT_RATE:
print(' Polling Rate (ms): %d' % _hidpp20.get_polling_rate(dev))
elif feature == _hidpp20.FEATURE.BATTERY_STATUS or feature == _hidpp20.FEATURE.BATTERY_VOLTAGE: