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'} ]