Package phones ::
Module com_samsungsphm300media
|
|
1
2
3
4
5
6
7
8
9
10 """Communicate with the Samsung SPH-M300 through the diag port (Diag)"""
11
12 import sha
13
14 import common
15 import commport
16 import com_brew
17 import com_phone
18 import com_samsung_packet
19 import fileinfo
20 import helpids
21 import prototypes
22 import p_brew
23 import p_samsungsphm300
24 import re
25
26 -class Phone(com_phone.Phone, com_brew.BrewProtocol):
27 "Talk to a Samsung SPH-M300 (Diag) phone"
28
29 desc="SPH-M300"
30 helpid=helpids.ID_PHONE_SAMSUNGSPHM300
31 protocolclass=p_samsungsphm300
32 serialsname='sphm300'
33
34 builtinringtones=tuple(['Ring %d'%x for x in range(1, 11)])+\
35 ('After The Summer', 'Focus on It', 'Get Happy',
36 'Here It Comes', 'In a Circle', 'Look Back',
37 'Right Here', 'Secret Life', 'Shadow of Your Smile',
38 'Sunday Morning', 'Default')
39
40 builtinimages=tuple(['People %d'%x for x in range(1, 11)])+\
41 tuple(['Animal %d'%x for x in range(1, 11)])+\
42 ('No Image',)
43 numbertypetab=('cell', 'home', 'office', 'pager', 'fax')
44 builtingroups=('Unassigned', 'Family', 'Friends', 'Colleagues',
45 'VIPs', None)
46
47 __audio_mimetype={ 'mid': 'audio/midi', 'qcp': 'audio/vnd.qcelp', 'pmd': 'application/x-pmd'}
48 __image_mimetype={ 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'gif': 'image/gif', 'bmp': 'image/bmp', 'png': 'image/png'}
49
50 - def __init__(self, logtarget, commport):
54
66 """Gets information fundamental to interopating with the phone and UI."""
67 self.log("Retrieving fundamental phone information")
68 self.log("Phone serial number")
69 results['uniqueserial']=sha.new(self.get_brew_esn()).hexdigest()
70 results['groups']=self.read_groups()
71 self.getmediaindex(results)
72 return results
73
91 """Get the indices of builtin ringtones and wallpapers"""
92 for _idx,_item in enumerate(self.builtinringtones):
93 rt_index[_idx]={ 'name': _item,
94 'origin': 'builtin' }
95 for _idx, _item in enumerate(self.builtinimages):
96 wp_index[_idx]={ 'name': _item,
97 'origin': 'builtin' }
117
127
129 _media={}
130 _rt_index=results.get('ringtone-index', {})
131 for _item in _rt_index.values():
132 if _item.get('origin', None)=='ringers':
133 _media[_item['name']]=self.getfilecontents(_item['location'],
134 True)
135 results['ringtone']=_media
136
155
156
157 - def makegcd(self, filename,size,mimetable):
158 "Build a GCD file for filename"
159 ext=common.getext(filename.lower())
160 try:
161 mimetype=mimetable[ext]
162 except:
163 return ""
164
165 noextname=common.stripext(filename)
166 gcdcontent="Content-Type: "+mimetype+"\nContent-Name: "+noextname+"\nContent-Version: 1.0\nContent-Vendor: BitPim\nContent-URL: file:"+filename+"\nContent-Size: "+`size`+"\n\n\n"
167 return gcdcontent
168
170 dircache=self.DirCache(self)
171 media_prefix=self.protocolclass.RINGERPREFIX
172 endtransactionpath=self.protocolclass.ENDTRANSACTION
173 media=result.get('ringtone', {})
174 media_index=result.get('ringtone-index', {})
175 media_names=[x['name'] for x in media.values() \
176 if x.get('origin', None)=='ringers' ]
177 index_names=[x['name'] for x in media_index.values() \
178 if x.get('origin', None)=='ringers' ]
179 if merge:
180 del_names=[]
181 else:
182 del_names=[common.stripext(x) for x in index_names if x not in media_names]
183 gcdpattern=re.compile("[\n\r]Content-Name: +(.*?)[\n\r]")
184 new_names=[x for x in media_names if x not in index_names]
185
186 progressmax=len(del_names)+len(new_names)
187 progresscur=0
188 self.log("Writing ringers")
189 self.progress(progresscur, progressmax, "Writing ringers")
190
191 for icnt in range(1,101):
192 if not (new_names or del_names):
193 break
194 fname=media_prefix+`icnt`
195 fnamegcd=media_prefix+`icnt`+".gcd"
196 fstat=dircache.stat(fnamegcd)
197 if del_names and fstat:
198
199 gcdcontents=dircache.readfile(fnamegcd)
200 thisfile=gcdpattern.search(gcdcontents).groups()[0]
201 if thisfile in del_names:
202 self.log("Deleting ringer "+thisfile)
203 self.progress(progresscur, progressmax, "Deleting ringer "+thisfile)
204 progresscur+=1
205 dircache.rmfile(fname)
206 dircache.rmfile(fnamegcd)
207 del_names.remove(thisfile)
208 fstat=False
209 if new_names and not fstat:
210 newname=new_names.pop()
211 contents=""
212 for k in media.keys():
213 if media[k]['name']==newname:
214 contents=media[k]['data']
215 break
216
217 contentsize=len(contents)
218 if contentsize:
219 gcdcontents=self.makegcd(newname,contentsize,self.__audio_mimetype)
220 self.log("Writing ringer "+newname)
221 self.progress(progresscur, progressmax, "Deleting ringer "+newname)
222 progresscur+=1
223 dircache.writefile(fname,contents)
224 dircache.writefile(fnamegcd,gcdcontents)
225
226 fstat=dircache.stat(endtransactionpath)
227 self.log("Finished writing ringers")
228 self.progress(progressmax, progressmax, "Finished writing ringers")
229 if fstat:
230 dircache.rmfile(endtransactionpath)
231 result['rebootphone']=True
232
233 return
234
236 dircache=self.DirCache(self)
237 media_prefix=self.protocolclass.WALLPAPERPREFIX
238 endtransactionpath=self.protocolclass.ENDTRANSACTION
239 media=result.get('wallpapers', {})
240 media_index=result.get('wallpaper-index', {})
241 media_names=[x['name'] for x in media.values() \
242 if x.get('origin', None)=='images' ]
243 index_names=[x['name'] for x in media_index.values() \
244 if x.get('origin', None)=='images' ]
245 if merge:
246 del_names=[]
247 else:
248 del_names=[common.stripext(x) for x in index_names if x not in media_names]
249 gcdpattern=re.compile("[\n\r]Content-Name: +(.*?)[\n\r]")
250 new_names=[x for x in media_names if x not in index_names]
251
252 progressmax=len(del_names)+len(new_names)
253 progresscur=0
254 self.log("Writing images")
255 self.progress(progresscur, progressmax, "Writing images")
256
257 for icnt in range(1,101):
258 if not (new_names or del_names):
259 break
260 fname=media_prefix+`icnt`
261 fnamegcd=media_prefix+`icnt`+".gcd"
262 fstat=dircache.stat(fnamegcd)
263 if del_names and fstat:
264
265 gcdcontents=dircache.readfile(fnamegcd)
266 thisfile=gcdpattern.search(gcdcontents).groups()[0]
267 if thisfile in del_names:
268 self.log("Deleting image "+thisfile)
269 self.progress(progresscur, progressmax, "Deleting image "+thisfile)
270 progresscur+=1
271 dircache.rmfile(fname)
272 dircache.rmfile(fnamegcd)
273 del_names.remove(thisfile)
274 fstat=False
275 if new_names and not fstat:
276 newname=new_names.pop()
277 contents=""
278 for k in media.keys():
279 if media[k]['name']==newname:
280 contents=media[k]['data']
281 break
282
283 contentsize=len(contents)
284 if contentsize:
285 gcdcontents=self.makegcd(newname,contentsize,self.__image_mimetype)
286 self.log("Writing image "+newname)
287 self.progress(progresscur, progressmax, "Deleting image "+newname)
288 progresscur+=1
289 dircache.writefile(fname,contents)
290 dircache.writefile(fnamegcd,gcdcontents)
291
292 fstat=dircache.stat(endtransactionpath)
293 self.log("Finished writing images")
294 self.progress(progressmax, progressmax, "Finished writing images")
295 if fstat:
296 dircache.rmfile(endtransactionpath)
297 result['rebootphone']=True
298
299 return
300
301
303 req=p_brew.memoryconfigrequest()
304 respc=p_brew.memoryconfigresponse
305
306 for baud in 0, 38400, 115200:
307 if baud:
308 if not self.comm.setbaudrate(baud):
309 continue
310 try:
311 self.sendbrewcommand(req, respc, callsetmode=False)
312 return True
313 except com_phone.modeignoreerrortypes:
314 pass
315 return False
316
324
332
333 @classmethod
334 - def detectphone(_, coms, likely_ports, res, _module, _log):
335 if not likely_ports:
336
337 return None
338 for port in likely_ports:
339 if not res.has_key(port):
340 res[port]={ 'mode_modem': None, 'mode_brew': None,
341 'manufacturer': None, 'model': None,
342 'firmware_version': None, 'esn': None,
343 'firmwareresponse': None }
344 try:
345 if res[port]['mode_brew']==False or \
346 res[port]['model']:
347
348
349 continue
350 p=_module.Phone(_log, commport.CommConnection(_log, port, timeout=1))
351 if res[port]['mode_brew'] is None:
352 res[port]['mode_brew']=p.is_mode_brew()
353 if res[port]['mode_brew']:
354 p.get_detect_data(res[port])
355 p.eval_detect_data(res[port])
356 p.comm.close()
357 except:
358 if __debug__:
359 raise
360
361 getphonebook=NotImplemented
362 getcalendar=NotImplemented
363
364 parentprofile=com_samsung_packet.Profile
366 protocolclass=Phone.protocolclass
367 serialsname=Phone.serialsname
368
369 WALLPAPER_WIDTH=128
370 WALLPAPER_HEIGHT=160
371
372 MAX_RINGTONE_BASENAME_LENGTH=19
373 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ."
374 RINGTONE_LIMITS= {
375 'MAXSIZE': 250000
376 }
377 phone_manufacturer='SAMSUNG'
378 phone_model='SPH-M300MEDIA'
379 numbertypetab=Phone.numbertypetab
380
381 usbids=( ( 0x04e8, 0x6640, 2),)
382 deviceclasses=("serial",)
383
384 ringtoneorigins=('ringers',)
385 excluded_ringtone_origins=('ringers',)
386
387 excluded_wallpaper_origins=('camera', 'camera-fullsize')
388 imageorigins={}
389 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images"))
390 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "camera"))
391 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "camera-fullsize"))
394
395 imagetargets={}
396 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper",
397 {'width': 128, 'height': 160, 'format': "JPEG"}))
400
401 _supportedsyncs=(
402 ('wallpaper', 'read', None),
403 ('wallpaper', 'write', None),
404 ('ringtone', 'read', None),
405 ('ringtone', 'write', None),
406 )
407
408 __audio_ext={ 'MIDI': 'mid', 'PMD': 'pmd', 'QCP': 'qcp' }
409 - def QueryAudio(self, origin, currentextension, afi):
419
420 field_color_data={
421 'phonebook': {
422 'name': {
423 'first': 0, 'middle': 0, 'last': 0, 'full': 0,
424 'nickname': 0, 'details': 0 },
425 'number': {
426 'type': 0, 'speeddial': 0, 'number': 5, 'details': 0 },
427 'email': 0,
428 'address': {
429 'type': 0, 'company': 0, 'street': 0, 'street2': 0,
430 'city': 0, 'state': 0, 'postalcode': 0, 'country': 0,
431 'details': 0 },
432 'url': 0,
433 'memo': 0,
434 'category': 0,
435 'wallpaper': 0,
436 'ringtone': 0,
437 'storage': 0,
438 },
439 'calendar': {
440 'description': False, 'location': False, 'allday': False,
441 'start': False, 'end': False, 'priority': False,
442 'alarm': False, 'vibrate': False,
443 'repeat': False,
444 'memo': False,
445 'category': False,
446 'wallpaper': False,
447 'ringtone': False,
448 },
449 'memo': {
450 'subject': False,
451 'date': False,
452 'secret': False,
453 'category': False,
454 'memo': False,
455 },
456 'todo': {
457 'summary': False,
458 'status': False,
459 'due_date': False,
460 'percent_complete': False,
461 'completion_date': False,
462 'private': False,
463 'priority': False,
464 'category': False,
465 'memo': False,
466 },
467 }
468