def parseConfiguration(field): """ >>> f = { ... "name": "Configuration", ... "bLength": 9, ... "bDescriptorType": 2, ... "wTotalLength": 53, ... "bNumInterfaces": 1, ... "bConfigurationValue": 1, ... "iConfiguration": 0, ... "bmAttributes": "0x40", ... "bMaxPower": 0, ... "Interface": []} >>> c = parseConfiguration(f) >>> c.get() [9, 2, 53, 0, 1, 1, 0, 64, 0] """ interface_list = [parse(i) for i in field["Interface"]] return ConfigDescriptor( bLength=getVal(field["bLength"], 0, 0xFF), bDescriptorType=getVal(field["bDescriptorType"], 2, 2), wTotalLength=getVal(field["wTotalLength"], 0, 0xFFFF), bNumInterfaces=getVal(field["bNumInterfaces"], 0, 0xFF), bConfigurationValue=getVal(field["bConfigurationValue"], 0, 0xFF), iConfiguration=getVal(field["iConfiguration"], 0, 0xFF), bmAttributes=getVal(field["bmAttributes"], 0, 0xFF), bMaxPower=getVal(field["bMaxPower"], 0, 0xFF), interfaces=interface_list)
def parseDeviceQualifier(field): """ >>> f = { ... "name": "Device Qualifier", ... "bLength": 18, ... "bDescriptorType": 1, ... "bcdUSB": "0x0100", ... "bDeviceClass": 255, ... "bDeviceSubClass": 0, ... "bDeviceProtocol": 255, ... "bMaxPacketSize0": 64, ... "bNumConfigurations": 1 ... } >>> dq = parseDeviceQualifier(f) >>> dq.get() [18, 1, 0, 1, 255, 0, 255, 64, 1, 0] """ return DeviceQualifierDescriptor( bLength=getVal(field["bLength"], 0, 0xFF), bDescriptorType=getVal(field["bDescriptorType"], 0, 0xFF), bcdUSB=getVal(field["bcdUSB"], 0, 0xFFFF), bDeviceClass=getVal(field["bDeviceClass"], 0, 0xFF), bDeviceSubClass=getVal(field["bDeviceSubClass"], 0, 0xFF), bDeviceProtocol=getVal(field["bDeviceProtocol"], 0, 0xFF), bMaxPacketSize0=getVal(field["bMaxPacketSize0"], 0, 0xFF), bNumConfigurations=getVal(field["bNumConfigurations"], 0, 0xFF))
def parseInterface(intf): """ >>> f = { ... "bLength": 9, ... "bDescriptorType": 4, ... "bInterfaceNumber": 0, ... "bAlternateSetting": 0, ... "bNumEndpoints": 5, ... "bInterfaceClass": 5, ... "bInterfaceSubClass": 1, ... "bInterfaceProtocol": 2, ... "iInterface": 0, ... "Subdescriptors": []} >>> i = parseInterface(f) >>> i.get() [9, 4, 0, 0, 5, 5, 1, 2, 0] """ bInterfaceClass = getVal(intf["bInterfaceClass"], 0, 0xFF) bInterfaceSubclass = getVal(intf["bInterfaceSubClass"], 0, 0xFF) bInterfaceProtocol = getVal(intf["bInterfaceProtocol"], 0, 0xFF) parsers = getClassParsers(bInterfaceClass) sub_list = [parse(e, parsers) for e in intf["Subdescriptors"]] return InterfaceDescriptor( bLength=getVal(intf["bLength"], 0, 0xFF), bInterfaceNumber=getVal(intf["bInterfaceNumber"], 0, 0xFF), bAlternateSetting=getVal(intf["bAlternateSetting"], 0, 0xFF), bNumEndpoints=getVal(intf["bNumEndpoints"], 0, 0xFF), bInterfaceClass=bInterfaceClass, bInterfaceSubclass=bInterfaceSubclass, bInterfaceProtocol=bInterfaceProtocol, iInterface=getVal(intf["iInterface"], 0, 0xFF), subdescriptors=sub_list)
def parseDfuFunctional(f): """Parser function to read values of supported DFU descriptors for the device from config file. Args: field: JSON structure for this class to be parsed. .. doctest: >>> f = { ... "name": "DFU Functional", ... "bLength": 9, ... "bDescriptorType": "0x21", ... "bmAttributes": "0x0D", ... "wDetachTimeout": 10000, ... "wTransferSize": 1024, ... "bcdDFUVersion": "0x0101" ... } >>> d = parseDfuFunctional(f) >>> d.get() [9, 33, 13, 16, 39, 0, 4, 1, 1] """ return DfuFunctionalDescriptor( bLength=getVal(f["bLength"], 0, 0xFF), bDescriptorType=getVal(f["bDescriptorType"], 0, 0xFF), bmAttributes=getVal(f["bmAttributes"], 0, 0xFF), wDetachTimeout=getVal(f["wDetachTimeout"], 0, 0xFFFF), wTransferSize=getVal(f["wTransferSize"], 0, 0xFFFF), bcdDFUVersion=getVal(f["bcdDFUVersion"], 0, 0xFFFF))
def parseDevice(field): """ >>> f = { ... "name": "Device", ... "bLength": 18, ... "bDescriptorType": 1, ... "bcdUSB": "0x0201", ... "bDeviceClass": "0xef", ... "bDeviceSubClass": 2, ... "bDeviceProtocol": 1, ... "bMaxPacketSize0": 64, ... "idVendor": "0x1209", ... "idProduct": "0x5bf0", ... "bcdDevice": "0x0101", ... "iManufacturer": 1, ... "iProduct": 2, ... "iSerial": 0, ... "bNumConfigurations": 1 ... } >>> d = parseDevice(f) >>> d.get() [18, 1, 1, 2, 239, 2, 1, 64, 9, 18, 240, 91, 1, 1, 1, 2, 0, 1] """ return DeviceDescriptor( bLength=getVal(field["bLength"], 0, 0xFF), bDescriptorType=getVal(field["bDescriptorType"], 1, 1), bcdUSB=getVal(field["bcdUSB"], 0, 0xFFFF), bDeviceClass=getVal(field["bDeviceClass"], 0, 0xFF), bDeviceSubClass=getVal(field["bDeviceSubClass"], 0, 0xFF), bDeviceProtocol=getVal(field["bDeviceProtocol"], 0, 0xFF), bMaxPacketSize0=getVal(field["bMaxPacketSize0"], 0, 0xFF), idVendor=getVal(field["idVendor"], 0, 0xFFFF), idProduct=getVal(field["idProduct"], 0, 0xFFFF), bcdDevice=getVal(field["bcdDevice"], 0, 0xFFFF), iManufacturer=getVal(field["iManufacturer"], 0, 0xFF), iProduct=getVal(field["iProduct"], 0, 0xFF), iSerialNumber=getVal(field["iSerial"], 0, 0xFF), bNumConfigurations=getVal(field["bNumConfigurations"], 0, 0xFF))
def parse(field, customParsers=None): """ >>> f = { ... "name": "Configuration", ... "bLength": 9, ... "bDescriptorType": 2, ... "wTotalLength": 53, ... "bNumInterfaces": 1, ... "bConfigurationValue": 1, ... "iConfiguration": 0, ... "bmAttributes": "0x40", ... "bMaxPower": 0, ... "Interface": [ ... { ... "bLength": 9, ... "bDescriptorType": 4, ... "bInterfaceNumber": 0, ... "bAlternateSetting": 0, ... "bNumEndpoints": 5, ... "bInterfaceClass": 5, ... "bInterfaceSubClass": 1, ... "bInterfaceProtocol": 55, ... "iInterface": 0, ... "Subdescriptors": [ ... { ... "name": "Endpoint", ... "bLength": 7, ... "bDescriptorType": 5, ... "bEndpointAddress": [1, "IN"], ... "bmAttributes": { ... "Transfer": "Isochronous", ... "Synch": "None", ... "Usage": "Data" ... }, ... "wMaxPacketSize": "0x0100", ... "bInterval": 1 ... }, ... { ... "name": "Endpoint", ... "bLength": 7, ... "bDescriptorType": 5, ... "bEndpointAddress": [2, "OUT"], ... "bmAttributes": { ... "Transfer": "Isochronous", ... "Synch": "None", ... "Usage": "Data" ... }, ... "wMaxPacketSize": "0x0100", ... "bInterval": 1 ... } ... ] ... } ... ] ... } >>> c = parse(f) >>> c.get() [9, 2, 53, 0, 1, 1, 0, 64, 0, 9, 4, 0, 0, 5, 5, 1, 55, 0, 7, 5, 129, 1, 0, 1, 1, 7, 5, 2, 1, 0, 1, 1] """ # noqa bDescriptorType = getVal(field["bDescriptorType"], 0, 0xFF) if isStandard(bDescriptorType): return standardParsers[bDescriptorType](field) elif customParsers is not None: try: return customParsers[bDescriptorType](field) except KeyError: print("Unexpected descriptor type: {}, ignoring".format( bDescriptorType)) else: print("Unknown descriptor: {}".format(bDescriptorType)) return None
def parseEndpoint(e): """ >>> f = { ... "name": "Endpoint", ... "bLength": 7, ... "bDescriptorType": 5, ... "bEndpointAddress": [3, "IN"], ... "bmAttributes": { ... "Transfer": "Bulk", ... "Synch": "None", ... "Usage": "Data" ... }, ... "wMaxPacketSize": "0x0040", ... "bInterval": 1 ... } >>> e = parseEndpoint(f) >>> e.get() [7, 5, 131, 2, 64, 0, 1] >>> f = { ... "name": "Endpoint", ... "bLength": 7, ... "bDescriptorType": 5, ... "bEndpointAddress": "0x81", ... "bmAttributes": "0x82", ... "wMaxPacketSize": "0x0040", ... "bInterval": 1 ... } >>> e = parseEndpoint(f) >>> e.get() [7, 5, 129, 130, 64, 0, 1] """ bLength = getVal(e["bLength"], 0, 0xFF) if isinstance(e["bEndpointAddress"], str): bEndpointAddress = getVal(e["bEndpointAddress"], 0, 0xFF) else: if e["bEndpointAddress"][1] == "IN": endpointDir = EndpointDescriptor.Direction.IN elif e["bEndpointAddress"][1] == "OUT": endpointDir = EndpointDescriptor.Direction.OUT bEndpointAddress = getVal(e["bEndpointAddress"][0], 0, 15) | (endpointDir << 7) if isinstance(e["bmAttributes"], str): bmAttributes = getVal(e["bmAttributes"], 0, 0xFF) else: if e["bmAttributes"]["Transfer"] == "Control": eTransfer = EndpointDescriptor.TransferType.CONTROL elif e["bmAttributes"]["Transfer"] == "Isochronous": eTransfer = EndpointDescriptor.TransferType.ISOCHRONOUS elif e["bmAttributes"]["Transfer"] == "Bulk": eTransfer = EndpointDescriptor.TransferType.BULK elif e["bmAttributes"]["Transfer"] == "Interrupt": eTransfer = EndpointDescriptor.TransferType.INTERRUPT if e["bmAttributes"]["Synch"] == "None": eSynch = EndpointDescriptor.SynchronizationType.NO elif e["bmAttributes"]["Synch"] == "Asynchronous": eSynch = EndpointDescriptor.SynchronizationType.ASYNC elif e["bmAttributes"]["Synch"] == "Adaptive": eSynch = EndpointDescriptor.SynchronizationType.ADAPTIVE elif e["bmAttributes"]["Synch"] == "Synchronous": eSynch = EndpointDescriptor.SynchronizationType.SYNC if e["bmAttributes"]["Usage"] == "Data": eUsage = EndpointDescriptor.UsageType.DATA elif e["bmAttributes"]["Usage"] == "Feedback": eUsage = EndpointDescriptor.UsageType.FEEDBACK elif e["bmAttributes"]["Usage"] == "Implicit feedback Data": eUsage = EndpointDescriptor.UsageType.IFDATA bmAttributes = eUsage << 5 | eSynch << 3 | eTransfer # Bits 15..13 must be set to zero below wMaxPacketSize = getVal(e["wMaxPacketSize"], 0, 0x1FFF) bInterval = getVal(e["bInterval"], 0, 0xFF) return EndpointDescriptor(bLength, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval)
def parseCDC(field): """Parser function to read values of supported CDC descriptors for the device from config file. Args: field: JSON structure for this class to be parsed. .. doctest: >>> f = { ... "name": "Header Functional", ... "bLength": 5, ... "bDescriptorType": "0x24", ... "bDescriptorSubtype": 0, ... "bcdCDC": "0x0110" ... } >>> h = parseCDC(f) >>> h.get() [5, 36, 0, 16, 1] >>> f = { ... "name": "Call Management Functional", ... "bLength": 5, ... "bDescriptorType": "0x24", ... "bDescriptorSubtype": 1, ... "bmCapabilities": 0, ... "bDataInterface": 1 ... } >>> cm = parseCDC(f) >>> cm.get() [5, 36, 1, 0, 1] >>> f = { ... "name": "ACM Functional", ... "bLength": 4, ... "bDescriptorType": "0x24", ... "bDescriptorSubtype": 2, ... "bmCapabilities": 6 ... } >>> acm = parseCDC(f) >>> acm.get() [4, 36, 2, 6] >>> f = { ... "name": "Union Functional", ... "bLength": 5, ... "bDescriptorType": "0x24", ... "bDescriptorSubtype": 6, ... "bMasterInterface": 0, ... "bSlaveInterface": [ 1 ] ... } >>> u = parseCDC(f) >>> u.get() [5, 36, 6, 0, 1] """ bDescriptorSubtype = getVal(field["bDescriptorSubtype"], 0, 0xFF) if bDescriptorSubtype == CDC.Subtype.HEADER: return Header(bLength=getVal(field["bLength"], 0, 0xFF), bDescriptorType=getVal(field["bDescriptorType"], 0, 0xFF), bDescriptorSubtype=getVal(field["bDescriptorSubtype"], 0, 0xFF), bcdCDC=getVal(field["bcdCDC"], 0, 0xFFFF)) elif bDescriptorSubtype == CDC.Subtype.CM: return CallManagement( bLength=getVal(field["bLength"], 0, 0xFF), bDescriptorType=getVal(field["bDescriptorType"], 0, 0xFF), bDescriptorSubtype=getVal(field["bDescriptorSubtype"], 0, 0xFF), bmCapabilities=getVal(field["bmCapabilities"], 0, 0xFF), bDataInterface=getVal(field["bDataInterface"], 0, 0xFF)) elif bDescriptorSubtype == CDC.Subtype.ACM: return AbstractControlManagement( bLength=getVal(field["bLength"], 0, 0xFF), bDescriptorType=getVal(field["bDescriptorType"], 0, 0xFF), bDescriptorSubtype=getVal(field["bDescriptorSubtype"], 0, 0xFF), bmCapabilities=getVal(field["bmCapabilities"], 0, 0xFF)) elif bDescriptorSubtype == CDC.Subtype.DLM: return DirectLineManagement( bLength=getVal(field["bLength"], 0, 0xFF), bDescriptorType=getVal(field["bDescriptorType"], 0, 0xFF), bDescriptorSubtype=getVal(field["bDescriptorSubtype"], 0, 0xFF), bmCapabilities=getVal(field["bmCapabilities"], 0, 0xFF)) elif bDescriptorSubtype == CDC.Subtype.UNION: bSlaveInterface_list = [ getVal(i, 0, 0xFF) for i in field["bSlaveInterface"] ] return Union(bDescriptorType=getVal(field["bDescriptorType"], 0, 0xFF), bDescriptorSubtype=getVal(field["bDescriptorSubtype"], 0, 0xFF), bMasterInterface=getVal(field["bMasterInterface"], 0, 0xFF), bSlaveInterface_list=bSlaveInterface_list) else: print("Unsupported CDC subclass")