|Palm test application
In part one of this article, I covered how to get started in developing a Palm handheld application. This time, I will give you a glimpse of the HotSync conduit platform.
HotSync is the primary interface between the Palm handheld and the PC. Typically, you put the handheld in the cradle, press the HotSync button, and the PC and the handheld begin synchronizing all the records for the datebook, todo list, address book, etc. Here, the PC does all the processing of the data via HotSync conduit applications. The handheld simply sits in the HotSync mode where it processes any database requests until the HotSync is complete. The HotSync Conduit API on the PC supports easy database and record iteration from the handheld. While it is assumed that the HotSync conduit will be synchronizing, it really could be doing anything with the data.
Anatomy of a Conduit
Palm Desktop maintains the conduits on the PC. It will maintain a Palm Home that contains the desktop executables, as well as associated tools and any included conduits. The CDK is a base implementation of the Palm Desktop tools, but without the actual Palm Desktop application.
A conduit is a DLL application installed on the PC side that implements the supported function calls. It is typically designed to respond to the existence of databases with certain Creator IDs, i.e., "addr" for the Address Book application. In most cases, the conduit will then save a PC version of the database. If the PC database already exists, it will compare records for a two-way synchronization and update the handheld and PC records appropriately.
A conduit DLL must contain these exported functions that will be called by the HotSync Manager:
SInt32 OpenConduit(PROGRESSFN pFn, CSyncProperties &syncProps)
Called to start HotSync of this conduit.
SInt32 GetConduitInfo(ConduitInfoEnum infoType, void *pInArgs, void *pOut, UInt32 *pdwOutSize)
SInt32 GetConduitName(char *name, UInt16 nLen)
Called to retrieve information about the conduit, usually during startup of the HotSync Manager.
SInt32 CfgConduit(ConduitCfgEnum cfgType, void *pArgs, UInt32 *pdwArgsSize)
Called when the user right-clicks the HotSync Manager and selects Custom->Change on a conduit. This function is required to popup a dialog to allow the user to view/change the synchronization type.
SInt32 ConfigureConduit(CSyncPreference &syncPrefs)
This function is required for the HotSync Manager versions before 3.0 (very old). Also called in case
ConfigureConduit() fails. The
CfgConduit() has additional fields for Creator ID, user name, and temporary sync preferences.
In order for the HotSync manager to know what conduits are available, they must be registered. You can do this with the conduit registration API in CondMgr.dll.
Requirements for Conduit Development
- Windows C/C++ Compiler (MS Visual C++. NET 2002+ required for generic conduit project wizards).
- CDK for its C headers, DLL import libraries, framework, tools, and reference materials.
- POSE for debugging (optional).
Be sure to check out the help files in the Common\Docs directory in the CDK installation. These will contain all the reference information you'll need.
The HotSync Manager orchestrates the execution of the HotSync process. It places its icon in the system tray and waits for a HotSync request from the handheld. Once it receives a HotSync request, it will first read the user account from the handheld, then iterate through the conduits, and finally, backup the handheld databases.
A registered conduit will contain data, such as: a file and path (based from the user's home directory), a Creator ID, remote database name, and priority level. These parameters will serve as a guide to the conduit as to where to store its PC files, which databases with what Creator IDs to obtain from the handheld, and what order the conduits will process.
The backup process will straight copy the PDB from the handheld to the user's backup directory for all databases flagged for backup. You can use Filez to modify the backup flags. This is useful if you lose battery power to the Palm and all the data is lost. The next HotSync will automatically restore the backed up PDB and PRC files. If not set by default, be sure to enable this flag for any PDB files your application generates.
The HotSync Manager can also utilize notifiers. These are DLLs that are notified when the HotSync starts and finishes. But, this is a topic for another article.
Conduit Config, CondCfg.exe, allows the developer to manually maintain the conduit registry for both user and system conduits.
Conduit Inspector allows you to view real-time log generation during conduit execution. It is started from "hotsync.exe -ic".
HotSync with POSE
You may want to setup POSE to HotSync with the host PC so that you can sync in some usable data or maybe you're developing a Hotsync conduit. To do this, there is some configuration necessary.
Configure HotSync on the PC
- Make sure the HotSync Manager is running.
- Right-click the HotSync Manager icon in the system tray, and enable "Network" in the popup menu.
- Right-click POSE and click Settings->Properties...
- Check the box "Redirect NetLib Calls to TCP/IP". Click OK.
Configure Handheld HotSync in POSE
- Open the "HotSync" app in the System category.
- Go to menu Options->Modem Sync Preferences. Set to "Network".
- Go back to menu Options->Primary PC Setup. Enter "127.0.0.1" for "Primary PC Address".
- In the HotSync application, select "Modem". Tap "Select Service" and then just tap "Done". The service itself doesn't matter, but one must be selected.
Now, you will be able to HotSync POSE with the host PC HotSync Manager.
Palm provides several DLLs in the Palm home directory for API calls of every kind. This is best covered in the C++SyncReference.chm help.
Binding to Palm DLLs
The design concept is to use the user's installed DLLs. It is generally not advisable to package Palm DLLs into your project to avoid version conflicts. Different version Palm DLLs may behave differently or store data in different formats or locations.
If your project will be installed to a separate directory than in the Palm home directory, the DLLs will not be in the path for an import library to load. In this case, there are two solutions: use late binding with
GetProcAddress(), or VC++'s delayed loading by setting the working directory before any Palm API calls. To use these methods, you will need to know the Palm bin path. For this, despite my first warning, it is possible to package CondMgr.dll so you can make a call to
CmGetSystemHotSyncExecPath() to retrieve the pathname of HotSync.exe. Strip off HotSync.exe to reveal the Palm bin path. Then, free the loaded CondMgr.dll and reload the necessary DLLs from the obtained path. If you are using delayed loading, it is possible to do
SetCurrentDirectory(), then attempt to make Palm API calls as if using a normal DLL import library.
Debugging a Conduit
The HotSync Manager will have a log you can read after a HotSync. Just right-click the system tray icon and click View Log.
However, if you want to view the log in real-time during a HotSync, you can use the Conduit Inspector. To be able to do this, you must use the CDK version of the HotSync Manager and start it with the command line "hotsync.exe -ic". The HotSync Manager and the Conduit Inspector will start together. On the next HotSync, the Conduit Inspector will begin scrolling the generated log output.
Like with any DLL, you can also put breakpoints in your code to step through your conduit code during HotSync. Configure the project so that the debugging command and the working directory point to that of hotsync.exe. Include "-ic" as a command argument to also see the Conduit Inspector. Be aware that the HotSync process on the handheld will timeout in 30 seconds, so you must be quick when stepping through the code. Tip: you can renew this timeout by making calls to
CDK 4.0.3 Generic Conduit Framework
The CDK provides a fairly good C++ framework for building a conduit. If using Visual C++ .NET 2002 or newer, you will get a New Project Wizard for creating a Palm OS Conduit project. I'll outline the process of using this framework.
Let's create a conduit against the handheld test application included with this article, and pictured at the top. The handheld application lets the user create rows of text, up to 31 characters per line, and displays the record index and lower 16 bits value of the record ID next to the text field. Install this application on your handheld (or POSE) and create some records. The handheld app works off of a single database "Test database" with a CreatorID "Test".
Create the conduit project using the New Project Wizard:
These are the important base classes to know in the generic conduit framework:
CSynchronizer: Wraps the entire conduit synchronization process.
CHHMgr: Interface to the handheld database.
CPcMgr: Interface to the PC database.
The HotSync operation will happen in this order:
OpenConduit(): The exported DLL function called by the HotSync Manager to start synchronization. Instantiates
CSynchronizer, then calls the
CSynchronizer::Perform(): Start synchronization. Instantiates
PCMgr classes. Determines what type of synchronization to perform and calls the appropriate method depending on the synchronization type:
CSynchronizer::CopyHHtoPC(): One-way copy to PC.
CSynchronizer::CopyPCtoHH(): One-way copy to handheld.
CSynchronizer::PerformFastSync(): Fast synchronization when only modified records are synchronized.
CSynchronizer::PerformSlowSync(): Slow synchronization when all records are synchronized.
Now, use CondCfg.exe to register your conduit like below:
Run HotSync.exe -ic to start with the Conduit Inspector. Now, start a HotSync from your Palm or POSE. In the spaghetti log generated, you should be able to find your conduit output:
Current conduit: Name: H:\code\TestConduit\Debug\TestConduit.dll,
Creator ID Test
Found task and attempting to load conduit.
OK Generic Conduit
Then, look in the installed CDK path. The HotSync Manager creates a folder for your user account, which contains all the synchronization files. In there, you will find a "Test Conduit" subfolder that contains the synchronized database from your conduit: Test.dat and Test.BAK, the current and previous database files from HotSync. Note: these files are in proprietary format determined by the generic conduit framework.
If you enabled the backup flag on the handheld "Test database" file, you will see its backup in the Backup folder in PDB format.
You can test that your conduit really works by deleting the "Test database" file from the handheld, using a tool like Filez, and running HotSync again. The conduit will automatically recreate the database and populate it with the records it saved from the last HotSync. Note: make sure there is no backup file of the database in the Backup folder, or else your database will be restored before the conduit starts.
Using the example conduit project from this article
Due to the nature of the CDK's New Project Wizard, it creates a Visual Studio project with references to source and header files in the CDK installation path. On my machine, I've installed the CDK to H:\code\palm\cdk403, therefore, the example will contain many references to that path. Since you will probably have the CDK installed somewhere else, you will want to do a search/replace on the paths found in the TestConduit.vcproj file, with a text editor, before opening it.
The generic conduit framework will get you started with a fully functional conduit, but you will need to customize it to do anything additional. Here are some presumably common scenarios:
I need the conduit to save to a different file format.
Override the method
CPcMgr::StoreDB() with your own code. You will also need to update
CPcMgr::RetrieveDB() to load your format into memory. Memory storage is handled via the
m_pRecordList array. If you want to store and retrieve in PDB format, you will have to write your own code based on the PDB file format specification.
I need to handle synchronization of multiple databases from the same application.
OpenConduit() so that it creates a
CSynchronizer object for each database. Update or create
CSyncProperties object(s), like the standard code does, for each
CSynchronizer instantiation. In the event that the databases are not fixed names, you will need to iterate the database directory of the handheld by using
How do I install the conduit?
First, read the "Writing an Installer" section of the CDK documentation. Then, bundle your installer code into an installer SDK like InstallShield or NSIS.
But wait! Palm has CDK 6.0.1. Isn't that newer and better?
Yes and no. CDK 6.0.1 provides minor updates on the generic conduit framework, integrates its help into the MSDN Library, supports system and user conduits, as well as has support for Palm OS 5.0 and up. The development tools are backwards compatible with Palm OS 3.5, except the generic conduit framework. Unfortunately for us, the framework was redesigned to target the extended database API, which Palm OS 3.5 does not support (only classic databases). This is likely the reason why Palm has kept the older 4.0.3 release online for download.
And there you have it. I hope that this article series provides the reader with the background to easily start up with the Palm handheld platform.