Alltel K1M3 preliminary support patch

David Ritter <[email protected]>
Newsgroups gmane.comp.mobile.bitpim.devel
Message-ID <[email protected]>
Here is what I have working so far. I could not get ringtone OBEX or  
BREW transfers past the phone filesystem permissions problems, so I  
have reverted to using BREW transfer of ringtones to and from the   
MicroSD card.
This only works if the files on the memory card are the same ones  
that have been copied to the phone memory.
Using the phone menus to move/copy the ringtones to and from the mmc  
to the phone memory is the required additional step.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

_______________________________________________
BitPim-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bitpim-devel
K1M3.patch (application/octet-stream, 20.1 KB)
diff -Nur bitpim-4600/help/phone-motok1m3-notes.htd bitpim-4600-K1M3added/help/phone-motok1m3-notes.htd
--- bitpim-4600/help/phone-motok1m3-notes.htd	1969-12-31 19:00:00.000000000 -0500
+++ bitpim-4600-K1M3added/help/phone-motok1m3-notes.htd	2008-02-29 16:38:44.000000000 -0500
@@ -0,0 +1,37 @@
+#include "pagestart.h"
+
+
+<H3>Phonebook</H3>
+<UL>
+<li><p>BitPim supports all phonebook features.
+<li><p>BitPim will set the first number on the list as the <B>Primary</B> number.  If a contact has no numbers, then the first email will be set as the <B>Primary</B>.  The order of the numbers and emails can be set from the <B>Edit Phonebook Entry</B> dialog.
+<LI><P>Within a single contact, BitPim can set different ringtone ID and picture ID to individual numbers/emails.
+<LI><P>BitPim can use <B>My Sounds</B> clips as ringtone IDs (in addition to ringtones clips).
+</UL>
+
+<H3>Calendar</H3>
+<UL>
+<li><p>All recurrent events are open-ended.  When viewed or edited from BitPim, the open-ended date would show as '4000-01-01'.
+<li><p>All recurrent events are automatically converted to have an interval of 1 (ie. an every-other-day-event in BitPim becomes an every-day-event in the phone, etc.)
+</UL>
+
+<H3>Ringtone</H3>
+<UL>
+<li><p>BitPim can only read or write ringtones to or from the memory card in the phone. The index for the ringtones only sees the ringtones in the phone memory. For this reason, it is necessary to use the phone menus to copy the ringtones to and from the memory card. In order to use bitpim to sync the ringtones between PC and Phone memory card, the same ringtones must be present on Phone memory and memory card. The important directories to check for this sync are motorola/shared/audio and mmc1/motorola/shared/audio.
+
+</UL>
+
+<H3>Wallpaper</H3>
+<UL>
+<li><p>BitPim can read, add, delete, and replace wallpapers on the phone.
+</UL>
+
+<H3>SMS</H3>
+<UL>
+<li><p>BitPim retrieves and classifies SMS incoming messages as <B>Inbox</B>, sent outgoing messages as <B>Sent</B>, and unsent outgoing messages as <B>Saved</B>.
+<li><p>BitPim does not retrieve draft messages.
+<li><p>Some <B>Sent</B> and <B>Saved</B> messages may not have date time info.  In those cases, the date time fields will be displayed as <B>YYYY-MM-DD hh:mm</B>.
+<li><p>BitPim does not save any SMS messages to the phone or send any messages through the phone.
+</UL>
+
+#include "pageend.h"
diff -Nur bitpim-4600/help/phone-motok1m3.htd bitpim-4600-K1M3added/help/phone-motok1m3.htd
--- bitpim-4600/help/phone-motok1m3.htd	1969-12-31 19:00:00.000000000 -0500
+++ bitpim-4600-K1M3added/help/phone-motok1m3.htd	2008-02-29 16:31:16.000000000 -0500
@@ -0,0 +1,23 @@
+#include "pagestart.h"
+
+<H2>What works</H2>
+<UL>
+<LI><P>Phonebook, calendar,  wallpapers, ringtones on memory card, SMS support, phone info.
+</UL>
+
+<H2>Cables</H2>
+<UL>
+<LI><P>The support for this phone was successfully tested with a standard mini USB cable. Bluetooth is not working. Phone detection is not working for this phone, manual selection is required.
+</UL>
+
+<h2>Contents</h2>
+
+<!-- CONTENTS BEGIN -->
+BEGIN_TOC
+    TOC_0
+    TOCITEM_0(Notes,phone-motok1m3-notes.htm)
+    ENDTOC_0
+END_TOC
+<!-- CONTENTS END -->
+
+#include "pageend.h"

diff -Nur bitpim-4600/src/phones/__init__.py bitpim-4600-K1M3added/src/phones/__init__.py
--- bitpim-4600/src/phones/__init__.py	2008-02-08 09:07:06.000000000 -0500
+++ bitpim-4600-K1M3added/src/phones/__init__.py	2008-03-04 16:00:15.000000000 -0500
@@ -501,6 +501,11 @@
                        'carrier': [c_vzw],
                        'helpid': helpids.ID_PHONE_MOTOK1M,
                        },
+              'K1m3': { 'module': 'com_motok1m3',
+                       'brand': b_moto,
+                       'carrier': [c_alltel],
+                       'helpid': helpids.ID_PHONE_MOTOK1M3,
+                       },
               'Other CDMA phone': { 'module': 'com_othercdma',
                                     'carrier': [c_other],
                                     'brand': b_other,
diff -Nur bitpim-4600/src/phones/com_motok1m3.py bitpim-4600-K1M3added/src/phones/com_motok1m3.py
--- bitpim-4600/src/phones/com_motok1m3.py	1969-12-31 19:00:00.000000000 -0500
+++ bitpim-4600-K1M3added/src/phones/com_motok1m3.py	2008-03-04 15:46:16.000000000 -0500
@@ -0,0 +1,324 @@
+### BITPIM
+###
+### Copyright (C) 2006 Joe Pham <[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.
+###
+### $Id: com_motok1m.py 4529 2007-12-26 18:38:19Z djpham $
+### Modified from K1M by D. Ritter 2008-03-04
+"""Communicate with Motorola K1m3 phones using AT commands"""
+
+# BitPim modules
+import common
+import com_motov710m
+import com_brew
+import p_brew
+import fileinfo
+import prototypes
+import p_motok1m3
+import helpids
+
+parentphone=com_motov710m.Phone
+class Phone(parentphone):
+    desc='Moto-K1m3'
+    helpid=helpids.ID_PHONE_MOTOK1M
+    serialsname='motok1m3'
+    protocolclass=p_motok1m3
+    # modified for Alltel ringtone index file
+    builtinringtones=(
+	(59, ('Adrenaline', 'Alert', 'Bells', 'Bits & Bytes',
+	     'Door Bell' )),
+	(64, ('Flawless', 'Free', 'Hello Moto', 'Illumination', 'Limelight',
+	      'Lounge', 'Metal')),
+	(71, ('Motion', 'Provincial')),
+	(73, ('Rings', 'Seguin', 'Standard', 'Sunshine',
+	      'Surge', 'Wind Chimes')),
+        )
+
+    def __init__(self, logtarget, commport):
+        parentphone.__init__(self, logtarget, commport)
+
+    # Ringtones stuff----------------------------------------------------------
+    # Alltel has apparently blocked BREW and OBEX ringtone transfer from the
+    # phone filesystem, so this will read and write from/to the SD card
+    # There is only one index for the ringtones on the phone itself.
+    # To use these, you need to "sync" ringtones by copying from the card 
+    # to the phone and from the phone to the card, so that both ringtone
+    # directories are identical
+  
+    def _get_ringtone_index(self):
+        res={}
+        # first the builtin ones
+        for _l in self.builtinringtones:
+            _idx=_l[0]
+            for _e in _l[1]:
+                res[_idx]={ 'name': _e, 'origin': 'builtin' }
+		self.log('Reading builtin ringtone index')
+		self.log( res[_idx] )
+                _idx+=1
+
+        # now the custome one
+        _buf=prototypes.buffer(self.getfilecontents('MyToneDB.db'))
+        _idx_file=self.protocolclass.ringtone_index_file()
+        _idx_file.readfrombuffer(_buf, logtitle='Read ringtone index file')
+
+        for _entry in _idx_file.items:
+            _filename=self.decode_utf16(_entry.name)
+	    _name=common.basename(_filename)
+	    self.log('Reading ringtones filenames from index')
+	    self.log (_filename)
+	    # alltel mod, start reading after frozenset
+
+	    if self.protocolclass.valid_rt_filename(_name):
+		self.log('Found a custom ringtone at: ')
+		self.log( _entry.index)
+		res[_entry.index]={ 'name': common.basename(_filename),
+                                'filename': _filename,
+                                'type': _entry.ringtone_type,
+                                'origin': 'ringers' }
+		self.log('Entry')
+		self.log(res[_entry.index])
+
+        return res
+
+    def getmmcdirlist(self, fundamentals, _dir):
+        self.log('Reading ringtones list from mmc')
+	_file_list2 = self.listfiles(_dir)
+
+	return _file_list2
+
+    def getringtones(self, fundamentals):
+        """Retrieve ringtones data"""
+        self.log('Reading ringtones')
+
+        self.setmode(self.MODEPHONEBOOK)
+        self.setmode(self.MODEBREW)
+	try:
+	    _file_list_mmc = self.getmmcdirlist(fundamentals,
+						'mmc1/motorola/shared/audio')
+	    try:
+		fundamentals['ringtone']=self._read_mmc_media('ringtone-index',
+                                                      fundamentals,
+						      _file_list_mmc)
+	    except:
+		if __debug__:
+		    raise
+               
+	except Exception, e:  ##mmc not installed
+                self.log('Failed to read Micro SD directory')
+
+
+
+        self.setmode(self.MODEMODEM)
+        return fundamentals
+
+    def _read_mmc_media(self, index_key, fundamentals, mmc_list):
+        """Read the contents of media files and return"""
+        _media={}
+        for _key,_entry in fundamentals.get(index_key, {}).items():
+            if _entry.get('filename', None):
+		filename2 = 'mmc1/motorola/shared/audio/'+ _entry['name']
+
+                # this one associates with a file, try to read it
+		if mmc_list.get(filename2, {}):
+		    # is this ringtone on mmc?
+		    try:
+			_media[_entry['name']]=self.getfilecontents(filename2,
+                                                                True)
+		    except (com_brew.BrewNoSuchFileException,
+			    com_brew.BrewBadPathnameException,
+			    com_brew.BrewNameTooLongException,
+			    com_brew.BrewAccessDeniedException):
+			self.log("Failed to read media file: %s"%_entry['name'])
+		    except:
+			self.log('Failed to read media file.')
+			if __debug__:
+			    raise
+        return _media
+    def _get_del_new_list(self, index_key, media_key, merge, fundamentals,
+                          origins):
+        """Return a list of media being deleted and being added"""
+        _index=fundamentals.get(index_key, {})
+        _media=fundamentals.get(media_key, {})
+        _index_file_list=[_entry['name'] for _entry in _index.values() \
+                          if _entry.has_key('filename') and \
+                          _entry.get('origin', None) in origins ]
+        _bp_file_list=[_entry['name'] for _entry in _media.values() \
+                       if _entry.get('origin', None) in origins ]
+        if merge:
+            # just add the new files, don't delete anything
+            _del_list=[]
+            _new_list=_bp_file_list
+        else:
+            # Delete specified files and add everything
+            _del_list=[x for x in _index_file_list if x not in _bp_file_list]
+            _new_list=_bp_file_list
+        return _del_list, _new_list
+
+    def saveringtones(self, fundamentals, merge):
+        """Save ringtones to the phone"""
+        self.log('Writing ringtones to the mmc card')
+        self.setmode(self.MODEPHONEBOOK)
+        self.setmode(self.MODEBREW)
+        try: 
+            _del_list, _new_list=self._get_del_new_list('ringtone-index',
+                                                        'ringtone',
+                                                        merge,
+                                                        fundamentals,
+                                                        frozenset(['ringers']))
+
+            # replace files on mmc, need to be in BREW mode
+            # add or delete files on mmc, need to be in BREW mode
+	    try:	    
+		self._replace_files('ringtone-index', 'ringtone',
+				    _new_list, fundamentals)
+		self.del_brew_files('ringtone-index', 'mmc1/motorola/shared/audio',
+				    _del_list, fundamentals)
+		self.add_brew_files('ringtone-index', 'ringtone', 'audio',
+                                    _new_list, fundamentals)
+	    except Exception, e:  #mmc not installed
+                self.log('Failed to write to Micro SD directory')
+
+
+        except:
+            if __debug__:
+                self.setmode(self.MODEMODEM)
+                raise
+        self.setmode(self.MODEMODEM)
+        return fundamentals
+
+    def add_brew_files(self, index_key, media_key, media_path,
+                   new_list, fundamentals):
+        """Add new file using BREW"""
+        _index=fundamentals.get(index_key, {})
+        _media=fundamentals.get(media_key, {})
+        for _file in new_list:
+            _data=self._item_from_index(_file, 'data', _media)
+            if not _data:
+                self.log('Failed to write file %s due to no data'%_file)
+                continue
+            if self._item_from_index(_file, None, _index) is None:
+                 _file_name='mmc1/motorola/shared/audio'+'/'+_file
+		 try:
+		     self.writefile(_file_name, _data)
+		 except:
+		     self.log('Failed to write BREW file '+_file_name)
+		     if __debug__:
+                        raise
+        
+    def del_brew_files(self, index_key, media_path, _del_list, fundamentals):
+        """Delete specified media files, need to be in BREW mode"""
+        _index=fundamentals.get(index_key, {})
+        for _file in _del_list:
+            _file_name=media_path+'/'+_file
+            try:
+
+                self.rmfile(_file_name)
+            except Exception, e:
+                self.log('Failed to delete BREW file %s: %s'%(_file_name, `e`))
+
+    def _item_from_index(self, name, item_key, index_dict):
+        for _key,_entry in index_dict.items():
+            if _entry.get('name', None)==name:
+                if item_key:
+                    # return a field
+                    return _entry.get(item_key, None)
+                else:
+                    # return the key
+                    return _key
+
+    def _replace_files(self, index_key, media_key,
+                   new_list, fundamentals):
+        """Replace existing media files with new contents"""
+        _index=fundamentals.get(index_key, {})
+        _media=fundamentals.get(media_key, {})
+        for _file in new_list:
+            _data=self._item_from_index(_file, 'data', _media)
+            if not _data:
+                self.log('Failed to write file %s due to no data'%_file)
+                continue
+            _file_name=self._item_from_index(_file, 'filename', _index)
+	    _file_name2='mmc1/motorola/shared/audio'+'/'+_file
+
+            if _file_name:
+                # existing file in index, check if the same one
+                _stat=self.statfile(_file_name2)
+                if _stat and _stat['size']!=len(_data):
+                    # and write out the data
+                    try:
+                        self.writefile(_file_name2, _data)
+                    except:
+                        self.log('Failed to write file '+_file_name2)
+                        if __debug__:
+                            raise
+        
+
+#------------------------------------------------------------------------------
+parentprofile=com_motov710m.Profile
+class Profile(parentprofile):
+    serialsname=Phone.serialsname
+    usbids=( ( 0x22B8, 0x2A64, 1),)
+
+    # fill in the list of ringtone/sound origins on your phone
+    ringtoneorigins=('ringers', 'sounds')
+    # ringtone origins that are not available for the contact assignment
+    excluded_ringtone_origins=()
+    imageorigins={}
+    imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images"))
+    excluded_wallpaper_origins=()
+    # use for auto-detection
+    phone_manufacturer='Motorola'
+    phone_model='K1m3'
+    common_model_name='K1m3'
+    generic_phone_model='Motorola CDMA K1m3 phone'
+
+    _supportedsyncs=(
+        ('phonebook', 'read', None),  # all phonebook reading
+        ('phonebook', 'write', 'OVERWRITE'),  # only overwriting phonebook
+        ('calendar', 'read', None),   # all calendar reading
+        ('calendar', 'write', 'OVERWRITE'),   # only overwriting calendar
+        ('ringtone', 'read', None),   # all ringtone reading blocked
+        ('ringtone', 'write', None),
+        ('ringtone', 'write', 'OVERWRITE'),
+        ('wallpaper', 'read', None),  # all wallpaper reading
+        ('wallpaper', 'write', None),
+        ('wallpaper', 'write', 'OVERWRITE'),
+        ('sms', 'read', None),
+        )
+
+
+    # our targets are the same for all origins
+    imagetargets={}
+    imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper",
+                                      {'width': 176, 'height': 184, 'format': "JPEG"}))
+    imagetargets.update(common.getkv(parentprofile.stockimagetargets, "outsidelcd",
+                                      {'width': 96, 'height': 67, 'format': "JPEG"}))
+    imagetargets.update(common.getkv(parentprofile.stockimagetargets, "fullscreen",
+                                      {'width': 176, 'height': 220, 'format': "JPEG"}))
+
+    field_color_data=parentprofile.field_color_data
+    field_color_data.update({
+        'phonebook': {
+            'name': {
+                'first': 1, 'middle': 1, 'last': 1, 'full': 1,
+                'nickname': 0, 'details': 1 },
+            'number': {
+                'type': 5, 'speeddial': 5, 'number': 5,
+                'details': 5,
+                'ringtone': 5, 'wallpaper': 5 },
+            'email': 2,
+            'email_details': {
+                'emailspeeddial': 2, 'emailringtone': 2,
+                'emailwallpaper': 2 },
+            'address': {
+                'type': 0, 'company': 0, 'street': 0, 'street2': 0,
+                'city': 0, 'state': 0, 'postalcode': 0, 'country': 0,
+                'details': 0 },
+            'url': 0,
+            'memo': 0,
+            'category': 1,
+            'wallpaper': 1,
+            'ringtone': 1,
+            'storage': 0,
+            }})
diff -Nur bitpim-4600/src/phones/p_motok1m3.p bitpim-4600-K1M3added/src/phones/p_motok1m3.p
--- bitpim-4600/src/phones/p_motok1m3.p	1969-12-31 19:00:00.000000000 -0500
+++ bitpim-4600-K1M3added/src/phones/p_motok1m3.p	2008-02-29 16:02:52.000000000 -0500
@@ -0,0 +1,48 @@
+### BITPIM
+###
+### Copyright (C) 2006 Joe Pham <[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.
+###
+### $Id: p_motok1m.p 4516 2007-12-21 22:00:57Z djpham $
+
+%{
+
+"""Various descriptions of data specific to Motorola V3c phones"""
+
+from prototypes import *
+from prototypes_moto import *
+from p_etsi import *
+from p_moto import *
+from p_motov710 import *
+
+import fnmatch
+
+PB_TOTAL_ENTRIES=1000
+PB_RANGE=xrange(1,PB_TOTAL_ENTRIES+1)
+# System files in the WP subdir that are not wallpapers/images
+WP_EXCLUDED_FILES=frozenset(['..dir.dat', 'amthumb.db',
+                             'customer_closing.gif',
+                             'customer_opening.gif'])
+
+_RT_EXCLUSION=frozenset(['Adrenaline.mp3', 'Alert.mid', 'Bells.mid',
+                         'Bits & Bytes.mid', 'Door Bell.mid',
+                         'Flawless.mp3', 'Free.mp3', 'Hello Moto.mp3',
+                         'Illumination.mid', 'Limelight.mp3', 'Lounge.mp3',
+                         'Metal.mp3', 'Motion.mp3', 'Provincial.mid',
+                         'Rings.mp3', 'Sequin.mp3', 'Standard.mid',
+                         'Sunshine.mp3', 'Surge.mp3', 'Wind Chimes.mid'])
+ 
+def valid_rt_filename(filename):
+    global _RT_EXCLUSION
+    for _name in _RT_EXCLUSION:
+        if fnmatch.fnmatch(filename, _name):
+            return False
+    return True
+
+
+RT_PATH='mmc1/motorola/shared/audio'
+
+%}
+
diff -Nur bitpim-4600/src/phones/p_motok1m3.py bitpim-4600-K1M3added/src/phones/p_motok1m3.py
--- bitpim-4600/src/phones/p_motok1m3.py	1969-12-31 19:00:00.000000000 -0500
+++ bitpim-4600-K1M3added/src/phones/p_motok1m3.py	2008-03-04 16:03:51.000000000 -0500
@@ -0,0 +1,37 @@
+# THIS FILE IS AUTOMATICALLY GENERATED.  EDIT THE SOURCE FILE NOT THIS ONE
+
+"""Various descriptions of data specific to Motorola V3c phones"""
+
+from prototypes import *
+from prototypes_moto import *
+from p_etsi import *
+from p_moto import *
+from p_motov710 import *
+
+import fnmatch
+
+PB_TOTAL_ENTRIES=1000
+PB_RANGE=xrange(1,PB_TOTAL_ENTRIES+1)
+# System files in the WP subdir that are not wallpapers/images
+WP_EXCLUDED_FILES=frozenset(['..dir.dat', 'amthumb.db',
+                             'customer_closing.gif',
+                             'customer_opening.gif'])
+
+_RT_EXCLUSION=frozenset(['Adrenaline.mp3', 'Alert.mid', 'Bells.mid',
+                         'Bits & Bytes.mid', 'Door Bell.mid',
+                         'Flawless.mp3', 'Free.mp3', 'Hello Moto.mp3',
+                         'Illumination.mid', 'Limelight.mp3', 'Lounge.mp3',
+                         'Metal.mp3', 'Motion.mp3', 'Provincial.mid',
+                         'Rings.mp3', 'Sequin.mp3', 'Standard.mid',
+                         'Sunshine.mp3', 'Surge.mp3', 'Wind Chimes.mid'])
+ 
+def valid_rt_filename(filename):
+    global _RT_EXCLUSION
+    for _name in _RT_EXCLUSION:
+        if fnmatch.fnmatch(filename, _name):
+            return False
+    return True
+
+
+RT_PATH='mmc1/motorola/shared/audio'
+
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.