'\n# '.join(sources)),
file=file)
+def add_item(items, key, value):
+ if key in items:
+ print(f'Ignoring duplicate entry: {key} = "{items[key]}", "{value}"')
+ else:
+ items[key] = value
+
def usb_vendor_model(p):
+ items = {}
+
+ for vendor_group in p.VENDORS:
+ vendor = vendor_group.VENDOR.vendor.upper()
+ text = vendor_group.VENDOR.text.strip()
+ add_item(items, (vendor,), text)
+
+ for vendor_dev in vendor_group.VENDOR_DEV:
+ device = vendor_dev.device.upper()
+ text = vendor_dev.text.strip()
+ add_item(items, (vendor, device), text)
+
with open('20-usb-vendor-model.hwdb', 'wt') as out:
header(out, 'http://www.linux-usb.org/usb.ids')
- for vendor_group in p.VENDORS:
- vendor = vendor_group.VENDOR.vendor.upper()
- text = vendor_group.VENDOR.text.strip()
- print(f'',
- f'usb:v{vendor}*',
- f' ID_VENDOR_FROM_DATABASE={text}', sep='\n', file=out)
-
- for vendor_dev in vendor_group.VENDOR_DEV:
- device = vendor_dev.device.upper()
- text = vendor_dev.text.strip()
- print(f'',
- f'usb:v{vendor}p{device}*',
- f' ID_MODEL_FROM_DATABASE={text}', sep='\n', file=out)
+ for key in sorted(items):
+ if len(key) == 1:
+ p, n = 'usb:v{}*', 'VENDOR'
+ else:
+ p, n = 'usb:v{}p{}*', 'MODEL',
+ print('', p.format(*key),
+ f' ID_{n}_FROM_DATABASE={items[key]}', sep='\n', file=out)
+
print(f'Wrote {out.name}')
def usb_classes(p):
+ items = {}
+
+ for klass_group in p.CLASSES:
+ klass = klass_group.KLASS.klass.upper()
+ text = klass_group.KLASS.text.strip()
+
+ if klass != '00' and not re.match(r'(\?|None|Unused)\s*$', text):
+ add_item(items, (klass,), text)
+
+ for subclass_group in klass_group.SUBCLASSES:
+ subclass = subclass_group.subclass.upper()
+ text = subclass_group.text.strip()
+ if subclass != '00' and not re.match(r'(\?|None|Unused)\s*$', text):
+ add_item(items, (klass, subclass), text)
+
+ for protocol_group in subclass_group.PROTOCOLS:
+ protocol = protocol_group.protocol.upper()
+ text = protocol_group.name.strip()
+ if klass != '00' and not re.match(r'(\?|None|Unused)\s*$', text):
+ add_item(items, (klass, subclass, protocol), text)
+
with open('20-usb-classes.hwdb', 'wt') as out:
header(out, 'http://www.linux-usb.org/usb.ids')
- for klass_group in p.CLASSES:
- klass = klass_group.KLASS.klass.upper()
- text = klass_group.KLASS.text.strip()
-
- if klass != '00' and not re.match(r'(\?|None|Unused)\s*$', text):
- print(f'',
- f'usb:v*p*d*dc{klass}*',
- f' ID_USB_CLASS_FROM_DATABASE={text}', sep='\n', file=out)
-
- for subclass_group in klass_group.SUBCLASSES:
- subclass = subclass_group.subclass.upper()
- text = subclass_group.text.strip()
- if subclass != '00' and not re.match(r'(\?|None|Unused)\s*$', text):
- print(f'',
- f'usb:v*p*d*dc{klass}dsc{subclass}*',
- f' ID_USB_SUBCLASS_FROM_DATABASE={text}', sep='\n', file=out)
-
- for protocol_group in subclass_group.PROTOCOLS:
- protocol = protocol_group.protocol.upper()
- text = protocol_group.name.strip()
- if klass != '00' and not re.match(r'(\?|None|Unused)\s*$', text):
- print(f'',
- f'usb:v*p*d*dc{klass}dsc{subclass}dp{protocol}*',
- f' ID_USB_PROTOCOL_FROM_DATABASE={text}', sep='\n', file=out)
+ for key in sorted(items):
+ if len(key) == 1:
+ p, n = 'usb:v*p*d*dc{}*', 'CLASS'
+ elif len(key) == 2:
+ p, n = 'usb:v*p*d*dc{}dsc{}*', 'SUBCLASS'
+ else:
+ p, n = 'usb:v*p*d*dc{}dsc{}dp{}*', 'PROTOCOL'
+ print('', p.format(*key),
+ f' ID_USB_{n}_FROM_DATABASE={items[key]}', sep='\n', file=out)
+
print(f'Wrote {out.name}')
def pci_vendor_model(p):
+ items = {}
+
+ for vendor_group in p.VENDORS:
+ vendor = vendor_group.VENDOR.vendor.upper()
+ text = vendor_group.VENDOR.text.strip()
+ add_item(items, (vendor,), text)
+
+ for device_group in vendor_group.DEVICES:
+ device = device_group.device.upper()
+ text = device_group.text.strip()
+ add_item(items, (vendor, device), text)
+
+ for subvendor_group in device_group.SUBVENDORS:
+ sub_vendor = subvendor_group.a.upper()
+ sub_model = subvendor_group.b.upper()
+ sub_text = subvendor_group.name.strip()
+ if sub_text.startswith(text):
+ sub_text = sub_text[len(text):].lstrip()
+ if sub_text:
+ sub_text = f' ({sub_text})'
+ add_item(items, (vendor, device, sub_vendor, sub_model), text + sub_text)
+
with open('20-pci-vendor-model.hwdb', 'wt') as out:
header(out, 'http://pci-ids.ucw.cz/v2.2/pci.ids')
- for vendor_group in p.VENDORS:
- vendor = vendor_group.VENDOR.vendor.upper()
- text = vendor_group.VENDOR.text.strip()
- print(f'',
- f'pci:v0000{vendor}*',
- f' ID_VENDOR_FROM_DATABASE={text}', sep='\n', file=out)
-
- for device_group in vendor_group.DEVICES:
- device = device_group.device.upper()
- text = device_group.text.strip()
- print(f'',
- f'pci:v0000{vendor}d0000{device}*',
- f' ID_MODEL_FROM_DATABASE={text}', sep='\n', file=out)
-
- for subvendor_group in device_group.SUBVENDORS:
- sub_vendor = subvendor_group.a.upper()
- sub_model = subvendor_group.b.upper()
- sub_text = subvendor_group.name.strip()
- if sub_text.startswith(text):
- sub_text = sub_text[len(text):].lstrip()
- if sub_text:
- sub_text = f' ({sub_text})'
- print(f'',
- f'pci:v0000{vendor}d0000{device}sv0000{sub_vendor}sd0000{sub_model}*',
- f' ID_MODEL_FROM_DATABASE={text}{sub_text}', sep='\n', file=out)
+ for key in sorted(items):
+ if len(key) == 1:
+ p, n = 'pci:v0000{}*', 'VENDOR'
+ elif len(key) == 2:
+ p, n = 'pci:v0000{}d0000{}*', 'MODEL'
+ else:
+ p, n = 'pci:v0000{}d0000{}sv0000{}sd0000{}*', 'MODEL'
+ print('', p.format(*key),
+ f' ID_{n}_FROM_DATABASE={items[key]}', sep='\n', file=out)
+
print(f'Wrote {out.name}')
def pci_classes(p):
+ items = {}
+
+ for klass_group in p.CLASSES:
+ klass = klass_group.KLASS.klass.upper()
+ text = klass_group.KLASS.text.strip()
+ add_item(items, (klass,), text)
+
+ for subclass_group in klass_group.SUBCLASSES:
+ subclass = subclass_group.subclass.upper()
+ text = subclass_group.text.strip()
+ add_item(items, (klass, subclass), text)
+
+ for protocol_group in subclass_group.PROTOCOLS:
+ protocol = protocol_group.protocol.upper()
+ text = protocol_group.name.strip()
+ add_item(items, (klass, subclass, protocol), text)
+
with open('20-pci-classes.hwdb', 'wt') as out:
header(out, 'http://pci-ids.ucw.cz/v2.2/pci.ids')
- for klass_group in p.CLASSES:
- klass = klass_group.KLASS.klass.upper()
- text = klass_group.KLASS.text.strip()
+ for key in sorted(items):
+ if len(key) == 1:
+ p, n = 'pci:v*d*sv*sd*bc{}*', 'CLASS'
+ elif len(key) == 2:
+ p, n = 'pci:v*d*sv*sd*bc{}sc{}*', 'SUBCLASS'
+ else:
+ p, n = 'pci:v*d*sv*sd*bc{}sc{}i{}*', 'INTERFACE'
+ print('', p.format(*key),
+ f' ID_PCI_{n}_FROM_DATABASE={items[key]}', sep='\n', file=out)
- print(f'',
- f'pci:v*d*sv*sd*bc{klass}*',
- f' ID_PCI_CLASS_FROM_DATABASE={text}', sep='\n', file=out)
-
- for subclass_group in klass_group.SUBCLASSES:
- subclass = subclass_group.subclass.upper()
- text = subclass_group.text.strip()
- print(f'',
- f'pci:v*d*sv*sd*bc{klass}sc{subclass}*',
- f' ID_PCI_SUBCLASS_FROM_DATABASE={text}', sep='\n', file=out)
-
- for protocol_group in subclass_group.PROTOCOLS:
- protocol = protocol_group.protocol.upper()
- text = protocol_group.name.strip()
- print(f'',
- f'pci:v*d*sv*sd*bc{klass}sc{subclass}i{protocol}*',
- f' ID_PCI_INTERFACE_FROM_DATABASE={text}', sep='\n', file=out)
print(f'Wrote {out.name}')
def sdio_vendor_model(p):
+ items = {}
+
+ for vendor_group in p.VENDORS:
+ vendor = vendor_group.VENDOR.vendor.upper()
+ text = vendor_group.VENDOR.text.strip()
+ add_item(items, (vendor,), text)
+
+ for device_group in vendor_group.DEVICES:
+ device = device_group.device.upper()
+ text = device_group.text.strip()
+ add_item(items, (vendor, device), text)
+
with open('20-sdio-vendor-model.hwdb', 'wt') as out:
header(out, 'hwdb/sdio.ids')
- for vendor_group in p.VENDORS:
- vendor = vendor_group.VENDOR.vendor.upper()
- text = vendor_group.VENDOR.text.strip()
- print(f'',
- f'sdio:c*v{vendor}*',
- f' ID_VENDOR_FROM_DATABASE={text}', sep='\n', file=out)
-
- for device_group in vendor_group.DEVICES:
- device = device_group.device.upper()
- text = device_group.text.strip()
- print(f'',
- f'sdio:c*v{vendor}d{device}*',
- f' ID_MODEL_FROM_DATABASE={text}', sep='\n', file=out)
+ for key in sorted(items):
+ if len(key) == 1:
+ p, n = 'sdio:c*v{}*', 'VENDOR'
+ else:
+ p, n = 'sdio:c*v{}d{}*', 'MODEL'
+ print('', p.format(*key),
+ f' ID_{n}_FROM_DATABASE={items[key]}', sep='\n', file=out)
+
print(f'Wrote {out.name}')
def sdio_classes(p):
+ items = {}
+
+ for klass_group in p.CLASSES:
+ klass = klass_group.KLASS.klass.upper()
+ text = klass_group.KLASS.text.strip()
+ add_item(items, klass, text)
+
with open('20-sdio-classes.hwdb', 'wt') as out:
header(out, 'hwdb/sdio.ids')
- for klass_group in p.CLASSES:
- klass = klass_group.KLASS.klass.upper()
- text = klass_group.KLASS.text.strip()
-
+ for klass in sorted(items):
print(f'',
f'sdio:c{klass}v*d*',
- f' ID_SDIO_CLASS_FROM_DATABASE={text}', sep='\n', file=out)
+ f' ID_SDIO_CLASS_FROM_DATABASE={items[klass]}', sep='\n', file=out)
+
print(f'Wrote {out.name}')
# MAC Address Block Large/Medium/Small
# Medium MA-M 28/20 bit (OUI prefix owned by IEEE)
# Small MA-S 36/12 bit (OUI prefix owned by IEEE)
def oui(p1, p2, p3):
+ prefixes = set()
+ items = {}
+
+ for p, check in ((p1, False), (p2, False), (p3, True)):
+ for vendor_group in p.VENDORS:
+ prefix = vendor_group.prefix.upper()
+ if check:
+ if prefix in prefixes:
+ continue
+ else:
+ prefixes.add(prefix)
+ start = vendor_group.start.upper()
+ end = vendor_group.end.upper()
+
+ if end and start != end:
+ print(f'{prefix:} {start} != {end}', file=sys.stderr)
+ text = vendor_group.text.strip()
+
+ key = prefix + start if end else prefix
+ add_item(items, key, text)
+
with open('20-OUI.hwdb', 'wt') as out:
header(out,
'https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-L&format=txt',
'https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-M&format=txt',
'https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-S&format=txt')
- prefixes = set()
-
- for p, check in ((p1, False), (p2, False), (p3, True)):
- for vendor_group in p.VENDORS:
- prefix = vendor_group.prefix.upper()
- if check:
- if prefix in prefixes:
- continue
- else:
- prefixes.add(prefix)
- start = vendor_group.start.upper()
- end = vendor_group.end.upper()
-
- if end and start != end:
- print(f'{prefix:} {start} != {end}', file=sys.stderr)
- text = vendor_group.text.strip()
-
- print(f'',
- f'OUI:{prefix}{start if end else ""}*',
- f' ID_OUI_FROM_DATABASE={text}', sep='\n', file=out)
+ for pattern in sorted(items):
+ print(f'',
+ f'OUI:{pattern}*',
+ f' ID_OUI_FROM_DATABASE={items[pattern]}', sep='\n', file=out)
+
print(f'Wrote {out.name}')
if __name__ == '__main__':
- p = usb_ids_grammar().parseFile(open('usb.ids'))
- usb_vendor_model(p)
- usb_classes(p)
-
- p = pci_ids_grammar().parseFile(open('pci.ids'))
- pci_vendor_model(p)
- pci_classes(p)
-
- p = pci_ids_grammar().parseFile(open('sdio.ids'))
- sdio_vendor_model(p)
- sdio_classes(p)
-
- p = oui_grammar('small').parseFile(open('ma-small.txt'))
- p2 = oui_grammar('medium').parseFile(open('ma-medium.txt'))
- p3 = oui_grammar('large').parseFile(open('ma-large.txt'))
-
- oui(p, p2, p3)
+ args = sys.argv[1:]
+
+ if not args or 'usb' in args:
+ p = usb_ids_grammar().parseFile(open('usb.ids', errors='replace'))
+ usb_vendor_model(p)
+ usb_classes(p)
+
+ if not args or 'pci' in args:
+ p = pci_ids_grammar().parseFile(open('pci.ids', errors='replace'))
+ pci_vendor_model(p)
+ pci_classes(p)
+
+ if not args or 'sdio' in args:
+ p = pci_ids_grammar().parseFile(open('sdio.ids', errors='replace'))
+ sdio_vendor_model(p)
+ sdio_classes(p)
+
+ if not args or 'oui' in args:
+ p = oui_grammar('small').parseFile(open('ma-small.txt'))
+ p2 = oui_grammar('medium').parseFile(open('ma-medium.txt'))
+ p3 = oui_grammar('large').parseFile(open('ma-large.txt'))
+ oui(p, p2, p3)