def verbose(self, handle=None): hashString = str(hex(hash(str(self.r)))) s = "\nHASH: [%s]" % hashString[int(len(hashString) / 2):] s +=\ """ RAW: %s bmRequestType (Byte 0): |--DIRECTION: %s (%s) (bit 7) |--TYPE: %s (%s) (bit 6, 5) `--RECIPIENT: %s (%s) (bit 4, 3, 2, 1, 0) bRequest (Byte 1): `--REQUEST NUMBER: 0x%02x <<%s>> wValue (Byte 3, 2) `--%s wIndex (Byte 5, 4) `--%s wLength (Byte 7, 6) `--LENGTH: 0x%04x (%s) """ % (bytes_as_hex(self.r), bin(self.get_direction()), "to device" if self.get_direction() == 0 else "to host", # direction bin(self.get_type()), "standard" if self.get_type() == 0 else "class" if self.get_type() == 1 else "vendor specific" if self.get_type() == 2 else "unknown!", bin(self.get_recipient()), "device" if self.get_recipient() == 0 else "interface" if self.get_recipient() == 1 else "endpoint" if self.get_recipient() == 2 else "other element" if self.get_recipient == 3 else "unknown!", self.request, self.request_lookup[self.request], self.value_string(), self.endpoint_string() if self.get_recipient() == 2 else self.interface_string() if self.get_recipient() == 1 else "DATA: 0x%02x" % self.index, self.length, "not a data stage" if self.length == 0 else "exact number of bytes host wants to transfer" if self.get_direction() == 0 else "maximum bytes device may send") return s
def verbose(self, handle=None): hashString = str(hex(hash(str(self.r)))) s = "\nHASH: [%s]" % hashString[int(len(hashString)/2):] s +=\ """ RAW: %s bmRequestType (Byte 0): |--DIRECTION: %s (%s) (bit 7) |--TYPE: %s (%s) (bit 6, 5) `--RECIPIENT: %s (%s) (bit 4, 3, 2, 1, 0) bRequest (Byte 1): `--REQUEST NUMBER: 0x%02x <<%s>> wValue (Byte 3, 2) `--%s wIndex (Byte 5, 4) `--%s wLength (Byte 7, 6) `--LENGTH: 0x%04x (%s) """ % (bytes_as_hex(self.r), bin(self.get_direction()), "to device" if self.get_direction() == 0 else "to host", # direction bin(self.get_type()), "standard" if self.get_type() == 0 else "class" if self.get_type() == 1 else "vendor specific" if self.get_type() == 2 else "unknown!", bin(self.get_recipient()), "device" if self.get_recipient() == 0 else "interface" if self.get_recipient() == 1 else "endpoint" if self.get_recipient() == 2 else "other element" if self.get_recipient == 3 else "unknown!", self.request, self.request_lookup[self.request], self.value_string(), self.endpoint_string() if self.get_recipient() == 2 else self.interface_string() if self.get_recipient() == 1 else "DATA: 0x%02x" % self.index, self.length, "not a data stage" if self.length == 0 else "exact number of bytes host wants to transfer" if self.get_direction() == 0 else "maximum bytes device may send") return s
def device_qualifier(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (Device Qualifer) bcdUSB: 0x%04x (USB specification release number, BCD. NOTE: Must be at least 0x0200) bDeviceClass: 0x%02x (Class code) `--%s bDeviceSubclass: 0x%02x (Subclass code) bDeviceProtocol: 0x%02x (Protocol code) bMaxPacketSize0: 0x%02x (Maximum packet size for endpoint 0) bNumConfigurations: 0x%02x (Number of possible configurations) Reserved: 0x%02x (For future use) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], (self.d[3] << 8| self.d[2]), self.d[4], self.device_class(self.d[5]), self.d[5], self.d[6], self.d[7], self.d[8], self.d[9]) self.d = bytearray(self.d[10:]) return s
def interface(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (Interface) bInterfaceNumber: 0x%02x (Number identifying this interface) bAlternateSetting: 0x%02x (Value used to select an alternate setting) bNumEndpoints: 0x%02x (Number of endpoints supported, not counting EP0) bInterfaceClass: 0x%02x (Class code. 0x01 to 0xfe are reserved for USB-defined classes. 0xff is vender specific. 0x00 is reserved) `--%s bInterfaceSubclass: 0x%02x (Subclass code. Diagnostic-device, wireless-controller, and application specific class have defined subclasses) bInterfaceProtocol: 0x%02x (Protocol code. If between 0x01 and 0xfe, must be zero or a code defined by USB spec) iInterface: 0x%02x (Index of string descriptor for the interface) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], self.d[2], self.d[3], self.d[4], self.d[5], self.device_class(self.d[5]), # interface_class and device class are same self.d[6], self.d[7], self.d[8]) self.d = bytearray(self.d[9:]) return s
def endpoint(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (Endpoint) bEndpointAddress: 0x%02x (Endpoint number and direction. NOTE: bits 4, 5, 6 are unused and must be 0) |--%s `--%s bmAttributtes: 0x%02x (Transfer type supported. NOTE: for all endpoints, bits 6 and 7 must be 9) |--%s (Bits 1, 0. Control assumed for EP0) |--%s (Bits 3, 2. In USB 1.1 bits 2 to 7 were reserved. USB 2.0 uses bits 2 to 5 for full and high speed isochronous endpoints) `--%s (Bits 5, 4.) wMaxPacketSize: 0x%04x (Maximum packet size supported. NOTE: bits 13 to 15 are reserved and must be 0) `--%s (Bits 12, 11. USB 2.0 only - number of additional transactions per microframe a high-speed endpoint supports) bInterval: 0x%02x (Maximum latency/polling interval/NAK rate) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], self.d[2], self.endpoint_number(self.d[2]), self.endpoint_direction(self.d[2]), self.d[3], self.endpoint_transfer_support(self.d[3]), self.endpoint_sync_type(self.d[3]), self.endpoint_usage_type(self.d[3]), (self.d[5] << 8| self.d[4]), #endpoint_packet_size(self.d[4]), self.endpoint_packet_additional(self.d[5]), self.d[6]) self.d = bytearray(self.d[7:]) return s
def other_speed_configuration(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (Other Speed Configuration) wTotalLength: 0x%04x (Number of bytes in the configuration descriptor and all of its subordinate descriptors) bNumInterfaces: 0x%02x (Number of interfaces in the configuration. NOTE: Must be at least 1) bConfigurationValue: 0x%02x (Identifier for set_configruation and get_configuration requests. NOTE: must be 1 or higher. A set_configuration request with a value of 0 causes the device to enter "Not Configured" state) iConfiguration: 0x%02x (Index of string descriptor for the configuration. 0 if no string descriptor) bmAttributes: 0x%02x (Self/bus power and remote wakeup settings). Other bits in the field are unused. NOTE: Bits 0 to 4 must be 0. Bit 7 must be 1. In USB 1.1, setting bit 6 to 0 is enough to indicate bus powered, but bit 7 required for USB 1.0) `--%s bMaxPower: 0x%02x (Bus power required, expressed as (maximum milliamperes/2) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], (self.d[3] << 8| self.d[2]), self.d[4], self.d[5], self.d[6], self.config_attributes(self.d[6]), self.d[7]) self.d = bytearray(self.d[8:]) return s
def hid(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (HID) bcdHID: 0x%04x (HID specification release number, BCD) bCountryCode: 0x%02x (Numeric expression identifying the country for localized hardware, BCD) bNumDescriptors: 0x%02x (Number of subordinate report and physical descriptors) bDescriptorType: 0x%02x (The type of a class-specific descriptor that follows. A report descriptor (required) is 0x22) wDescriptorLength: 0x%04x (Total length of the descriptor identified above) bDescriptorType: 0x%02x (Optional. The type of a class-specific descriptor that follows. A physical descriptor is type 0x23) wDescriptorLength: 0X%04X (Total length of the descriptor identified above. Present only if bDescriptorType is present immediately above. NOTE: May be followed by additional wDescriptorType and DescriptorLength fields) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], (self.d[3] << 8| self.d[2]), self.d[4], self.d[5], self.d[6], (self.d[8] << 8| self.d[7]), self.d[9], (self.d[11]| self.d[10])) length = self.d[0] self.d = bytearray(self.d[length:]) # trim it return s
def __str__(self): s = "dir=0x%02x, type=0x%02x, rec=0x%02x, r=0x%02x, v=0x%02x, i=0x%02x, l=0x%02x" \ % (self.get_direction(), self.get_type(), self.get_recipient(), self.request, self.value, self.index, self.length) hashString = str(hex(hash(str(self.raw_bytes)))) s =\ """ HASH: %s RAW: %s bmRequestType (Byte 0): |--DIRECTION: %s (%s) (bit 7) |--TYPE: %s (%s) (bit 6, 5) |--RECIPIENT: %s (%s) (bit 4, 3, 2, 1, 0) bRequest (Byte 1): |--REQUEST NUMBER: 0x%02x <<%s>> wValue (Byte 3, 2) |--%s wIndex (Byte 5, 4) |--%s wLength (Byte 7, 6) |--LENGTH: 0x%04x (%s) """ % (hashString[int(len(hashString)/2):], bytes_as_hex(self.raw_bytes), # raw bin(self.get_direction()), "to device" if self.get_direction() == 0 else "to host", # direction bin(self.get_type()), "standard" if self.get_type() == 0 else "class" if self.get_type() == 1 else "vendor specific" if self.get_type() == 2 else "unknown!", bin(self.get_recipient()), "device" if self.get_recipient() == 0 else "interface" if self.get_recipient() == 1 else "endpoint" if self.get_recipient() == 2 else "other element" if self.get_recipient == 3 else "unknown!", self.request, request_lookup[self.request], self.value_string(), self.endpoint_string() if self.get_recipient() == 2 else self.interface_string() if self.get_recipient() == 1 else "DATA: 0x%02x" % self.index, self.length, "not a data stage" if self.length == 0 else "exact number of bytes host wants to transfer" if self.get_direction() == 0 else "maximum bytes device may send") return s
def report_descriptor(self): s =\ """ RAW: %s 0x%02x 0x%02x Usage page (generic desktop) 0x%02x 0x%02x Usage (keyboard) 0x%02x 0x%02x Collection (Application) 0x%02x 0x%02x Usage Page 7 (keyboard/keypad) 0x%02x 0x%02x Usage min = 224 0x%02x 0x%02x Usage max = 231 0x%02x 0x%02x Logical min = 0 0x%02x 0x%02x Logical max = 1 0x%02x 0x%02x Report size = 1 0x%02x 0x%02x Report count = 8 0x%02x 0x%02x Input (Data, Variable, Absolute) 0x%02x 0x%02x Report Count = 1 0x%02x 0x%02x Report size = 8 0x%02x 0x%02x Input (Constant) 0x%02x 0x%02x Usage min = 0 0x%02x 0x%02x Usage max = 101 0x%02x 0x%02x Logical min = 0 0x%02x 0x%02x Logical max = 101 0x%02x 0x%02x Report size = 8 0x%02x 0x%02x Report Count = 1 0x%02x 0x%02x Input (Data, Variable, Array) 0x%02x End Collection """ % (bytes_as_hex(self.d), self.d[0], self.d[1], self.d[2], self.d[3], self.d[4], self.d[5], self.d[6], self.d[7], self.d[8], self.d[9], self.d[10], self.d[11], self.d[12], self.d[13], self.d[14], self.d[15], self.d[16], self.d[17], self.d[18], self.d[19], self.d[20], self.d[21], self.d[22], self.d[23], self.d[24], self.d[25], self.d[26], self.d[27], self.d[28], self.d[29], self.d[30], self.d[31], self.d[32], self.d[33], self.d[34], self.d[35], self.d[36], self.d[37], self.d[38], self.d[39], self.d[40], self.d[41], self.d[42]) length = self.d[0] self.d = bytearray(self.d[length:]) # trim it if len(self.d) > 0: print("There's still some left...") return s
def string(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (String) bString or wLangID: %s (Depends on string index requested. wLangID for English is 0x0009, subcode for US is 0x0004) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], (''.join(map(chr, self.d[2::2])))) length = self.d[0] self.d = bytearray(self.d[length:]) # trim it return s
def device(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (Device) bcdUSB: 0x%04x (USB specification release number, BCD) bDeviceClass: 0x%02x (Class code. 0x01 to 0xfe are USB defined classes. 0x00 if class specified in interface descriptor. 0xff is vendor specific) `--%s bDeviceSubclass: 0x%02x (Subclass code) bDeviceProtocol: 0x%02x (Protocol code) bMaxPacketSize0: 0x%02x (Maximum packet size for endpoint 0) idVendor: 0x%04x (Vendor ID) idProduct: 0x%04x (Product ID) bcdDevice: 0x%04x (Device release number, BCD) iManufacturer: 0x%02x (Index of string descriptor for the manufacturer) iProduct: 0x%02x (Index of string for the product) iSerialNumber: 0x%02x (Index of string descriptor containing the serial number) bNumConfigurations: 0x%02x (Number of possible configurations) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], (self.d[3] << 8| self.d[2]), self.d[4], self.device_class(self.d[5]), self.d[5], self.d[6], self.d[7], (self.d[9] << 8| self.d[8]), (self.d[11] << 8| self.d[10]), (self.d[13] << 8| self.d[12]), self.d[14], self.d[15], self.d[16], self.d[17]) self.d = bytearray(self.d[18:]) return s
def interface_association(self): s =\ """ RAW: %s bLength: 0x%02x bDescriptorType: 0x%02x (Interface Association) bFirstInterface 0x%02x (Number identifying the first interface associated with the function) bInterfaceCount 0x%02x (Number of contiguous interfaces associated with the function) bFunctionClass 0x%02 (Class code) bFunctionSubClass 0x%02 (Sublcass code) bFunctionProtocol 0x%02 (Protocol code) iFunction 0x%02 (Index string descriptor for the function. 0 if no string descriptor) """ % (bytes_as_hex(self.d), self.d[0], self.d[1], (self.d[3] << 8| self.d[2]), self.d[4], self.d[5], self.d[6], self.d[7]) self.d = bytearray(self.d[8:]) return s