0001 ### BITPIM 0002 ### 0003 ### Copyright (C) 2004 Joe Pham <djpham@bitpim.org> 0004 ### 0005 ### This program is free software; you can redistribute it and/or modify 0006 ### it under the terms of the BitPim license as detailed in the LICENSE file. 0007 ### 0008 ### $Id: phone_detect.py 4656 2008-08-02 15:57:20Z hjelmn $ 0009 0010 """ 0011 Auto detect of phones. 0012 This module provides functionality to perform auto-detection of connected phone. 0013 To implement auto-detection for your phone, perform the following: 0014 0015 1. If your phone can be determined by examining the Phone Manufacturer and 0016 Phone Model values returned by +GMI and +GMM commands, just set the following 0017 attributes in your Profile class: 0018 0019 phone_manufacturer='string' 0020 phone_model='string' 0021 0022 The phone_manufacturer attribute will be checked for substring ie, 'SAMSUNG' in 0023 'SAMSUNG ELECTRONICS CO.,LTD.'; phone_model must match exactly. 0024 0025 2. If your phone detection scheme is more complex, define a staticmethod 0026 'detectphone' in your Phone class. The declaration of the method is: 0027 0028 def detectphone(ports, likely_ports, detect_dict) 0029 0030 ports: list of available ports returned from comscan 0031 likely_ports: list of likely ports as returned from comdiagnose.islikelyport, 0032 ie ['com1', 'com2']. 0033 where detect_dict is a dict with the following key/value pairs: 0034 'port': { 0035 'mode_modem': True if the phone can be set to modem mode, False otherwise 0036 'mode_brew': True if the phone can be set to DM mode, False otherwise. This 0037 value is not currently set since I'm not sure all phones can 0038 transition out of DM mode. 0039 'manufacturer': string value returned by +GMI 0040 'model': string value returned by +GMM 0041 'firmware_version': string value returned by +GMR 0042 'esn': ESN value of this phone, will be used to associate a name with it. 0043 'firmwareresponse': response data based on BREW firmwarerequest command. 0044 Currently not implemented. 0045 } 0046 0047 If a possitive identification is made, method detectphone should return the 0048 port associated with that phone, otherwise just return None. 0049 0050 """ 0051 0052 # standard modules 0053 import Queue 0054 import threading 0055 0056 # wx modules 0057 0058 # BitPim modules 0059 import comdiagnose 0060 import common 0061 import commport 0062 import comscan 0063 import phones 0064 import usbscan 0065 0066 class DetectPhone(object): 0067 __default_timeout=1 0068 def __init__(self, log=None): 0069 # get standard commport parameters 0070 self.__log=log 0071 self.__data={} 0072 self.__data_lock=threading.Lock() 0073 self.__q_log=Queue.Queue(0) 0074 self.__q_on=False 0075 0076 def log(self, log_str): 0077 if self.__log is None: 0078 print log_str 0079 else: 0080 if self.__q_on: 0081 self.__q_log.put_nowait(log_str) 0082 else: 0083 self.__log.log(log_str) 0084 def logdata(self, log_str, log_data, klass=None, data_type=None): 0085 if self.__log is None: 0086 print log_str,log_data, klass 0087 else: 0088 if self.__q_on: 0089 self.__q_log.put_nowait((log_str, log_data, klass, data_type)) 0090 else: 0091 self.__log.logdata(log_str, log_data, klass, data_type) 0092 0093 def progress(self, pos, max, desc=""): 0094 if self.__log: 0095 self.__log.progress(pos, max, desc) 0096 0097 def __get_mode_modem(self, comm): 0098 """ check if this port supports mode modem""" 0099 try: 0100 resp=comm.sendatcommand('E0V1') 0101 return True 0102 except: 0103 return False 0104 def __send_at_and_get(self, comm, cmd): 0105 try: 0106 resp=comm.sendatcommand(cmd) 0107 return ': '.join(resp[0].split(': ')[1:]) 0108 except: 0109 return None 0110 def __get_manufacturer(self, comm): 0111 return self.__send_at_and_get(comm, '+GMI') 0112 def __get_model(self, comm): 0113 return self.__send_at_and_get(comm, '+GMM') 0114 def __get_firmware_version(self, comm): 0115 return self.__send_at_and_get(comm, '+GMR') 0116 def __get_esn(self, comm): 0117 return self.__send_at_and_get(comm, '+GSN') 0118 def __get_mode_brew(self, comm): 0119 raise NotImplementedError 0120 ## try: 0121 ## resp=comm.sendatcommand('$QCDMG') 0122 ## return True 0123 ## except: 0124 ## return False 0125 def __get_firmware_response(self, comm): 0126 raise NotImplementedError 0127 0128 def __get_data(self, port): 0129 r={ 'mode_modem': False, 'mode_brew': False, 0130 'manufacturer': None, 'model': None, 'firmware_version': None, 0131 'esn': None, 'firmwareresponse': None } 0132 try: 0133 c=commport.CommConnection(self, port, 0134 timeout=self.__default_timeout) 0135 except: 0136 self.log('Failed to open port: '+port) 0137 return r 0138 r['mode_modem']=self.__get_mode_modem(c) 0139 if r['mode_modem']: 0140 # in modem mode, ok to try other info 0141 r['manufacturer']=self.__get_manufacturer(c) 0142 r['model']=self.__get_model(c) 0143 r['firmware_version']=self.__get_firmware_version(c) 0144 r['esn']=self.__get_esn(c) 0145 c.close() 0146 return r 0147 0148 def __check_profile(self, profile): 0149 if not hasattr(profile, 'phone_manufacturer') or \ 0150 not hasattr(profile, 'phone_model'): 0151 return None 0152 res=None 0153 phone_model=profile.phone_model 0154 phone_manufacturer=profile.phone_manufacturer 0155 deviceclasses=profile.deviceclasses 0156 phone_needsbrew=getattr(profile, 'brew_required', 0) 0157 for k,e in self.__data.items(): 0158 match=False 0159 # check to see if the port supports brew if it is required by phone 0160 if phone_needsbrew and not e['mode_brew']: 0161 continue 0162 if e['manufacturer'] is None or\ 0163 e['model'] is None: 0164 continue 0165 if phone_manufacturer in e['manufacturer'] and \ 0166 phone_model==e['model'][:len(phone_model)]: 0167 return k 0168 0169 def __check_for_other_cdma(self): 0170 "If no phone is detected see if any of the scanned ports contain a Brew device" 0171 for k,e in self.__data.items(): 0172 if e['mode_brew']: 0173 return k, 'Other CDMA phone' 0174 return None, None 0175 0176 def do_get_data(self, port): 0177 self.log('Gathering data on port: '+port) 0178 r=self.__get_data(port) 0179 self.__data_lock.acquire() 0180 self.__data[port]=r 0181 self.__data_lock.release() 0182 self.log('Done on port: '+port) 0183 0184 def detect(self, using_port=None, using_model=None): 0185 # start the detection process 0186 # 1st, get the list of available ports 0187 coms=comscan.comscan()+usbscan.usbscan() 0188 self.log('coms:'+str(coms)) 0189 available_modem_coms=[x['name'] for x in coms if x['available'] \ 0190 and x.get('class', None)=='modem'] 0191 if not using_port: 0192 available_coms=[x['name'] for x in coms if x['available']] 0193 else: 0194 available_coms=[using_port] 0195 available_modem_coms=[x for x in available_coms if x in available_modem_coms] 0196 # loop through each port and gather data 0197 self.log('Available ports: '+str(available_coms)) 0198 self.log('Available modem ports: '+str(available_modem_coms)) 0199 # only try those AT commands on modem ports 0200 # using threads 0201 self.__q_on=True 0202 threads=[threading.Thread(target=self.do_get_data, args=(e,)) \ 0203 for e in available_modem_coms] 0204 for t in threads: 0205 t.start() 0206 for t in threads: 0207 t.join() 0208 self.__q_on=False 0209 while not self.__q_log.empty(): 0210 q=self.__q_log.get_nowait() 0211 if isinstance(q, (list, tuple)): 0212 self.logdata(*q) 0213 else: 0214 self.log(q) 0215 # non-thread version 0216 ## for e in available_modem_coms: 0217 ## self.do_get_data(e) 0218 # go through each phone and ask it 0219 ## pm=phones.phonemodels 0220 if using_model: 0221 models=[using_model] 0222 else: 0223 models=phones.phonemodels 0224 found_port=found_model=None 0225 for model in models: 0226 self.log('Checking for model: '+model) 0227 module=common.importas(phones.module(model)) 0228 # check for detectphone in module.Phone or 0229 # phone_model and phone_manufacturer in module.Profile 0230 if hasattr(module.Phone, 'detectphone'): 0231 if using_port is None: 0232 likely_ports=[x['name'] for x in coms if \ 0233 x['available'] and \ 0234 comdiagnose.islikelyport(x, module)] 0235 else: 0236 likely_ports=[using_port] 0237 self.log('Likely ports:'+str(likely_ports)) 0238 found_port=getattr(module.Phone, 'detectphone')(coms, 0239 likely_ports, 0240 self.__data, 0241 module, 0242 self) 0243 self.log('Detect Phone result: '+`self.__data`) 0244 if found_port is not None: 0245 self.log('Phone '+model+' returned port:'+`found_port`) 0246 # found it 0247 found_model=model 0248 break 0249 found_port=self.__check_profile(module.Profile) 0250 if found_port is not None: 0251 found_model=model 0252 break 0253 if found_port is None and using_port is None and using_model is None: 0254 # if we're not looking for a specific model on a specific port, 0255 # scan for other CDMA phone 0256 found_port, found_model=self.__check_for_other_cdma() 0257 if found_port is not None and found_model is not None: 0258 self.log('Found phone:'+found_model+' port:'+`found_port`) 0259 return { 'port': found_port, 'phone_name': found_model, 0260 'phone_module': phones.module(found_model), 0261 'phone_esn': self.__data[found_port]['esn'] } 0262 def get(self): 0263 return self.__data 0264
Generated by PyXR 0.9.4