1
2
3
4
5
6
7
8
9
10
11
12 """Generate opinions on the attached com devices"""
13
14
15 import re
16 import sys
17
18
19 import comscan
20 import usbscan
21 import bitflingscan
22
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
31
32
33
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
140
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
150 if k.startswith('usb-') and not k.endswith('string'):
151
152 continue
153 res+='<tr><td valign="top">'+sfont+k+efont+'</td><td valign="top">\n'
154
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
162 res+=sfont+("%d-%d-%d" % tuple(port[k]))+efont
163 elif k=='driverstatus':
164 res+=sfont+`port[k]`+efont
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
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+=" "
212
213
214 res+="</td></tr>\n"
215
216 res+="\n</table>"
217
218 return res
219
222
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
233 if port.has_key("class") and port["class"] not in deviceclasses:
234 return -1
235
236 score=0
237
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
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
257 if port.has_key("libusb"):
258 return -1
259
260
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
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
271
272
273
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
280 return -1
281
283 """Returns a list of ports (most likely first) for finding the phone on"""
284
285 res=[]
286
287 ports=[(islikelyportscore(port, phonemodule), port) for port in comscan.comscan()+usbscan.usbscan()+bitflingscan.flinger.scan() if port['available']]
288
289 ports.sort()
290
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