0001 #!/usr/bin/env python 0002 0003 ### BITPIM 0004 ### 0005 ### Copyright (C) 2003-2004 Roger Binns <rogerb@rogerbinns.com> 0006 ### 0007 ### This program is free software; you can redistribute it and/or modify 0008 ### it under the terms of the BitPim license as detailed in the LICENSE file. 0009 ### 0010 ### $Id: comdiagnose.py 4656 2008-08-02 15:57:20Z hjelmn $ 0011 0012 """Generate opinions on the attached com devices""" 0013 0014 # Standard modules 0015 import re 0016 import sys 0017 0018 # My modules 0019 import comscan 0020 import usbscan 0021 import bitflingscan 0022 0023 def diagnose(portlist, phonemodule): 0024 """Returns data suitable for use in com port settings dialog 0025 0026 @param portlist: A list of ports as returned by L{comscan.comscan}() 0027 @return: A list of tuples (whattodisplay, portselected, htmldiagnosis) 0028 """ 0029 res=[] 0030 # we sort into 3 lists 0031 # available 0032 # not available but active 0033 # the rest 0034 available=[] 0035 bfavailable=[] 0036 bfrest=[] 0037 notavailablebutactive=[] 0038 therest=[] 0039 for port in portlist: 0040 if port.has_key("available") and port["available"]: 0041 if port.has_key("BitFling"): 0042 bfavailable.append(port) 0043 else: 0044 available.append(port) 0045 continue 0046 if not port.has_key("BitFling") and (port.has_key("available") and port.has_key("active") and port["active"]): 0047 notavailablebutactive.append(port) 0048 continue 0049 if port.has_key("BitFling"): 0050 bfrest.append(port) 0051 else: 0052 therest.append(port) 0053 0054 if len(available): 0055 whattodisplay="===== Available Ports ===== " 0056 portselected=None 0057 htmldiagnosis="<p>These ports are open and can be selected" 0058 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0059 for port in available: 0060 likely=islikelyport(port, phonemodule) 0061 whattodisplay=port['description'] 0062 if likely: 0063 whattodisplay="(*) "+whattodisplay 0064 portselected=port['name'] 0065 if likely: 0066 htmldiagnosis="<p>This port is likely to be your phone. The port is available and can be selected.<p>"+genhtml(port) 0067 else: 0068 htmldiagnosis="<p>This port is available and can be selected.<p>"+genhtml(port) 0069 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0070 0071 if len(notavailablebutactive): 0072 whattodisplay="===== Ports not available =====" 0073 portselected=None 0074 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." 0075 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0076 for port in notavailablebutactive: 0077 whattodisplay=port['description'] 0078 portselected=port['name'] 0079 htmldiagnosis="<p>This port is active but not available for use.<p>"+genhtml(port) 0080 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0081 0082 if len(therest): 0083 whattodisplay="===== Inoperable Ports =====" 0084 portselected=None 0085 htmldiagnosis="""<p>These ports are known to your operating system, but cannot be used. 0086 This may be because the device is not plugged in (such as on a USB to serial cable) or because 0087 you don't have sufficient permissions to use them.""" 0088 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0089 for port in therest: 0090 whattodisplay=port['description'] 0091 portselected=port['name'] 0092 htmldiagnosis="""<p>This port should not be selected. If you believe it is the correct 0093 port, you should cause it to become available such as by plugging in the cable or ensuring 0094 you have correct permissions. Press refresh once you have done so and it should be listed 0095 under available. Note that the name may change as it becomes available.<p>"""+genhtml(port) 0096 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0097 0098 if len(bfavailable): 0099 whattodisplay="===== BitFling Available Ports ===== " 0100 portselected=None 0101 htmldiagnosis="<p>These BitFling ports are open and can be selected" 0102 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0103 for port in bfavailable: 0104 likely=islikelyport(port, phonemodule) 0105 whattodisplay=port['description'] 0106 if likely: 0107 whattodisplay="(*) "+whattodisplay 0108 portselected=port['name'] 0109 if likely: 0110 htmldiagnosis="<p>This port is likely to be your phone. The port is available and can be selected.<p>"+genhtml(port) 0111 else: 0112 htmldiagnosis="<p>This port is available and can be selected.<p>"+genhtml(port) 0113 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0114 0115 if len(bfrest): 0116 whattodisplay="===== BitFling Other Ports ===== " 0117 portselected=None 0118 htmldiagnosis="<p>These BitFling ports exist but are not available" 0119 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0120 for port in bfrest: 0121 likely=islikelyport(port, phonemodule) 0122 whattodisplay=port['description'] 0123 if likely: 0124 whattodisplay="(*) "+whattodisplay 0125 portselected=port['name'] 0126 if likely: 0127 htmldiagnosis="<p>This port is likely to be your phone. The port is available and can be selected.<p>"+genhtml(port) 0128 else: 0129 htmldiagnosis="<p>This port is available and can be selected.<p>"+genhtml(port) 0130 res.append( (whattodisplay, portselected, htmldiagnosis) ) 0131 0132 0133 return res 0134 0135 def htmlify(text): 0136 text=re.sub("&", "&", text) 0137 text=re.sub("<", "<", text) 0138 text=re.sub(">", ">", text) 0139 return text 0140 0141 def genhtml(port): 0142 """Returns nice html describing a port dict""" 0143 sfont='<font size="-1">' 0144 efont='</font>' 0145 res='<table width="100%"><tr><th width="20%">Property<th width="40%">Value<th width="40%">Description</tr>\n' 0146 keys=port.keys() 0147 keys.sort() 0148 for k in keys: 0149 # property 0150 if k.startswith('usb-') and not k.endswith('string'): 0151 # ignore these 0152 continue 0153 res+='<tr><td valign="top">'+sfont+k+efont+'</td><td valign="top">\n' 0154 # value 0155 if k=='active' or k=='available': 0156 if port[k]: 0157 res+=sfont+"True"+efont 0158 else: 0159 res+=sfont+"False"+efont 0160 elif k=='driverdate': 0161 # XML-RPC converts tuples to lists, so we have to convert back again here 0162 res+=sfont+("%d-%d-%d" % tuple(port[k]))+efont 0163 elif k=='driverstatus': 0164 res+=sfont+`port[k]`+efont # should print it nicer at some point 0165 else: 0166 if isinstance(port[k], type("")): 0167 res+=sfont+htmlify(port[k])+efont 0168 else: 0169 res+=sfont+`port[k]`+efont 0170 res+='</td><td valign="top">' 0171 # description 0172 if k=='name': 0173 res+=sfont+"This is the name the port is known to your operating system as"+efont 0174 elif k=='available': 0175 if port[k]: 0176 res+=sfont+"It was possible to open this port"+efont 0177 else: 0178 res+=sfont+"It was not possible to open this port"+efont 0179 elif k=='active': 0180 if port[k]: 0181 res+=sfont+"Your operating system shows this driver and port is correctly configured and a device attached"+efont 0182 else: 0183 res+=sfont+"This driver/port combination is not currently running"+efont 0184 elif k=='driverstatus': 0185 res+=sfont+"""This is low level detail. If problem is non-zero then you need to look in the 0186 control panel for an explanation as to why this driver/device is not working."""+efont 0187 elif k=='hardwareinstance': 0188 res+=sfont+"""This is how the device is named internally. For example USB devices include 0189 the vendor (VID) and product (PID) identities"""+efont 0190 elif k=="libusb": 0191 res+=sfont+"""This indicates if the usb library is in use to access this device. Operating system 0192 device drivers (if any) are bypassed when BitPim talks to the device"""+efont 0193 elif k=="driver-required": 0194 res+=sfont+"""This indicates if you must use a device driver, not direct USB access"""+efont 0195 elif k=="BitFling": 0196 res+=sfont+"""This indicates that the port is being accessed from a remote machine via BitFling,"""+efont 0197 elif k=="protocol": 0198 res+=sfont+"""This is the protocol the USB device claims to speak"""+efont 0199 elif k=="class": 0200 if port[k]=="serial": 0201 res+=sfont+"""This is a serial connection"""+efont 0202 elif port[k]=="modem": 0203 res+=sfont+"""This is a modem connection"""+efont 0204 else: 0205 res+=sfont+"""The port type (serial, modem etc)"""+efont 0206 elif k=='PID': 0207 res+=sfont+'Product ID'+efont 0208 elif k=='VID': 0209 res+=sfont+'Vendor ID'+efont 0210 else: 0211 res+=" " 0212 0213 # tail it 0214 res+="</td></tr>\n" 0215 0216 res+="\n</table>" 0217 0218 return res 0219 0220 def islikelyport(port, phonemodule): 0221 return islikelyportscore(port, phonemodule)>=0 0222 0223 def islikelyportscore(port, phonemodule): 0224 """Returns a port score. 0225 0226 @return: -1 if no match, 0 best match, 1 next etc 0227 """ 0228 0229 usbids=phonemodule.Profile.usbids 0230 deviceclasses=phonemodule.Profile.deviceclasses 0231 0232 # it must be the right class 0233 if port.has_key("class") and port["class"] not in deviceclasses: 0234 return -1 0235 0236 score=0 0237 # check the usbids 0238 for vid,pid,iface in usbids: 0239 score+=1 0240 if port.has_key("libusb"): 0241 if port['usb-vendor#']==vid and \ 0242 port['usb-product#']==pid and \ 0243 port['usb-interface#']==iface: 0244 return score 0245 if port.has_key('hardwareinstance'): 0246 v=port['hardwareinstance'].lower() 0247 str="vid_%04x&pid_%04x" % (vid,pid) 0248 if v.find(str)>=0: 0249 return score 0250 0251 # LG phones generall have ports named cu.name-BTDIAG-1 or cu.name-SerialPort-1 where name is the bluetooth id of the phone 0252 if sys.platform=='darwin' and (port['name'].lower().find('btdiag') > 0 or port['name'].lower().find('serialport') > 0): 0253 return score 0254 0255 score+=10 0256 # did it have a usb id that didn't match? 0257 if port.has_key("libusb"): 0258 return -1 0259 0260 # did the hardware instance have usb info? 0261 if port.has_key("hardwareinstance") and \ 0262 re.search("vid_([0-9a-f]){4}&pid_([0-9a-f]){4}", port['hardwareinstance'], re.I) is not None: 0263 return -1 0264 0265 # are we on non-windows platform? if so, just be happy if 'usb' is in the name or the driver name 0266 if sys.platform!='win32' and ( \ 0267 port['name'].lower().find('usb')>0 or port.get("driver","").lower().find('usb')>=0): 0268 return score 0269 0270 # if we are on windows check to see if this phone supports bluetooth as we may have a bluetooth comport 0271 # we check that the bluetooth device contains the manufacturers ID for the phone, this filters 0272 # other bluetooth devices from the search, on windows the 'hardwareinstance' contains BTHENUM indicating 0273 # a bluetooth device and the manufacturer's ID 0274 if sys.platform=='win32' and (getattr(phonemodule.Profile, 'bluetooth_mfg_id', 0) != 0) and \ 0275 port['hardwareinstance'].find('BTHENUM\\')==0 and \ 0276 port['hardwareinstance'].find(getattr(phonemodule.Profile, 'bluetooth_mfg_id', 'XXX'))>0: 0277 return score 0278 0279 # ok, not then 0280 return -1 0281 0282 def autoguessports(phonemodule): 0283 """Returns a list of ports (most likely first) for finding the phone on""" 0284 # this function also demonsrates the use of list comprehensions :-) 0285 res=[] 0286 # we only care about available ports 0287 ports=[(islikelyportscore(port, phonemodule), port) for port in comscan.comscan()+usbscan.usbscan()+bitflingscan.flinger.scan() if port['available']] 0288 # sort on score 0289 ports.sort() 0290 # return all ones with score >=0 0291 return [ (port['name'], port) for score,port in ports if score>=0] 0292 0293 0294 0295 0296 if __name__=='__main__': 0297 import common 0298 print autoguessports(common.importas("phones.com_lgvx4400")) 0299
Generated by PyXR 0.9.4