Module usb_ids
[hide private]
[frames] | no frames]

Source Code for Module usb_ids

  1  #!/usr/bin/env python 
  2  ### BITPIM 
  3  ### 
  4  ### Copyright (C) 2003 Steve Palm <n9yty@n9yty.com> 
  5  ### 
  6  ### This program is free software; you can redistribute it and/or modify 
  7  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  8  ### 
  9  ### $Id: usb_ids.py 2867 2006-03-05 01:03:55Z djpham $ 
 10   
 11  """Parse the usb.ids file for quick access to the information contained therein""" 
 12   
 13  import re 
 14   
 15  vendor_re = re.compile(r"^([0-9A-Fa-f]{4,4})\s+(.*)$") 
 16  device_re = re.compile(r"^\t([0-9A-Fa-f]{4,4})\s+(.*)$") 
 17  iface_re = re.compile(r"^\t\t([0-9A-Fa-f]{2,2})\s+(.*)$") 
 18  usbclass_re = re.compile(r"^C\s([0-9A-Fa-f]{2,2})\s+(.*)$") 
 19  usbsubclass_re = re.compile(r"^\t([0-9A-Fa-f]{2,2})\s+(.*)$") 
 20  usbprotocol_re = re.compile(r"^\t\t([0-9A-Fa-f]{2,2})\s+(.*)$") 
 21   
 22  ### 
 23  ###  USB Info superclass 
 24  ### 
25 -class usbInfoObject:
26 """ Super class for all types of USB vendor/device/interface/class/sublcass/protocol 27 classes which will be descendants of this. I chose to make and use various children 28 of this class, as it's possible they may have unique information of their own some 29 time later, as well as allowing a more natural name/syntax based on object use. 30 """
31 - def __init__(self, id, description):
32 """ Set our ID code, description, and prepare to accept children """ 33 self.id = id 34 self.description = description 35 self.children = {};
36
37 - def description(self):
38 """ Return the description for this object """ 39 return self.description
40
41 - def id(self):
42 """ Return our ID code """ 43 return self.id
44
45 - def addChild(self, child):
46 """ Add a child to our list """ 47 self.children[int(child.id, 16)] = child
48
49 - def getChild(self, child):
50 """ If we have a child matching the request, return it """ 51 if child in self.children: 52 return self.children[child] 53 else: 54 return None
55
56 - def getChildren(self):
57 """ Return a list of all our children """ 58 return self.children.values()
59 60 ### 61 ### USB ID file superclass --- This is our master object 62 ###
63 -class usb_ids:
64 """ Class that represents the data in the usb.ids file 65 It reads/parses the file and creates the objects to match 66 """ 67
68 - def __init__(self, fname=None):
69 """ Initialize the class. This includes reading the supplied file 70 and creating/populating as many related objects as needed. 71 """ 72 self.vendorlist = VendorList() 73 self.usbclasslist = USBClassList() 74 self.inVendor = 0 75 self.inClass = 0 76 if fname is not None: 77 self.add_data(fname)
78
79 - def add_data(self, fname):
80 try: 81 ufile = open(fname, "rt") 82 try: 83 aline = ufile.readline() 84 while aline != "": 85 # Remove any EOL characters 86 while (aline[:-1] in ["\r", "\n"]): 87 aline = aline[:-1] 88 89 # Check for a vendor ID line 90 m = vendor_re.match(aline) 91 if (m): 92 self.inVendor = 1 93 self.inClass = 0 94 self.curr_vendor = VendorID(m.group(1), m.group(2)) 95 self.vendorlist.addVendor(m.group(1), self.curr_vendor) 96 97 if (self.inVendor): 98 # Check for a device ID line 99 m = device_re.match(aline) 100 if (m): 101 self.curr_device = DeviceID(m.group(1), m.group(2)) 102 self.curr_vendor.addDevice(self.curr_device) 103 104 # Check for a interface ID line 105 m = iface_re.match(aline) 106 if (m): 107 self.curr_device.addInterface(InterfaceID(m.group(1), m.group(2))) 108 109 # Check for a USB Class line 110 m = usbclass_re.match(aline) 111 if (m): 112 self.inClass = 1 113 self.inVendor = 0 114 self.curr_usbclass = USBClass(m.group(1), m.group(2)) 115 self.usbclasslist.addClass(m.group(1), self.curr_usbclass) 116 117 if (self.inClass): 118 # Check for a USB SubClass line 119 m = usbsubclass_re.match(aline) 120 if (m): 121 self.curr_usbsubclass = USBClassSubclass(m.group(1), m.group(2)) 122 self.curr_usbclass.addSubclass(self.curr_usbsubclass) 123 124 # Check for a USB Protocol line 125 m = usbprotocol_re.match(aline) 126 if (m): 127 self.curr_usbsubclass.addProtocol(USBClassProtocol(m.group(1), m.group(2))) 128 129 # Get next line (if it exists) 130 aline = ufile.readline() 131 except IOError: 132 # We'll take a pass on it, live with what (if any) data we get 133 pass 134 135 except IOError: 136 print ("Cannot open the USB ID file: %s" % fname) 137 raise 138 139 if (ufile): 140 ufile.close()
141
142 - def lookupdevice(self, vendor, product=None, interface=None):
143 return self.vendorlist.getVendorInfo(vendor, product, interface)
144
145 - def lookupclass(self, klass, subclass=None, protocol=None):
146 return self.usbclasslist.getClassInfo(klass, subclass, protocol)
147
148 - def getVendorList(self):
149 """ Return the object representing the list of vendors """ 150 return self.vendorlist
151
152 - def getUSBClassList(self):
153 """ Return the object representing the list of USB Classes """ 154 return self.usbclasslist
155 156 ### 157 ### USB VendorID/DeviceID information related classes 158 ###
159 -class VendorID(usbInfoObject):
160 """ This class abstracts USB Vendor ID information 161 It holds the description, and a list of Device ID's 162 """
163 - def addDevice(self, device):
164 """ Put this device on our list """ 165 self.addChild(device)
166
167 - def getDevice(self, device):
168 """ Return the requested device by ID, if we have it """ 169 return self.getChild(device)
170
171 - def getDevices(self):
172 """ Return a list of our devices """ 173 return self.getChildren()
174
175 -class DeviceID(usbInfoObject):
176 """ This class abstracts USB Device ID information 177 It holds the description and a list of the Interface ID's 178 """
179 - def addInterface(self, interface):
180 """ Put this interface on our list """ 181 self.addChild(interface)
182
183 - def getInterface(self, interface):
184 """ Return the requested interface by ID, if we have it """ 185 return self.getChild(interface)
186
187 - def getInterfaces(self):
188 """ Return a list of our interfaces """ 189 return self.getChildren()
190
191 -class InterfaceID(usbInfoObject):
192 """ This class abstracts USB Interface information 193 It holds the description 194 """ 195 pass
196
197 -class VendorList:
198 """ This class is responsible for the collection of vendor data 199 It allows you to ask for: 200 - vendor info by VendorID 201 - device info by VendorID/DeviceID 202 - interface """
203 - def __init__(self):
204 """ Prepare a dict to handle all of our children vendor objects """ 205 self.vendorlist = {}
206
207 - def addVendor(self, vID, vDesc):
208 """ Put this vendor into our dictionary """ 209 self.vendorlist[int(vID,16)] = vDesc
210
211 - def getVendorInfo(self, vID, dID=None, iID=None):
212 """ Lookup info for vendor, device, interface - last two are optional """ 213 # First things first... Get information if available.... 214 self.vendor = self.device = self.iface = None 215 self.vDesc = self.dDesc = self.iDesc = None 216 217 # --- Vendor 218 if vID in self.vendorlist: 219 self.vendor = self.vendorlist[vID] 220 self.vDesc = self.vendor.description 221 222 # --- Device 223 if self.vendor: 224 self.device = self.vendor.getDevice(dID) 225 if self.device: 226 self.dDesc = self.device.description 227 228 # --- Interface 229 if self.device: 230 self.iface = self.device.getInterface(iID) 231 if self.iface: 232 self.iDesc = self.iface.description 233 234 # Now, decide how we were called, and return appropriately 235 if ((dID is None) and (iID is None)): 236 return (self.vDesc,) 237 elif (iID is None): 238 return (self.vDesc, self.dDesc) 239 else: 240 return (self.vDesc, self.dDesc, self.iDesc)
241
242 - def getVendorList(self):
243 return self.vendorlist.values()
244 245 246 ### 247 ### USB Class information related classes 248 ###
249 -class USBClass(usbInfoObject):
250 """ This class abstracts USB Class information 251 It holds the description, and a list of Subclasses 252 """
253 - def addSubclass(self, subclass):
254 """ Put this subclass on our list """ 255 self.addChild(subclass)
256
257 - def getSubclass(self, subclass):
258 """ Return subclass by ID, if we have it """ 259 return self.getChild(subclass)
260
261 - def getSubclasses(self):
262 """ Return a list of our subclasses """ 263 return self.getChildren()
264 265
266 -class USBClassSubclass(usbInfoObject):
267 """ This class abstracts USB Device SubClass information 268 It holds the description and a list of the protocols 269 """
270 - def addProtocol(self, protocol):
271 """ Put this protocol on our list """ 272 self.addChild(protocol)
273
274 - def getProtocol(self, protocol):
275 """ Return protocol as ID, if we have it """ 276 return self.getChild(protocol)
277
278 - def getProtocols(self):
279 """ Return a list of our protocols """ 280 return self.getChildren()
281
282 -class USBClassProtocol(usbInfoObject):
283 """ This class abstracts USB Interface information 284 It holds the description 285 """ 286 pass
287 288
289 -class USBClassList:
290 """ This class is responsible for the collection of USB Class data 291 It allows you to ask for: 292 - USB Class info by Class ID 293 - USB SubClass info by ClassID/SubclassID 294 - USB Protocol info by ClassID/SubclassID/ProtocolID 295 """
296 - def __init__(self):
297 self.classlist = {}
298
299 - def addClass(self, cID, cDesc):
300 self.classlist[int(cID, 16)] = cDesc
301
302 - def getClassInfo(self, cID, sID=None, pID=None):
303 """ Lookup info for class, subclass, protocol - last two are optional """ 304 # First things first... Get information if available.... 305 self.usbclass = self.subclass = self.protocol = None 306 self.cDesc = self.sDesc = self.pDesc = None 307 308 # --- USB Class 309 if cID in self.classlist: 310 self.usbclass = self.classlist[cID] 311 self.cDesc = self.usbclass.description 312 313 # --- USB Subclass 314 if self.usbclass: 315 self.subclass = self.usbclass.getSubclass(sID) 316 if self.subclass: 317 self.sDesc = self.subclass.description 318 319 # --- USB Protocol 320 if self.subclass: 321 self.protocol = self.subclass.getProtocol(pID) 322 if self.protocol: 323 self.pDesc = self.protocol.description 324 325 # Now, decide how we were called, and return appropriately 326 if ((sID is None) and (pID is None)): 327 return (self.cDesc,) 328 elif (pID is None): 329 return (self.cDesc, self.sDesc) 330 else: 331 return (self.cDesc, self.sDesc, self.pDesc)
332
333 - def getUSBClassList(self):
334 return self.classlist.values()
335 336 337 338 ### 339 ### Interactive testing code 340 ### 341 if (__name__ == "__main__"): 342 import os, guihelper 352 362 363 myUSBids = usb_ids(os.path.join(guihelper.resourcedirectory, 364 "usb.ids")) 365 366 # PRINT OUT THE WHOLE TREE AS A TEST CASE 367 # print_vendor_info(myUSBids) 368 # print_class_info(myUSBids) 369 370 # Our list is now internally decimal, so to lookup/inquire by hex 371 # You must convert to decimal before passing your inquiry in... 372 373 # Test lookup for various bits of USB Vendor/Device/Interface information 374 print "Inquire on Vendor 1452, Device 518, Iface 1 using various levels of detail:" 375 vlist = myUSBids.getVendorList() 376 print vlist.getVendorInfo(1452) 377 print vlist.getVendorInfo(1452, 518) 378 print vlist.getVendorInfo(1452, 518, 1) 379 print 380 381 # Test lookup for various bits of USB Class/Subclass/Protocol information 382 print "Inquire on Class 8, Subclass 4, Protocol 0 using various levels of detail:" 383 clist = myUSBids.getUSBClassList() 384 print clist.getClassInfo(8) 385 print clist.getClassInfo(8, 4) 386 print clist.getClassInfo(8, 4, 0) 387 print 388 389 # For reference, this is how you'd inquire on hex values 390 # print vlist.getVendorInfo(int("05ac", 16)) 391 # print vlist.getVendorInfo(int("05ac", 16), int("0206", 16)) 392 # print vlist.getVendorInfo(int("05ac", 16), int("0206", 16), int("01", 16)) 393 # print clist.getClassInfo(int("08", 16)) 394 # print clist.getClassInfo(int("08", 16), int("04", 16)) 395 # print clist.getClassInfo(int("08", 16), int("04", 16), int("00", 16)) 396 397 # The following are in hex just becuase that way I can visually match them 398 # up with the entries in the test.ids file 399 400 # Now, let's test for something that doesn't exist: 401 print "Look up something with little detail in Internet file... 1004/6000/(00..02)" 402 print vlist.getVendorInfo(int("1004", 16), int("6000", 16), int("00", 16)) 403 print vlist.getVendorInfo(int("1004", 16), int("6000", 16), int("01", 16)) 404 print vlist.getVendorInfo(int("1004", 16), int("6000", 16), int("02", 16)) 405 print 406 407 # Put the data in from our local copy 408 print "Add in our test data to override internet data" 409 myUSBids.add_data(os.path.join(guihelper.resourcedirectory, 410 "test.ids")) 411 print 412 413 # Now, it should be there 414 print "Check it again..." 415 print vlist.getVendorInfo(int("1004", 16), int("6000", 16), int("00", 16)) 416 print vlist.getVendorInfo(int("1004", 16), int("6000", 16), int("01", 16)) 417 print vlist.getVendorInfo(int("1004", 16), int("6000", 16), int("02", 16)) 418