Package phones :: Module com_samsungsphn400
[hide private]
[frames] | no frames]

Source Code for Module phones.com_samsungsphn400

  1  ### BITPIM 
  2  ### 
  3  ### Copyright (C) 2006 Stephen Wood <saw@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: com_samsungsphn400.py 3918 2007-01-19 05:15:12Z djpham $ 
  9   
 10  """Communicate with a Samsung SPH-N400""" 
 11   
 12  # standard modules 
 13  import sha 
 14   
 15  # Bitpim modules 
 16  import p_brew 
 17  import p_samsungsphn400 
 18  import com_brew 
 19  import com_phone 
 20  import prototypes 
 21  import common 
 22  import commport 
 23  import helpids 
 24   
25 -class N400CommandException(Exception):
26 - def __init__(self, errnum, str=None):
27 if str is None: 28 str="N400 Packet Error 0x%02x" % (errnum,) 29 Exception.__init__(self, str) 30 self.errnum=errnum
31 32 numbertypetab=( 'home', 'office', 'cell', 'pager', 'fax', 'none' ) 33
34 -class Phone(com_phone.Phone,com_brew.BrewProtocol):
35 "Talk to a Samsung SPH-N400 cell phone" 36 37 desc="SPH-N400" 38 helpid=helpids.ID_PHONE_SAMSUNGOTHERS 39 MODEPHONEBOOK="modephonebook" 40 41 protocolclass=p_samsungsphn400 42 serialsname='sphn400' 43
44 - def __init__(self, logtarget, commport):
45 com_phone.Phone.__init__(self, logtarget, commport) 46 com_brew.BrewProtocol.__init__(self) 47 self.mode=self.MODENONE
48
49 - def getfundamentals(self, results):
50 self.log("Retrieving fundamental phone information") 51 self.log("Phone serial number") 52 53 self.setmode(self.MODEPHONEBOOK) 54 55 req=p_brew.ESN_req() 56 res=self.sendpbcommand(req, p_brew.ESN_resp) 57 results['uniqueserial']=sha.new('%8.8X' % res.esn).hexdigest() 58 59 return results
60
61 - def _setmodephonebook(self):
62 req=self.protocolclass.firmwarerequest() 63 respc=self.protocolclass.firmwareresponse 64 65 for baud in 38400, 57600: 66 if not self.comm.setbaudrate(baud): 67 continue 68 69 # Perhaps overkill. Will experiment more 70 self.comm.setrts(1) 71 self.comm.setdtr(1) 72 73 self.comm.setbaudrate(baud) 74 self.comm.setrts(0) 75 self.comm.setdtr(1) 76 77 self.comm.setbaudrate(baud) 78 self.comm.setrts(0) 79 self.comm.setdtr(0) 80 81 self.comm.setbaudrate(baud) 82 self.comm.setrts(0) 83 self.comm.setdtr(0) 84 85 self.comm.setbaudrate(baud) 86 self.comm.setrts(0) 87 self.comm.setdtr(0) 88 89 try: 90 self.sendpbcommand(req, respc, callsetmode=False) 91 return True 92 except com_phone.modeignoreerrortypes: 93 pass 94 95 return 0
96
97 - def sendpbcommand(self, request, responseclass, callsetmode=True, writemode=False, numsendretry=0, returnerror=False):
98 if writemode: 99 numretry=3 100 else: 101 numretry=0 102 103 if callsetmode: 104 self.setmode(self.MODEPHONEBOOK) 105 buffer=prototypes.buffer() 106 107 request.writetobuffer(buffer, logtitle="N400 phonebook request") 108 data=buffer.getvalue() 109 firsttwo=data[:2] 110 data=common.pppescape(data+common.crcs(data))+common.pppterminator 111 isendretry=numsendretry 112 while isendretry>=0: 113 try: 114 rdata=self.comm.writethenreaduntil(data, False, common.pppterminator, logreaduntilsuccess=False, numfailures=numretry) 115 break 116 except com_phone.modeignoreerrortypes: 117 if isendretry>0: 118 self.log("Resending request packet...") 119 time.sleep(0.3) 120 else: 121 self.comm.success=False 122 self.mode=self.MODENONE 123 self.raisecommsdnaexception("manipulating the phonebook") 124 isendretry-=1 125 126 self.comm.success=True 127 128 origdata=rdata 129 # sometimes there is junk at the beginning, eg if the user 130 # turned off the phone and back on again. So if there is more 131 # than one 7e in the escaped data we should start after the 132 # second to last one 133 d=rdata.rfind(common.pppterminator,0,-1) 134 if d>=0: 135 self.log("Multiple N400 packets in data - taking last one starting at "+`d+1`) 136 self.logdata("Original N400 data", origdata, None) 137 rdata=rdata[d+1:] 138 139 # turn it back to normal 140 data=common.pppunescape(rdata) 141 142 # Sometimes there is other crap at the beginning. But it might 143 # be a N400 error byte. So strip off bytes from the beginning 144 # until the crc agrees, or we get to the first two bytes of the 145 # request packet. 146 d=data.find(firsttwo) 147 crc=data[-3:-1] 148 crcok=False 149 for i in range(0,d+1): 150 trydata=data[i:-3] 151 if common.crcs(trydata)==crc: 152 crcok=True 153 break 154 155 if not crcok: 156 self.logdata("first two",firsttwo, None) 157 self.logdata("Original N400 data", origdata, None) 158 self.logdata("Working on N400 data", data, None) 159 raise common.CommsDataCorruption("N400 packet failed CRC check", self.desc) 160 161 res=responseclass() 162 if d>0: 163 if d==i: 164 self.log("Junk at beginning of N400 packet, data at "+`d`) 165 self.logdata("Original N400 data", origdata, None) 166 self.logdata("Working on N400 data", data, None) 167 else: 168 if returnerror: 169 res=self.protocolclass.sanyoerror() 170 else: 171 self.log("N400 Error code "+`ord(data[0])`) 172 self.logdata("Samsung phonebook response", data, None) 173 raise N400CommandException(ord(data[0])) 174 175 data=trydata 176 177 # parse data 178 buffer=prototypes.buffer(data) 179 res.readfrombuffer(buffer, logtitle="sanyo phonebook response") 180 return res
181
182 - def getphonebook(self, result):
183 pbook={} 184 185 reqname=self.protocolclass.phonebooknamerequest() 186 reqnumbers=self.protocolclass.phonebooknumbersrequest() 187 count = 0 188 for i in range(2, 251): 189 reqname.slot=i 190 resname=self.sendpbcommand(reqname, self.protocolclass.phonebooknameresponse) 191 if resname.entry.nonzeroifused: 192 entry={} 193 entry['serials']=[ {'sourcetype': self.serialsname, 194 'slot': i, 195 'sourceuniqueid': result['uniqueserial']} ] 196 entry['names']=[{'full': resname.entry.name} ] 197 entry['numbers'] = [] 198 for i in range(7): 199 numptr = resname.entry.numbers[i].pnumber 200 if numptr: 201 reqnumbers.slot=numptr 202 resnumbers=self.sendpbcommand(reqnumbers, self.protocolclass.phonebooknumbersresponse) 203 numhash={'number': resnumbers.entry.number, 'type': numbertypetab[i]} 204 if numptr==resname.entry.pspeed: 205 numhash['speeddial']=i 206 entry['numbers'].append(numhash) 207 208 if resname.entry.pemail: 209 reqnumbers.slot=resname.entry.pemail 210 resnumbers=self.sendpbcommand(reqnumbers, self.protocolclass.phonebooknumbersresponse) 211 entry['emails']=[{'email': resnumbers.entry.number}] 212 213 if resname.entry.purl: 214 reqnumbers.slot=resname.entry.purl 215 resnumbers=self.sendpbcommand(reqnumbers, self.protocolclass.phonebooknumbersresponse) 216 entry['urls']=[{'url': resnumbers.entry.number}] 217 218 self.log("Read entry "+`i`+": "+resname.entry.name) 219 pbook[count]=entry 220 count+=1 221 222 result['phonebook']=pbook 223 return result
224
225 - def getcalendar(self, result):
226 pbook={} 227 result['calendar']=pbook 228 return result
229
230 - def getwallpapers(self, results):
231 pass
232
233 - def getringtones(self, results):
234 pass
235 236
237 -class Profile(com_phone.Profile):
238 protocolclass=Phone.protocolclass 239 serialsname=Phone.serialsname 240 phone_manufacturer='SAMSUNG' 241 phone_model='SPH-N400' 242 usbids_usbtoserial=( 243 ( 0x067b, 0x2303, None), # VID=Prolific, PID=USB to serial 244 ( 0x0403, 0x6001, None), # VID=FTDI, PID=USB to serial 245 ( 0x0731, 0x2003, None), # VID=Susteen, PID=Universal USB to serial 246 ) 247 usbids=usbids_usbtoserial 248 249 deviceclasses=("serial",) 250
251 - def __init__(self):
253 254 _supportedsyncs=( 255 ('phonebook', 'read', None), 256 )
257