Package phones ::
Module com_samsungspha900
|
|
1
2
3
4
5
6
7
8
9
10 """Communicate with a Samsung SPH-A900"""
11
12 import sha
13 import re
14 import struct
15
16 import common
17 import commport
18 import p_brew
19 import p_samsungspha900
20 import com_brew
21 import com_phone
22 import prototypes
23 import helpids
24
25 numbertypetab=('cell','home','office','pager','none')
26
27 -class Phone(com_phone.Phone, com_brew.BrewProtocol):
28 "Talk to a Samsung SPH-A900 phone"
29
30 desc="SPH-A900"
31 helpid=helpids.ID_PHONE_SAMSUNGOTHERS
32 protocolclass=p_samsungspha900
33 serialsname='spha900'
34
35 MODEPHONEBOOK="modephonebook"
36
37
38
39 imagelocations=(
40
41
42 (400, "cam/dldJpeg", "camera", 100, 124),
43 (300, "cam/jpeg", "camera", 100, 124),
44 )
45
46 ringtonelocations=(
47
48 )
49
50
51 - def __init__(self, logtarget, commport):
56
73
74 - def sendpbcommand(self, request, responseclass, callsetmode=True, writemode=False, numsendretry=0, returnerror=False):
75 if writemode:
76 numretry=3
77 else:
78 numretry=0
79
80 if callsetmode:
81 self.setmode(self.MODEPHONEBOOK)
82 buffer=prototypes.buffer()
83
84 request.writetobuffer(buffer, logtitle="Samsung phonebook request")
85 data=buffer.getvalue()
86 firsttwo=data[:2]
87 data=common.pppescape(data+common.crcs(data))+common.pppterminator
88 isendretry=numsendretry
89 while isendretry>=0:
90 try:
91 rdata=self.comm.writethenreaduntil(data, False, common.pppterminator, logreaduntilsuccess=False, numfailures=numretry)
92 break
93 except com_phone.modeignoreerrortypes:
94 if isendretry>0:
95 self.log("Resending request packet...")
96 time.sleep(0.3)
97 else:
98 self.comm.success=False
99 self.mode=self.MODENONE
100 self.raisecommsdnaexception("manipulating the phonebook")
101 isendretry-=1
102
103 self.comm.success=True
104
105 origdata=rdata
106
107
108
109
110 d=rdata.rfind(common.pppterminator,0,-1)
111 if d>=0:
112 self.log("Multiple Samsung packets in data - taking last one starting at "+`d+1`)
113 self.logdata("Original Samsung data", origdata, None)
114 rdata=rdata[d+1:]
115
116
117 data=common.pppunescape(rdata)
118
119
120
121
122
123 d=data.find(firsttwo)
124 crc=data[-3:-1]
125 crcok=False
126 for i in range(0,d+1):
127 trydata=data[i:-3]
128 if common.crcs(trydata)==crc:
129 crcok=True
130 break
131
132 if not crcok:
133 self.logdata("first two",firsttwo, None)
134 self.logdata("Original Sanyo data", origdata, None)
135 self.logdata("Working on Sanyo data", data, None)
136 raise common.CommsDataCorruption("Sanyo packet failed CRC check", self.desc)
137
138 res=responseclass()
139 if d>0:
140 if d==i:
141 self.log("Junk at beginning of Sanyo packet, data at "+`d`)
142 self.logdata("Original Sanyo data", origdata, None)
143 self.logdata("Working on Sanyo data", data, None)
144 else:
145 if returnerror:
146 res=self.protocolclass.sanyoerror()
147 else:
148 self.log("Sanyo Error code "+`ord(data[0])`)
149 self.logdata("sanyo phonebook response", data, None)
150 raise SanyoCommandException(ord(data[0]))
151
152 data=trydata
153
154
155 buffer=prototypes.buffer(data)
156 res.readfrombuffer(buffer, logtitle="sanyo phonebook response")
157 return res
158
160 """Gets information fundamental to interopating with the phone and UI."""
161 results['uniqueserial']=1
162 return results
163
165 pbook={}
166
167 count = 0
168 numcount = 0
169 numemail = 0
170 numurl = 0
171
172 reqname=self.protocolclass.namerequest()
173 reqnumber=self.protocolclass.numberrequest()
174 for slot in range(1,self.protocolclass.NUMPHONEBOOKENTRIES+1):
175 reqname.slot=slot
176 resname=self.sendpbcommand(reqname, self.protocolclass.nameresponse)
177 bitmask=resname.entry.bitmask
178 if bitmask:
179 entry={}
180 name=resname.entry.name
181 entry['serials']=[ {'sourcetype': self.serialsname,
182
183 'slot': slot,
184 'sourceuniqueid': result['uniqueserial']} ]
185 entry['names']=[{'full':name}]
186 entry['numbers']=[]
187 bit=1
188 print resname.entry.p2,name
189 for num in range(self.protocolclass.NUMPHONENUMBERS):
190 bit <<= 1
191 if bitmask & bit:
192 numslot=resname.entry.numberps[num].slot
193 reqnumber.slot=numslot
194 resnumber=self.sendpbcommand(reqnumber, self.protocolclass.numberresponse)
195 numhash={'number':resnumber.entry.num, 'type' : self.numbertypetab[resnumber.entry.numbertype-1]}
196 entry['numbers'].append(numhash)
197
198 print " ",self.numbertypetab[resnumber.entry.numbertype-1]+": ",numslot,resnumber.entry.num
199 bit <<= 1
200 if bitmask & bit:
201 reqnumber.slot=resname.entry.emailp
202 resnumber=self.sendpbcommand(reqnumber, self.protocolclass.numberresponse)
203 print " Email: ",resname.entry.emailp,resnumber.entry.num
204 entry['emails']=[]
205 entry['emails'].append({'email':resnumber.entry.num})
206 bit <<= 1
207 if bitmask & bit:
208 reqnumber.slot=resname.entry.urlp
209 resnumber=self.sendpbcommand(reqnumber, self.protocolclass.numberresponse)
210 print " URL: ",resname.entry.urlp,resnumber.entry.num
211 entry['urls']=[{'url':resnumber.entry.num}]
212 if resname.entry.nickname:
213 print " Nick: ",resname.entry.nickname
214 if resname.entry.memo:
215 print " Memo ",resname.entry.memo
216 entry['memos']=[{'memo':resname.entry.memo}]
217
218 pbook[count]=entry
219 self.progress(slot, self.protocolclass.NUMPHONEBOOKENTRIES+1, name)
220 count+=1
221 numcount+=len(entry['numbers'])
222 if entry.has_key('emails'):
223 numemail+=len(entry['emails'])
224 if entry.has_key('urls'):
225 numurl+=len(entry['urls'])
226
227 self.progress(slot,slot,"Phonebook read completed")
228 self.log("Phone contains "+`count`+" contacts, "+`numcount`+" phone numbers, "+`numemail`+" Emails, "+`numurl`+" URLs")
229 result['phonebook']=pbook
230
231 return pbook
232
234 """Loop until phone status indicates ready to write"""
235 for i in range(100):
236 req=self.protocolclass.statusrequest()
237 res=self.sendpbcommand(req, self.protocolclass.statusresponse)
238
239 if res.ready==res.readyvalue:
240 return
241 time.sleep(0.1)
242
243 self.log("Phone did not transfer to ready to write state")
244 self.log("Waiting a bit longer and trying anyway")
245 return
246
248 newphonebook={}
249
250 nump=2
251 urlp=0
252 memop=0
253 addressp=0
254 emailp=0
255 slotsused=1
256
257 namemap=[]
258 contactmap=[]
259 urlmap=[]
260
261 pbook=data['phonebook']
262 self.log("Putting phone into write mode")
263 req=self.protocolclass.beginendupdaterequest()
264 req.beginend=1
265 res=self.sendpbcommand(req, self.protocolclass.beginendupdateresponse, writemode=True)
266
267
268 req=self.protocolclass.writeenable()
269 try:
270 res=self.sendpbcommand(req, self.protocolclass.writeenableresponse, writemode=True)
271 except:
272 pass
273
274 keys=pbook.keys()
275 keys.sort()
276 nnames = len(keys)
277
278 reqnumber=self.protocolclass.numberupdaterequest()
279 for ikey in keys:
280 ii=pbook[ikey]
281 slot=slotsused
282 slotsused+=1
283
284 reqname=self.protocolclass.nameupdaterequest()
285 reqname.slot=slot
286 name=ii['name']
287 self.progress(slot-1, nnames, "Writing "+name)
288 self.log("Writing "+`name`+" to slot "+`slot`)
289 namemap.append((slot,name))
290
291 reqname.entry.name=name
292 reqname.entry.name_len=ii['name_len']
293
294 bitmask=0
295 bit=1
296 for numindex in range(len(ii['numbers'])):
297 reqnumber.slot=nump
298 reqnumber.entry.num=ii['numbers'][numindex]
299 reqnumber.entry.numlen=len(ii['numbers'][numindex])
300 numbertype=ii['numbertypes'][numindex]
301 reqnumber.entry.numbertype=numbertype
302 reqnumber.entry.pos=numindex+1
303
304 resnumber=self.sendpbcommand(reqnumber,self.protocolclass.numberresponse)
305
306 reqname.entry.numberps.append(nump)
307 bitmask |= bit
308 bit <<= 1
309
310 nump+=1
311
312 for numindex in range(len(ii['numbers']),self.protocolclass.NUMPHONENUMBERS):
313 reqname.entry.numberps.append(0)
314
315 reqname.entry.bitmask=bitmask
316 resname=self.sendpbcommand(reqname,self.protocolclass.nameresponse)
317
318
319 for slot in range(nump,self.protocolclass.NUMPHONEBOOKENTRIES+2):
320 reqnumber.slot=slot
321 reqnumber.entry.num=''
322 reqnumber.entry.numlen=0
323 reqnumber.entry.numbertype=0
324 reqnumber.entry.pos=0
325 resnumber=self.sendpbcommand(reqnumber,self.protocolclass.numberresponse)
326 for slot in range(slotsused,self.protocolclass.NUMPHONEBOOKENTRIES+1):
327 reqname=self.protocolclass.nameupdaterequest()
328 reqname.slot=slot
329 reqname.entry.name=''
330 reqname.entry.name_len=0
331 for numindex in range(self.protocolclass.NUMPHONENUMBERS):
332 reqname.entry.numberps.append(0)
333 reqname.entry.bitmask=0
334 resname=self.sendpbcommand(reqname,self.protocolclass.nameresponse)
335
336 self.progress(1,1, "Phonebook write completed")
337
338 req=self.protocolclass.beginendupdaterequest()
339 req.beginend=2
340 res=self.sendpbcommand(req, self.protocolclass.beginendupdateresponse, writemode=True)
341 req=p_brew.setmodemmoderequest()
342 res=self.sendpbcommand(req, p_brew.setmoderesponse, writemode=True)
343
344
347
348 getwallpapers=None
349 getringtones=None
350
351
353 deviceclasses=("modem",)
354
355 usbids=( ( 0x04e8, 0x6601, 1),
356 )
357
358 deviceclasses=("modem","serial")
359
360 protocolclass=Phone.protocolclass
361 serialsname=Phone.serialsname
362 phone_manufacturer='SAMSUNG'
363 phone_model='SPH-A900/154'
364
365 _supportedsyncs=(
366 ('phonebook', 'read', None),
367 ('phonebook', 'write', 'OVERWRITE'),
368 )
369
373
375 "Converts the data to what will be used by the phone"
376
377 results={}
378
379 slotsused={}
380 pb=data['phonebook']
381 for pbentry in pb:
382 entry=pb[pbentry]
383 slot=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'slot', -1)
384 if(slot > 0 and slot <= self.protocolclass.NUMPHONEBOOKENTRIES):
385 slotsused[slot]=1
386
387 lastunused=0
388
389 for pbentry in pb:
390 e={}
391 entry=pb[pbentry]
392 try:
393 try:
394 e['name']=helper.getfullname(entry.get('names', []),1,1,20)[0]
395 except:
396 e['name']=''
397 e['name_len']=len(e['name'])
398 if len(e['name'])==0:
399 print "Entry with no name"
400
401
402
403
404
405
406
407
408
409
410 e['group']=0
411
412 serial1=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'slot', -1)
413
414 if(slot > 0 and slot <= self.protocolclass.NUMPHONEBOOKENTRIES):
415 e['slot']=slot
416 else:
417 while(slotsused.has_key(lastunused)):
418 lastunused+=1
419 if(lastunused > self.protocolclass.NUMPHONEBOOKENTRIES):
420 raise helper.ConversionFailed()
421 e['slot']=lastunused
422 slotsused[lastunused]=1
423
424
425
426
427
428 e['memo']=helper.makeone(helper.getmemos(entry.get('memos', []), 0,1,self.protocolclass.MAXMEMOLEN), "")
429
430 numbers=helper.getnumbers(entry.get('numbers', []),0,self.protocolclass.NUMPHONENUMBERS)
431 e['numbertypes']=[]
432 e['numbers']=[]
433 e['numberspeeds']=[]
434
435 for numindex in range(len(numbers)):
436 num=numbers[numindex]
437 type=num['type']
438 numtype=len(self.numbertypetab)
439 for i,t in enumerate(self.numbertypetab):
440 if type==t:
441 numtype=i+1
442 break
443
444 e['numbertypes'].append(numtype)
445
446
447 number=self.phonize(num['number'])
448 e['numbers'].append(number)
449
450
451
452
453
454
455
456
457
458
459
460
461
462 e['ringtone']=helper.getringtone(entry.get('ringtones', []), 'call', None)
463 e['wallpaper']=helper.getwallpaper(entry.get('wallpapers', []), 'call', None)
464
465 e['secret']=helper.getflag(entry.get('flags', []), 'secret', False)
466 results[pbentry]=e
467
468 except helper.ConversionFailed:
469
470 print "No Free Slot for "+e['name']
471 continue
472
473 data['phonebook']=results
474 return data
475