LGDM Phone patch
Nathan Hjelm <[email protected]>
| Newsgroups | gmane.comp.mobile.bitpim.devel |
|---|---|
| Message-ID | <[email protected]> |
Just noticed 1.0.0 was out. So, here is an updated version of my DM phone patch. Changes from SVN source: - DM v5 for VX5300(T53VZV04), VX8600(T86VZV03), VX9900 (T99VZV02) - DM code moved to new class com_lg.LGDMPhone. All DM phones now inherit from this class (this makes DM phone implementation much easier). DMv5 has been confirmed to work will all of the phones listed above (using the VX-8700 setting). -Nathan ------------------------------------------------------------------------- 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
lgdmphone.patch
(application/octet-stream, 39.6 KB)
Index: src/phones/com_lgvx8600.py
===================================================================
--- src/phones/com_lgvx8600.py (revision 4288)
+++ src/phones/com_lgvx8600.py (working copy)
@@ -30,6 +30,18 @@
my_model='VX8600'
+ def __init__(self, logtarget, commport):
+ parentphone.__init__(self, logtarget, commport)
+
+ # set DM version
+ if self.my_model == 'VX8600':
+ _fw_vers = self.get_firmware_version()[-1]
+ if _fw_vers > '2':
+ self._DM_vers = 5
+ else:
+ self._DM_vers = 4
+
+
#-------------------------------------------------------------------------------
parentprofile=com_lgvx8500.Profile
class Profile(parentprofile):
Index: src/phones/p_lg.py
===================================================================
--- src/phones/p_lg.py (revision 4288)
+++ src/phones/p_lg.py (working copy)
@@ -1832,3 +1832,554 @@
+class LockKeyReq(BaseProtogenClass):
+ __fields=['cmd', 'lock']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(LockKeyReq,self).__init__(**dict)
+ if self.__class__ is LockKeyReq:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(LockKeyReq,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(LockKeyReq,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()
+ try: self.__field_cmd
+ except:
+ self.__field_cmd=UINT(**{'sizeinbytes': 1, 'default': 0x21 })
+ self.__field_cmd.writetobuffer(buf)
+ try: self.__field_lock
+ except:
+ self.__field_lock=UINT(**{'sizeinbytes': 2, 'default': 0 })
+ self.__field_lock.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_cmd=UINT(**{'sizeinbytes': 1, 'default': 0x21 })
+ self.__field_cmd.readfrombuffer(buf)
+ self.__field_lock=UINT(**{'sizeinbytes': 2, 'default': 0 })
+ self.__field_lock.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_cmd(self):
+ try: self.__field_cmd
+ except:
+ self.__field_cmd=UINT(**{'sizeinbytes': 1, 'default': 0x21 })
+ return self.__field_cmd.getvalue()
+
+ def __setfield_cmd(self, value):
+ if isinstance(value,UINT):
+ self.__field_cmd=value
+ else:
+ self.__field_cmd=UINT(value,**{'sizeinbytes': 1, 'default': 0x21 })
+
+ def __delfield_cmd(self): del self.__field_cmd
+
+ cmd=property(__getfield_cmd, __setfield_cmd, __delfield_cmd, None)
+
+ def __getfield_lock(self):
+ try: self.__field_lock
+ except:
+ self.__field_lock=UINT(**{'sizeinbytes': 2, 'default': 0 })
+ return self.__field_lock.getvalue()
+
+ def __setfield_lock(self, value):
+ if isinstance(value,UINT):
+ self.__field_lock=value
+ else:
+ self.__field_lock=UINT(value,**{'sizeinbytes': 2, 'default': 0 })
+
+ def __delfield_lock(self): del self.__field_lock
+
+ lock=property(__getfield_lock, __setfield_lock, __delfield_lock, "0=Lock, 1=Unlock")
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('cmd', self.__field_cmd, None)
+ yield ('lock', self.__field_lock, "0=Lock, 1=Unlock")
+
+
+
+
+class KeyPressReq(BaseProtogenClass):
+ __fields=['cmd', 'hold', 'key']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(KeyPressReq,self).__init__(**dict)
+ if self.__class__ is KeyPressReq:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(KeyPressReq,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(KeyPressReq,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()
+ try: self.__field_cmd
+ except:
+ self.__field_cmd=UINT(**{'sizeinbytes': 1, 'default': 0x20 })
+ self.__field_cmd.writetobuffer(buf)
+ try: self.__field_hold
+ except:
+ self.__field_hold=UINT(**{'sizeinbytes': 1, 'default': 0 })
+ self.__field_hold.writetobuffer(buf)
+ self.__field_key.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_cmd=UINT(**{'sizeinbytes': 1, 'default': 0x20 })
+ self.__field_cmd.readfrombuffer(buf)
+ self.__field_hold=UINT(**{'sizeinbytes': 1, 'default': 0 })
+ self.__field_hold.readfrombuffer(buf)
+ self.__field_key=STRING(**{'sizeinbytes': 1, 'terminator': None, 'sizeinbytes': 1 })
+ self.__field_key.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_cmd(self):
+ try: self.__field_cmd
+ except:
+ self.__field_cmd=UINT(**{'sizeinbytes': 1, 'default': 0x20 })
+ return self.__field_cmd.getvalue()
+
+ def __setfield_cmd(self, value):
+ if isinstance(value,UINT):
+ self.__field_cmd=value
+ else:
+ self.__field_cmd=UINT(value,**{'sizeinbytes': 1, 'default': 0x20 })
+
+ def __delfield_cmd(self): del self.__field_cmd
+
+ cmd=property(__getfield_cmd, __setfield_cmd, __delfield_cmd, None)
+
+ def __getfield_hold(self):
+ try: self.__field_hold
+ except:
+ self.__field_hold=UINT(**{'sizeinbytes': 1, 'default': 0 })
+ return self.__field_hold.getvalue()
+
+ def __setfield_hold(self, value):
+ if isinstance(value,UINT):
+ self.__field_hold=value
+ else:
+ self.__field_hold=UINT(value,**{'sizeinbytes': 1, 'default': 0 })
+
+ def __delfield_hold(self): del self.__field_hold
+
+ hold=property(__getfield_hold, __setfield_hold, __delfield_hold, None)
+
+ def __getfield_key(self):
+ return self.__field_key.getvalue()
+
+ def __setfield_key(self, value):
+ if isinstance(value,STRING):
+ self.__field_key=value
+ else:
+ self.__field_key=STRING(value,**{'sizeinbytes': 1, 'terminator': None, 'sizeinbytes': 1 })
+
+ def __delfield_key(self): del self.__field_key
+
+ key=property(__getfield_key, __setfield_key, __delfield_key, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('cmd', self.__field_cmd, None)
+ yield ('hold', self.__field_hold, None)
+ yield ('key', self.__field_key, None)
+
+
+
+
+class ULReq(BaseProtogenClass):
+ ""
+ __fields=['cmd', 'unlock_code', 'unlock_key', 'zero']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(ULReq,self).__init__(**dict)
+ if self.__class__ is ULReq:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(ULReq,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(ULReq,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()
+ try: self.__field_cmd
+ except:
+ self.__field_cmd=UINT(**{'sizeinbytes': 1, 'default': 0xFE })
+ self.__field_cmd.writetobuffer(buf)
+ try: self.__field_unlock_code
+ except:
+ self.__field_unlock_code=UINT(**{'sizeinbytes': 1, 'default': 0x00 })
+ self.__field_unlock_code.writetobuffer(buf)
+ self.__field_unlock_key.writetobuffer(buf)
+ try: self.__field_zero
+ except:
+ self.__field_zero=UINT(**{'sizeinbytes': 1, 'default': 0x00 })
+ self.__field_zero.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_cmd=UINT(**{'sizeinbytes': 1, 'default': 0xFE })
+ self.__field_cmd.readfrombuffer(buf)
+ self.__field_unlock_code=UINT(**{'sizeinbytes': 1, 'default': 0x00 })
+ self.__field_unlock_code.readfrombuffer(buf)
+ self.__field_unlock_key=UINT(**{'sizeinbytes': 4})
+ self.__field_unlock_key.readfrombuffer(buf)
+ self.__field_zero=UINT(**{'sizeinbytes': 1, 'default': 0x00 })
+ self.__field_zero.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_cmd(self):
+ try: self.__field_cmd
+ except:
+ self.__field_cmd=UINT(**{'sizeinbytes': 1, 'default': 0xFE })
+ return self.__field_cmd.getvalue()
+
+ def __setfield_cmd(self, value):
+ if isinstance(value,UINT):
+ self.__field_cmd=value
+ else:
+ self.__field_cmd=UINT(value,**{'sizeinbytes': 1, 'default': 0xFE })
+
+ def __delfield_cmd(self): del self.__field_cmd
+
+ cmd=property(__getfield_cmd, __setfield_cmd, __delfield_cmd, None)
+
+ def __getfield_unlock_code(self):
+ try: self.__field_unlock_code
+ except:
+ self.__field_unlock_code=UINT(**{'sizeinbytes': 1, 'default': 0x00 })
+ return self.__field_unlock_code.getvalue()
+
+ def __setfield_unlock_code(self, value):
+ if isinstance(value,UINT):
+ self.__field_unlock_code=value
+ else:
+ self.__field_unlock_code=UINT(value,**{'sizeinbytes': 1, 'default': 0x00 })
+
+ def __delfield_unlock_code(self): del self.__field_unlock_code
+
+ unlock_code=property(__getfield_unlock_code, __setfield_unlock_code, __delfield_unlock_code, None)
+
+ def __getfield_unlock_key(self):
+ return self.__field_unlock_key.getvalue()
+
+ def __setfield_unlock_key(self, value):
+ if isinstance(value,UINT):
+ self.__field_unlock_key=value
+ else:
+ self.__field_unlock_key=UINT(value,**{'sizeinbytes': 4})
+
+ def __delfield_unlock_key(self): del self.__field_unlock_key
+
+ unlock_key=property(__getfield_unlock_key, __setfield_unlock_key, __delfield_unlock_key, None)
+
+ def __getfield_zero(self):
+ try: self.__field_zero
+ except:
+ self.__field_zero=UINT(**{'sizeinbytes': 1, 'default': 0x00 })
+ return self.__field_zero.getvalue()
+
+ def __setfield_zero(self, value):
+ if isinstance(value,UINT):
+ self.__field_zero=value
+ else:
+ self.__field_zero=UINT(value,**{'sizeinbytes': 1, 'default': 0x00 })
+
+ def __delfield_zero(self): del self.__field_zero
+
+ zero=property(__getfield_zero, __setfield_zero, __delfield_zero, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('cmd', self.__field_cmd, None)
+ yield ('unlock_code', self.__field_unlock_code, None)
+ yield ('unlock_key', self.__field_unlock_key, None)
+ yield ('zero', self.__field_zero, None)
+
+
+
+
+class ULRes(BaseProtogenClass):
+ ""
+ __fields=['cmd', 'unlock_code', 'unlock_key', 'unlock_ok']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(ULRes,self).__init__(**dict)
+ if self.__class__ is ULRes:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(ULRes,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(ULRes,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_cmd.writetobuffer(buf)
+ self.__field_unlock_code.writetobuffer(buf)
+ self.__field_unlock_key.writetobuffer(buf)
+ self.__field_unlock_ok.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_cmd=UINT(**{'sizeinbytes': 1})
+ self.__field_cmd.readfrombuffer(buf)
+ self.__field_unlock_code=UINT(**{'sizeinbytes': 1})
+ self.__field_unlock_code.readfrombuffer(buf)
+ self.__field_unlock_key=UINT(**{'sizeinbytes': 4})
+ self.__field_unlock_key.readfrombuffer(buf)
+ self.__field_unlock_ok=UINT(**{'sizeinbytes': 1})
+ self.__field_unlock_ok.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_cmd(self):
+ return self.__field_cmd.getvalue()
+
+ def __setfield_cmd(self, value):
+ if isinstance(value,UINT):
+ self.__field_cmd=value
+ else:
+ self.__field_cmd=UINT(value,**{'sizeinbytes': 1})
+
+ def __delfield_cmd(self): del self.__field_cmd
+
+ cmd=property(__getfield_cmd, __setfield_cmd, __delfield_cmd, None)
+
+ def __getfield_unlock_code(self):
+ return self.__field_unlock_code.getvalue()
+
+ def __setfield_unlock_code(self, value):
+ if isinstance(value,UINT):
+ self.__field_unlock_code=value
+ else:
+ self.__field_unlock_code=UINT(value,**{'sizeinbytes': 1})
+
+ def __delfield_unlock_code(self): del self.__field_unlock_code
+
+ unlock_code=property(__getfield_unlock_code, __setfield_unlock_code, __delfield_unlock_code, None)
+
+ def __getfield_unlock_key(self):
+ return self.__field_unlock_key.getvalue()
+
+ def __setfield_unlock_key(self, value):
+ if isinstance(value,UINT):
+ self.__field_unlock_key=value
+ else:
+ self.__field_unlock_key=UINT(value,**{'sizeinbytes': 4})
+
+ def __delfield_unlock_key(self): del self.__field_unlock_key
+
+ unlock_key=property(__getfield_unlock_key, __setfield_unlock_key, __delfield_unlock_key, None)
+
+ def __getfield_unlock_ok(self):
+ return self.__field_unlock_ok.getvalue()
+
+ def __setfield_unlock_ok(self, value):
+ if isinstance(value,UINT):
+ self.__field_unlock_ok=value
+ else:
+ self.__field_unlock_ok=UINT(value,**{'sizeinbytes': 1})
+
+ def __delfield_unlock_ok(self): del self.__field_unlock_ok
+
+ unlock_ok=property(__getfield_unlock_ok, __setfield_unlock_ok, __delfield_unlock_ok, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('cmd', self.__field_cmd, None)
+ yield ('unlock_code', self.__field_unlock_code, None)
+ yield ('unlock_key', self.__field_unlock_key, None)
+ yield ('unlock_ok', self.__field_unlock_ok, None)
+
+
+
+
+class data(BaseProtogenClass):
+ __fields=['bytes']
+
+ def __init__(self, *args, **kwargs):
+ dict={}
+ # What was supplied to this function
+ dict.update(kwargs)
+ # Parent constructor
+ super(data,self).__init__(**dict)
+ if self.__class__ is data:
+ self._update(args,dict)
+
+
+ def getfields(self):
+ return self.__fields
+
+
+ def _update(self, args, kwargs):
+ super(data,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(data,kwargs)
+ if len(args):
+ dict2={}
+ dict2.update(kwargs)
+ kwargs=dict2
+ self.__field_bytes=DATA(*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_bytes.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_bytes=DATA()
+ self.__field_bytes.readfrombuffer(buf)
+ self._bufferendoffset=buf.getcurrentoffset()
+
+
+ def __getfield_bytes(self):
+ return self.__field_bytes.getvalue()
+
+ def __setfield_bytes(self, value):
+ if isinstance(value,DATA):
+ self.__field_bytes=value
+ else:
+ self.__field_bytes=DATA(value,)
+
+ def __delfield_bytes(self): del self.__field_bytes
+
+ bytes=property(__getfield_bytes, __setfield_bytes, __delfield_bytes, None)
+
+ def iscontainer(self):
+ return True
+
+ def containerelements(self):
+ yield ('bytes', self.__field_bytes, None)
+
+
+
+
Index: src/phones/com_lgvx8700.py
===================================================================
--- src/phones/com_lgvx8700.py (revision 4288)
+++ src/phones/com_lgvx8700.py (working copy)
@@ -20,6 +20,7 @@
import commport
import p_brew
import helpids
+import com_lg
import com_lgvx8300
import com_lgvx8500
import p_lgvx8700
@@ -59,8 +60,11 @@
def __init__(self, logtarget, commport):
parentphone.__init__(self, logtarget, commport)
- self._in_DM = False
+ # set DM version
+ if self.my_model == 'VX8700':
+ self._DM_vers = 5
+
def getfundamentals(self, results):
"""Gets information fundamental to interopating with the phone and UI.
@@ -154,46 +158,9 @@
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):
- continue
- try:
- self.sendbrewcommand(req, respc, callsetmode=False)
- return True
- except com_phone.modeignoreerrortypes:
- pass
- return False
-
def listsubdirs(self, dir='', recurse=0):
return com_brew.RealBrewProtocol2.getfilesystem(self, dir, recurse, directories=1, files=0)
- def listfiles(self, dir=''):
- if self._in_DM==False and self.my_model=='VX8700':
- # enter DM to enable file reading/writing
- self.enter_DM()
- return com_brew.RealBrewProtocol2.listfiles(self, dir)
-
- def enter_DM (self):
- # request challenge
- req = self.protocolclass.ULReq(unlock_key=0)
- res = self.sendbrewcommand(req, self.protocolclass.ULRes)
-
- # generate and send response
- key = self.get_challenge_response(res.unlock_key);
- req = self.protocolclass.ULReq(unlock_code=1, unlock_key=key)
- res = self.sendbrewcommand(req, self.protocolclass.ULRes)
-
- if res.unlock_ok == 1:
- self.log('Phone is now in DM mode')
- self._in_DM=True
- else:
- self.log('Failed to enter DM mode')
-
#-------------------------------------------------------------------------------
parentprofile=com_lgvx8500.Profile
class Profile(parentprofile):
Index: src/phones/com_lgvx9900.py
===================================================================
--- src/phones/com_lgvx9900.py (revision 4288)
+++ src/phones/com_lgvx9900.py (working copy)
@@ -16,12 +16,13 @@
import common
import com_lg
import com_lgvx9800
+import p_brew
import p_lgvx9900
import helpids
#-------------------------------------------------------------------------------
parentphone=com_lgvx9800.Phone
-class Phone(com_lg.LGUncountedIndexedMedia, parentphone):
+class Phone(com_lg.LGUncountedIndexedMedia, com_lg.LGDMPhone, parentphone):
"Talk to the LG VX9900 cell phone"
desc="LG-VX9900"
@@ -54,9 +55,24 @@
( 'video(sd)', 'dload/sd_video.dat', 'mmc1/my_flix', '', 100, 0x13, None),
)
+ def get_firmware_version(self):
+ # return the firmware version
+ req=p_brew.firmwarerequest()
+ res=self.sendbrewcommand(req, self.protocolclass.firmwareresponse)
+ return res.firmware
+
def __init__(self, logtarget, commport):
parentphone.__init__(self, logtarget, commport)
+ # initialize DM code
+ com_lg.LGDMPhone.__init__(self)
+
+ # set DM version
+ if self.my_model == 'VX9900':
+ _fw_version = self.get_firmware_version()[-1]
+ if _fw_version > '1':
+ self._DM_vers = 5
+
#-------------------------------------------------------------------------------
parentprofile=com_lgvx9800.Profile
class Profile(parentprofile):
Index: src/phones/com_lg.py
===================================================================
--- src/phones/com_lg.py (revision 4288)
+++ src/phones/com_lg.py (working copy)
@@ -1499,7 +1499,150 @@
def saveringtones(self, results, merge):
return self.savemedia('ringtone', 'ringtone-index', self.ringtonelocations, results, merge, self.getringtoneindices)
+class LGDMPhone:
+ _DM_inited = 0
+
+ # default to no DM
+ def _rotate_left(self, value, nbits):
+ return ((value << nbits) | (value >> (32-nbits))) & 0xffffffffL
+ def get_challenge_response(self, challenge):
+ # Reverse engineered and contributed by Nathan Hjelm <[email protected]>
+ # get_challenge_response(challenge):
+ # - Takes the SHA-1 hash of a 16-byte block containing the challenge and returns the proper response.
+ # - The hash used by the vx8700 differs from the standard implementation only in that it does not append a
+ # 1 bit before padding the message with 0's.
+ #
+ # Return value:
+ # Last three bytes of the SHA-1 hash or'd with 0x80000000.
+ # IV = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0)
+ input_vector = [0x67452301L, 0xefcdab89L, 0x98badcfeL, 0x10325476L, 0xc3d2e1f0L]
+ hash_result = [0x67452301L, 0xefcdab89L, 0x98badcfeL, 0x10325476L, 0xc3d2e1f0L]
+ hash_data = []
+ hash_data.append(long(challenge))
+ # pad message with zeros as well and zero first word of bit length
+ # if this were standard SHA-1 then 0x00000080 would be appended here as its a 56-bit message
+ for i in range(14):
+ hash_data.append(0L)
+ # append second word of the bit length (56 bit message?)
+ hash_data.append(56L)
+ for i in range(80):
+ j = i & 0x0f
+ if i > 15:
+ index1 = (i - 3) & 0x0f
+ index2 = (i - 8) & 0x0f
+ index3 = (i - 14) & 0x0f
+ hash_data[j] = hash_data[index1] ^ hash_data[index2] ^ hash_data[index3] ^ hash_data[j]
+ hash_data[j] = self._rotate_left (hash_data[j], 1)
+ if i < 20:
+ # f = (B and C) or ((not B) and C), k = 0x5a827999
+ f = (hash_result[1] & hash_result[2]) | ((~hash_result[1]) & hash_result[3])
+ k = 0x5a827999L
+ elif i < 40:
+ # f = B xor C xor D, k = 0x6ed9eba1
+ f = hash_result[1] ^ hash_result[2] ^ hash_result[3]
+ k = 0x6ed9eba1L
+ elif i < 60:
+ # f = (B and C) or (B and D) or (B and C), k = 0x8f1bbcdc
+ f = (hash_result[1] & hash_result[2]) | (hash_result[1] & hash_result[3]) | (hash_result[2] & hash_result[3])
+ k = 0x8f1bbcdcL
+ else:
+ # f = B xor C xor D, k = 0xca62c1d6
+ f = hash_result[1] ^ hash_result[2] ^ hash_result[3]
+ k = 0xca62c1d6L
+ # A = E + rotate_left (A, 5) + w[j] + f + k
+ newA = (hash_result[4] + self._rotate_left(hash_result[0], 5) + hash_data[j] + f + k) & 0xffffffffL
+ # B = oldA, C = rotate_left(B, 30), D = C, E = D
+ hash_result = [newA] + hash_result[0:4]
+ hash_result[2] = self._rotate_left (hash_result[2], 30)
+ for i in range(5):
+ hash_result[i] = (hash_result[i] + input_vector[i]) & 0xffffffffL
+ return 0x80000000L | (hash_result[4] & 0x00ffffffL)
+
+ def _unlock_key(self):
+ _req=self.protocolclass.LockKeyReq(lock=1)
+ self.sendbrewcommand(_req, self.protocolclass.data)
+
+ def _lock_key(self):
+ _req=self.protocolclass.LockKeyReq()
+ self.sendbrewcommand(_req, self.protocolclass.data)
+
+ def _press_key(self, keys):
+ # simulate a series of keypress
+ if not keys:
+ return
+ _req=self.protocolclass.KeyPressReq()
+ for _k in keys:
+ _req.key=_k
+ self.sendbrewcommand(_req, self.protocolclass.data)
+
+ def _enter_DMv4(self):
+ self._lock_key()
+ self._press_key('\x06\x513733929\x51')
+ self._unlock_key()
+
+ def _enter_DMv5(self):
+ # request the seed
+ _req=self.protocolclass.ULReq(unlock_key=0)
+ _resp=self.sendbrewcommand(_req, self.protocolclass.ULRes)
+
+ # respond with the key
+ _key=self.get_challenge_response(_resp.unlock_key)
+ if _key is None:
+ self.log('Failed to get the key.')
+ raise
+
+ _req=self.protocolclass.ULReq(unlock_code=1, unlock_key=_key)
+ _resp=self.sendbrewcommand(_req, self.protocolclass.ULRes)
+ if _resp.unlock_ok!=1:
+ raise
+
+ def enter_DM(self):
+ if self._DM_vers != -1:
+ try:
+ if self._DM_vers == 5:
+ self._enter_DMv5()
+ self._enter_DMv4()
+ self.log('Now in download mode (DM)')
+ self._in_DM=True
+ except:
+ if __debug__:
+ raise
+ self.log('Failed to enter download mode (DM)')
+
+ def _getfilecontents(self, name, use_cache=False):
+ if self._in_DM==False:
+ self.enter_DM()
+ return self._real_getfilecontents(name, use_cache)
+
+ def _writefile(self, name, contents):
+ if self._in_DM==False:
+ self.enter_DM()
+ return self._real_writefile(name, contents)
+
+ def _statfile(self, name):
+ if self._in_DM==False:
+ self.enter_DM()
+ return self._real_statfile(name)
+
+ def __init__(self):
+ self._DM_vers = -1
+ self._in_DM = False
+
+ # don't call setup code more than once
+ if self._DM_inited == 0:
+ # intercept filesystem commands to ensure phone gets set into download mode when needed
+ setattr (self, '_real_getfilecontents', self.getfilecontents)
+ setattr (self, '_real_writefile', self.writefile)
+ setattr (self, '_real_statfile', self.statfile)
+
+ setattr (self, 'getfilecontents', self._getfilecontents)
+ setattr (self, 'writefile', self._writefile)
+ setattr (self, 'statfile', self._statfile)
+ self._DM_inited = 1
+
+ self.log ('Download mode setup complete')
+
def basename(name):
if name.rfind('/')>=0:
pos=name.rfind('/')
Index: src/phones/com_lgvx8500.py
===================================================================
--- src/phones/com_lgvx8500.py (revision 4288)
+++ src/phones/com_lgvx8500.py (working copy)
@@ -20,6 +20,7 @@
# BitPim modules
import common
import com_brew
+import com_lg
import com_lgvx8300
import helpids
import fileinfo
@@ -31,13 +32,9 @@
import prototypes
import prototypeslg
import t9editor
-try:
- import pyvx8500
-except ImportError:
- pyvx8500=None
parentphone=com_lgvx8300.Phone
-class Phone(parentphone):
+class Phone(com_lg.LGDMPhone, parentphone):
desc="LG-VX8500"
helpid=helpids.ID_PHONE_LGVX8500
@@ -68,8 +65,17 @@
def __init__(self, logtarget, commport):
parentphone.__init__(self, logtarget, commport)
- self._in_DM=False
+ # initialize DM code
+ com_lg.LGDMPhone.__init__(self)
+ # set DM version
+ if self.my_model == 'VX8500':
+ _fw_version = self.get_firmware_version()[-1]
+ if _fw_version > '4':
+ self._DM_vers = 5
+ else:
+ self._DM_vers = 4
+
def getfundamentals(self, results):
"""Gets information fundamental to interopating with the phone and UI.
@@ -403,111 +409,6 @@
res=self.sendbrewcommand(req, self.protocolclass.firmwareresponse)
return res.firmware
- def _unlock_key(self):
- _req=self.protocolclass.LockKeyReq(lock=1)
- self.sendbrewcommand(_req, self.protocolclass.data)
- def _lock_key(self):
- _req=self.protocolclass.LockKeyReq()
- self.sendbrewcommand(_req, self.protocolclass.data)
-
- def _press_key(self, keys):
- # simulate a series of keypress
- if not keys:
- return
- _req=self.protocolclass.KeyPressReq()
- for _k in keys:
- _req.key=_k
- self.sendbrewcommand(_req, self.protocolclass.data)
-
- def _enter_DMv4(self):
- self._lock_key()
- self._press_key('\x06\x513733929\x51')
- self._unlock_key()
- self._in_DM=True
-
- def _rotate_left(self, value, nbits):
- return ((value << nbits) | (value >> (32-nbits))) & 0xffffffffL
-
- def get_challenge_response(self, challenge):
- # Reverse engineered and contributed by Nathan Hjelm <[email protected]>
- # get_challenge_response(challenge):
- # - Takes the SHA-1 hash of a 16-byte block containing the challenge and returns the proper response.
- # - The hash used by the vx8700 differs from the standard implementation only in that it does not append a
- # 1 bit before padding the message with 0's.
- #
- # Return value:
- # Last three bytes of the SHA-1 hash or'd with 0x80000000.
- # IV = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0)
- input_vector = [0x67452301L, 0xefcdab89L, 0x98badcfeL, 0x10325476L, 0xc3d2e1f0L]
- hash_result = [0x67452301L, 0xefcdab89L, 0x98badcfeL, 0x10325476L, 0xc3d2e1f0L]
- hash_data = []
- hash_data.append(long(challenge))
- # pad message with zeros as well and zero first word of bit length
- # if this were standard SHA-1 then 0x00000080 would be appended here as its a 56-bit message
- for i in range(14):
- hash_data.append(0L)
- # append second word of the bit length (56 bit message?)
- hash_data.append(56L)
- for i in range(80):
- j = i & 0x0f
- if i > 15:
- index1 = (i - 3) & 0x0f
- index2 = (i - 8) & 0x0f
- index3 = (i - 14) & 0x0f
- hash_data[j] = hash_data[index1] ^ hash_data[index2] ^ hash_data[index3] ^ hash_data[j]
- hash_data[j] = self._rotate_left (hash_data[j], 1)
- if i < 20:
- # f = (B and C) or ((not B) and C), k = 0x5a827999
- f = (hash_result[1] & hash_result[2]) | ((~hash_result[1]) & hash_result[3])
- k = 0x5a827999L
- elif i < 40:
- # f = B xor C xor D, k = 0x6ed9eba1
- f = hash_result[1] ^ hash_result[2] ^ hash_result[3]
- k = 0x6ed9eba1L
- elif i < 60:
- # f = (B and C) or (B and D) or (B and C), k = 0x8f1bbcdc
- f = (hash_result[1] & hash_result[2]) | (hash_result[1] & hash_result[3]) | (hash_result[2] & hash_result[3])
- k = 0x8f1bbcdcL
- else:
- # f = B xor C xor D, k = 0xca62c1d6
- f = hash_result[1] ^ hash_result[2] ^ hash_result[3]
- k = 0xca62c1d6L
- # A = E + rotate_left (A, 5) + w[j] + f + k
- newA = (hash_result[4] + self._rotate_left(hash_result[0], 5) + hash_data[j] + f + k) & 0xffffffffL
- # B = oldA, C = rotate_left(B, 30), D = C, E = D
- hash_result = [newA] + hash_result[0:4]
- hash_result[2] = self._rotate_left (hash_result[2], 30)
- for i in range(5):
- hash_result[i] = (hash_result[i] + input_vector[i]) & 0xffffffffL
- return 0x80000000L | (hash_result[4] & 0x00ffffffL)
-
- def _enter_DMv5(self):
- self._in_DM=True
- # request the seed
- _req=self.protocolclass.DMKeyReq()
- _resp=self.sendbrewcommand(_req, self.protocolclass.DMKeyResp)
- # respond with the key
- _key=self.get_challenge_response(_resp.key)
- if _key is None:
- self.log('Failed to get the key.')
- return
- _req=self.protocolclass.DMReq(key=_key)
- self.sendbrewcommand(_req, self.protocolclass.DMResp)
-
- def enter_DM(self):
- try:
- _fw_version=self.get_firmware_version()[-1]
- if self.my_model=='VX8500' and _fw_version>'4':
- self._enter_DMv5()
- else:
- self._enter_DMv4()
- self.log('Now in DM')
- except:
- if __debug__:
- raise
- self.log('Failed to enter DM')
- self._in_DM=True
-
#-------------------------------------------------------------------------------
parentprofile=com_lgvx8300.Profile
class Profile(parentprofile):
Index: src/phones/com_lgvx9400.py
===================================================================
--- src/phones/com_lgvx9400.py (revision 4288)
+++ src/phones/com_lgvx9400.py (working copy)
@@ -39,11 +39,11 @@
my_model='VX9400'
- # Joe Pham: defer this along with other LG patches.
-## def __init__(self, logtarget, commport):
-## parentphone.__init__(self, logtarget, commport)
-## if self.my_model == 'VX9400':
-## self._DM_vers = 5
+ def __init__(self, logtarget, commport):
+ parentphone.__init__(self, logtarget, commport)
+ # set DM version
+ if self.my_model == 'VX9400':
+ self._DM_vers = 5
#-------------------------------------------------------------------------------
parentprofile=com_lgvx8700.Profile
Index: src/phones/p_lg.p
===================================================================
--- src/phones/p_lg.p (revision 4288)
+++ src/phones/p_lg.p (working copy)
@@ -125,3 +125,33 @@
# 0x05 delete entry
# 0x04 write entry (advances to next entry)
# 0x03 append entry (advances to next entry)
+
+
+# download mode
+PACKET LockKeyReq:
+ 1 UINT { 'default': 0x21 } +cmd
+ 2 UINT { 'default': 0 } +lock "0=Lock, 1=Unlock"
+
+PACKET KeyPressReq:
+ 1 UINT { 'default': 0x20 } +cmd
+ 1 UINT { 'default': 0 } +hold
+ 1 STRING { 'terminator': None,
+ 'sizeinbytes': 1 } key
+
+PACKET ULReq:
+ ""
+ 1 UINT { 'default': 0xFE } +cmd
+ 1 UINT { 'default': 0x00 } +unlock_code
+ 4 UINT unlock_key
+ 1 UINT { 'default': 0x00 } +zero
+
+PACKET ULRes:
+ ""
+ 1 UINT cmd
+ 1 UINT unlock_code
+ 4 UINT unlock_key
+ 1 UINT unlock_ok
+
+
+PACKET data:
+ * DATA bytes
Index: src/phones/com_lgvx5300.py
===================================================================
--- src/phones/com_lgvx5300.py (revision 4288)
+++ src/phones/com_lgvx5300.py (working copy)
@@ -40,7 +40,7 @@
import fileinfo
import helpids
-class Phone(com_lg.LGUncountedIndexedMedia, com_lgvx8100.Phone):
+class Phone(com_lg.LGDMPhone, com_lg.LGUncountedIndexedMedia, com_lgvx8100.Phone):
"Talk to the LG VX5300 cell phone"
desc="LG-VX5300"
@@ -74,11 +74,25 @@
( 'video', 'dload/video.dat', 'brew/16452/mf', '', 100, 0x03, None),
)
+ def get_firmware_version(self):
+ # return the firmware version
+ req=p_brew.firmwarerequest()
+ res=self.sendbrewcommand(req, self.protocolclass.firmwareresponse)
+ return res.firmware
+
def __init__(self, logtarget, commport):
com_lgvx8100.Phone.__init__(self, logtarget, commport)
p_brew.PHONE_ENCODING=self.protocolclass.PHONE_ENCODING
self.mode=self.MODENONE
+ # DM mode
+ if self.my_model=='VX5300':
+ _fw_vers = self.get_firmware_version()[-1]
+ if _fw_vers > '3':
+ com_lg.LGDMPhone.__init__(self)
+ self._DM_vers = 5
+
+
def get_esn(self, data=None):
# return the ESN of this phone
return self.get_brew_esn()