1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<!-- $Id: phonespec.html 2690 2005-12-19 03:58:14Z skyjunky $ -->
<title>Supporting a phone in BitPim</title>
</head>
<body>
<h1>Supporting a phone in BitPim</h1>
<p>This document describes how to support a phone in BitPim. The
intention of the implementation behind BitPim is to allow both a
GUI driven user interface as well as a command line driven one
(although the latter has not been implemented). It is also good
abstraction to keep phone communication details and the actual UI
etc seperate.
<p>In the GUI version of BitPim, the UI operates in the main
thread, and the phone communication code operates in a background
thread. This keeps the UI responsive and means the phone thread
doesn't have to remember state and be event driven. It also means
that the phone thread cannot make any gui requests. In the
command line version, everything will run in the main (and only)
thread.
<p>You should browse through the source and become familiar with
the layout and purpose of each module. The developer page has
links to the apidoc and cross-referenced source. If there is a
function with no or inadequate documentation, please point it out
on the bitpim-devel list. I consider that a bug and will fix it
immediately.
<h1>Example</h1>
<p>The best example to look at is the LG VX4400. This was the
first phone implemented, and is the most feature complete.
<h1>Your code</h1>
<p>You should put the code that implements your phone into a file
with the prefix com_ (for example com_lgvx4400.py). The code
executed in the communications thread should be a class named
Phone. You will want to multiply inherit from the base phone
class (com_phone.Phone) as well as from other phone classes (eg
com_brew.BrewProtocol). There may also be a base class for the
manufacturer of your phone since there is normally a lot in common
for all models (for example com_lg is common for all LG phones).
<p>The phone is always in a mode (starting with MODE_NONE). You
may add extra modes or more typically your base classes will. For
example com_brew adds MODE_BREW. The modes are used to switch the
phone into different modes (for example brew, phonebook, modem).
com_phone.Phone defines the setmode function which changes to a
new mode and documents how the mode transition happens.
<p>You need to add a config value for your phone together with the
basename of the module at the start of ConfigDialog in
guiwidgets.py.
<p>You will also likely need to describe the protocol used by your
phone. The protocol descriptions go in p_*.p files. Run
<code>protogen.py</code> to compile the .p files into .py
<p>The file packetdescription.txt describes the format and
functionality of the descriptions. It is also highly recommended
that you run analyser.py supplying various files in the examples
directory. This will give you and idea as to how the other phones
work. You can also use this to work on your description.
<p>While running BitPim, you can turn on the protocol log view.
If you press ctrl-alt-p the protocol analyser will appear. If
will import whatever text you had selected, or all of it if there
was no selection. You can also copy and paste the text to save
for a file to put in examples.
<p>It is a good idea to contribute some files to examples. It
lets other developers see what the protocol and record formats
look like on your phone. You should try to make the examples
interesting and featureful. For example for a phonebook record
you may want to fill out every number to the maximum number of
digits. Since the files are public you should not use private
data.
<p>You also need a second class, named Profile. All the methods
in this class are called from the gui thread and are to do with
gui interaction between the gui and your phone. For example it
munges phonebook data into a format suitable for the phone and can
generate warnings. It also returns what the size and format
constraints are for images.
<p>Many of the methods take a dictionary as a parameter. Your
methods are expected to return information by adding new keys and
can consult other keys to get more information.
<h1>Calling convention</h1>
<pre>
- mention results/data dict parameter
</pre>
<h1>Phone requirements</h1>
<pre>
serials source and unique id stuff
</pre>
<h1>Methods in your Phone class</h1>
<dl>
<dt>getfundamentals
<dd>This method should get any data off the phone that may be necessary
for other methods in the Phone or Profile classes to use when processing
data.
<p>In the LGVX4400 code, this method retrieves the wallpaper and ringtone
indices (needed to convert the wallpaper and ringtone names into numbers
as used in the phonebook and calendar). It also gets hash of the ESN
of the phone.
<dt>getphonebook
<dd>This method retrieves the phonebook. It should update the 'phonebook'
key with the phonebook. Each entry in the dict should have a value in the
same format as specified in the top of phonebook.py. The user interface
will then deal with merging or replacing of the results.
<dt>savephonebook
<dd>This method saves the phonebook to the phone. By convention the
convertphonebooktophone method in Profile will munge the phonebook
into something suitable for this method and save it back into the
phonebook key.
<p>You will probably also want to update the serials for each
entry (especially for new entries). You can add a key named
serialupdates. It is a list of tuple. Each tuple consists
of the bitpim serial for an entry (sourcetype="bitpim") and
your serial update. See the updateserials() function in
phonebook.py for more information.
</dl>
<pre>
getcalendar
savecalendar
getringtones
saveringtones
getwallpapers
savewallpapers
</pre>
<h1>Methods in your Profile class</h1>
<pre>
convertphonebooktophone - don't conv wallpaper and ringtone names since they
may be updated after call to this fun
</pre>
<h1>Constants in your Profile class</h1>
<h2>usbids</h2>
<p>This is a list of tuples (vendorid, productid, interfacenumber) that
correspond to the device. You should include USB to serial converters.
You must have an interface number for the device to accessible via
libusb. If you only work through OS device drivers then interfacenumber
can be none.
<p>The list should be in most preferred first. Typically you would list
direct USB connections before USB to serial converters.
<h2>deviceclasses</h2>
A tuple containing one or both of <code>"serial"</code> and <code>"modem"</code>.
This is used to filter out interfaces for composite devices in the detection
code. For example the LG VX4400 presents both a modem interface and a serial
interface. BitPim can only talk to the serial interface as the modem interface
only does modem stuff. The Sanyo phones only present a modem interface.
<h2>WALLPAPER_WIDTH WALLPAPER_HEIGHT</h2>
<p>The normal width and height of wallpapers for use on the
device. These values are used for auto resizing when the user
adds a new wallpaper (eg via drag and drop). Wallpapers and
images from the phone are not resized unless the user explicitly
asks for it (ie you don't have to worry about camera images being
resized to this size).
<h2>MAX_WALLPAPER_BASENAME_LENGTH</h2>
<p>The maximum length of a wallpaper filename extension. Files
added via BitPim will be truncated if necessary.
<h2>WALLPAPER_FILENAME_CHARS</h2>
<p>A list of acceptable characters in wallpaper filenames. Any
characters not in the list will be removed when files are added
via BitPim. If there are no upper case letters then names are
converted to lowercase, and if there are no lowercase letters then
names are converted to uppercase.
<h2>WALLPAPER_CONVERT_FORMAT</h2>
<p>The file extension that wallpapers are automatically converted
to (without the dot). Examples are 'bmp', 'jpg' and 'png'.
<h1>Calling sequence</h1>
<p>Remember that all methods in Phone are called in comms thread
and all methods in Profile are called in gui thread. If the user
has selected multiple actions (eg write phonebook and ringtones)
then Phone.getfundamentals is called only once first, all Profile
methods are called, and then Phone methods are called.
<h2>Reading phonebook</h2>
<ul>
<li>Phone.getfundamentals
<li>Phone.getphonebook
</ul>
<h2>Writing phonebook</h2>
<ul>
<li>Phone.getfundamentals
<li>Profile.convertphonebooktophone
<li>Phone.savephonebook
</ul>
<h1>Monolog on adding phone support...</h1>
<p>Each phone supported by bitpim has two source files and one protocol file.
The protocol file is used to generate one of the protocol files.
Say you wanted to add support for a new phone "newphone". The filenames would be
<pre>
com_newphone.py
p_newphone.p
p_newphone.py (this one is generated when you run protogen.py, you do not edit it)
</pre>
<p>To make things easy for yourself you should copy one of the existing phones in bitpim.
Try to choose a phone which is similar, i.e. the same manufacturer and the same basic
feature set. Do a search and replace on the model name to create your new files.
Remember to run protogen.py to generate the protocol source file. Make sure you change the
import directive in the com_newphone to use the new p_newphone file.
<p>To make your phone appear in the list of supported phones edit guiwidgets.py.
Find the ConfigDialog class (~ln 340) and add your new phone to the list, the second
field in the list is the filename of the new file you just created without the extension.
<p>In the p_newphone.py are a bunch of PACKET defnintions, these tell bitpim how to communicate
with your phone. You have to create a PACKET definition for the files and messages you are decoding.
Most of the time if you are copying a similar phone these PACKET definition will not need to
be changed, or if they do the change will be slight, often the size of a field will change from
one model to another. The SMS PACKET definitions on the LG phones are a really good example of
how the manufacturers constantly change things.
<p>Figuring out the correct PACKET definitions is probably the hardest thing to do. There are 2 ways
to get data from the phone, Sending messages over the serial port and reading/writing the phone's
filesystem directly. In general using the serial port to send messages is better than directly accessing
the filesystem as the serial protocols change less from one phone to another. Also writing the
filesystem directly can require a phone reboot for the changes to take effect.
<p>These packet definitions get used by get and save functions in the com_newphone.py class.
<p>The com_newphone class contains 2 classes that your phone inherits from and overrides.
<p><b>Phone</b> -
<p>This class is where you will write most of the code to convert from the phone's proprietary
format into the standard bitpim format. The get and save functions are called by bitpim to
read and write things like the phonebook, calendar and ringtones.
<p><b>Profile</b> -
<p>This class contains static information about your phone that bitpim needs.
This includes things likde the usbIDs, the size of the wallpaper files, valid characters for filenames
and other infomation. It can also contain helper functions that bitpim uses to convert data from the
bitpim format into a format that is more convenient for your Phone class to manipulate.
<h2> Really important info...</h2>
<p>The get and save functions (in the Phone class). There is one pair for each feature supported by
bitpim, these functions are what bitpim uses to talk to your phone:
<pre>
getmemo, savememo
getsms, savesms
gettodo, savetodo
getcalendar, savecalendar
getwallpapers, savewallpapers
getringtones, saveringtones
getcallhistory, (no save function for call history)
</pre>
<p>If you are copying an existing phone then it is very likely that some or all of the code
you need to make the phone work is already written and all you have to do is tweek the
PACKET definitions in the p_newphone.p file. It is better to reuse existing code than duplicate
it.
<p>If you want to add support for a new feature that is not supported like say SMS or memo the
following will help...
<p>You need to add code to your phone class to allow bitpim to access the SMS (or memo etc)
messages on your phone.
<p>As mentioned before, for each type of data bitpim retrieves there is a get and a save
function defined, so to add SMS support you have to implement getsms() and savesms().
You need to implement these functions in the Phone class in the com_newphone.py file.
<p>In the Profile class you define the features supported by the phone, look for the
_supportedsyncs list, you need to add SMS (or whatever new feature you are adding) to this,
note that SMS write only allows the user to change the prewritten presponses at the moment.
<p>For example, this is the _supportedsync from the lgvx4400, it supports everything except the
todo feature (limitation of the phone not bitpim).
<p>This list determines what options are greyed out in the get/send data dialog boxes in bitpim.
<pre>
_supportedsyncs=(
('phonebook', 'read', None), # all phonebook reading
('calendar', 'read', None), # all calendar reading
('wallpaper', 'read', None), # all wallpaper reading
('ringtone', 'read', None), # all ringtone reading
('call_history', 'read', None),# all call history list reading
('sms', 'read', None), # all SMS list reading
('phonebook', 'write', 'OVERWRITE'), # only overwriting phonebook
('calendar', 'write', 'OVERWRITE'), # only overwriting calendar
('wallpaper', 'write', 'MERGE'), # merge and overwrite wallpaper
('wallpaper', 'write', 'OVERWRITE'),
('ringtone', 'write', 'MERGE'), # merge and overwrite ringtone
('ringtone', 'write', 'OVERWRITE'),
('sms', 'write', 'OVERWRITE'), # all SMS list writing
)
</pre>
<p>The contents of the getsms() function in your phone will decode the proprietary contents of
files on your phone and convert them into a standard format understood by bitpim.
Bitpim expects the data to be stored in records in a python dictionary data type.
The easiest way to do this is to copy code from another phone. I would recommend the
com_lgvx4400. Many other phones also implement this, most of the LG family uses the code in
the 4400, but the other models contain other implmentations you can copy.
Just search for getsms() or whatever function you are trying to add to find them.
<p>As a rule try not to duplicate code from other phones, it is much better to add code to a base
class and allow the code to be shared. This makes maintaining the code easier.
<hr>
<address><a href="mailto:rogerb@rogerbinns.com"></a></address>
<!-- Created: Thu Dec 04 20:37:58 Pacific Standard Time 2003 -->
<!-- hhmts start -->
Last modified: Sat Feb 19 22:57:24 Pacific Standard Time 2005
<!-- hhmts end -->
</body>
</html>
|