Re: A start on the LG LX-260 (Sprint Rumor)

Joe Siegrist <[email protected]>
Newsgroups gmane.comp.mobile.bitpim.devel
Message-ID <[email protected]>
Attached is a patch against the current SVN; my changes to com_lgvx4400.py are clearly just a hack to make phonebook import/export so don’t commit those to the main tree. 

 

I wish I had more time to spend on this to fully complete it, but this is  a pretty good start, and will properly fetch and put contacts onto the phone.

 

Joe

 

From: Joe Siegrist [mailto:[email protected]] 
Sent: Wednesday, June 11, 2008 10:10 AM
To: [email protected]
Subject: A start on the LG LX-260 (Sprint Rumor)

 

I've started work to support the Sprint Rumor LG LX-260, so far it detects properly, and the phone info page is done including the phone number, firmware and ESN, and I'm able to seeing info from the pbreadentryresponse on reading, and if I hack around groups in com_lgvx4400.py I can write the names into the phonebook.

Do the devs congregate on an IRC channel?   I see #bitpim exists on irc.freenode.net, but no one is home. My biggest blocker on making faster progress has been the need to ask quick questions.

I'm not sure how to figure out the groups, it looks like just about all the lg phones grab pim/pbgroup.dat which I don't have (see below).. for now I've just commented it out but that seems pretty fundamental; I'm not sure where to begin on this.

I made an entry in the phonebook to help figure out what everything is, but I'm still unsure if I'm on the right track (NNN is name, MMM is memo, e1,e2,e3 email, 1111 first phone number, etc); for stuff that appears to be all null what is the convention in the pbentry?

<#! phones.p_lglx260.pbreadentryresponse !#>
00000000 ff 13 03 00 48 01 00 00 a0 02 48 01 00 00 00 00     ....H.....H.....
00000010 00 00 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e     ..NNNNNNNNNNNNNN
00000020 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e     NNNNNNNNNNNNNNNN
00000030 4e 4e 00 00 00 00 00 00 00 00 00 00 00 00 00 00     NN..............
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000050 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00     ................
00000060 00 00 00 00 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d     ....MMMMMMMMMMMM
00000070 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d     MMMMMMMMMMMMMMMM
00000080 4d 4d 4d 4d 00 65 31 40 65 65 65 65 65 65 65 65     MMMM.e1@eeeeeeee
00000090 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
000000a0 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
000000b0 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
000000c0 65 65 65 65 65 65 65 65 65 65 65 65 65 00 65 32     eeeeeeeeeeeee.e2
000000d0 40 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     @eeeeeeeeeeeeeee
000000e0 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
000000f0 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
00000100 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
00000110 65 65 65 65 65 65 00 65 33 40 65 65 65 65 65 65     eeeeee.e3@eeeeee
00000120 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
00000130 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
00000140 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65     eeeeeeeeeeeeeeee
00000150 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 00     eeeeeeeeeeeeeee.
00000160 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55     UUUUUUUUUUUUUUUU
00000170 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55     UUUUUUUUUUUUUUUU
00000180 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55     UUUUUUUUUUUUUUUU
00000190 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55     UUUUUUUUUUUUUUUU
000001a0 55 55 55 55 55 55 55 55 00 ff ff ff ff ff 00 01     UUUUUUUU........
000001b0 02 03 04 31 31 31 31 31 31 31 31 31 31 31 31 31     ...1111111111111
000001c0 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31     1111111111111111
000001d0 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31     1111111111111111
000001e0 31 31 31 00 32 32 32 32 32 32 32 32 32 32 32 32     111.222222222222
000001f0 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32     2222222222222222
00000200 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32     2222222222222222
00000210 32 32 32 32 00 33 33 33 33 33 33 33 33 33 33 33     2222.33333333333
00000220 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33     3333333333333333
00000230 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33     3333333333333333
00000240 33 33 33 33 33 00 34 34 34 34 34 34 34 34 34 34     33333.4444444444
00000250 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34     4444444444444444
00000260 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34     4444444444444444
00000270 34 34 34 34 34 34 00 35 35 35 35 35 35 35 35 35     444444.555555555
00000280 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35     5555555555555555
00000290 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35     5555555555555555
000002a0 35 35 35 35 35 35 35 00 00 00                       5555555...

Based on this I wrote pbentry: 
PACKET pbentry:
    4  UINT serial1
    2  UINT {'constant': 0x02A0}  +entrysize
    4  UINT serial2
    2  UINT entrynumber
    1  BOOL secret
    1  BOOL secret
    33 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} name
    49 USTRING memo
    33 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} memo
    *  LIST {'length': NUMEMAILS} +emails:
        73 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} email
    73 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} url
    1  BOOL secret
    1  BOOL secret
    1  BOOL secret
    1  BOOL secret
    1  BOOL secret
    *  LIST {'length': NUMPHONENUMBERS} +numbertypes:
       1 UINT numbertype
    *  LIST {'length': NUMPHONENUMBERS} +numbers:
        49 USTRING {'raiseonunterminatedread': True} number
    2  UINT entrynumber

Is there a good example of someone doing this from the protocol output?

It seems like some code like this would be helpful after phone detection (as I wasted time assuming that my lx260 was like any of the other lg phones with files like pim/pbgroup.dat ):

 dirlisting=self.getfilesystem('', 1)
 keys = dirlisting.keys()
 keys.sort()
 for i in keys:
    self.log('file: '+ i)

Running this on the rumor looks like this:

22:22:13.453 LG-LX260: file: /$SYS.FACTORY
22:22:13.453 LG-LX260: file: /CLK_DB
22:22:13.453 LG-LX260: file: /RDM_DEV_MAP
22:22:13.454 LG-LX260: file: /config
22:22:13.454 LG-LX260: file: /devices
22:22:13.454 LG-LX260: file: CIQ
22:22:13.454 LG-LX260: file: CIQ/CIQCOOK
22:22:13.456 LG-LX260: file: CIQ/CIQPROFIL
22:22:13.456 LG-LX260: file: CIQ/CIQPRSTAT
22:22:13.456 LG-LX260: file: DB
22:22:13.457 LG-LX260: file: DB/SchemaFiles
22:22:13.457 LG-LX260: file: DB/SysDB
22:22:13.457 LG-LX260: file: Dcam
22:22:13.457 LG-LX260: file: Dcam/PictbridgeFat.dat
22:22:13.457 LG-LX260: file: Dcam/Review
22:22:13.457 LG-LX260: file: Dcam/ReviewFat.dat
22:22:13.457 LG-LX260: file: Dcam/Wallet
22:22:13.457 LG-LX260: file: Dcam/WalletFat.dat
22:22:13.457 LG-LX260: file: EPM
22:22:13.457 LG-LX260: file: EPM/FileStore
22:22:13.457 LG-LX260: file: EPM/MediaStore
22:22:13.459 LG-LX260: file: EPM/MessageStore
22:22:13.459 LG-LX260: file: EPM/OEM_Transfers
22:22:13.459 LG-LX260: file: EPM/phone.cfg
22:22:13.459 LG-LX260: file: VoiceDB
22:22:13.459 LG-LX260: file: VoiceDB/All
22:22:13.459 LG-LX260: file: VoiceDB/Lang
22:22:13.460 LG-LX260: file: alarm
22:22:13.460 LG-LX260: file: alarm/alarm.dat
22:22:13.460 LG-LX260: file: alarm/ani_preloaded1.m3g
22:22:13.460 LG-LX260: file: brew
22:22:13.460 LG-LX260: file: brew/.ui_fill
22:22:13.460 LG-LX260: file: brew/ams
22:22:13.460 LG-LX260: file: brew/mif
22:22:13.460 LG-LX260: file: brew/mod
22:22:13.460 LG-LX260: file: brew/shared
22:22:13.460 LG-LX260: file: brew/sys
22:22:13.460 LG-LX260: file: brew/version.txt
22:22:13.460 LG-LX260: file: core
22:22:13.460 LG-LX260: file: core/CLOCK
22:22:13.460 LG-LX260: file: core/CMFL-1300
22:22:13.460 LG-LX260: file: core/CMFL-1310
22:22:13.460 LG-LX260: file: core/CMFL-6093
22:22:13.461 LG-LX260: file: core/CMFL-60D0
22:22:13.461 LG-LX260: file: mmc1
22:22:13.463 LG-LX260: file: mmc1/DCIM
22:22:13.463 LG-LX260: file: nvm
22:22:13.463 LG-LX260: file: nvm/$SYS.ESN
22:22:13.463 LG-LX260: file: nvm/$SYS.INVAR1
22:22:13.463 LG-LX260: file: nvm/$SYS.INVAR2
22:22:13.463 LG-LX260: file: nvm/$SYS.INVAR3
22:22:13.463 LG-LX260: file: nvm/$SYS.MEID
22:22:13.463 LG-LX260: file: nvm/nvm
22:22:13.463 LG-LX260: file: nvm/prl
22:22:13.463 LG-LX260: file: nvm/sms
22:22:13.463 LG-LX260: file: pim
22:22:13.463 LG-LX260: file: pim/MyInformation.dat
22:22:13.463 LG-LX260: file: pim/multiAlert.dat
22:22:13.464 LG-LX260: file: pim/sp_num.dat
22:22:13.464 LG-LX260: file: pim/tsb58a.dat
22:22:13.464 LG-LX260: file: rom_ui
22:22:13.464 LG-LX260: file: rom_ui/file1
22:22:13.466 LG-LX260: file: rom_ui/file2
22:22:13.466 LG-LX260: file: rom_ui/file3
22:22:13.466 LG-LX260: file: rom_ui/file4
22:22:13.466 LG-LX260: file: rom_ui/file5
22:22:13.466 LG-LX260: file: rom_ui/file6
22:22:13.467 LG-LX260: file: rom_ui/file7
22:22:13.467 LG-LX260: file: rom_vdb
22:22:13.467 LG-LX260: file: rom_vdb/file1
22:22:13.467 LG-LX260: file: rom_vdb/file2
22:22:13.467 LG-LX260: file: rom_vdb/file3
22:22:13.467 LG-LX260: file: rom_vdb/file4
22:22:13.467 LG-LX260: file: sch
22:22:13.467 LG-LX260: file: sch/dday.dat
22:22:13.467 LG-LX260: file: setas
22:22:13.469 LG-LX260: file: setas/amsImageIndex.map
22:22:13.469 LG-LX260: file: setas/slideshow
22:22:13.469 LG-LX260: file: sms
22:22:13.469 LG-LX260: file: sms/canned_msg.dat
22:22:13.469 LG-LX260: file: sms/inbox000.dat
22:22:13.470 LG-LX260: file: sms/inbox001.dat
22:22:13.470 LG-LX260: file: sms/inbox002.dat
22:22:13.470 LG-LX260: file: sms/inbox003.dat
22:22:13.470 LG-LX260: file: sms/inbox004.dat
22:22:13.470 LG-LX260: file: sms/inbox005.dat
22:22:13.470 LG-LX260: file: sms/recentlists.dat
22:22:13.470 LG-LX260: file: sms/user_folder.dat
22:22:13.470 LG-LX260: file: sms/voice.dat
22:22:13.470 LG-LX260: file: t9cdb
22:22:13.471 LG-LX260: file: t9cdb/t9cdb_eng.dat
22:22:13.471 LG-LX260: file: t9cdb/t9cdb_spa.dat
22:22:13.473 LG-LX260: file: t9udb
22:22:13.473 LG-LX260: file: t9udb/t9udb_eng.dat
22:22:13.473 LG-LX260: file: t9udb/t9udb_spa.dat
22:22:13.473 LG-LX260: file: user
22:22:13.473 LG-LX260: file: user/sound

Thanks,

Joe

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php

_______________________________________________
BitPim-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bitpim-devel
lglx260_support.patch (application/octet-stream, 22 KB)
Index: __init__.py
===================================================================
--- __init__.py	(revision 4618)
+++ __init__.py	(working copy)
@@ -34,7 +34,12 @@
 b_audiovox='Audiovox'
 b_moto='Motorola'
 
-_phonedata= { 'LG-AX8600': { 'module': 'com_lgax8600',
+_phonedata= { 'LG-LX260': {  'module': 'com_lglx260',
+                             'carrier': [c_sprint],
+                             'brand': b_lg,
+                             'helpid': None,
+                             }, 
+	      'LG-AX8600': { 'module': 'com_lgax8600',
 	    		     'carrier': [c_alltel],
 			     'brand': b_lg,
 			     'helpid': helpids.ID_PHONE_LGAX8600,
@@ -509,6 +514,7 @@
               }
 
 if __debug__:
+
     _phonedata.update( {'Audiovox CDM-8900': { 'module': 'com_audiovoxcdm8900',     # phone is too fragile for normal use
                                                'brand': b_audiovox,
                                                'helpid': None,
Index: p_lglx260.p
===================================================================
--- p_lglx260.p	(revision 0)
+++ p_lglx260.p	(revision 0)
@@ -0,0 +1,337 @@
+### BITPIM
+###
+### Copyright (C) 2006 Simon Cappper <[email protected]>
+###
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of the BitPim license as detailed in the LICENSE file.
+###
+
+%{
+
+"""Various descriptions of data specific to LG LX260"""
+
+from prototypes import *
+
+# Make all lg stuff available in this module as well
+from p_lg import *
+
+# we are the same as lgvx4400 except as noted
+# below
+from p_lgvx4400 import *
+
+# We use LSB for all integer like fields
+UINT=UINTlsb
+BOOL=BOOLlsb
+
+NOWALLPAPER=1
+NUMSPEEDDIALS=100
+FIRSTSPEEDDIAL=2
+LASTSPEEDDIAL=99
+NUMPHONEBOOKENTRIES=499
+MAXCALENDARDESCRIPTION=38
+MAX_PHONEBOOK_GROUPS=0
+
+NUMEMAILS=3
+NUMPHONENUMBERS=5
+
+MEMOLENGTH=32
+
+# Calendar parameters
+NUMCALENDARENTRIES=300
+CAL_REP_NONE=0x10
+CAL_REP_DAILY=0x11
+CAL_REP_MONFRI=0x12
+CAL_REP_WEEKLY=0x13
+CAL_REP_MONTHLY=0x14
+CAL_REP_YEARLY=0x15
+CAL_DOW_SUN=0x0800
+CAL_DOW_MON=0x0400
+CAL_DOW_TUE=0x0200
+CAL_DOW_WED=0x0100
+CAL_DOW_THU=0x0080
+CAL_DOW_FRI=0x0040
+CAL_DOW_SAT=0x0020
+CAL_DOW_EXCEPTIONS=0x0010
+CAL_REMINDER_NONE=0
+CAL_REMINDER_ONTIME=1
+CAL_REMINDER_5MIN=2
+CAL_REMINDER_10MIN=3
+CAL_REMINDER_1HOUR=4
+CAL_REMINDER_1DAY=5
+CAL_REMINDER_2DAYS=6
+CAL_NO_VOICE=0xffff
+CAL_REPEAT_DATE=(2100, 12, 31)
+
+cal_dir='sch'
+cal_voice_ext='.qcp'      # full name='sche000.qcp'
+cal_data_file_name='sch/schedule.dat'
+cal_exception_file_name='sch/schexception.dat'
+cal_voice_id_ofs=0x0f
+cal_has_voice_id=True
+
+PHONE_ENCODING='iso8859_1'
+%}
+
+
+PACKET pbgroup:
+    "A single group"
+    1 UINT icon
+    23 USTRING {'encoding': PHONE_ENCODING} name
+
+PACKET pbgroups:
+    "Phonebook groups"
+    * LIST {'elementclass': pbgroup} +groups
+
+PACKET speeddial:
+    2 UINT {'default': 0xffff} +entry
+    1 UINT {'default': 0xff} +number
+
+PACKET speeddials:
+    * LIST {'length': NUMSPEEDDIALS, 'elementclass': speeddial} +speeddials
+
+PACKET indexentry:
+    2 UINT {'default': 0xffff} +index
+    50 USTRING {'default': ""} +name
+
+PACKET indexfile:
+    "Used for tracking wallpaper and ringtones"
+    # A bit of a silly design again.  Entries with an index of 0xffff are
+    # 'blank'.  Thus it is possible for numactiveitems and the actual
+    # number of valid entries to be mismatched.
+    2 UINT numactiveitems
+    * LIST {'elementclass': indexentry, 'createdefault': True} +items
+
+# All STRINGS have raiseonterminatedread as False since the phone does
+# occassionally leave out the terminator byte
+# Note if you change the length of any of these fields, you also
+# need to modify com_lgLX260 to give a different truncatate parameter
+# in the convertphonebooktophone method
+PACKET pbentry:
+    4  UINT serial1    
+    2  UINT {'constant': 0x02A0}  +entrysize
+    4  UINT serial2
+    2  UINT entrynumber 
+    2  UINT {'default': 0} +unknown0
+    33 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} name
+    49 USTRING {'default': ""} +unknown1
+    33 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} memo
+    *  LIST {'length': NUMEMAILS} +emails:   
+        73 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} email
+    73 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': True} url
+    1  UINT {'default': 0xff} +unknownf1
+    1  UINT {'default': 0xff} +unknownf2
+    1  UINT {'default': 0xff} +unknownf3
+    1  UINT {'default': 0xff} +unknownf4
+    1  UINT {'default': 0xff} +unknownf5
+    *  LIST {'length': NUMPHONENUMBERS} +numbertypes:   
+       1 UINT numbertype
+    *  LIST {'length': NUMPHONENUMBERS} +numbers:   
+        49 USTRING {'raiseonunterminatedread': True} number
+    1  UINT {'default': 0} +unknown2
+
+PACKET pbreadentryresponse:
+    "Results of reading one entry"
+    *  pbheader header
+    *  pbentry  entry
+
+PACKET pbupdateentryrequest:
+    * pbheader {'command': 0x04, 'flag': 0x01} +header
+    * pbentry entry
+
+PACKET pbappendentryrequest:
+    * pbheader {'command': 0x03, 'flag': 0x01} +header
+    * pbentry entry
+
+###
+### The calendar
+###
+#
+#   The calendar consists of one file listing events and an exception
+#   file that lists exceptions.  These exceptions suppress a particular
+#   instance of a repeated event.  For example, if you setup something
+#   to happen monthly, but changed the 1st february event, then the
+#   schedule will contain the repeating event, and the 1st feb one,
+#   and the suppresions/exceptions file will point to the repeating
+#   event and suppress the 1st feb.
+#   The phone uses the position within the file to give an event an id
+
+PACKET scheduleexception:
+    4 UINT pos "Refers to event id (position in schedule file) that this suppresses"
+    1 UINT day
+    1 UINT month
+    2 UINT year
+
+PACKET scheduleexceptionfile:
+    * LIST {'elementclass': scheduleexception} +items
+
+PACKET scheduleevent:
+    4 UINT pos "position within file, used as an event id"
+    4 LGCALDATE start
+    4 LGCALDATE end
+    1 UINT repeat
+    2 UINT daybitmap  "which days a weekly repeat event happens on"
+    1 UINT { 'default': 0 } +pad2
+    1 UINT alarmminutes  "a value of 100 indicates not set"
+    1 UINT alarmhours    "a value of 100 indicates not set"
+    1 UINT alarmtype    "preset alarm reminder type"
+    1 UINT { 'default': 0 } +snoozedelay   "in minutes, not for this phone"
+    1 UINT ringtone
+    37 USTRING {'encoding': PHONE_ENCODING, 'raiseontruncate': False,
+               'raiseonunterminatedread': False } description
+    2 UINT hasvoice
+    2 UINT voiceid
+    2 UINT { 'default': 0 } +pad3
+
+PACKET schedulefile:
+    2 UINT numactiveitems
+    * LIST {'elementclass': scheduleevent} +events
+
+PACKET call:
+    4 GPSDATE GPStime #no. of seconds since 0h 1-6-80, based off local time.
+    4 UINT unknown1 # different for each call
+    4 UINT duration #seconds, not certain about length of this field
+    49 USTRING {'raiseonunterminatedread': False} number
+    36 USTRING {'encoding': PHONE_ENCODING, 'raiseonunterminatedread': False} name
+    1 UINT numberlength # length of phone number
+    1 UINT unknown2 # set to 1 on some calls
+    1 UINT pbnumbertype # 1=cell, 2=home, 3=office, 4=cell2, 5=fax, 6=vmail, 0xFF=not in phone book
+    2 UINT unknown3 # always seems to be 0
+    2 UINT pbentrynum #entry number in phonebook
+
+PACKET callhistory:
+    4 UINT numcalls
+    1 UINT unknown1
+    * LIST {'elementclass': call} +calls
+    
+PACKET firmwareresponse:
+    1 UINT command
+    11 USTRING {'terminator': None}  date1
+    8 USTRING {'terminator': None}  time1
+    11 USTRING {'terminator': None}  date2
+    8 USTRING {'terminator': None}  time2
+    8 USTRING {'terminator': None}  firmware
+
+###
+### SMS 
+###
+#
+#   There are 3 types of SMS records, The inbox, outbox and unsent (pending)
+#   Unlike other records in the phone each message is stored in a separate file
+#   All messages are in the 'sms' directory in the root of the phone
+#   Inbox messages are in files called 'inbox000.dat', the number 000 varies for
+#   each message, typically there are no gaps in the numbering, but gaps can appear
+#   if a message is deleted.
+#   Outbox message are named 'outbox000.dat', unsent messages are named 'sf00.dat',
+#   only two digit file name that suggests a max of 100 message for this type.
+#   Messages in the outbox get updated when the message is received by the recipient,
+#   they contain a delivery flag and a delivery time for all the possible 10 recipients.
+#   The vx8100 supports SMS contatination, this allows you to send text messages that are
+#   longer than 160 characters. The format is different for these type of messages, but
+#   it is supported by this implementation.
+#   The vx8100 also allows you to put small graphics, sounds and animations in a message.
+#   This implementation does not support these, if they are contained in a message they
+#   will be ignored and just the text will be shown when you view the message in bitpim.
+#   The text in the the messages is stored in 7-bit characters, so they have
+#   to be unpacked, in concatinated messages and messages with embeded graphics etc. the
+#   format uses the GSM 03.38 specified format, a good example of this can be found at
+#   "http://www.dreamfabric.com/sms/hello.html".
+#   For simple messages less than 161 characters with no graphics the format is simpler, 
+#   the 7-bit characters are just packed into memory in the order they appear in the
+#   message.
+
+PACKET msg_record:
+    # the first few fields in this packet have something to do with the type of SMS
+    # message contained. EMS and concatinated text are coded differently than a
+    # simple text message
+    1 UINT unknown1 # 0
+    1 UINT binary   # 0=simple text, 1=binary/concatinated
+    1 UINT unknown3 # 0=simple text, 1=binary/concatinated
+    1 UINT unknown4 # 0
+    1 UINT unknown6 # 2=simple text, 9=binary/concatinated
+    1 UINT length
+    * LIST {'length': 219} +msg:
+        1 UINT byte "individual byte of message"
+
+PACKET recipient_record:
+    40 DATA unknown
+    49 USTRING number
+    1 UINT status   # 1 when sent, 5 when received, 2 failed to send
+    2 UINT unknown1
+    4 LGCALDATE timesent
+    4 LGCALDATE timereceived
+    104 DATA unknown2
+
+PACKET sms_saved:
+    4 UINT outboxmsg
+    4 UNKNOWN pad # used for GPStime on some phones
+    if self.outboxmsg:
+        * sms_out outbox
+    if not self.outboxmsg:
+        * sms_in inbox
+
+PACKET sms_out:
+    4 UINT index # starting from 1, unique
+    1 UINT locked # 1=locked
+    3 UINT unknown1 # zero
+    4 LGCALDATE timesent # time the message was sent
+    21 USTRING {'encoding': PHONE_ENCODING} subject
+    1 DATA unknown2
+    1 UINT num_msg_elements # up to 10
+    * LIST {'elementclass': msg_record, 'length': 10} +messages
+    2253 UINT unknown5
+    1 UINT priority # 0=normal, 1=high
+    23 USTRING callback
+    14 DATA unknown6
+    * LIST {'elementclass': recipient_record,'length': 9} +recipients
+    * DATA unknown7
+
+PACKET SMSINBOXMSGFRAGMENT:
+    * LIST {'length': 181} +msg: # this size could be wrong
+        1 UINT byte "individual byte of message"
+
+PACKET sms_in:
+    4 UINT msg_index1
+    4 UINT msg_index2 # equal to the numerical part of the filename eg inbox002.dat
+    2 UINT unknown2 # set to 0 for simple message and 3 for binary, 9 for page
+    4 UINT unknown3 # set to 0
+    6 SMSDATE timesent
+    3 UINT unknown
+    1 UINT callback_length # 0 for no callback number
+    38 USTRING callback
+    1 UINT sender_length
+    * LIST {'length': 38} +sender:
+        1 UINT byte "individual byte of senders phone number"
+    15 DATA unknown4 # set to zeros
+    4 LGCALDATE lg_time # time the message was sent
+    4 GPSDATE GPStime # num seconds since 0h 1-6-80, time message received by phone
+    2 UINT unknown5 # zero
+    1 UINT read # 1 if message has been read, 0 otherwise
+    1 UINT locked # 1 if the message is locked, 0 otherwise
+    2 UINT unknown8 # zero
+    1 UINT priority # 1 if the message is high priority, 0 otherwise
+    5 DATA flags # message flags, read, priority, locked etc
+    21 USTRING {'encoding': PHONE_ENCODING} subject
+    1 UINT bin_header1 # 0 in simple message 1 if the message contains a binary header
+    1 UINT bin_header2 # 0 in simple message 9 if the message contains a binary header
+    2 UINT unknown6 # zeros
+    2 UINT multipartID # multi-part message ID, used for concatinated messages only
+    1 UINT bin_header3 # 0 in simple message 2 if the message contains a binary header
+    1 UINT unknown9
+    1 UINT num_msg_elements # max 10 elements (guessing on max here)
+    * LIST {'length': 10} +msglengths:
+        1 UINT msglength "lengths of individual messages in septets"
+    10 UINT unknown10
+    * LIST {'length': 10, 'elementclass': SMSINBOXMSGFRAGMENT} +msgs 
+                # 181 bytes per message, uncertain on this, no multipart message available
+                # 20 messages, 7-bit ascii for simple text. for binary header 
+                # first byte is header length not including the length byte
+                # rest depends on content of header, not known at this time.
+                # text alway follows the header although the format it different
+                # than a simple SMS
+    * DATA unknown5
+
+PACKET sms_quick_text:
+# the vx4400 has variable length NULL terminated strings null terminated in it's canned messages
+# file sms/mediacan000.dat, not sure about the max
+    * LIST {} +msgs:
+        * USTRING {'encoding': PHONE_ENCODING} msg #
Index: com_lglx260.py
===================================================================
--- com_lglx260.py	(revision 0)
+++ com_lglx260.py	(revision 0)
@@ -0,0 +1,181 @@
+### BITPIM
+###
+### Copyright (C) 2003-2004 Roger Binns <[email protected]>
+### Copyright (C) 2005 Simon Capper <[email protected]>
+### Copyright (C) 2008 Joe Siegrist <[email protected]>
+###
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of the BitPim license as detailed in the LICENSE file.
+###
+
+"""Communicate with the LG LX260 cell phone
+
+The LX260 is like other LG phones, I got this to import and export phonebook data 
+which is all I care about at the moment, extending should be straightforward
+
+
+"""
+
+# standard modules
+import time
+import cStringIO
+import sha
+
+# my modules
+import common
+import copy
+import p_brew
+import p_lglx260
+import com_lgvx4400
+import com_brew
+import com_phone
+import com_lg
+import prototypes
+
+class Phone(com_lgvx4400.Phone):
+    "Talk to the LG LX260 cell phone"
+
+    desc="LG-LX260"
+    helpid=None
+    protocolclass=p_lglx260
+    serialsname='lglx260'
+
+    # more LX260 indices
+    imagelocations=(
+        # offset, index file, files location, type, maximumentries
+        ( 10, "download/dloadindex/brewImageIndex.map", "brew/shared", "images", 30) ,
+        ( 0xc8, "download/dloadindex/mmsImageIndex.map", "brew/shared/mms", "mms", 20),
+        ( 0xdc, "download/dloadindex/mmsDrmImageIndex.map", "brew/shared/mms/d", "drm", 20), 
+        ( 0x82, None, None, "camera", 20) # nb camera must be last
+        )
+
+    ringtonelocations=(
+        # offset, index file, files location, type, maximumentries
+        ( 50, "download/dloadindex/brewRingerIndex.map", "user/sound/ringer", "ringers", 30),
+        ( 150, "download/dloadindex/mmsRingerIndex.map", "mms/sound", "mms", 20),
+        ( 180, "download/dloadindex/mmsDrmRingerIndex.map", "mms/sound/drm", "drm", 20)
+        )
+
+    builtinimages= ('Beach Ball', 'Towerbridge', 'Sunflower', 'Beach', 'Fish', 
+                    'Sea', 'Snowman')
+
+    builtinringtones= ('Ring 1', 'Ring 2', 'Ring 3', 'Ring 4', 'Ring 5', 'Ring 6',
+                       'Annen Polka', 'Beethoven Symphony No. 9', 'Pachelbel Canon', 
+                       'Hallelujah', 'La Traviata', 'Leichte Kavallerie Overture', 
+                       'Mozart Symphony No.40', 'Bach Minuet', 'Farewell', 
+                       'Mozart Piano Sonata', 'Sting', 'Trout', 'O solemio', 
+                       'Pizzicata Polka', 'Stars and Stripes Forever', 
+                       'Pineapple Rag', 'When the Saints Go Marching In', 'Latin', 
+                       'Carol 1', 'Carol 2') 
+                       
+    
+    def __init__(self, logtarget, commport):
+        com_lgvx4400.Phone.__init__(self,logtarget,commport)
+        self.mode=self.MODENONE
+
+    def getcameraindex(self):
+        index={}
+        return index
+
+    # this phone lacks groups
+    def getgroups(self, results):
+	g=self.protocolclass.pbgroups()
+	groups={}
+        #for i in range(len(g.groups)):
+            #if len(g.groups[i].name): # sometimes have zero length names
+                #groups[i]={ 'icon': g.groups[i].icon, 'name': g.groups[i].name }
+        	#self.log('Getting group: ' +i)
+        results['groups']=groups
+	return groups
+
+    def getphoneinfo(self, phone_info):
+        self.log('Getting Phone Info')
+        phone_info.model=self.my_model
+        phone_info.manufacturer=Profile.phone_manufacturer
+	phone_info.append('ESN:', self.get_brew_esn())
+        req=p_brew.firmwarerequest()
+        res=self.sendbrewcommand(req, p_lglx260.firmwareresponse)
+        phone_info.append('Firmware Version:', res.firmware)
+        s=self.getfilecontents('pim/MyInformation.dat')
+        phone_info.append('Phone Number:', s[363:373])
+        try:
+            dirlisting=self.getfilesystem('', 1)
+	    keys = dirlisting.keys()
+	    keys.sort()
+            #dirlisting=self.getfilesystem('nvm/')
+            for i in keys:
+	      self.log('file: '+ i)
+	      #s=self.getfilecontents(i)
+        except com_brew.BrewNoSuchDirectoryException:
+	    self.log('no such directory pim/')
+  	#self.log(self.getfilecontents('pim/sp_num.dat'))
+
+    def eval_detect_data(self, res):
+	found=False
+        s=self.getfilecontents('brew/version.txt')
+	if s[:5]==self.my_model:
+	    found=True
+            res['model']=self.my_model
+            res['manufacturer']='LG Electronics Inc'
+	    res['esn'] = self.get_brew_esn()
+
+
+    my_model='LX260'
+
+parentprofile=com_lgvx4400.Profile
+class Profile(parentprofile):
+    protocolclass=Phone.protocolclass
+    serialsname=Phone.serialsname
+    phone_manufacturer='LG Electronics Inc'
+    phone_model='LX260'
+
+    WALLPAPER_WIDTH=120
+    WALLPAPER_HEIGHT=131
+    MAX_WALLPAPER_BASENAME_LENGTH=32
+    WALLPAPER_FILENAME_CHARS="_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ."
+    WALLPAPER_CONVERT_FORMAT="bmp"
+   
+    MAX_RINGTONE_BASENAME_LENGTH=32
+    RINGTONE_FILENAME_CHARS="_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ."
+
+    # nb we don't allow save to camera so it isn't listed here
+    imageorigins={}
+    imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images"))
+    imageorigins.update(common.getkv(parentprofile.stockimageorigins, "mms"))
+    imageorigins.update(common.getkv(parentprofile.stockimageorigins, "drm"))
+    def GetImageOrigins(self):
+        return self.imageorigins
+
+    ringtoneorigins=('ringers', 'mms', 'drm')
+    excluded_ringtone_origins=('mms', 'drm')
+    excluded_wallpaper_origins=('mms', 'drm')
+
+    # our targets are the same for all origins
+    imagetargets={}
+    imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper",
+                                      {'width': 120, 'height': 131, 'format': "BMP"}))
+
+    def GetTargetsForImageOrigin(self, origin):
+        return self.imagetargets
+    
+    _supportedsyncs=(
+        ('sms', 'read', None),
+        ('sms', 'write', 'OVERWRITE'),
+        ('phonebook', 'read', None),  # all phonebook reading
+        ('phonebook', 'write', 'OVERWRITE'),  # only overwriting phonebook
+        ('calendar', 'write', 'OVERWRITE'),   # only overwriting calendar
+        ('calendar', 'read', None),   # all calendar reading
+        ('wallpaper', 'read', None),  # all wallpaper reading
+        ('wallpaper', 'write', 'MERGE'),      # merge and overwrite wallpaper
+        ('wallpaper', 'write', 'OVERWRITE'),
+        ('ringtone', 'read', None),   # all ringtone reading
+        ('ringtone', 'write', 'MERGE'),      # merge and overwrite ringtone
+        ('ringtone', 'write', 'OVERWRITE'),
+        ('memo', 'read', None),     # all memo list reading DJP
+        ('memo', 'write', 'OVERWRITE'),  # all memo list writing DJP
+        ('call_history', 'read', None),
+       )
+ 
+    def __init__(self):
+        parentprofile.__init__(self)
+
Index: com_lgvx4400.py
===================================================================
--- com_lgvx4400.py	(revision 4618)
+++ com_lgvx4400.py	(working copy)
@@ -632,7 +632,7 @@
 
             # We check the existing speed dial file as changes require a reboot
             self.log("Checking existing speed dials")
-            if buffer.getvalue()!=self.getfilecontents("pim/pbspeed.dat"):
+            if 0 and buffer.getvalue()!=self.getfilecontents("pim/pbspeed.dat"):
                 self.writefile("pim/pbspeed.dat", buffer.getvalue())
                 self.log("Your phone has to be rebooted due to the speed dials changing")
                 self.progress(progressmax, progressmax, "Rebooting phone")
@@ -676,9 +676,10 @@
         # only one name
         res['names']=[ {'full': entry.name} ]
         # only one category
-        cat=fundamentals['groups'].get(entry.group, {'name': "No Group"})['name']
-        if cat!="No Group":
-            res['categories']=[ {'category': cat} ]
+        #cat=fundamentals['groups'].get(entry.group, {'name': "No Group"})['name']
+        #if cat!="No Group":
+        #    res['categories']=[ {'category': cat} ]
+
         # emails
         res['emails']=[]
         for i in entry.emails:
@@ -696,7 +697,7 @@
         if  'memo' in entry.getfields() and len(entry.memo):
             res['memos']=[ {'memo': entry.memo } ]
         # wallpapers
-        if entry.wallpaper!=self.protocolclass.NOWALLPAPER:
+        if 0 and entry.wallpaper!=self.protocolclass.NOWALLPAPER:
             try:
                 paper=fundamentals['wallpaper-index'][entry.wallpaper]['name']
                 res['wallpapers']=[ {'wallpaper': paper, 'use': 'call'} ]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.