1# Copyright (c) 2010, Tomohiro Kusumi 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are met: 6# 7# 1. Redistributions of source code must retain the above copyright notice, this 8# list of conditions and the following disclaimer. 9# 2. Redistributions in binary form must reproduce the above copyright notice, 10# this list of conditions and the following disclaimer in the documentation 11# and/or other materials provided with the distribution. 12# 13# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24from .. import extension 25from .. import filebytes 26from .. import util 27 28byte_to_int = util.byte_to_int 29le_to_int = util.le_to_int 30 31USB_DT_DEVICE = 0x01 32USB_DT_CONFIG = 0x02 33USB_DT_STRING = 0x03 34USB_DT_INTERFACE = 0x04 35USB_DT_ENDPOINT = 0x05 36 37TYPE_CLASS = (0x01 << 5) 38HID_DT_HID = (TYPE_CLASS | 0x01) 39HID_DT_REPORT = (TYPE_CLASS | 0x02) 40HID_DT_PHYSICAL = (TYPE_CLASS | 0x03) 41 42def get_text(co, fo, args): 43 b = fo.read(args[-1], util.KiB) 44 if not b: 45 extension.fail("Empty buffer") 46 desc = [] 47 while b: 48 if len(b) <= 2: 49 extension.fail("Invalid descriptor: " + btoh(b)) 50 bLength = filebytes.ord(b[0:1]) 51 bDescriptorType = filebytes.ord(b[1:2]) 52 if bLength <= 0: 53 extension.fail("Invalid bLength: {0}".format(bLength)) 54 d = b[:bLength] 55 if len(d) != bLength or len(d) <= 2: 56 extension.fail("Invalid bLength: {0}".format(bLength)) 57 desc.append(d) 58 b = b[bLength:] 59 l = [] 60 for b in desc: 61 bLength = filebytes.ord(b[0:1]) 62 bDescriptorType = filebytes.ord(b[1:2]) 63 if bDescriptorType == USB_DT_DEVICE: 64 l.extend(__get_device_descriptor(b)) 65 elif bDescriptorType == USB_DT_CONFIG: 66 l.extend(__get_config_descriptor(b)) 67 elif bDescriptorType == USB_DT_STRING: 68 l.extend(__get_string_descriptor(b)) 69 elif bDescriptorType == USB_DT_INTERFACE: 70 l.extend(__get_interface_descriptor(b)) 71 elif bDescriptorType == USB_DT_ENDPOINT: 72 l.extend(__get_endpoint_descriptor(b)) 73 elif bDescriptorType == HID_DT_HID: 74 l.extend(__get_hid_descriptor(b)) 75 else: 76 l.extend(__get_unknown_descriptor(b)) 77 l.append('') 78 return l 79 80def btoh(b): 81 return ''.join(["\\x{0:02X}".format(x) for x in filebytes.iter_ords(b)]) 82 83def __get_device_descriptor(b): 84 assert len(b) == 18, "Invalid device descriptor: " + btoh(b) 85 l = [] 86 l.append("device descriptor " + util.get_size_repr(len(b))) 87 l.append(" bLength = {0}".format(byte_to_int(b[0:1]))) 88 l.append(" bDescriptorType = {0}".format(byte_to_int(b[1:2]))) 89 l.append(" bcdUSB = 0x{0:04X}".format(le_to_int(b[2:4]))) 90 l.append(" bDeviceClass = {0}".format(byte_to_int(b[4:5]))) 91 l.append(" bDeviceSubClass = {0}".format(byte_to_int(b[5:6]))) 92 l.append(" bDeviceProtocol = {0}".format(byte_to_int(b[6:7]))) 93 l.append(" bMaxPacketSize0 = {0}".format(byte_to_int(b[7:8]))) 94 l.append(" idVendor = 0x{0:04X}".format(le_to_int(b[8:10]))) 95 l.append(" idProduct = 0x{0:04X}".format(le_to_int(b[10:12]))) 96 l.append(" bcdDevice = 0x{0:04X}".format(le_to_int(b[12:14]))) 97 l.append(" iManufacturer = {0}".format(byte_to_int(b[14:15]))) 98 l.append(" iProduct = {0}".format(byte_to_int(b[15:16]))) 99 l.append(" iSerialNumber = {0}".format(byte_to_int(b[16:17]))) 100 l.append(" bNumConfigurations = {0}".format(byte_to_int(b[17:18]))) 101 return l 102 103def __get_config_descriptor(b): 104 assert len(b) == 9, "Invalid config descriptor: " + btoh(b) 105 l = [] 106 l.append("config descriptor " + util.get_size_repr(len(b))) 107 l.append(" bLength = {0}".format(byte_to_int(b[0:1]))) 108 l.append(" bDescriptorType = {0}".format(byte_to_int(b[1:2]))) 109 l.append(" wTotalLength = {0}".format(le_to_int(b[2:4]))) 110 l.append(" bNumInterfaces = {0}".format(byte_to_int(b[4:5]))) 111 l.append(" bConfigurationValue = {0}".format(byte_to_int(b[5:6]))) 112 l.append(" iConfiguration = {0}".format(byte_to_int(b[6:7]))) 113 l.append(" bmAttributes = 0x{0:02X}".format(byte_to_int(b[7:8]))) 114 l.append(" bMaxPower = {0}".format(byte_to_int(b[8:9]))) 115 return l 116 117def __get_string_descriptor(b): 118 assert len(b) > 2, "Invalid string descriptor: " + btoh(b) 119 l = [] 120 l.append("string descriptor " + util.get_size_repr(len(b))) 121 l.append(" bLength = {0}".format(byte_to_int(b[0:1]))) 122 l.append(" bDescriptorType = {0}".format(byte_to_int(b[1:2]))) 123 return l 124 125def __get_interface_descriptor(b): 126 assert len(b) == 9, "Invalid interface descriptor: " + btoh(b) 127 l = [] 128 l.append("interface descriptor " + util.get_size_repr(len(b))) 129 l.append(" bLength = {0}".format(byte_to_int(b[0:1]))) 130 l.append(" bDescriptorType = {0}".format(byte_to_int(b[1:2]))) 131 l.append(" bInterfaceNumber = {0}".format(byte_to_int(b[2:3]))) 132 l.append(" bAlternateSetting = {0}".format(byte_to_int(b[3:4]))) 133 l.append(" bNumEndpoints = {0}".format(byte_to_int(b[4:5]))) 134 l.append(" bInterfaceClass = {0}".format(byte_to_int(b[5:6]))) 135 l.append(" bInterfaceSubClass = {0}".format(byte_to_int(b[6:7]))) 136 l.append(" bInterfaceProtocol = {0}".format(byte_to_int(b[7:8]))) 137 l.append(" iInterface = {0}".format(byte_to_int(b[8:9]))) 138 return l 139 140def __get_endpoint_descriptor(b): 141 assert len(b) == 7, "Invalid endpoint descriptor: " + btoh(b) 142 l = [] 143 l.append("endpoint descriptor " + util.get_size_repr(len(b))) 144 l.append(" bLength = {0}".format(byte_to_int(b[0:1]))) 145 l.append(" bDescriptorType = {0}".format(byte_to_int(b[1:2]))) 146 l.append(" bEndpointAddress = 0x{0:02X}".format(byte_to_int(b[2:3]))) 147 l.append(" bmAttributes = 0x{0:02X}".format(byte_to_int(b[3:4]))) 148 l.append(" wMaxPacketSize = 0x{0:04X}".format(le_to_int(b[4:6]))) 149 l.append(" bInterval = {0}".format(byte_to_int(b[6:7]))) 150 return l 151 152def __get_hid_descriptor(b): 153 assert len(b) > 2, "Invalid hid descriptor: " + btoh(b) 154 l = [] 155 l.append("hid descriptor " + util.get_size_repr(len(b))) 156 l.append(" bLength = {0}".format(byte_to_int(b[0:1]))) 157 l.append(" bDescriptorType = {0}".format(byte_to_int(b[1:2]))) 158 return l 159 160def __get_unknown_descriptor(b): 161 assert len(b) > 2, "Invalid descriptor: " + btoh(b) 162 l = [] 163 l.append("unknown descriptor " + util.get_size_repr(len(b))) 164 l.append(" bLength = {0}".format(byte_to_int(b[0:1]))) 165 l.append(" bDescriptorType = {0}".format(byte_to_int(b[1:2]))) 166 return l 167