VX-8700 support update
Nathan Hjelm <[email protected]>
| Newsgroups | gmane.comp.mobile.bitpim.devel |
|---|---|
| Message-ID | <[email protected]> |
Hopefully this is the last update that will be needed for VX-8700
support. Every supported function has been tested and should be ready
for release :).
Changes:
LG VX-8700:
- Fixed calendar support
- Phonebook support updates and groups support (correct
ringtones, pictures)
LG Phonebook:
- Identify and throw LG phonebook busy error.
Brew2:
- Corrected stat implementation. It was incorrectly identifying
files on external media.
I am still prepping my VX-9400 support files. I expect to be able to
submit a patch sometime tomorrow.
-Nathan Hjelm
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
BitPim-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bitpim-devel
vx8700_final.patch
(application/octet-stream, 32.6 KB)
Index: src/phones/com_brew.py
===================================================================
--- src/phones/com_brew.py (revision 4235)
+++ src/phones/com_brew.py (working copy)
@@ -1034,14 +1034,15 @@
res=self.sendbrewcommand(req, p_brew.new_statfileresponse)
if res.flags==2:
raise BrewNoSuchFileException
- if res.type==1:
+ if res.type==1 or res.type==0x86:
+ # files on external media have type 0x86
results={ 'name': name, 'type': 'file', 'size': res.size }
- if res.created_date==0:
- results['date']=(0, '')
- else:
- results['date']=(res.created_date, time.strftime("%x %X", time.localtime(res.created_date)))
else:
results={ 'name': name, 'type': 'directory' }
+ if res.created_date==0:
+ results['date']=(0, '')
+ else:
+ results['date']=(res.created_date, time.strftime("%x %X", time.localtime(res.created_date)))
return results
class BrewProtocol(RealBrewProtocol):
Index: src/phones/p_lgvx8700.p
===================================================================
--- src/phones/p_lgvx8700.p (revision 4235)
+++ src/phones/p_lgvx8700.p (working copy)
@@ -16,29 +16,57 @@
# we are the same as lgvx9900 except as noted below
from p_lgvx9900 import *
from p_lgvx8500 import t9udbfile
-
+
# We use LSB for all integer like fields
UINT=UINTlsb
BOOL=BOOLlsb
BREW_FILE_SYSTEM=2
+# Phonebook stuff
+RTPathIndexFile='pim/pbRingIdSetAsPath.dat'
+WPPathIndexFile='pim/pbPictureIdSetAsPath.dat'
+pb_file_name='pim/pbentry.dat'
+
T9USERDBFILENAME='t9udb/t9udb_eng.dat'
%}
+# phonebook
PACKET pbgroup:
- 36 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False } name
+ 33 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False } name
+ 2 UINT groupid
+ 1 UINT {'default': 0} +unknown0
PACKET pbgroups:
"Phonebook groups"
* LIST {'elementclass': pbgroup} +groups
+PACKET pbfileentry:
+ 4 UINT serial1
+ 2 UINT entrynumber
+ 133 DATA data1
+ 2 UINT ringtone
+ 2 UINT wallpaper
+ 15 DATA data2
+
+PACKET pbfile:
+ * LIST { 'elementclass': pbfileentry } items
+
+PACKET PathIndexEntry:
+ 255 USTRING { 'encoding': PHONE_ENCODING,
+ 'default': '' } +pathname
+PACKET PathIndexFile:
+ * LIST { 'elementclass': PathIndexEntry,
+ 'createdefault': True,
+ 'length': NUMPHONEBOOKENTRIES } +items
+
+# calendar
PACKET scheduleevent:
4 UINT pos "position within file, used as an event id"
33 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False } description
- 4 GPSDATE cdate # creation date
- 4 GPSDATE mdate # modification date
+ 4 GPSDATE { 'default': GPSDATE.now() } +cdate # creation date
+ 4 GPSDATE { 'default': GPSDATE.now() } +mdate # modification date
4 LGCALDATE start
4 LGCALDATE end_time
4 LGCALDATE end_date
Index: src/phones/com_lgvx8700.py
===================================================================
--- src/phones/com_lgvx8700.py (revision 4235)
+++ src/phones/com_lgvx8700.py (working copy)
@@ -20,12 +20,13 @@
import commport
import p_brew
import helpids
+import com_lgvx8300
import com_lgvx8500
import p_lgvx8700
#-------------------------------------------------------------------------------
parentphone=com_lgvx8500.Phone
-class Phone(parentphone, com_brew.RealBrewProtocol2):
+class Phone(com_brew.RealBrewProtocol2, parentphone):
"Talk to LG VX-8700 cell phone"
desc="LG-VX8700"
@@ -34,6 +35,9 @@
serialsname='lgvx8700'
my_model='VX8700'
+ builtinringtones= ('Low Beep Once', 'Low Beeps', 'Loud Beep Once', 'Loud Beeps', 'Door Bell', 'VZW Default Ringtone') + \
+ tuple(['Ringtone '+`n` for n in range(1,12)]) + \
+ ('No Ring',)
ringtonelocations= (
# type index file default dir external dir max type index
@@ -72,12 +76,88 @@
"""
if not self._in_DM:
self.enter_DM()
- return parentphone.getfundamentals(self, results)
+ results = parentphone.getfundamentals(self, results)
+ if self.my_model=='VX8700':
+ self.getgroups(results)
+ return results
+
+ # phonebook
+ def _update_pb_file(self, pb, fundamentals, pbinfo):
+ # update the pbentry file
+ update_flg=False
+ for e in pb.items:
+ _info=pbinfo.get(e.serial1, None)
+ if _info:
+ wp=_info.get('wallpaper', None)
+ if wp is not None and wp!=e.wallpaper:
+ update_flg=True
+ e.wallpaper=wp
+ if update_flg:
+ self.log('Updating wallpaper index')
+ buf=prototypes.buffer()
+ pb.writetobuffer(buf, logtitle="Updated index "+self.protocolclass.pb_file_name)
+ self.writefile(self.protocolclass.pb_file_name, buf.getvalue())
+
+ def savephonebook(self, data):
+ "Saves out the phonebook"
+ res=com_lgvx8300.Phone.savephonebook(self, data)
+ # retrieve the phonebook entries
+ _buf=prototypes.buffer(self.getfilecontents(self.protocolclass.pb_file_name))
+ _pb_entries=self.protocolclass.pbfile()
+ _pb_entries.readfrombuffer(_buf, logtitle="Read phonebook file "+self.protocolclass.pb_file_name)
+ _rt_index=data.get('ringtone-index', {})
+ _wp_index=data.get('wallpaper-index', {})
+ # update info that the phone software failed to do!!
+ self._update_pb_info(_pb_entries, data)
+ # fix up ringtone index
+ self._write_path_index(_pb_entries, 'ringtone',
+ _rt_index,
+ self.protocolclass.RTPathIndexFile,
+ (0xffff,))
+ # fix up wallpaer index
+ self._write_path_index(_pb_entries, 'wallpaper',
+ _wp_index,
+ self.protocolclass.WPPathIndexFile,
+ (0, 0xffff,))
+ return res
+
+ # groups
+ def getgroups(self, results):
+ "Read groups"
+ # Reads groups that use explicit IDs
+ self.log("Reading group information")
+ buf=prototypes.buffer(self.getfilecontents("pim/pbgroup.dat"))
+ g=self.protocolclass.pbgroups()
+ g.readfrombuffer(buf, logtitle="Groups read")
+ groups={}
+ for i in range(len(g.groups)):
+ if len(g.groups[i].name) and (g.groups[i].groupid or i==0):
+ groups[g.groups[i].groupid]={'name': g.groups[i].name }
+ results['groups'] = groups
+ return groups
+
+ def savegroups(self, data):
+ groups=data['groups']
+ keys=groups.keys()
+ keys.sort()
+ g=self.protocolclass.pbgroups()
+ for k in keys:
+ e=self.protocolclass.pbgroup()
+ e.name=groups[k]['name']
+ if 'groupid' in e.getfields():
+ e.groupid = k
+ if k != 0:
+ e.unknown0 = 1
+ g.groups.append(e)
+ buffer=prototypes.buffer()
+ g.writetobuffer(buffer, logtitle="New group file")
+ self.writefile("pim/pbgroup.dat", buffer.getvalue())
+
def is_mode_brew(self):
req=p_brew.memoryconfigrequest()
respc=p_brew.memoryconfigresponse
-
+
for baud in 0, 38400, 115200:
if baud:
if not self.comm.setbaudrate(baud):
@@ -97,11 +177,7 @@
# enter DM to enable file reading/writing
self.enter_DM()
return com_brew.RealBrewProtocol2.listfiles(self, dir)
-
- def getfilesystem(self, dir="", recurse=0, directories=1, files=1):
- # BREW2's get filesystem is used here because BREW1's does not appear not to work well on the vx8700
- return com_brew.RealBrewProtocol2.getfilesystem(self, dir, recurse, directories, files)
-
+
def enter_DM (self):
# request challenge
req = self.protocolclass.ULReq(unlock_key=0)
@@ -118,33 +194,6 @@
else:
self.log('Failed to enter DM mode')
- def sendbrewcommand(self, request, responseclass, callsetmode=True):
- if callsetmode:
- self.setmode(self.MODEBREW)
- buffer=prototypes.buffer()
- request.writetobuffer(buffer, logtitle="com_lgvx8700: sendbrewcommand")
- data=buffer.getvalue()
-
- # the memory config request does not need to be unlocked
- if (data[0]=="\x59" or data[0]=="\x4b") and data[1]!="\x0c":
- # "unlock" the brew command by sending a 0x5c command with the same data
- # unlocking works with the LG vx9400 as well (tested)
- if data[0]=="\x59":
- uldata = "\x5c" + data[1:]
- else:
- # do we need to drop a character from a brew2 command? it works.
- uldata = "\x5c" + data[2:]
- uldata=common.pppescape(uldata+common.crcs(uldata))+common.pppterminator
- self.logdata("Unlock brew command", uldata, None)
- try:
- data=self.comm.writethenreaduntil(uldata, False, common.pppterminator, logreaduntilsuccess=False)
- except modeignoreerrortypes:
- self.mode=self.MODENONE
- self.raisecommsdnaexception("unlocking filesystem command")
- self.logdata("Unlock brew command response", data, None)
- return com_brew.RealBrewProtocol.sendbrewcommand(self, request, responseclass, callsetmode=False)
-
-
#-------------------------------------------------------------------------------
parentprofile=com_lgvx8500.Profile
class Profile(parentprofile):
Index: src/phones/p_lgvx8700.py
===================================================================
--- src/phones/p_lgvx8700.py (revision 4235)
+++ src/phones/p_lgvx8700.py (working copy)
@@ -8,17 +8,22 @@
# we are the same as lgvx9900 except as noted below
from p_lgvx9900 import *
from p_lgvx8500 import t9udbfile
-
+
# We use LSB for all integer like fields
UINT=UINTlsb
BOOL=BOOLlsb
BREW_FILE_SYSTEM=2
+# Phonebook stuff
+RTPathIndexFile='pim/pbRingIdSetAsPath.dat'
+WPPathIndexFile='pim/pbPictureIdSetAsPath.dat'
+pb_file_name='pim/pbentry.dat'
+
T9USERDBFILENAME='t9udb/t9udb_eng.dat'
class pbgroup(BaseProtogenClass):
- __fields=['name']
+ __fields=['name', 'groupid', 'unknown0']
def __init__(self, *args, **kwargs):
dict={}
@@ -44,11 +49,7 @@
# Were any unrecognized kwargs passed in?
if __debug__:
self._complainaboutunusedargs(pbgroup,kwargs)
- if len(args):
- dict2={'sizeinbytes': 36, 'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False }
- dict2.update(kwargs)
- kwargs=dict2
- self.__field_name=USTRING(*args,**dict2)
+ if len(args): raise TypeError('Unexpected arguments supplied: '+`args`)
# Make all P fields that haven't already been constructed
@@ -56,6 +57,11 @@
'Writes this packet to the supplied buffer'
self._bufferstartoffset=buf.getcurrentoffset()
self.__field_name.writetobuffer(buf)
+ self.__field_groupid.writetobuffer(buf)
+ try: self.__field_unknown0
+ except:
+ self.__field_unknown0=UINT(**{'sizeinbytes': 1, 'default': 0})
+ self.__field_unknown0.writetobuffer(buf)
self._bufferendoffset=buf.getcurrentoffset()
if autolog and self._bufferstartoffset==0: self.autologwrite(buf, logtitle=logtitle)
@@ -64,8 +70,12 @@
'Reads this packet from the supplied buffer'
self._bufferstartoffset=buf.getcurrentoffset()
if autolog and self._bufferstartoffset==0: self.autologread(buf, logtitle=logtitle)
- self.__field_name=USTRING(**{'sizeinbytes': 36, 'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False })
+ self.__field_name=USTRING(**{'sizeinbytes': 33, 'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False })
self.__field_name.readfrombuffer(buf)
+ self.__field_groupid=UINT(**{'sizeinbytes': 2})
+ self.__field_groupid.readfrombuffer(buf)
+ self.__field_unknown0=UINT(**{'sizeinbytes': 1, 'default': 0})
+ self.__field_unknown0.readfrombuffer(buf)
self._bufferendoffset=buf.getcurrentoffset()
@@ -76,17 +86,48 @@
if isinstance(value,USTRING):
self.__field_name=value
else:
- self.__field_name=USTRING(value,**{'sizeinbytes': 36, 'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False })
+ self.__field_name=USTRING(value,**{'sizeinbytes': 33, 'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False })
def __delfield_name(self): del self.__field_name
name=property(__getfield_name, __setfield_name, __delfield_name, None)
+ def __getfield_groupid(self):
+ return self.__field_groupid.getvalue()
+
+ def __setfield_groupid(self, value):
+ if isinstance(value,UINT):
+ self.__field_groupid=value
+ else:
+ self.__field_groupid=UINT(value,**{'sizeinbytes': 2})
+
+ def __delfield_groupid(self): del self.__field_groupid
+
+ groupid=property(__getfield_groupid, __setfield_groupid, __delfield_groupid, None)
+
+ def __getfield_unknown0(self):
+ try: self.__field_unknown0
+ except:
+ self.__field_unknown0=UINT(**{'sizeinbytes': 1, 'default': 0})
+ return self.__field_unknown0.getvalue()
+
+ def __setfield_unknown0(self, value):
+ if isinstance(value,UINT):
+ self.__field_unknown0=value
+ else:
+ self.__field_unknown0=UINT(value,**{'sizeinbytes': 1, 'default': 0})
+
+ def __delfield_unknown0(self): del self.__field_unknown0
+
+ unknown0=property(__getfield_unknown0, __setfield_unknown0, __delfield_unknown0, None)
+
def iscontainer(self):
return True
def containerelements(self):
yield ('name', self.__field_name, None)
+ yield ('groupid', self.__field_groupid, None)
+ yield ('unknown0', self.__field_unknown0, None)
@@ -172,6 +213,395 @@
+class pbfileentry(BaseProtogenClass):
+ __fields=['serial1', 'entrynumber', 'data1', 'ringtone', 'wallpaper', 'data2']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(pbfileentry,self).__init__(**dict)
+ if self.__class__ is pbfileentry:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(pbfileentry,self)._update(args,kwargs)
+ keys=kwargs.keys()
+ for key in keys:
+ if key in self.__fields:
+ setattr(self, key, kwargs[key])
+ del kwargs[key]
+ # Were any unrecognized kwargs passed in?
+ if __debug__:
+ self._complainaboutunusedargs(pbfileentry,kwargs)
+ if len(args): raise TypeError('Unexpected arguments supplied: '+`args`)
+ # Make all P fields that haven't already been constructed
+
+
+ def writetobuffer(self,buf,autolog=True,logtitle="<written data>"):
+ 'Writes this packet to the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ self.__field_serial1.writetobuffer(buf)
+ self.__field_entrynumber.writetobuffer(buf)
+ self.__field_data1.writetobuffer(buf)
+ self.__field_ringtone.writetobuffer(buf)
+ self.__field_wallpaper.writetobuffer(buf)
+ self.__field_data2.writetobuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologwrite(buf, logtitle=logtitle)
+
+
+ def readfrombuffer(self,buf,autolog=True,logtitle="<read data>"):
+ 'Reads this packet from the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologread(buf, logtitle=logtitle)
+ self.__field_serial1=UINT(**{'sizeinbytes': 4})
+ self.__field_serial1.readfrombuffer(buf)
+ self.__field_entrynumber=UINT(**{'sizeinbytes': 2})
+ self.__field_entrynumber.readfrombuffer(buf)
+ self.__field_data1=DATA(**{'sizeinbytes': 133})
+ self.__field_data1.readfrombuffer(buf)
+ self.__field_ringtone=UINT(**{'sizeinbytes': 2})
+ self.__field_ringtone.readfrombuffer(buf)
+ self.__field_wallpaper=UINT(**{'sizeinbytes': 2})
+ self.__field_wallpaper.readfrombuffer(buf)
+ self.__field_data2=DATA(**{'sizeinbytes': 15})
+ self.__field_data2.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_serial1(self):
+ return self.__field_serial1.getvalue()
+
+ def __setfield_serial1(self, value):
+ if isinstance(value,UINT):
+ self.__field_serial1=value
+ else:
+ self.__field_serial1=UINT(value,**{'sizeinbytes': 4})
+
+ def __delfield_serial1(self): del self.__field_serial1
+
+ serial1=property(__getfield_serial1, __setfield_serial1, __delfield_serial1, None)
+
+ def __getfield_entrynumber(self):
+ return self.__field_entrynumber.getvalue()
+
+ def __setfield_entrynumber(self, value):
+ if isinstance(value,UINT):
+ self.__field_entrynumber=value
+ else:
+ self.__field_entrynumber=UINT(value,**{'sizeinbytes': 2})
+
+ def __delfield_entrynumber(self): del self.__field_entrynumber
+
+ entrynumber=property(__getfield_entrynumber, __setfield_entrynumber, __delfield_entrynumber, None)
+
+ def __getfield_data1(self):
+ return self.__field_data1.getvalue()
+
+ def __setfield_data1(self, value):
+ if isinstance(value,DATA):
+ self.__field_data1=value
+ else:
+ self.__field_data1=DATA(value,**{'sizeinbytes': 133})
+
+ def __delfield_data1(self): del self.__field_data1
+
+ data1=property(__getfield_data1, __setfield_data1, __delfield_data1, None)
+
+ def __getfield_ringtone(self):
+ return self.__field_ringtone.getvalue()
+
+ def __setfield_ringtone(self, value):
+ if isinstance(value,UINT):
+ self.__field_ringtone=value
+ else:
+ self.__field_ringtone=UINT(value,**{'sizeinbytes': 2})
+
+ def __delfield_ringtone(self): del self.__field_ringtone
+
+ ringtone=property(__getfield_ringtone, __setfield_ringtone, __delfield_ringtone, None)
+
+ def __getfield_wallpaper(self):
+ return self.__field_wallpaper.getvalue()
+
+ def __setfield_wallpaper(self, value):
+ if isinstance(value,UINT):
+ self.__field_wallpaper=value
+ else:
+ self.__field_wallpaper=UINT(value,**{'sizeinbytes': 2})
+
+ def __delfield_wallpaper(self): del self.__field_wallpaper
+
+ wallpaper=property(__getfield_wallpaper, __setfield_wallpaper, __delfield_wallpaper, None)
+
+ def __getfield_data2(self):
+ return self.__field_data2.getvalue()
+
+ def __setfield_data2(self, value):
+ if isinstance(value,DATA):
+ self.__field_data2=value
+ else:
+ self.__field_data2=DATA(value,**{'sizeinbytes': 15})
+
+ def __delfield_data2(self): del self.__field_data2
+
+ data2=property(__getfield_data2, __setfield_data2, __delfield_data2, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('serial1', self.__field_serial1, None)
+ yield ('entrynumber', self.__field_entrynumber, None)
+ yield ('data1', self.__field_data1, None)
+ yield ('ringtone', self.__field_ringtone, None)
+ yield ('wallpaper', self.__field_wallpaper, None)
+ yield ('data2', self.__field_data2, None)
+
+
+
+
+class pbfile(BaseProtogenClass):
+ __fields=['items']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(pbfile,self).__init__(**dict)
+ if self.__class__ is pbfile:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(pbfile,self)._update(args,kwargs)
+ keys=kwargs.keys()
+ for key in keys:
+ if key in self.__fields:
+ setattr(self, key, kwargs[key])
+ del kwargs[key]
+ # Were any unrecognized kwargs passed in?
+ if __debug__:
+ self._complainaboutunusedargs(pbfile,kwargs)
+ if len(args):
+ dict2={ 'elementclass': pbfileentry }
+ dict2.update(kwargs)
+ kwargs=dict2
+ self.__field_items=LIST(*args,**dict2)
+ # Make all P fields that haven't already been constructed
+
+
+ def writetobuffer(self,buf,autolog=True,logtitle="<written data>"):
+ 'Writes this packet to the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ self.__field_items.writetobuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologwrite(buf, logtitle=logtitle)
+
+
+ def readfrombuffer(self,buf,autolog=True,logtitle="<read data>"):
+ 'Reads this packet from the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologread(buf, logtitle=logtitle)
+ self.__field_items=LIST(**{ 'elementclass': pbfileentry })
+ self.__field_items.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_items(self):
+ return self.__field_items.getvalue()
+
+ def __setfield_items(self, value):
+ if isinstance(value,LIST):
+ self.__field_items=value
+ else:
+ self.__field_items=LIST(value,**{ 'elementclass': pbfileentry })
+
+ def __delfield_items(self): del self.__field_items
+
+ items=property(__getfield_items, __setfield_items, __delfield_items, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('items', self.__field_items, None)
+
+
+
+
+class PathIndexEntry(BaseProtogenClass):
+ __fields=['pathname']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(PathIndexEntry,self).__init__(**dict)
+ if self.__class__ is PathIndexEntry:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(PathIndexEntry,self)._update(args,kwargs)
+ keys=kwargs.keys()
+ for key in keys:
+ if key in self.__fields:
+ setattr(self, key, kwargs[key])
+ del kwargs[key]
+ # Were any unrecognized kwargs passed in?
+ if __debug__:
+ self._complainaboutunusedargs(PathIndexEntry,kwargs)
+ if len(args):
+ dict2={'sizeinbytes': 255, 'encoding': PHONE_ENCODING, 'default': '' }
+ dict2.update(kwargs)
+ kwargs=dict2
+ self.__field_pathname=USTRING(*args,**dict2)
+ # Make all P fields that haven't already been constructed
+
+
+ def writetobuffer(self,buf,autolog=True,logtitle="<written data>"):
+ 'Writes this packet to the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ try: self.__field_pathname
+ except:
+ self.__field_pathname=USTRING(**{'sizeinbytes': 255, 'encoding': PHONE_ENCODING, 'default': '' })
+ self.__field_pathname.writetobuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologwrite(buf, logtitle=logtitle)
+
+
+ def readfrombuffer(self,buf,autolog=True,logtitle="<read data>"):
+ 'Reads this packet from the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologread(buf, logtitle=logtitle)
+ self.__field_pathname=USTRING(**{'sizeinbytes': 255, 'encoding': PHONE_ENCODING, 'default': '' })
+ self.__field_pathname.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_pathname(self):
+ try: self.__field_pathname
+ except:
+ self.__field_pathname=USTRING(**{'sizeinbytes': 255, 'encoding': PHONE_ENCODING, 'default': '' })
+ return self.__field_pathname.getvalue()
+
+ def __setfield_pathname(self, value):
+ if isinstance(value,USTRING):
+ self.__field_pathname=value
+ else:
+ self.__field_pathname=USTRING(value,**{'sizeinbytes': 255, 'encoding': PHONE_ENCODING, 'default': '' })
+
+ def __delfield_pathname(self): del self.__field_pathname
+
+ pathname=property(__getfield_pathname, __setfield_pathname, __delfield_pathname, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('pathname', self.__field_pathname, None)
+
+
+
+
+class PathIndexFile(BaseProtogenClass):
+ __fields=['items']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(PathIndexFile,self).__init__(**dict)
+ if self.__class__ is PathIndexFile:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(PathIndexFile,self)._update(args,kwargs)
+ keys=kwargs.keys()
+ for key in keys:
+ if key in self.__fields:
+ setattr(self, key, kwargs[key])
+ del kwargs[key]
+ # Were any unrecognized kwargs passed in?
+ if __debug__:
+ self._complainaboutunusedargs(PathIndexFile,kwargs)
+ if len(args):
+ dict2={ 'elementclass': PathIndexEntry, 'createdefault': True, 'length': NUMPHONEBOOKENTRIES }
+ dict2.update(kwargs)
+ kwargs=dict2
+ self.__field_items=LIST(*args,**dict2)
+ # Make all P fields that haven't already been constructed
+
+
+ def writetobuffer(self,buf,autolog=True,logtitle="<written data>"):
+ 'Writes this packet to the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ try: self.__field_items
+ except:
+ self.__field_items=LIST(**{ 'elementclass': PathIndexEntry, 'createdefault': True, 'length': NUMPHONEBOOKENTRIES })
+ self.__field_items.writetobuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologwrite(buf, logtitle=logtitle)
+
+
+ def readfrombuffer(self,buf,autolog=True,logtitle="<read data>"):
+ 'Reads this packet from the supplied buffer'
+ self._bufferstartoffset=buf.getcurrentoffset()
+ if autolog and self._bufferstartoffset==0: self.autologread(buf, logtitle=logtitle)
+ self.__field_items=LIST(**{ 'elementclass': PathIndexEntry, 'createdefault': True, 'length': NUMPHONEBOOKENTRIES })
+ self.__field_items.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_items(self):
+ try: self.__field_items
+ except:
+ self.__field_items=LIST(**{ 'elementclass': PathIndexEntry, 'createdefault': True, 'length': NUMPHONEBOOKENTRIES })
+ return self.__field_items.getvalue()
+
+ def __setfield_items(self, value):
+ if isinstance(value,LIST):
+ self.__field_items=value
+ else:
+ self.__field_items=LIST(value,**{ 'elementclass': PathIndexEntry, 'createdefault': True, 'length': NUMPHONEBOOKENTRIES })
+
+ def __delfield_items(self): del self.__field_items
+
+ items=property(__getfield_items, __setfield_items, __delfield_items, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('items', self.__field_items, None)
+
+
+
+
class scheduleevent(BaseProtogenClass):
__fields=['pos', 'description', 'cdate', 'mdate', 'start', 'end_time', 'end_date', 'repeat', 'alarmindex_vibrate', 'ringtone', 'unknown1', 'alarmminutes', 'alarmhours', 'unknown2', 'unknown3', 'unknown4']
@@ -208,7 +638,13 @@
self._bufferstartoffset=buf.getcurrentoffset()
self.__field_pos.writetobuffer(buf)
self.__field_description.writetobuffer(buf)
+ try: self.__field_cdate
+ except:
+ self.__field_cdate=GPSDATE(**{'sizeinbytes': 4, 'default': GPSDATE.now() })
self.__field_cdate.writetobuffer(buf)
+ try: self.__field_mdate
+ except:
+ self.__field_mdate=GPSDATE(**{'sizeinbytes': 4, 'default': GPSDATE.now() })
self.__field_mdate.writetobuffer(buf)
self.__field_start.writetobuffer(buf)
self.__field_end_time.writetobuffer(buf)
@@ -243,9 +679,9 @@
self.__field_pos.readfrombuffer(buf)
self.__field_description=USTRING(**{'sizeinbytes': 33, 'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False, 'raiseontruncate': False })
self.__field_description.readfrombuffer(buf)
- self.__field_cdate=GPSDATE(**{'sizeinbytes': 4})
+ self.__field_cdate=GPSDATE(**{'sizeinbytes': 4, 'default': GPSDATE.now() })
self.__field_cdate.readfrombuffer(buf)
- self.__field_mdate=GPSDATE(**{'sizeinbytes': 4})
+ self.__field_mdate=GPSDATE(**{'sizeinbytes': 4, 'default': GPSDATE.now() })
self.__field_mdate.readfrombuffer(buf)
self.__field_start=LGCALDATE(**{'sizeinbytes': 4})
self.__field_start.readfrombuffer(buf)
@@ -301,26 +737,32 @@
description=property(__getfield_description, __setfield_description, __delfield_description, None)
def __getfield_cdate(self):
+ try: self.__field_cdate
+ except:
+ self.__field_cdate=GPSDATE(**{'sizeinbytes': 4, 'default': GPSDATE.now() })
return self.__field_cdate.getvalue()
def __setfield_cdate(self, value):
if isinstance(value,GPSDATE):
self.__field_cdate=value
else:
- self.__field_cdate=GPSDATE(value,**{'sizeinbytes': 4})
+ self.__field_cdate=GPSDATE(value,**{'sizeinbytes': 4, 'default': GPSDATE.now() })
def __delfield_cdate(self): del self.__field_cdate
cdate=property(__getfield_cdate, __setfield_cdate, __delfield_cdate, None)
def __getfield_mdate(self):
+ try: self.__field_mdate
+ except:
+ self.__field_mdate=GPSDATE(**{'sizeinbytes': 4, 'default': GPSDATE.now() })
return self.__field_mdate.getvalue()
def __setfield_mdate(self, value):
if isinstance(value,GPSDATE):
self.__field_mdate=value
else:
- self.__field_mdate=GPSDATE(value,**{'sizeinbytes': 4})
+ self.__field_mdate=GPSDATE(value,**{'sizeinbytes': 4, 'default': GPSDATE.now() })
def __delfield_mdate(self): del self.__field_mdate
Index: src/phones/com_lg.py
===================================================================
--- src/phones/com_lg.py (revision 4235)
+++ src/phones/com_lg.py (working copy)
@@ -104,6 +104,11 @@
# turn it back to normal
data=common.pppunescape(data)
+ if data[:2] != firsttwo:
+ # phonebook is busy
+ self.logdata("LG Phonebook busy response", data, None)
+ raise common.PhoneBookBusyException()
+
# take off crc and terminator
crc=data[-3:-1]
data=data[:-3]
Index: help/phone-lgvx8700.htd
===================================================================
--- help/phone-lgvx8700.htd (revision 4235)
+++ help/phone-lgvx8700.htd (working copy)
@@ -2,7 +2,7 @@
<h2>What works</h2>
-<p>Phonebook, wallpaper, ringers, calendar, memo, call history, SMS, Play List, and file system. BitPim can autodetect this phone if it is connected to the PC via a straight USB cable. BitPim can also make use of ringtone files stored on the microSD card.<BR>
+<p>Phonebook, wallpaper, ringers, calendar, memo, call history, SMS, and file system. BitPim can autodetect this phone if it is connected to the PC via a straight USB cable.<BR>
<P>Due to their similarities, please see the <a href="phone-lgvx8600.htm">LG VX8600 Help</a> for more details.