- EthernetNetworkFunctionalDescriptor added
- automatic String Descriptor generation added
This commit is contained in:
		
							parent
							
								
									53226e79cb
								
							
						
					
					
						commit
						5b8f76161d
					
				@ -68,13 +68,13 @@ class ConfigGenerator:
 | 
				
			|||||||
        # string management
 | 
					        # string management
 | 
				
			||||||
        self.str_mgr = StringManager()
 | 
					        self.str_mgr = StringManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        string_fields = [
 | 
					        # string_fields = [
 | 
				
			||||||
            "vendor_string",
 | 
					        #     "vendor_string",
 | 
				
			||||||
            "product_string",
 | 
					        #     "product_string",
 | 
				
			||||||
            "serial_number"
 | 
					        #     "serial_number"
 | 
				
			||||||
        ]
 | 
					        # ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.str_mgr.add_placeholders(string_fields)
 | 
					        #self.str_mgr.add_placeholders(string_fields)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.LANG_ID_US_EN = "0x0409"
 | 
					        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"]:
 | 
					        for intf in conf["interfaces"]:
 | 
				
			||||||
            # generate interface descriptor
 | 
					            # generate interface descriptor
 | 
				
			||||||
            intf_varname = "intf{:d}".format(intf["id"])
 | 
					            intf_varname = "intf{:d}".format(intf["id"])
 | 
				
			||||||
@ -153,13 +156,15 @@ class ConfigGenerator:
 | 
				
			|||||||
            full_conf_struct.add_record(intf_struct)
 | 
					            full_conf_struct.add_record(intf_struct)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # generate additional interface descriptors
 | 
					            # generate additional interface descriptors
 | 
				
			||||||
#            if [intf.keys()].count("additional_interfaces") > 0:
 | 
					 | 
				
			||||||
            for addintf in intf["additional_interfaces"]:
 | 
					            for addintf in intf["additional_interfaces"]:
 | 
				
			||||||
                type = addintf["type"]
 | 
					                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)
 | 
					                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
 | 
					            # generate endpoint descriptors
 | 
				
			||||||
            self.generate_endpoint_descriptors(intf, full_conf_struct)  # generate endpoints
 | 
					            self.generate_endpoint_descriptors(intf, full_conf_struct)  # generate endpoints
 | 
				
			||||||
@ -212,8 +217,10 @@ class ConfigGenerator:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # generate individual string descriptors
 | 
					        # generate individual string descriptors
 | 
				
			||||||
        for text_id in self.str_mgr.get_text_ids():
 | 
					        for text_id in self.str_mgr.get_text_ids():
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            # self.str_mgr.change_text(text_id, self.config[text_id])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # create descriptor
 | 
					            # 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)
 | 
					            str_struct = desc.StringDescriptor(self.str_mgr.get_text(text_id), text_id)
 | 
				
			||||||
            self.c += str_struct.gen_c()
 | 
					            self.c += str_struct.gen_c()
 | 
				
			||||||
            self.h += str_struct.gen_h(print_typedef=True)
 | 
					            self.h += str_struct.gen_h(print_typedef=True)
 | 
				
			||||||
@ -235,10 +242,10 @@ class ConfigGenerator:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def generate(self):
 | 
					    def generate(self):
 | 
				
			||||||
        self.generate_macros()  # generate macro definitions
 | 
					        self.generate_macros()  # generate macro definitions
 | 
				
			||||||
        self.generate_string_descriptors()  # generate string descriptors
 | 
					 | 
				
			||||||
        self.generate_device_descriptor()  # generate device descriptor
 | 
					        self.generate_device_descriptor()  # generate device descriptor
 | 
				
			||||||
        self.generate_device_qualifier_descriptor()  # generate device qualifier descriptor
 | 
					        self.generate_device_qualifier_descriptor()  # generate device qualifier descriptor
 | 
				
			||||||
        self.generate_configuration_descriptors()  # generate configuration descriptors
 | 
					        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
 | 
					        # save generated files
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
import math
 | 
					import math
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ConfigGenerator
 | 
				
			||||||
import StructGenerator
 | 
					import StructGenerator
 | 
				
			||||||
from enum import Enum
 | 
					from enum import Enum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -47,7 +48,12 @@ class Descriptor(StructGenerator.StructRecord):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# -----------------------------
 | 
					# -----------------------------
 | 
				
			||||||
class DeviceDescriptor(Descriptor):
 | 
					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
 | 
					        # generate device descriptor
 | 
				
			||||||
        numOfConfs = len(dev["configurations"])  # get number of configurations
 | 
					        numOfConfs = len(dev["configurations"])  # get number of configurations
 | 
				
			||||||
        records = [
 | 
					        records = [
 | 
				
			||||||
@ -66,7 +72,8 @@ class DeviceDescriptor(Descriptor):
 | 
				
			|||||||
            ["iSerialNumber", "u8", str_mgr.get_numeric_id("serial_number")],
 | 
					            ["iSerialNumber", "u8", str_mgr.get_numeric_id("serial_number")],
 | 
				
			||||||
            ["bNumConfigurations", "u8", numOfConfs]]
 | 
					            ["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):
 | 
					class DeviceQualifierDescriptor(Descriptor):
 | 
				
			||||||
@ -83,7 +90,8 @@ class DeviceQualifierDescriptor(Descriptor):
 | 
				
			|||||||
            ["bMaxPacketSize", "u8", dev["max_ep0_packet_size"]],
 | 
					            ["bMaxPacketSize", "u8", dev["max_ep0_packet_size"]],
 | 
				
			||||||
            ["bNumConfigurations", "u8", numOfConfs]]
 | 
					            ["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):
 | 
					class StringDescriptor(Descriptor):
 | 
				
			||||||
@ -99,7 +107,8 @@ class StringDescriptor(Descriptor):
 | 
				
			|||||||
                ["bDescriptorType", "u8", "UD_String", True],
 | 
					                ["bDescriptorType", "u8", "UD_String", True],
 | 
				
			||||||
                ["bString", "u16", text_langid]]
 | 
					                ["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):
 | 
					class ConfigurationDescriptor(Descriptor):
 | 
				
			||||||
@ -122,7 +131,8 @@ class ConfigurationDescriptor(Descriptor):
 | 
				
			|||||||
            ["bmAttributes", "u8", attributes, True],
 | 
					            ["bmAttributes", "u8", attributes, True],
 | 
				
			||||||
            ["bMaxPower", "u8", math.ceil(conf["max_power_mA"] / 2)]]
 | 
					            ["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):
 | 
					class InterfaceDescriptor(Descriptor):
 | 
				
			||||||
@ -139,7 +149,8 @@ class InterfaceDescriptor(Descriptor):
 | 
				
			|||||||
            ["bInterfaceProtocol", "u8", intf["protocol_code"]],
 | 
					            ["bInterfaceProtocol", "u8", intf["protocol_code"]],
 | 
				
			||||||
            ["iInterface", "u8", 0]]
 | 
					            ["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):
 | 
					class EndpointDescriptor(Descriptor):
 | 
				
			||||||
@ -173,7 +184,8 @@ class EndpointDescriptor(Descriptor):
 | 
				
			|||||||
            ["bInterval", "u8", ep["service_interval"]]
 | 
					            ["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):
 | 
					class HeaderFunctionalDescriptor(Descriptor):
 | 
				
			||||||
    def __init__(self, name, hfd):
 | 
					    def __init__(self, name, hfd, str_mgr):
 | 
				
			||||||
        records = [
 | 
					        records = [
 | 
				
			||||||
            ["bLength", "u8", 0x05],
 | 
					            ["bLength", "u8", 0x05],
 | 
				
			||||||
            ["bDescriptorType", "u8", 0x24],
 | 
					            ["bDescriptorType", "u8", 0x24],
 | 
				
			||||||
            ["bDescriptorSubType", "u8", 0x00],
 | 
					            ["bDescriptorSubType", "u8", 0x00],
 | 
				
			||||||
            ["bcdCDC", "u16", 0x0110]]
 | 
					            ["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):
 | 
					class AbstractControlManagementFunctionalDescriptor(Descriptor):
 | 
				
			||||||
    def __init__(self, name, acmfd):
 | 
					    def __init__(self, name, acmfd, str_mgr):
 | 
				
			||||||
        records = [
 | 
					        records = [
 | 
				
			||||||
            ["bLength", "u8", 0x04],
 | 
					            ["bLength", "u8", 0x04],
 | 
				
			||||||
            ["bDescriptorType", "u8", 0x24],
 | 
					            ["bDescriptorType", "u8", 0x24],
 | 
				
			||||||
            ["bDescriptorSubType", "u8", 0x02],
 | 
					            ["bDescriptorSubType", "u8", 0x02],
 | 
				
			||||||
            ["bmCapabilities", "u8", 0x02]]  # TODO: no capabilities
 | 
					            ["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):
 | 
					class UnionFunctionalDescriptor(Descriptor):
 | 
				
			||||||
    def __init__(self, name, ufd):
 | 
					    def __init__(self, name, ufd, str_mgr):
 | 
				
			||||||
        records = [
 | 
					        records = [
 | 
				
			||||||
            ["bLength", "u8", 0x05],
 | 
					            ["bLength", "u8", 0x05],
 | 
				
			||||||
            ["bDescriptorType", "u8", 0x24],
 | 
					            ["bDescriptorType", "u8", 0x24],
 | 
				
			||||||
            ["bDescriptorSubType", "u8", 0x06],
 | 
					            ["bDescriptorSubType", "u8", 0x06],
 | 
				
			||||||
            ["bMasterInterface", "u8", 0x00],  # TODO: control interface
 | 
					            ["bMasterInterface", "u8", ufd["master_interface"]],  # TODO: control interface
 | 
				
			||||||
            ["bSlaveInterface0", "u8", 0x01]]  # TODO: data 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):
 | 
					class CallManagementFunctionalDescriptor(Descriptor):
 | 
				
			||||||
    def __init__(self, name, ufd):
 | 
					    def __init__(self, name, cmfd, str_mgr):
 | 
				
			||||||
        records = [
 | 
					        records = [
 | 
				
			||||||
            ["bLength", "u8", 0x05],
 | 
					            ["bLength", "u8", 0x05],
 | 
				
			||||||
            ["bDescriptorType", "u8", 0x24],
 | 
					            ["bDescriptorType", "u8", 0x24],
 | 
				
			||||||
            ["bDescriptorSubType", "u8", 0x01],
 | 
					            ["bDescriptorSubType", "u8", 0x01],
 | 
				
			||||||
            ["bmCapabilities", "u8", 0x00],
 | 
					            ["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:
 | 
					class DescriptorFactory:
 | 
				
			||||||
@ -231,10 +272,10 @@ class DescriptorFactory:
 | 
				
			|||||||
        "hfd": HeaderFunctionalDescriptor,
 | 
					        "hfd": HeaderFunctionalDescriptor,
 | 
				
			||||||
        "acmfd": AbstractControlManagementFunctionalDescriptor,
 | 
					        "acmfd": AbstractControlManagementFunctionalDescriptor,
 | 
				
			||||||
        "ufd": UnionFunctionalDescriptor,
 | 
					        "ufd": UnionFunctionalDescriptor,
 | 
				
			||||||
        "cmfd": CallManagementFunctionalDescriptor
 | 
					        "cmfd": CallManagementFunctionalDescriptor,
 | 
				
			||||||
 | 
					        "enfd": EthernetNetworkingFunctionalDescriptor
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def generate(name, varname, data):
 | 
					    def generate(name, varname, data, str_mgr):
 | 
				
			||||||
        return DescriptorFactory.REGISTRY[name](varname, data)
 | 
					        return DescriptorFactory.REGISTRY[name](varname, data, str_mgr)
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user