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

Source Code for Module phones.com_samsungschu750

  1  ### BITPIM 
  2  ### 
  3  ### Copyright (C) 2009 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: com_samsungschu750.py 4778 2010-01-08 04:21:54Z djpham $ 
  9   
 10  """Communicate with the Samsung SCH-U750 (Alias 2) Phone""" 
 11   
 12  # System modules 
 13   
 14  # BitPim modules 
 15  import common 
 16  import commport 
 17  import com_brew 
 18  import com_samsungschu470 as schu470 
 19  import p_samsungschu750 as p_schu750 
 20  import helpids 
 21  import prototypes 
 22   
 23  parentphone=schu470.Phone 
24 -class Phone(com_brew.RealBrewProtocol2, parentphone):
25 desc='SCH-U750' 26 helpid=helpids.ID_PHONE_SAMSUNGSCHU750 27 protocolclass=p_schu750 28 serialsname='schu750' 29 30 my_model='SCH-U750/DM' 31 my_manufacturer='SAMSUNG' 32 detected_model='U750' 33 34 ringtone_noring_range='range_tones_preloaded_el_22' 35 ringtone_default_range='range_tones_preloaded_el_01' 36 builtin_ringtones={ 37 'VZW Default Tone': ringtone_default_range, 38 'Animato': 'range_tones_preloaded_el_02', 39 'Belly Dance': 'range_tones_preloaded_el_03', 40 'Chair In The Sky': 'range_tones_preloaded_el_04', 41 'Classic Bell': 'range_tones_preloaded_el_05', 42 "Club In The 80's": 'range_tones_preloaded_el_06', 43 'Club Mix': 'range_tones_preloaded_el_07', 44 'Crossing Tone': 'range_tones_preloaded_el_08', 45 'Fell Groovy': 'range_tones_preloaded_el_09', 46 'Fuss & Feathers': 'range_tones_preloaded_el_10', 47 'Gutta Tone': 'range_tones_preloaded_el_11', 48 'Hip Hop Guy': 'range_tones_preloaded_el_12', 49 'Late Night': 'range_tones_preloaded_el_13', 50 'Mix Master': 'range_tones_preloaded_el_14', 51 'Popple Tone': 'range_tones_preloaded_el_15', 52 'Serene Tone': 'range_tones_preloaded_el_16', 53 'Sonic Boom': 'range_tones_preloaded_el_17', 54 'Spanish Guitar': 'range_tones_preloaded_el_18', 55 'The Floor': 'range_tones_preloaded_el_19', 56 'Trip To Heaven': 'range_tones_preloaded_el_20', 57 'Beep Once': 'range_tones_preloaded_el_21', 58 'No Ring': ringtone_noring_range, 59 } 60 61 builtin_sounds={ 62 'Clapping': 'range_sound_preloaded_el_clapping', 63 'Crowd Roar': 'range_sound_preloaded_el_crowed_roar', 64 'Happy Birthday': 'range_sound_preloaded_el_birthday', 65 'Rainforest': 'range_sound_preloaded_el_rainforest', 66 'Train': 'range_sound_preloaded_el_train', 67 # same as ringtones ?? 68 'Sound Beep Once': 'range_sound_preloaded_el_beep_once', 69 'Sound No Ring': 'range_sound_preloaded_el_no_rings', 70 } 71 72 # We can't use bult-in wallpapers for contact ID 73 builtin_wallpapers={} 74
75 - def __init__(self, logtarget, commport):
76 "Calls all the constructors and sets initial modes" 77 parentphone.__init__(self, logtarget, commport) 78 global PBEntry, CalendarEntry 79 self.pbentryclass=PBEntry 80 self.calendarclass=CalendarEntry
81 82 # ringtone stuff-----------------------------------------------------------
83 - def _get_file_ringtone_index(self, idx, result, 84 index_file_name, index_file_class, 85 origin):
86 try: 87 _buf=prototypes.buffer(self.getfilecontents(index_file_name)) 88 except (com_brew.BrewNoSuchFileException, 89 com_brew.BrewBadPathnameException, 90 com_brew.BrewFileLockedException, 91 com_brew.BrewAccessDeniedException): 92 return idx 93 except: 94 if __debug__: 95 raise 96 return idx 97 _index_file=index_file_class() 98 _index_file.readfrombuffer(_buf) 99 for _entry in _index_file.items: 100 if _entry.pathname.startswith('/ff/'): 101 _file_name=_entry.pathname[4:] 102 else: 103 _file_name=_entry.pathname 104 if not _file_name.startswith(self.protocolclass.SND_PRELOADED_PREFIX): 105 result[idx]= { 'name': common.basename(_entry.pathname), 106 'filename': _file_name, 107 'origin': origin, 108 } 109 idx+=1 110 return idx
111 - def get_ringtone_index(self):
112 _res={} 113 _idx=self._get_builtin_ringtone_index(0, _res) 114 # Cannot get any of the ringtones (ringers) index 115 # get the index of Sounds items 116 _idx=self._get_file_ringtone_index(_idx, _res, 117 self.protocolclass.SND_INDEX_FILE_NAME, 118 self.protocolclass.RSoundsIndexFile, 119 'sounds') 120 return _res
121
122 - def _append_sounds_index_file(self, new_files_list):
123 """Update the Sounds index file with new/added files""" 124 self.log("Appending Sounds index file") 125 # read in existing index entries from index file 126 _old_snd=self.readobject(self.protocolclass.SND_INDEX_FILE_NAME, 127 self.protocolclass.RSoundsIndexFile) 128 _new_snd=self.protocolclass.WSoundsIndexFile() 129 for _v in _old_snd.items: 130 _new_snd.items.append(self.protocolclass.WSoundsIndexEntry(name='', 131 pathname=_v.pathname[4:], 132 eor='|'+_v.misc+'\x0A')) 133 # now append new entries 134 for _f in new_files_list: 135 _new_snd.items.append(self.protocolclass.WSoundsIndexEntry(name='', 136 pathname=self.protocolclass.SND_PATH+'/'+_f)) 137 # and write it out 138 self.writeobject(self.protocolclass.SND_INDEX_FILE_NAME, 139 _new_snd)
140
141 - def saveringtones(self, fundamentals, merge):
142 """Save ringtones to the phone""" 143 self.log('Writing ringtones to the phone') 144 try: 145 _del_list, _new_list=self._get_del_new_list('ringtone-index', 146 'ringtone', 147 merge, 148 fundamentals) 149 if __debug__: 150 self.log('Delete list: '+','.join(_del_list)) 151 self.log('New list: '+','.join(_new_list)) 152 _added_files_list=self._add_files('ringtone-index', 'ringtone', 153 _new_list, fundamentals) 154 if _added_files_list: 155 self._append_sounds_index_file(_added_files_list) 156 fundamentals['rebootphone']=True 157 except: 158 if __debug__: 159 raise 160 return fundamentals
161 162 # SMS Stuff----------------------------------------------------------------
163 - def _build_locked_field(self, entry, buf):
164 _locked=self.protocolclass.UINT(sizeinbytes=2) 165 _locked.readfrombuffer(buf) 166 entry.locked=bool(_locked.getvalue() & 0x100)
167 168 # Phone Detection-----------------------------------------------------------
169 - def is_mode_brew(self):
170 # Borrowed from the VX4400 171 req=self.protocolclass.testing0crequest() 172 respc=self.protocolclass.data 173 for baud in 0, 38400, 115200: 174 if baud: 175 if not self.comm.setbaudrate(baud): 176 continue 177 try: 178 self.sendbrewcommand(req, respc, callsetmode=False) 179 return True 180 except com_phone.modeignoreerrortypes: 181 pass 182 return False
183 184 @classmethod
185 - def detectphone(_, coms, likely_ports, res, _module, _log):
186 if not likely_ports: 187 # cannot detect any likely ports 188 return None 189 for port in likely_ports: 190 if not res.has_key(port): 191 res[port]={ 'mode_modem': None, 'mode_brew': None, 192 'manufacturer': None, 'model': None, 193 'firmware_version': None, 'esn': None, 194 'firmwareresponse': None } 195 try: 196 if res[port]['model']: 197 # been found, not much we can do now 198 continue 199 p=_module.Phone(_log, commport.CommConnection(_log, port, timeout=1)) 200 # Force to check for BREW 201 if not res[port]['mode_brew']: 202 res[port]['mode_brew']=p.is_mode_brew() 203 if res[port]['mode_brew']: 204 p.check_my_phone(res[port]) 205 p.comm.close() 206 except: 207 if __debug__: 208 raise
209 210 211 # CalendarEntry class----------------------------------------------------------- 212 parentcalendarentry=schu470.CalendarEntry
213 -class CalendarEntry(parentcalendarentry):
214 """Transient class to handle calendar data being sent to, retrieved from 215 the phone. 216 """ 217 # routines to build phone data from BitPim dict
218 - def _build(self, entry):
219 # populate this object with data from BitPim 220 self.cal.titlelen=len(entry.desc_loc) 221 self.cal.title=entry.desc_loc 222 self.cal.start=entry.start 223 self.cal.end=entry.end 224 self.cal.repeat=self._build_repeat(entry) 225 self.cal.alarm=self._build_alarm(entry) 226 self.cal.alert=self._build_alert(entry) 227 self.cal.duration=self._build_duration(entry) 228 self.cal.timezone=self._build_tz() 229 self.cal.creationtime=self.phone._time_now() 230 _ringtone=self.phone.get_ringtone_range(entry.ringtone, 231 self.fundamentals) 232 self.cal.ringtonelen=len(_ringtone) 233 self.cal.ringtone=_ringtone
234 235 # routines to extract data from the phone into BitPim dict
236 - def _extract_end(self):
237 return self.cal.end[:5]
238 239 # PBEntry class----------------------------------------------------------------- 240 parentpbentry=schu470.PBEntry
241 -class PBEntry(parentpbentry):
242 243 _IM_Type_String={ 1: 'AIM', 2: 'Yahoo!', 3: 'WL Messenger' } 244 _IM_Type_Index={ 'AIM': 1, 'Yahoo!': 2, 'WL Messenger': 3 } 245 246 # routines to convert BitPim dict into phone's data
247 - def _build_address(self, address):
248 if address: 249 self.pb.address=address
250
251 - def _build_IM(self, im):
252 if im: 253 self.pb.im_type=self._IM_Type_Index.get(im.get('type', ''), 1) 254 self.pb.im_name=im.get('username', '')
255
256 - def _build(self, entry):
257 parentpbentry._build(self, entry) 258 self._build_address(entry.get('addresses', [{}])[0]) 259 self._build_IM(entry.get('ims', [{}])[0])
260 261 # routines to convert phone's data into BitPim dict
262 - def _extract_group(self, entry, p_class):
263 if not self.pb.has_group: 264 # no group specified 265 return 266 _groups=self.fundamentals.get('groups', {}) 267 _res=[] 268 # each group is turned on/off via each bit of the _groups value 269 for _index, _item in _groups.items(): 270 if (1<<_index)&self.pb.group: 271 _res.append({ 'category': _item['name'] }) 272 if _res: 273 entry['categories']=_res
274
275 - def _extract_wallpaper(self, entry, p_class):
276 if not self.pb.has_cached_wp: 277 return 278 # really ugly hack here !!! 279 _wp=self.pb.cached_wp.split('|')[1] 280 # BitPim can only deal with non-builtin wallpapers 281 if not _wp.startswith('Preloaded'): 282 # assume that the name has extension .jpg 283 entry['wallpapers']=[{ 'wallpaper': _wp+'.jpg', 284 'use': 'call' }]
285
286 - def _extract_IM(self, entry, p_class):
287 if self.pb.has_im_name: 288 entry['ims']=[{ 'type': self._IM_Type_String.get(self.pb.im_type, ''), 289 'username': self.pb.im_name }]
290
291 - def _extract_address(self, entry, p_class):
292 if self.pb.has_address: 293 entry['addresses']=[self.pb.address]
294
295 - def getvalue(self):
296 _entry=parentpbentry.getvalue(self) 297 self._extract_IM(_entry, self.phone.protocolclass) 298 self._extract_address(_entry, self.phone.protocolclass) 299 return _entry
300 301 # Profile class----------------------------------------------------------------- 302 parentprofile=schu470.Profile
303 -class Profile(parentprofile):
304 serialsname=Phone.serialsname 305 WALLPAPER_WIDTH=240 306 WALLPAPER_HEIGHT=274 307 # 128x96: outside LCD 308 autodetect_delay=3 309 usbids=( ( 0x04e8, 0x6640, 2),) 310 deviceclasses=("serial",) 311 BP_Calendar_Version=3 312 # For phone detection 313 phone_manufacturer=Phone.my_manufacturer 314 phone_model=Phone.my_model 315 # arbitrary ringtone file size limit 316 RINGTONE_LIMITS= { 317 'MAXSIZE': 100000 318 } 319 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789 ._:" 320 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789 ._:" 321 322 # fill in the list of ringtone/sound origins on your phone 323 ringtoneorigins=('sounds',) 324 # ringtone origins that are not available for the contact assignment 325 excluded_ringtone_origins=() 326 327 imageorigins={} 328 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images")) 329 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video")) 330 # wallpaper origins that are not available for the contact assignment 331 excluded_wallpaper_origins=('video',) 332 333 # our targets are the same for all origins 334 imagetargets={} 335 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper", 336 {'width': 240, 'height': 274, 'format': "JPEG"})) 337 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "pictureid", 338 {'width': 80, 'height': 106, 'format': "JPEG"}))
339 - def GetTargetsForImageOrigin(self, origin):
340 return self.imagetargets
341
342 - def __init__(self):
343 parentprofile.__init__(self)
344 345 _supportedsyncs=( 346 ('phonebook', 'read', None), # all phonebook reading 347 ('phonebook', 'write', 'OVERWRITE'), # only overwriting phonebook 348 ('calendar', 'read', None), # all calendar reading 349 ('calendar', 'write', 'OVERWRITE'), # only overwriting calendar 350 ('ringtone', 'read', None), # all ringtone reading 351 ('ringtone', 'write', 'MERGE'), 352 ('wallpaper', 'read', None), # all wallpaper reading 353 ('wallpaper', 'write', 'MERGE'), 354 ('memo', 'read', None), # all memo list reading DJP 355 ('memo', 'write', 'OVERWRITE'), # all memo list writing DJP 356 ('call_history', 'read', None),# all call history list reading 357 ('sms', 'read', None), # all SMS list reading DJP 358 ) 359 360 field_color_data={ 361 'phonebook': { 362 'name': { 363 'first': 1, 'middle': 1, 'last': 1, 'full': 1, 364 'nickname': 0, 'details': 1 }, 365 'number': { 366 'type': 5, 'speeddial': 5, 'number': 5, 367 'details': 5, 368 'ringtone': False, 'wallpaper': False }, 369 'email': 2, 370 'email_details': { 371 'emailspeeddial': False, 'emailringtone': False, 372 'emailwallpaper': False }, 373 'address': { 374 'type': 0, 'company': 0, 'street': 1, 'street2': 0, 375 'city': 1, 'state': 1, 'postalcode': 1, 'country': 1, 376 'details': 1 }, 377 'url': 0, 378 'memo': 1, 379 'category': 1, 380 'wallpaper': 1, 381 'ringtone': 1, 382 'storage': 0, 383 'im': 1, 384 }, 385 'calendar': { 386 'description': True, 'location': True, 'allday': False, 387 'start': True, 'end': True, 'priority': False, 388 'alarm': True, 'vibrate': True, 389 'repeat': True, 390 'memo': False, 391 'category': False, 392 'wallpaper': False, 393 'ringtone': True, 394 }, 395 'memo': { 396 'subject': False, 397 'date': False, 398 'secret': False, 399 'category': False, 400 'memo': True, 401 }, 402 'todo': { 403 'summary': False, 404 'status': False, 405 'due_date': False, 406 'percent_complete': False, 407 'completion_date': False, 408 'private': False, 409 'priority': False, 410 'category': False, 411 'memo': False, 412 }, 413 }
414