udev: add function to get wpid from udev
base: make workaround flag name more generic descriptors: fix wpid's for 27Mhz devices device: Improve wpid and kind processing for 27Mhz devices notifications: Improve wpid generation for 27Mhz devices docs: fix wpid's for EX100
This commit is contained in:
parent
9de4d392d4
commit
7a82b93aaf
|
@ -211,8 +211,8 @@ setting is useful only to disable smooth scrolling.
|
|||
| MK550 | | | | |
|
||||
| MK700 | 2008 | 1.0 | yes | FN swap, reprog keys |
|
||||
| MK710 | | 1.0 | yes | FN swap, reprog keys |
|
||||
| EX100 keyboard | 6500 | 1.0 | yes | |
|
||||
| EX100 mouse | 3f00 | 1.0 | yes | |
|
||||
| EX100 keyboard | 0065 | 1.0 | yes | |
|
||||
| EX100 mouse | 003f | 1.0 | yes | |
|
||||
|
||||
* The EX100 is old, preunifying set, supporting only part of HID++ 1.0 features
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
|||
from hidapi.udev import close # noqa: F401
|
||||
from hidapi.udev import enumerate # noqa: F401
|
||||
from hidapi.udev import find_paired_node # noqa: F401
|
||||
from hidapi.udev import find_paired_node_wpid # noqa: F401
|
||||
from hidapi.udev import get_manufacturer # noqa: F401
|
||||
from hidapi.udev import get_product # noqa: F401
|
||||
from hidapi.udev import get_serial # noqa: F401
|
||||
|
|
|
@ -176,6 +176,27 @@ def find_paired_node(receiver_path, index, timeout):
|
|||
return None
|
||||
|
||||
|
||||
def find_paired_node_wpid(receiver_path, index):
|
||||
"""Find the node of a device paired with a receiver, get wpid from udev"""
|
||||
context = _Context()
|
||||
receiver_phys = _Devices.from_device_file(context, receiver_path).find_parent('hid').get('HID_PHYS')
|
||||
|
||||
if not receiver_phys:
|
||||
return None
|
||||
|
||||
phys = f'{receiver_phys}:{index}'
|
||||
for dev in context.list_devices(subsystem='hidraw'):
|
||||
dev_phys = dev.find_parent('hid').get('HID_PHYS')
|
||||
if dev_phys and dev_phys == phys:
|
||||
# get hid id like 0003:0000046D:00000065
|
||||
hid_id = dev.find_parent('hid').get('HID_ID')
|
||||
# get wpid - last 4 symbols
|
||||
udev_wpid = hid_id[-4:]
|
||||
return udev_wpid
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def monitor_glib(callback, *device_filters):
|
||||
from gi.repository import GLib
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
|||
## should this last be changed so that may_unpair is used for all receivers? writing to _R.receiver_pairing doesn't seem right
|
||||
# re_pairs determines whether a receiver pairs by replacing existing pairings, default to False
|
||||
## currently only one receiver is so marked - should there be more?
|
||||
# ex100_wpid_fix enable workarounds for EX100 and possible other old 27Mhz receivers
|
||||
# ex100_27mhz_wpid_fix enable workarounds for EX100 and possible other old 27Mhz receivers
|
||||
|
||||
_DRIVER = ('hid-generic', 'generic-usb', 'logitech-djreceiver')
|
||||
|
||||
|
@ -96,7 +96,7 @@ _ex100_receiver = lambda product_id: {
|
|||
'max_devices': 4,
|
||||
'may_unpair': False,
|
||||
're_pairs': True,
|
||||
'ex100_wpid_fix': True
|
||||
'ex100_27mhz_wpid_fix': True
|
||||
}
|
||||
|
||||
_wired_device = lambda product_id: {'vendor_id': 0x046d, 'product_id': product_id, 'usb_interface': 2}
|
||||
|
|
|
@ -169,7 +169,7 @@ _D(
|
|||
_D(
|
||||
'Wireless Keyboard MK300',
|
||||
protocol=1.0,
|
||||
wpid='8521',
|
||||
wpid='0068',
|
||||
registers=(_R.battery_status, ),
|
||||
)
|
||||
|
||||
|
@ -292,14 +292,14 @@ _D(
|
|||
'Wireless Keyboard S510',
|
||||
codename='S510',
|
||||
protocol=1.0,
|
||||
wpid='3622',
|
||||
wpid='0056',
|
||||
registers=(_R.battery_status, ),
|
||||
)
|
||||
_D(
|
||||
'Wireless Keyboard EX100',
|
||||
codename='EX100',
|
||||
protocol=1.0,
|
||||
wpid='6500',
|
||||
wpid='0065',
|
||||
registers=(_R.battery_status, ),
|
||||
)
|
||||
|
||||
|
@ -523,21 +523,21 @@ _D(
|
|||
'LX5 Cordless Mouse',
|
||||
codename='LX5',
|
||||
protocol=1.0,
|
||||
wpid='5612',
|
||||
wpid='0036',
|
||||
registers=(_R.battery_status, ),
|
||||
)
|
||||
_D(
|
||||
'Wireless Mouse M30',
|
||||
codename='M30',
|
||||
protocol=1.0,
|
||||
wpid='6822',
|
||||
wpid='0085',
|
||||
registers=(_R.battery_status, ),
|
||||
)
|
||||
_D(
|
||||
'Wireless Mouse EX100',
|
||||
codename='EX100m',
|
||||
protocol=1.0,
|
||||
wpid='3F00',
|
||||
wpid='003F',
|
||||
registers=(_R.battery_status, ),
|
||||
# settings=[ _RS.smooth_scroll(), ], # command accepted, but no change in whell action
|
||||
)
|
||||
|
|
|
@ -81,9 +81,13 @@ class Device(object):
|
|||
self.wpid = _strhex(link_notification.data[2:3] + link_notification.data[1:2])
|
||||
# assert link_notification.address == (0x04 if unifying else 0x03)
|
||||
kind = ord(link_notification.data[0:1]) & 0x0F
|
||||
# get 27Mhz wpid and set kind based on index
|
||||
if receiver.ex100_27mhz_wpid_fix: # 27 Mhz receiver
|
||||
self.wpid = '00' + _strhex(link_notification.data[2:3])
|
||||
kind = self.get_kind_from_index(number, receiver)
|
||||
self._kind = _hidpp10.DEVICE_KIND[kind]
|
||||
else:
|
||||
# force a reading of the wpid
|
||||
# Not a notification, force a reading of the wpid
|
||||
pair_info = self.receiver.read_register(_R.receiver_info, 0x20 + number - 1)
|
||||
if pair_info:
|
||||
# may be either a Unifying receiver, or an Unifying-ready
|
||||
|
@ -91,20 +95,14 @@ class Device(object):
|
|||
self.wpid = _strhex(pair_info[3:5])
|
||||
kind = ord(pair_info[7:8]) & 0x0F
|
||||
self._kind = _hidpp10.DEVICE_KIND[kind]
|
||||
elif receiver.ex100_wpid_fix:
|
||||
# ex100 receiver, fill fake device_info with known wpid's
|
||||
# accordingly to drivers/hid/hid-logitech-dj.c
|
||||
# index 1 or 2 always mouse, index 3 always the keyboard,
|
||||
# index 4 is used for an optional separate numpad
|
||||
if number == 1: # mouse
|
||||
self.wpid = '3F00'
|
||||
self._kind = _hidpp10.DEVICE_KIND[2]
|
||||
elif number == 3: # keyboard
|
||||
self.wpid = '6500'
|
||||
self._kind = _hidpp10.DEVICE_KIND[1]
|
||||
else: # unknown device number on EX100
|
||||
_log.error('failed to set fake EX100 wpid for device %d of %s', number, receiver)
|
||||
raise _base.NoSuchDevice(number=number, receiver=receiver, error='Unknown EX100 device')
|
||||
elif receiver.ex100_27mhz_wpid_fix:
|
||||
# 27Mhz receiver, fill extracting WPID from udev path
|
||||
self.wpid = _hid.find_paired_node_wpid(receiver.path, number)
|
||||
if not self.wpid:
|
||||
_log.error('Unable to get wpid from udev for device %d of %s', number, receiver)
|
||||
raise _base.NoSuchDevice(number=number, receiver=receiver, error='Not present 27Mhz device')
|
||||
kind = self.get_kind_from_index(number, receiver)
|
||||
self._kind = _hidpp10.DEVICE_KIND[kind]
|
||||
else:
|
||||
# unifying protocol not supported, must be a Nano receiver
|
||||
device_info = self.receiver.read_register(_R.receiver_info, 0x04)
|
||||
|
@ -289,6 +287,25 @@ class Device(object):
|
|||
self._feature_settings_checked = _check_feature_settings(self, self._settings)
|
||||
return self._settings
|
||||
|
||||
def get_kind_from_index(self, index, receiver):
|
||||
"""Get device kind from 27Mhz device index"""
|
||||
# accordingly to drivers/hid/hid-logitech-dj.c
|
||||
# index 1 or 2 always mouse, index 3 always the keyboard,
|
||||
# index 4 is used for an optional separate numpad
|
||||
|
||||
if index == 1: # mouse
|
||||
kind = 2
|
||||
elif index == 2: # mouse
|
||||
kind = 2
|
||||
elif index == 3: # keyboard
|
||||
kind = 1
|
||||
elif index == 4: # numpad
|
||||
kind = 3
|
||||
else: # unknown device number on 27Mhz receiver
|
||||
_log.error('failed to calculate device kind for device %d of %s', index, receiver)
|
||||
raise _base.NoSuchDevice(number=index, receiver=receiver, error='Unknown 27Mhz device number')
|
||||
return kind
|
||||
|
||||
def enable_notifications(self, enable=True):
|
||||
"""Enable or disable device (dis)connection notifications on this
|
||||
receiver."""
|
||||
|
|
|
@ -203,6 +203,9 @@ def _process_hidpp10_notification(device, status, n):
|
|||
)
|
||||
if protocol_name:
|
||||
wpid = _strhex(n.data[2:3] + n.data[1:2])
|
||||
# workaround for short EX100 and other 27 MHz wpids
|
||||
if protocol_name == '27 MHz':
|
||||
wpid = '00' + _strhex(n.data[2:3])
|
||||
if wpid != device.wpid:
|
||||
_log.warn('%s wpid mismatch, got %s', device, wpid)
|
||||
flags = ord(n.data[:1]) & 0xF0
|
||||
|
|
|
@ -79,7 +79,7 @@ class Receiver(object):
|
|||
self._str = '<%s(%s,%s%s)>' % (
|
||||
self.name.replace(' ', ''), self.path, '' if isinstance(self.handle, int) else 'T', self.handle
|
||||
)
|
||||
self.ex100_wpid_fix = product_info.get('ex100_wpid_fix', False)
|
||||
self.ex100_27mhz_wpid_fix = product_info.get('ex100_27mhz_wpid_fix', False)
|
||||
|
||||
self._firmware = None
|
||||
self._devices = {}
|
||||
|
|
Loading…
Reference in New Issue