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

Source Code for Module comdiagnose

  1  #!/usr/bin/env python 
  2   
  3  ### BITPIM 
  4  ### 
  5  ### Copyright (C) 2003-2004 Roger Binns <rogerb@rogerbinns.com> 
  6  ### 
  7  ### This program is free software; you can redistribute it and/or modify 
  8  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  9  ### 
 10  ### $Id: comdiagnose.py 4656 2008-08-02 15:57:20Z hjelmn $ 
 11   
 12  """Generate opinions on the attached com devices""" 
 13   
 14  # Standard modules 
 15  import re 
 16  import sys 
 17   
 18  # My modules 
 19  import comscan 
 20  import usbscan 
 21  import bitflingscan 
 22   
23 -def diagnose(portlist, phonemodule):
24 """Returns data suitable for use in com port settings dialog 25 26 @param portlist: A list of ports as returned by L{comscan.comscan}() 27 @return: A list of tuples (whattodisplay, portselected, htmldiagnosis) 28 """ 29 res=[] 30 # we sort into 3 lists 31 # available 32 # not available but active 33 # the rest 34 available=[] 35 bfavailable=[] 36 bfrest=[] 37 notavailablebutactive=[] 38 therest=[] 39 for port in portlist: 40 if port.has_key("available") and port["available"]: 41 if port.has_key("BitFling"): 42 bfavailable.append(port) 43 else: 44 available.append(port) 45 continue 46 if not port.has_key("BitFling") and (port.has_key("available") and port.has_key("active") and port["active"]): 47 notavailablebutactive.append(port) 48 continue 49 if port.has_key("BitFling"): 50 bfrest.append(port) 51 else: 52 therest.append(port) 53 54 if len(available): 55 whattodisplay="===== Available Ports ===== " 56 portselected=None 57 htmldiagnosis="<p>These ports are open and can be selected" 58 res.append( (whattodisplay, portselected, htmldiagnosis) ) 59 for port in available: 60 likely=islikelyport(port, phonemodule) 61 whattodisplay=port['description'] 62 if likely: 63 whattodisplay="(*) "+whattodisplay 64 portselected=port['name'] 65 if likely: 66 htmldiagnosis="<p>This port is likely to be your phone. The port is available and can be selected.<p>"+genhtml(port) 67 else: 68 htmldiagnosis="<p>This port is available and can be selected.<p>"+genhtml(port) 69 res.append( (whattodisplay, portselected, htmldiagnosis) ) 70 71 if len(notavailablebutactive): 72 whattodisplay="===== Ports not available =====" 73 portselected=None 74 htmldiagnosis="<p>These ports are active, but cannot be used because they are in use by another program or device driver, you do not have permissions to access them, or a device driver is required." 75 res.append( (whattodisplay, portselected, htmldiagnosis) ) 76 for port in notavailablebutactive: 77 whattodisplay=port['description'] 78 portselected=port['name'] 79 htmldiagnosis="<p>This port is active but not available for use.<p>"+genhtml(port) 80 res.append( (whattodisplay, portselected, htmldiagnosis) ) 81 82 if len(therest): 83 whattodisplay="===== Inoperable Ports =====" 84 portselected=None 85 htmldiagnosis="""<p>These ports are known to your operating system, but cannot be used. 86 This may be because the device is not plugged in (such as on a USB to serial cable) or because 87 you don't have sufficient permissions to use them.""" 88 res.append( (whattodisplay, portselected, htmldiagnosis) ) 89 for port in therest: 90 whattodisplay=port['description'] 91 portselected=port['name'] 92 htmldiagnosis="""<p>This port should not be selected. If you believe it is the correct 93 port, you should cause it to become available such as by plugging in the cable or ensuring 94 you have correct permissions. Press refresh once you have done so and it should be listed 95 under available. Note that the name may change as it becomes available.<p>"""+genhtml(port) 96 res.append( (whattodisplay, portselected, htmldiagnosis) ) 97 98 if len(bfavailable): 99 whattodisplay="===== BitFling Available Ports ===== " 100 portselected=None 101 htmldiagnosis="<p>These BitFling ports are open and can be selected" 102 res.append( (whattodisplay, portselected, htmldiagnosis) ) 103 for port in bfavailable: 104 likely=islikelyport(port, phonemodule) 105 whattodisplay=port['description'] 106 if likely: 107 whattodisplay="(*) "+whattodisplay 108 portselected=port['name'] 109 if likely: 110 htmldiagnosis="<p>This port is likely to be your phone. The port is available and can be selected.<p>"+genhtml(port) 111 else: 112 htmldiagnosis="<p>This port is available and can be selected.<p>"+genhtml(port) 113 res.append( (whattodisplay, portselected, htmldiagnosis) ) 114 115 if len(bfrest): 116 whattodisplay="===== BitFling Other Ports ===== " 117 portselected=None 118 htmldiagnosis="<p>These BitFling ports exist but are not available" 119 res.append( (whattodisplay, portselected, htmldiagnosis) ) 120 for port in bfrest: 121 likely=islikelyport(port, phonemodule) 122 whattodisplay=port['description'] 123 if likely: 124 whattodisplay="(*) "+whattodisplay 125 portselected=port['name'] 126 if likely: 127 htmldiagnosis="<p>This port is likely to be your phone. The port is available and can be selected.<p>"+genhtml(port) 128 else: 129 htmldiagnosis="<p>This port is available and can be selected.<p>"+genhtml(port) 130 res.append( (whattodisplay, portselected, htmldiagnosis) ) 131 132 133 return res
134
135 -def htmlify(text):
136 text=re.sub("&", "&amp;", text) 137 text=re.sub("<", "&lt;", text) 138 text=re.sub(">", "&gt;", text) 139 return text
140
141 -def genhtml(port):
142 """Returns nice html describing a port dict""" 143 sfont='<font size="-1">' 144 efont='</font>' 145 res='<table width="100%"><tr><th width="20%">Property<th width="40%">Value<th width="40%">Description</tr>\n' 146 keys=port.keys() 147 keys.sort() 148 for k in keys: 149 # property 150 if k.startswith('usb-') and not k.endswith('string'): 151 # ignore these 152 continue 153 res+='<tr><td valign="top">'+sfont+k+efont+'</td><td valign="top">\n' 154 # value 155 if k=='active' or k=='available': 156 if port[k]: 157 res+=sfont+"True"+efont 158 else: 159 res+=sfont+"False"+efont 160 elif k=='driverdate': 161 # XML-RPC converts tuples to lists, so we have to convert back again here 162 res+=sfont+("%d-%d-%d" % tuple(port[k]))+efont 163 elif k=='driverstatus': 164 res+=sfont+`port[k]`+efont # should print it nicer at some point 165 else: 166 if isinstance(port[k], type("")): 167 res+=sfont+htmlify(port[k])+efont 168 else: 169 res+=sfont+`port[k]`+efont 170 res+='</td><td valign="top">' 171 # description 172 if k=='name': 173 res+=sfont+"This is the name the port is known to your operating system as"+efont 174 elif k=='available': 175 if port[k]: 176 res+=sfont+"It was possible to open this port"+efont 177 else: 178 res+=sfont+"It was not possible to open this port"+efont 179 elif k=='active': 180 if port[k]: 181 res+=sfont+"Your operating system shows this driver and port is correctly configured and a device attached"+efont 182 else: 183 res+=sfont+"This driver/port combination is not currently running"+efont 184 elif k=='driverstatus': 185 res+=sfont+"""This is low level detail. If problem is non-zero then you need to look in the 186 control panel for an explanation as to why this driver/device is not working."""+efont 187 elif k=='hardwareinstance': 188 res+=sfont+"""This is how the device is named internally. For example USB devices include 189 the vendor (VID) and product (PID) identities"""+efont 190 elif k=="libusb": 191 res+=sfont+"""This indicates if the usb library is in use to access this device. Operating system 192 device drivers (if any) are bypassed when BitPim talks to the device"""+efont 193 elif k=="driver-required": 194 res+=sfont+"""This indicates if you must use a device driver, not direct USB access"""+efont 195 elif k=="BitFling": 196 res+=sfont+"""This indicates that the port is being accessed from a remote machine via BitFling,"""+efont 197 elif k=="protocol": 198 res+=sfont+"""This is the protocol the USB device claims to speak"""+efont 199 elif k=="class": 200 if port[k]=="serial": 201 res+=sfont+"""This is a serial connection"""+efont 202 elif port[k]=="modem": 203 res+=sfont+"""This is a modem connection"""+efont 204 else: 205 res+=sfont+"""The port type (serial, modem etc)"""+efont 206 elif k=='PID': 207 res+=sfont+'Product ID'+efont 208 elif k=='VID': 209 res+=sfont+'Vendor ID'+efont 210 else: 211 res+="&nbsp;" 212 213 # tail it 214 res+="</td></tr>\n" 215 216 res+="\n</table>" 217 218 return res
219
220 -def islikelyport(port, phonemodule):
221 return islikelyportscore(port, phonemodule)>=0
222
223 -def islikelyportscore(port, phonemodule):
224 """Returns a port score. 225 226 @return: -1 if no match, 0 best match, 1 next etc 227 """ 228 229 usbids=phonemodule.Profile.usbids 230 deviceclasses=phonemodule.Profile.deviceclasses 231 232 # it must be the right class 233 if port.has_key("class") and port["class"] not in deviceclasses: 234 return -1 235 236 score=0 237 # check the usbids 238 for vid,pid,iface in usbids: 239 score+=1 240 if port.has_key("libusb"): 241 if port['usb-vendor#']==vid and \ 242 port['usb-product#']==pid and \ 243 port['usb-interface#']==iface: 244 return score 245 if port.has_key('hardwareinstance'): 246 v=port['hardwareinstance'].lower() 247 str="vid_%04x&pid_%04x" % (vid,pid) 248 if v.find(str)>=0: 249 return score 250 251 # LG phones generall have ports named cu.name-BTDIAG-1 or cu.name-SerialPort-1 where name is the bluetooth id of the phone 252 if sys.platform=='darwin' and (port['name'].lower().find('btdiag') > 0 or port['name'].lower().find('serialport') > 0): 253 return score 254 255 score+=10 256 # did it have a usb id that didn't match? 257 if port.has_key("libusb"): 258 return -1 259 260 # did the hardware instance have usb info? 261 if port.has_key("hardwareinstance") and \ 262 re.search("vid_([0-9a-f]){4}&pid_([0-9a-f]){4}", port['hardwareinstance'], re.I) is not None: 263 return -1 264 265 # are we on non-windows platform? if so, just be happy if 'usb' is in the name or the driver name 266 if sys.platform!='win32' and ( \ 267 port['name'].lower().find('usb')>0 or port.get("driver","").lower().find('usb')>=0): 268 return score 269 270 # if we are on windows check to see if this phone supports bluetooth as we may have a bluetooth comport 271 # we check that the bluetooth device contains the manufacturers ID for the phone, this filters 272 # other bluetooth devices from the search, on windows the 'hardwareinstance' contains BTHENUM indicating 273 # a bluetooth device and the manufacturer's ID 274 if sys.platform=='win32' and (getattr(phonemodule.Profile, 'bluetooth_mfg_id', 0) != 0) and \ 275 port['hardwareinstance'].find('BTHENUM\\')==0 and \ 276 port['hardwareinstance'].find(getattr(phonemodule.Profile, 'bluetooth_mfg_id', 'XXX'))>0: 277 return score 278 279 # ok, not then 280 return -1
281
282 -def autoguessports(phonemodule):
283 """Returns a list of ports (most likely first) for finding the phone on""" 284 # this function also demonsrates the use of list comprehensions :-) 285 res=[] 286 # we only care about available ports 287 ports=[(islikelyportscore(port, phonemodule), port) for port in comscan.comscan()+usbscan.usbscan()+bitflingscan.flinger.scan() if port['available']] 288 # sort on score 289 ports.sort() 290 # return all ones with score >=0 291 return [ (port['name'], port) for score,port in ports if score>=0]
292 293 294 295 296 if __name__=='__main__': 297 import common 298 print autoguessports(common.importas("phones.com_lgvx4400")) 299