From 5b8f76161d6c0cf4eea4b72b17bab137e94aa631 Mon Sep 17 00:00:00 2001 From: Epagris Date: Sat, 27 Apr 2024 22:13:03 +0200 Subject: [PATCH] - EthernetNetworkFunctionalDescriptor added - automatic String Descriptor generation added --- desc/ConfigGenerator.py | 29 ++++++++------ desc/Descriptor.py | 85 ++++++++++++++++++++++++++++++----------- 2 files changed, 81 insertions(+), 33 deletions(-) diff --git a/desc/ConfigGenerator.py b/desc/ConfigGenerator.py index e9cbf37..ef9bad2 100644 --- a/desc/ConfigGenerator.py +++ b/desc/ConfigGenerator.py @@ -68,13 +68,13 @@ class ConfigGenerator: # string management self.str_mgr = StringManager() - string_fields = [ - "vendor_string", - "product_string", - "serial_number" - ] + # string_fields = [ + # "vendor_string", + # "product_string", + # "serial_number" + # ] - self.str_mgr.add_placeholders(string_fields) + #self.str_mgr.add_placeholders(string_fields) self.LANG_ID_US_EN = "0x0409" @@ -145,6 +145,9 @@ class ConfigGenerator: # ----------------- + # collect type definitions for all interfaces, so that no type definition gets printed more than once + addintf_tdefs = [] + for intf in conf["interfaces"]: # generate interface descriptor intf_varname = "intf{:d}".format(intf["id"]) @@ -153,13 +156,15 @@ class ConfigGenerator: full_conf_struct.add_record(intf_struct) # generate additional interface descriptors -# if [intf.keys()].count("additional_interfaces") > 0: for addintf in intf["additional_interfaces"]: type = addintf["type"] - addintf_struct = desc.DescriptorFactory.generate(type, intf_varname + type, addintf) + addintf_struct = desc.DescriptorFactory.generate(type, intf_varname + type, addintf, self.str_mgr) full_conf_struct.add_record(addintf_struct) - self.h += addintf_struct.print_typedef() + # generate typedef only, if not done before + if addintf_tdefs.count(type) == 0: + self.h += addintf_struct.print_typedef() # print typedef + addintf_tdefs.append(type) # add to already generated typedefs to avoid duplication # generate endpoint descriptors self.generate_endpoint_descriptors(intf, full_conf_struct) # generate endpoints @@ -212,8 +217,10 @@ class ConfigGenerator: # generate individual string descriptors for text_id in self.str_mgr.get_text_ids(): + # + # self.str_mgr.change_text(text_id, self.config[text_id]) + # create descriptor - self.str_mgr.change_text(text_id, self.config[text_id]) str_struct = desc.StringDescriptor(self.str_mgr.get_text(text_id), text_id) self.c += str_struct.gen_c() self.h += str_struct.gen_h(print_typedef=True) @@ -235,10 +242,10 @@ class ConfigGenerator: def generate(self): self.generate_macros() # generate macro definitions - self.generate_string_descriptors() # generate string descriptors self.generate_device_descriptor() # generate device descriptor self.generate_device_qualifier_descriptor() # generate device qualifier descriptor self.generate_configuration_descriptors() # generate configuration descriptors + self.generate_string_descriptors() # generate string descriptors (should be the last one, since additional interface descriptors may add new string descriptors) # save generated files self.save() diff --git a/desc/Descriptor.py b/desc/Descriptor.py index 6dddbf1..2e848ea 100644 --- a/desc/Descriptor.py +++ b/desc/Descriptor.py @@ -1,5 +1,6 @@ import math +import ConfigGenerator import StructGenerator from enum import Enum @@ -47,7 +48,12 @@ class Descriptor(StructGenerator.StructRecord): # ----------------------------- class DeviceDescriptor(Descriptor): - def __init__(self, dev, str_mgr): + def __init__(self, dev, str_mgr: ConfigGenerator.StringManager): + # add strings to the string manager + str_mgr.add_string("vendor_string", dev["vendor_string"]) + str_mgr.add_string("product_string", dev["product_string"]) + str_mgr.add_string("serial_number", dev["serial_number"]) + # generate device descriptor numOfConfs = len(dev["configurations"]) # get number of configurations records = [ @@ -66,7 +72,8 @@ class DeviceDescriptor(Descriptor): ["iSerialNumber", "u8", str_mgr.get_numeric_id("serial_number")], ["bNumConfigurations", "u8", numOfConfs]] - super().__init__("devDesc", "struct _USB_DeviceDesc", StructGenerator.RecordFactory.createa(records), comment="Device Descriptor") + super().__init__("devDesc", "struct _USB_DeviceDesc", StructGenerator.RecordFactory.createa(records), + comment="Device Descriptor") class DeviceQualifierDescriptor(Descriptor): @@ -83,7 +90,8 @@ class DeviceQualifierDescriptor(Descriptor): ["bMaxPacketSize", "u8", dev["max_ep0_packet_size"]], ["bNumConfigurations", "u8", numOfConfs]] - super().__init__("devQualDesc", "struct _USB_DeviceQualifierDesc", StructGenerator.RecordFactory.createa(records), comment="Device Qualifier descriptor") + super().__init__("devQualDesc", "struct _USB_DeviceQualifierDesc", + StructGenerator.RecordFactory.createa(records), comment="Device Qualifier descriptor") class StringDescriptor(Descriptor): @@ -99,7 +107,8 @@ class StringDescriptor(Descriptor): ["bDescriptorType", "u8", "UD_String", True], ["bString", "u16", text_langid]] - super().__init__(name, "struct _USB_StrDesc_{:s}".format(name), StructGenerator.RecordFactory.createa(records), comment="String descriptor") + super().__init__(name, "struct _USB_StrDesc_{:s}".format(name), StructGenerator.RecordFactory.createa(records), + comment="String descriptor") class ConfigurationDescriptor(Descriptor): @@ -122,7 +131,8 @@ class ConfigurationDescriptor(Descriptor): ["bmAttributes", "u8", attributes, True], ["bMaxPower", "u8", math.ceil(conf["max_power_mA"] / 2)]] - super().__init__(name, "struct _USB_ConfigurationDesc", StructGenerator.RecordFactory.createa(records), comment="Configuration descriptor") + super().__init__(name, "struct _USB_ConfigurationDesc", StructGenerator.RecordFactory.createa(records), + comment="Configuration descriptor") class InterfaceDescriptor(Descriptor): @@ -139,7 +149,8 @@ class InterfaceDescriptor(Descriptor): ["bInterfaceProtocol", "u8", intf["protocol_code"]], ["iInterface", "u8", 0]] - super().__init__(name, "struct _USB_InterfaceDesc", StructGenerator.RecordFactory.createa(records), comment="Interface descriptor : {:d}".format(intf["id"])) + super().__init__(name, "struct _USB_InterfaceDesc", StructGenerator.RecordFactory.createa(records), + comment="Interface descriptor : {:d}".format(intf["id"])) class EndpointDescriptor(Descriptor): @@ -173,7 +184,8 @@ class EndpointDescriptor(Descriptor): ["bInterval", "u8", ep["service_interval"]] ] - super().__init__(name, "struct _USB_EndpointDesc", StructGenerator.RecordFactory.createa(records), comment="Endpoint descriptor : {:d} {:s}".format(ep["n"], ep["direction"])) + super().__init__(name, "struct _USB_EndpointDesc", StructGenerator.RecordFactory.createa(records), + comment="Endpoint descriptor : {:d} {:s}".format(ep["n"], ep["direction"])) # -------------------------- @@ -181,49 +193,78 @@ class EndpointDescriptor(Descriptor): # -------------------------- class HeaderFunctionalDescriptor(Descriptor): - def __init__(self, name, hfd): + def __init__(self, name, hfd, str_mgr): records = [ ["bLength", "u8", 0x05], ["bDescriptorType", "u8", 0x24], ["bDescriptorSubType", "u8", 0x00], ["bcdCDC", "u16", 0x0110]] - super().__init__(name, "struct _USB_HeaderFunctionalDescriptor", StructGenerator.RecordFactory.createa(records), comment="Header Functional descriptor") + super().__init__(name, "struct _USB_HeaderFunctionalDescriptor", StructGenerator.RecordFactory.createa(records), + comment="Header Functional descriptor") class AbstractControlManagementFunctionalDescriptor(Descriptor): - def __init__(self, name, acmfd): + def __init__(self, name, acmfd, str_mgr): records = [ ["bLength", "u8", 0x04], ["bDescriptorType", "u8", 0x24], ["bDescriptorSubType", "u8", 0x02], ["bmCapabilities", "u8", 0x02]] # TODO: no capabilities - super().__init__(name, "struct _USB_AbstractControlManagementFunctionalDescriptor", StructGenerator.RecordFactory.createa(records), comment="Abstract Control Management Functional descriptor") + super().__init__(name, "struct _USB_AbstractControlManagementFunctionalDescriptor", + StructGenerator.RecordFactory.createa(records), + comment="Abstract Control Management Functional descriptor") class UnionFunctionalDescriptor(Descriptor): - def __init__(self, name, ufd): + def __init__(self, name, ufd, str_mgr): records = [ ["bLength", "u8", 0x05], ["bDescriptorType", "u8", 0x24], ["bDescriptorSubType", "u8", 0x06], - ["bMasterInterface", "u8", 0x00], # TODO: control interface - ["bSlaveInterface0", "u8", 0x01]] # TODO: data interface + ["bMasterInterface", "u8", ufd["master_interface"]], # TODO: control interface + ["bSlaveInterface0", "u8", ufd["slave_interface"]]] # TODO: data interface - super().__init__(name, "struct _USB_UnionFunctionalDescriptor", StructGenerator.RecordFactory.createa(records), comment="Abstract Control Management Functional descriptor") + super().__init__(name, "struct _USB_UnionFunctionalDescriptor", StructGenerator.RecordFactory.createa(records), + comment="Union Functional descriptor") class CallManagementFunctionalDescriptor(Descriptor): - def __init__(self, name, ufd): + def __init__(self, name, cmfd, str_mgr): records = [ ["bLength", "u8", 0x05], ["bDescriptorType", "u8", 0x24], ["bDescriptorSubType", "u8", 0x01], ["bmCapabilities", "u8", 0x00], - ["dDataInterface", "u8", ufd["data_interface"]]] + ["dDataInterface", "u8", cmfd["data_interface"]]] - super().__init__(name, "struct _USB_CallManagementFunctionalDescriptor", StructGenerator.RecordFactory.createa(records), comment="Call Management Functional descriptor") + super().__init__(name, "struct _USB_CallManagementFunctionalDescriptor", + StructGenerator.RecordFactory.createa(records), + comment="Call Management Functional descriptor") + + +class EthernetNetworkingFunctionalDescriptor(Descriptor): + def __init__(self, name, enfd, str_mgr: ConfigGenerator.StringManager): + + # add MAC address to the string manager + str_mgr.add_string("mac_address", enfd["mac_address"]) + + # populate fields + records = [ + ["bLength", "u8", 0x0D], + ["bDescriptorType", "u8", 0x24], + ["bDescriptorSubType", "u8", 0x0F], + ["iMACAddress", "u8", str_mgr.get_numeric_id("mac_address")], # MAC address is stored as a string + ["bmEthernetStatistics", "u32", 0x00], # no collection of statistics + ["wMaxSegmentSize", "u16", enfd["max_segment_size"]], + ["wNumberMCFilters", "u16", 0x00], # we don't support multicast filters + ["bNumberPowerFilters", "u8", 0x00], # no pattern for waking up the host + ] + + super().__init__(name, "struct _USB_EthernetNetworkingFunctionalDescriptor", + StructGenerator.RecordFactory.createa(records), + comment="Ethernet Networking Functional descriptor") class DescriptorFactory: @@ -231,10 +272,10 @@ class DescriptorFactory: "hfd": HeaderFunctionalDescriptor, "acmfd": AbstractControlManagementFunctionalDescriptor, "ufd": UnionFunctionalDescriptor, - "cmfd": CallManagementFunctionalDescriptor + "cmfd": CallManagementFunctionalDescriptor, + "enfd": EthernetNetworkingFunctionalDescriptor } @staticmethod - def generate(name, varname, data): - return DescriptorFactory.REGISTRY[name](varname, data) - + def generate(name, varname, data, str_mgr): + return DescriptorFactory.REGISTRY[name](varname, data, str_mgr)