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

Source Code for Module phone_detect

  1  ### BITPIM 
  2  ### 
  3  ### Copyright (C) 2004 Joe Pham <djpham@bitpim.org> 
  4  ### 
  5  ### This program is free software; you can redistribute it and/or modify 
  6  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  7  ### 
  8  ### $Id: phone_detect.py 4656 2008-08-02 15:57:20Z hjelmn $ 
  9   
 10  """ 
 11  Auto detect of phones. 
 12  This module provides functionality to perform auto-detection of connected phone. 
 13  To implement auto-detection for your phone, perform the following: 
 14   
 15  1.  If your phone can be determined by examining the Phone Manufacturer and 
 16  Phone Model values returned by +GMI and +GMM commands, just set the following 
 17  attributes in your Profile class: 
 18   
 19  phone_manufacturer='string' 
 20  phone_model='string' 
 21   
 22  The phone_manufacturer attribute will be checked for substring ie, 'SAMSUNG' in 
 23  'SAMSUNG ELECTRONICS CO.,LTD.'; phone_model must match exactly. 
 24   
 25  2.  If your phone detection scheme is more complex, define a staticmethod 
 26  'detectphone' in your Phone class.  The declaration of the method is: 
 27   
 28  def detectphone(ports, likely_ports, detect_dict) 
 29   
 30  ports: list of available ports returned from comscan 
 31  likely_ports: list of likely ports as returned from comdiagnose.islikelyport, 
 32              ie ['com1', 'com2']. 
 33  where detect_dict is a dict with the following key/value pairs: 
 34  'port': { 
 35  'mode_modem': True if the phone can be set to modem mode, False otherwise 
 36  'mode_brew': True if the phone can be set to DM mode, False otherwise.  This 
 37               value is not currently set since I'm not sure all phones can 
 38               transition out of DM mode. 
 39  'manufacturer': string value returned by +GMI 
 40  'model': string value returned by +GMM 
 41  'firmware_version': string value returned by +GMR 
 42  'esn': ESN value of this phone, will be used to associate a name with it. 
 43  'firmwareresponse': response data based on BREW firmwarerequest command. 
 44                      Currently not implemented. 
 45  } 
 46   
 47  If a possitive identification is made, method detectphone should return the 
 48  port associated with that phone, otherwise just return None. 
 49   
 50  """ 
 51   
 52  # standard modules 
 53  import Queue 
 54  import threading 
 55   
 56  # wx modules 
 57   
 58  # BitPim modules 
 59  import comdiagnose 
 60  import common 
 61  import commport 
 62  import comscan 
 63  import phones 
 64  import usbscan 
 65   
66 -class DetectPhone(object):
67 __default_timeout=1
68 - def __init__(self, log=None):
69 # get standard commport parameters 70 self.__log=log 71 self.__data={} 72 self.__data_lock=threading.Lock() 73 self.__q_log=Queue.Queue(0) 74 self.__q_on=False
75
76 - def log(self, log_str):
77 if self.__log is None: 78 print log_str 79 else: 80 if self.__q_on: 81 self.__q_log.put_nowait(log_str) 82 else: 83 self.__log.log(log_str)
84 - def logdata(self, log_str, log_data, klass=None, data_type=None):
85 if self.__log is None: 86 print log_str,log_data, klass 87 else: 88 if self.__q_on: 89 self.__q_log.put_nowait((log_str, log_data, klass, data_type)) 90 else: 91 self.__log.logdata(log_str, log_data, klass, data_type)
92
93 - def progress(self, pos, max, desc=""):
94 if self.__log: 95 self.__log.progress(pos, max, desc)
96
97 - def __get_mode_modem(self, comm):
98 """ check if this port supports mode modem""" 99 try: 100 resp=comm.sendatcommand('E0V1') 101 return True 102 except: 103 return False
104 - def __send_at_and_get(self, comm, cmd):
105 try: 106 resp=comm.sendatcommand(cmd) 107 return ': '.join(resp[0].split(': ')[1:]) 108 except: 109 return None
110 - def __get_manufacturer(self, comm):
111 return self.__send_at_and_get(comm, '+GMI')
112 - def __get_model(self, comm):
113 return self.__send_at_and_get(comm, '+GMM')
114 - def __get_firmware_version(self, comm):
115 return self.__send_at_and_get(comm, '+GMR')
116 - def __get_esn(self, comm):
117 return self.__send_at_and_get(comm, '+GSN')
118 - def __get_mode_brew(self, comm):
119 raise NotImplementedError
120 ## try: 121 ## resp=comm.sendatcommand('$QCDMG') 122 ## return True 123 ## except: 124 ## return False
125 - def __get_firmware_response(self, comm):
126 raise NotImplementedError
127
128 - def __get_data(self, port):
129 r={ 'mode_modem': False, 'mode_brew': False, 130 'manufacturer': None, 'model': None, 'firmware_version': None, 131 'esn': None, 'firmwareresponse': None } 132 try: 133 c=commport.CommConnection(self, port, 134 timeout=self.__default_timeout) 135 except: 136 self.log('Failed to open port: '+port) 137 return r 138 r['mode_modem']=self.__get_mode_modem(c) 139 if r['mode_modem']: 140 # in modem mode, ok to try other info 141 r['manufacturer']=self.__get_manufacturer(c) 142 r['model']=self.__get_model(c) 143 r['firmware_version']=self.__get_firmware_version(c) 144 r['esn']=self.__get_esn(c) 145 c.close() 146 return r
147
148 - def __check_profile(self, profile):
149 if not hasattr(profile, 'phone_manufacturer') or \ 150 not hasattr(profile, 'phone_model'): 151 return None 152 res=None 153 phone_model=profile.phone_model 154 phone_manufacturer=profile.phone_manufacturer 155 deviceclasses=profile.deviceclasses 156 phone_needsbrew=getattr(profile, 'brew_required', 0) 157 for k,e in self.__data.items(): 158 match=False 159 # check to see if the port supports brew if it is required by phone 160 if phone_needsbrew and not e['mode_brew']: 161 continue 162 if e['manufacturer'] is None or\ 163 e['model'] is None: 164 continue 165 if phone_manufacturer in e['manufacturer'] and \ 166 phone_model==e['model'][:len(phone_model)]: 167 return k
168
169 - def __check_for_other_cdma(self):
170 "If no phone is detected see if any of the scanned ports contain a Brew device" 171 for k,e in self.__data.items(): 172 if e['mode_brew']: 173 return k, 'Other CDMA phone' 174 return None, None
175
176 - def do_get_data(self, port):
177 self.log('Gathering data on port: '+port) 178 r=self.__get_data(port) 179 self.__data_lock.acquire() 180 self.__data[port]=r 181 self.__data_lock.release() 182 self.log('Done on port: '+port)
183
184 - def detect(self, using_port=None, using_model=None):
185 # start the detection process 186 # 1st, get the list of available ports 187 coms=comscan.comscan()+usbscan.usbscan() 188 self.log('coms:'+str(coms)) 189 available_modem_coms=[x['name'] for x in coms if x['available'] \ 190 and x.get('class', None)=='modem'] 191 if not using_port: 192 available_coms=[x['name'] for x in coms if x['available']] 193 else: 194 available_coms=[using_port] 195 available_modem_coms=[x for x in available_coms if x in available_modem_coms] 196 # loop through each port and gather data 197 self.log('Available ports: '+str(available_coms)) 198 self.log('Available modem ports: '+str(available_modem_coms)) 199 # only try those AT commands on modem ports 200 # using threads 201 self.__q_on=True 202 threads=[threading.Thread(target=self.do_get_data, args=(e,)) \ 203 for e in available_modem_coms] 204 for t in threads: 205 t.start() 206 for t in threads: 207 t.join() 208 self.__q_on=False 209 while not self.__q_log.empty(): 210 q=self.__q_log.get_nowait() 211 if isinstance(q, (list, tuple)): 212 self.logdata(*q) 213 else: 214 self.log(q) 215 # non-thread version 216 ## for e in available_modem_coms: 217 ## self.do_get_data(e) 218 # go through each phone and ask it 219 ## pm=phones.phonemodels 220 if using_model: 221 models=[using_model] 222 else: 223 models=phones.phonemodels 224 found_port=found_model=None 225 for model in models: 226 self.log('Checking for model: '+model) 227 module=common.importas(phones.module(model)) 228 # check for detectphone in module.Phone or 229 # phone_model and phone_manufacturer in module.Profile 230 if hasattr(module.Phone, 'detectphone'): 231 if using_port is None: 232 likely_ports=[x['name'] for x in coms if \ 233 x['available'] and \ 234 comdiagnose.islikelyport(x, module)] 235 else: 236 likely_ports=[using_port] 237 self.log('Likely ports:'+str(likely_ports)) 238 found_port=getattr(module.Phone, 'detectphone')(coms, 239 likely_ports, 240 self.__data, 241 module, 242 self) 243 self.log('Detect Phone result: '+`self.__data`) 244 if found_port is not None: 245 self.log('Phone '+model+' returned port:'+`found_port`) 246 # found it 247 found_model=model 248 break 249 found_port=self.__check_profile(module.Profile) 250 if found_port is not None: 251 found_model=model 252 break 253 if found_port is None and using_port is None and using_model is None: 254 # if we're not looking for a specific model on a specific port, 255 # scan for other CDMA phone 256 found_port, found_model=self.__check_for_other_cdma() 257 if found_port is not None and found_model is not None: 258 self.log('Found phone:'+found_model+' port:'+`found_port`) 259 return { 'port': found_port, 'phone_name': found_model, 260 'phone_module': phones.module(found_model), 261 'phone_esn': self.__data[found_port]['esn'] }
262 - def get(self):
263 return self.__data
264