Skip to content

Instantly share code, notes, and snippets.

@mdkcore0
Created December 12, 2019 21:12
Show Gist options
  • Save mdkcore0/bb11af19470ab6f741d971fc6eef1f5a to your computer and use it in GitHub Desktop.
Save mdkcore0/bb11af19470ab6f741d971fc6eef1f5a to your computer and use it in GitHub Desktop.
python hid/pyusb test (linux/macos)
# hid==1.0.4
# pyusb==1.0.2
# NOTE: should install hidpai (brew/package manager)
import hid
import binascii
# MAYBE, we can register a callback to be notified about device
# add/remove (https://github.com/pyusb/pyusb/pull/160)
from usb import core
from usb import util
def dec_to_hex(value):
return "{0:x}".format(value)
def str_to_int(value):
return int(value, base=16)
def str_to_hex(value):
return hex(str_to_int(value))
class find_class(object):
def __init__(self, class_):
self._class = class_
def __call__(self, device):
if device.bDeviceClass == self._class:
return True
for cfg in device:
intf = util.find_descriptor(cfg, bInterfaceClass=self._class)
if intf is not None:
return True
return False
# some info can be gathered by:
# $ lsusb -v
# or device specific:
# $ lsusb -d vid:pid -v
supported_devices = {
'Tipro': {'vendor_id': '1222',
'devices': [
{'name': 'Handset Controller',
'product_id': 'facb'}
]
}
}
devices_to_bind = {}
# we can enumarate with vendor_id and product_id as well, useful after some
# type of hotplug event
for dev in hid.enumerate():
manufacturer = dev.get('manufacturer_string')
product = dev.get('product_string')
if manufacturer in supported_devices:
for device in supported_devices[manufacturer]['devices']:
vendor_id = str_to_int(
supported_devices[manufacturer]['vendor_id'])
if product == device['name'] and \
dec_to_hex(dev.get('product_id')) == device['product_id']:
product_id = str_to_int(device['product_id'])
# 3 == hid, 1 == audio
usb_device = core.find(custom_match=find_class(3),
idVendor=vendor_id,
idProduct=product_id)
# bInterfaceProtocol 0 (0 == None, 1 == Keyboard, 2 == Mouse)
# iInterface 7?
for conf in usb_device:
for interface in conf:
if interface.bInterfaceProtocol == 0 and \
interface.bInterfaceNumber == dev.get(
'interface_number'):
devices_to_bind["%s %s" % (manufacturer,
product)] = \
{'path': dev.get('path'),
'packet_size': interface[0].wMaxPacketSize}
print("devices to bind:", devices_to_bind)
# open a device to read it's data
# on linux we can open hidraw directly; check if we can do it on macos as well
d = hid.Device(path=devices_to_bind['Tipro Handset Controller']['path'])
packet_size = devices_to_bind['Tipro Handset Controller']['packet_size']
while True:
# macos keep reading "0000000000000000" (or "0100000000000000") while idle
data = binascii.hexlify(d.read(packet_size)).decode()
if data:
print(data)
d.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment