The simplest form of communication for a Palm OS® application to implement is the sending and receiving of typed data objects, such as MIME data, databases, or database records.
You use the Exchange Manager to send and receive typed data objects. The Exchange Manager interface is independent of the transport mechanism. You can use Bluetooth, email, IR, SMS, or any other protocol that has an Exchange Manager plug-in called an exchange library.
This chapter describes how applications use the Exchange Manager to send and receive typed data objects. It covers the following topics:
- About the Exchange Manager
- Initializing the Exchange Socket Structure
- Registering for Data
- Registering to Receive Unwrapped Data
- Receiving Data
- Sending and Receiving Databases
- Requesting Data
- Sending and Receiving Locally
- Interacting with the Launcher
- HotSync Exchange
- Attachment Support Guidelines
- Summary of Exchange Manager
About the Exchange Manager
This section explains concepts you need to know before you can begin using the Exchange Manager. It discusses the following topics:
Exchange Libraries
The Exchange Manager works in conjunction with an exchange library. Each exchange library is transport-dependent and performs the actual communication with the remote device. When an application makes an Exchange Manager call, the Exchange Manager forwards the request to the appropriate exchange library. The Exchange Manager's main duty is to maintain a registry of which libraries implement each protocol and which applications receive each type of data. See Figure 4.1.
Figure 4.1 Object exchange using Exchange Manager

The list of available exchange libraries depends on the particular device hardware and on what other software the user has installed. Some typically available libraries include: IR Library (IrDA), Local Exchange Library, SMS (Short Messaging System) Library, Bluetooth Library, and HotSync® Exchange Library.
As other exchange libraries become available, users can install them on their Palm Powered™ handhelds and use the communications functionality they provide.
Typed Data Objects
The Exchange Manager sends and receives typed data objects. A typed data object (or object) is a stream of bytes plus some information about its contents. The content information includes any of: a creator ID, a MIME data type, or a filename.
The object itself can be in any format, but it's best to use a standardized data format rather than a proprietary one if you have a choice. Table 4.1 lists the standardized data formats that the built-in Palm OS applications can receive.
Table 4.1 Built-in applications and standard data types
NOTE: The MIME type application/vnd.palm has been registered with the IANA and is preferred over the application/x-pilot MIME type.
More information on the vCard and vCalendar formats is available at http://www.imc.org/pdi/. For text, the basic MIME text format is described in RFC 822 (http://www.ietf.org/rfc/rfc822.txt). Palm OS builds on that with support for the quoted printable format (for international character sets) in RFC 2045 (http://www.ietf.org/rfc/rfc2045.txt) and multipart MIME (for categories) in RFC 2046 (http://www.ietf.org/rfc/rfc2046.txt). Palm OS doesn't implement everything in these RFCs, but it does generate and read content that is compliant with these standards.
If you want your application to receive objects, you must first register with the Exchange Manager for the type of data you want to receive. See "Registering for Data" for instructions on how to do so. You can override the built-in applications by registering for any data type listed in Table 4.1 and becoming the default application for that type (but only with the user's permission). See "Setting the Default Application" for more information.
If you only want to send data, you do not have to register. Your application can send data of the types listed in Table 4.1, and the Exchange Manager ensures that the appropriate application receives it.
Initializing the Exchange Socket Structure
The Exchange Manager, exchange library, and application use an exchange socket structure (ExgSocketType
) to communicate with each other. This structure is passed from the application to the Exchange Manager to the exchange library and vice versa. (The use of the term "socket" in the Exchange Manager API is not related to the term "socket" as used in sockets communication programming.) When your application sends data, you must create this structure and initialize it with the appropriate information. When you receive data, this structure provides information about the connection and the incoming data.
The ExgSocketType
structure you use must identify two important pieces of information:
- the exchange library that should do the sending (see "Identifying the Exchange Library")
- the type of data being sent (see "Identifying the Type of Data")
The socket structure defines other fields that you may use to provide other information if you want. See the description of the ExgSocketType
structure for complete details.
Identifying the Exchange Library
The ExgSocketType
structure identifies the library to be used via a Uniform Resource Locator (URL) in the name
field.
When your application sends data, it should always identify which exchange library to use. (If you do not specify an exchange library, the IR Library is used to maintain backward compatibility.)
The URL scheme specifies which exchange library to use. The scheme is the part of the URL that appears before the colon (:). For example, the scheme in the following URL is "http"
http://www.palmos.com
When you pass the preceding URL to a web browser, the scheme tells the browser to connect to the server using the HTTP protocol. Similarly, when you pass the Exchange Manager a URL, the scheme tells the Exchange Manager which exchange library to use. For example, the following URL tells the Exchange Manager to connect to a remote Palm Powered device using the IR Library:
_beam:BusinessCard.vcf
Multiple exchange libraries can register for the same scheme.
On Palm OS, a URL has the following format (in BNF notation):
[?][scheme
{;scheme
}:]filename
-
?
- If more than one exchange library is registered for the provided schemes, the Exchange Manager has the user select the exchange library by displaying the Send With dialog.
-
scheme
{;scheme
} - The URL schemes that identify which exchange library should be used. If more than one exchange library is registered for the scheme, the default exchange library is selected unless the URL begins with a question mark.
- As shown, multiple schemes may be provided, separated by semicolons. Multiple schemes are only supported in conjunction with the question mark. For example, the string "?_send;_beam:" has the Exchange Manager display a Send With dialog that lists all exchange libraries that support either the _send scheme or the _beam scheme.
-
filename
- The name of the file to send. Typically, this file also has an extension that is used, if necessary, to determine which application should receive the data. See "Identifying the Type of Data" for more information about the file extension.
Palm OS URL schemes all begin with the underscore (_) character. Standard schemes, such as mailto, are supported without the underscore.
Palm OS defines some URL prefixes that any application can use to connect with the installed exchange libraries. A URL prefix is everything up to and including the colon character. Table 4.2 describes the prefix constants. Note that you generally only need to use exgBeamPrefix
or exgSendPrefix
unless a specific transport is required.
Table 4.2 Exchange Library URL Prefixes
The section "Implementing the Send Command" provides more information on using exgSendPrefix
or exgSendBeamPrefix
.
The section "HotSync Exchange" provides more information on using exgDesktopPrefix
.
The section "Attachment Support Guidelines" provides more information on using exgGetPrefix
.
For more information on the SMS exchange library, refer to Chapter 5, "SMS Exchange Library Reference," in Exploring Palm OS: Telephony and SMS.
For more information on the Bluetooth exchange library, refer to Chapter 12, "Bluetooth Exchange Library Support," in Exploring Palm OS: Low-Level Communications.
Identifying the Type of Data
When your application sends data, the exchange socket structure (ExgSocketType
) identifies the type of data being sent. It can do so with one of the following values:
- A MIME type in the
type
field. - A file extension for the file in the
name
field. That is, you might supplyMyDB.pdb
as the value of thename
field. The part after the last period (.) is the extension.
In most cases, the data type determines which application receives the data on the remote side. (If the target
field is specified, it determines which application receives the data instead of the data type as described below.) The Exchange Manager maintains a registry of applications and the types of data each application can receive. When the Exchange Manager receives an object, it checks the exchange socket for the data type. It checks the type
field first, and if it is not defined or if no application is registered to receive that MIME type, it checks the name
field for a file extension. This is discussed in more detail in the "Registering for Data" section.
Note that you may also directly specify which application should receive the data. To do so, place the creator ID in the target
field. You do not have to specify a MIME type or file extension in this instance. If the target
field is nonzero, the Exchange Manager checks to see if an application is registered for that creator ID and, if so, delivers the data directly to that application.
If the target application does not exist, the Exchange Manager searches the registry as usual. Use the target
field only if you know that you are communicating with a Palm Powered device and want to explicitly specify which application should receive the data.
An application can register for another application's creator ID and receive all objects targeted to that creator ID, but only with the user's permission. See "Setting the Default Application" for more details.
Registering for Data
In most cases, applications that want to receive data from the Exchange Manager must register for the MIME type and/or file extension that they want to receive.
To do so, call ExgRegisterDatatype()
and pass it five parameters:
- Your application's creator ID.
- A constant that identifies the type of data you want to register to receive:
exgRegExtensionID
for file extensions,exgRegTypeID
for MIME types,exgRegCreatorID
for creator IDs (see "Setting the Default Application"), orexgRegSchemeID
for URL schemes (see "Requesting a URL"). Alternatively, you can register for direct delivery of data (bypassing an email application) by specifying one of these constants:exgRegDirectExtensionID
,exgRegDirectCreatorID
, orexgRegDirectTypeID
. Or, you can indicate that the application supports data viewing by specifying one of these constants:exgRegViewExtensionID
,exgRegViewCreatorID
, orexgRegViewTypeID
. - A string that lists the MIME types or file extensions.
- A string containing descriptions of the data you are registering to receive; these are displayed to preview the data in the exchange dialog under certain circumstances.
- A flag value of zero.
ExgRegisterDatatype
(beamerCreator,
exgRegExtensionID, BitmapExt, "bitmap", 0);
General Registration Guidelines
Follow these guidelines when registering for data:
- Register as early as possible.
To ensure that your application can receive data at any time after it is installed, call
ExgRegisterDatatype()
in response to thesysAppLaunchCmdSyncNotify
andsysAppLaunchCmdSystemReset
launch codes. ThesysAppLaunchCmdSyncNotify
launch code is sent to your application upon its first installation and any time the HotSync® operation modifies the application's database. The sysAppLaunchCmdSystemReset is sent to your application when the system is reset. - It's best to use a standardized data format rather than a proprietary one if you have a choice.
- Provide user-friendly descriptive information for the
descriptionsP
parameter ofExgRegisterDatatype()
. The descriptions are used in dialogs displayed by Exchange Manager to identify applications or libraries. Use information that describes the type of information handled, such as pictures, sounds, contact information, etc. Don't use MIME types or file extensions because they are not meaningful to the average user. - Multiple applications can register to receive the same data type, however, an application must not automatically register itself as the default application without prompting the user for permission. The section "Setting the Default Application" describes this further. An application might check when it is launched if it is still the default application (with
ExgGetDefaultApplication()
). However, it must honor the user's choices for handling a particular data type by saving this information in its database and by providing a "Don't ask me again" option regarding changing the default. - When registering for file extensions, do not include the period (.) as part of the extension. Register for "TXT", for example, not ".TXT".
- Do not make multiple calls if you want to register for more than one MIME type or more than one file extension.
Instead, make one call for all file extensions and one call for all MIME types. Pass a single string containing file extensions or MIME types separated by a tab (\t) character. For example, the following call registers the application for two file extensions, TXT and DOC:
ExgRegisterDatatype(myCreator,
exgRegExtensionID,"TXT\tDOC", "plain text", 0);
- Applications that want to serve as display applications for specific kinds of data should register to receive data in view mode by using one of the view mode constants:
exgRegViewExtensionID
,exgRegViewCreatorID
, orexgRegViewTypeID
. For more details on supporting view mode, see "Viewing Attachments."
Setting the Default Application
Because multiple applications can register for the same data type, the Exchange Manager supports the concept of a default application that receives all objects of a particular data type. To set the default application, call the function ExgSetDefaultApplication()
. There is one default application per data type in the registry.
Suppose a device receives a vCard object, and it has three applications registered to receive vCards. The Exchange Manager checks the registry to see if any of these applications is assigned as the default. If so, the default application receives all vCards (unless the exchange socket structure's target
field is set). If none of the three applications is the default, the Exchange Manager chooses one, and that application receives all vCards.
Do not automatically register as the default application without the user's permission. It's imperative that you allow users to choose which application is the default. To do so, you could display a panel via a menu option that shows users the applications that can receive the same type of data as your application, show them which is the default, and allow them to select a different default. Use ExgGetRegisteredApplications()
to get a list of all applications registered to receive the same data type as yours, and use ExgGetDefaultApplication()
to retrieve the current default, if any. See Listing 4.2 to see how an application performs this task for the mailto
URL scheme.
Listing 4.1 Initializing a List of Registered Applications
void PrvSetMailAppsList(int32_t listSelection) { ControlPtr ctl; ListPtr lst; uint32_t defaultID; ctl = GetObjectPtr(PrefDefaultMailTrigger); lst = GetObjectPtr(PrefDefaultMailList); // crIDs, appCnt, appNames are all global variables. // Get the list of creator IDs if we don't have it already. if(!crIDs) { ExgGetRegisteredApplications(&crIDs, &appCnt, &appNames, NULL, exgRegSchemeID, "mailto"); if(appCnt) { MemHandle tmpH = SysFormPointerArrayToStrings(appNames, appCnt); if(tmpH) appNamesArray = MemHandleLock(tmpH); else return; } else return; } if(appNamesArray) LstSetListChoices(lst, appNamesArray, appCnt); LstSetHeight(lst, appCnt < 6 ? appCnt : 6); if(listSelection == -1) { uint16_t i; ExgGetDefaultApplication(&defaultID, exgRegSchemeID, "mailto"); for(i=0;i<appCnt;i++) { if(crIDs[i] == defaultID) LstSetSelection(lst, i); } } else LstSetSelection(lst, listSelection); CtlSetLabel(ctl, appNamesArray[LstGetSelection(lst)]); }
To become the default application for a data type that a built-in Palm OS application is registered to receive (see Table 4.1), you must perform some extra steps to ensure that you can receive that type of object when it is beamed from a device running Palm OS 3.X. You must register for the built-in application's creator ID and become the default application for that creator ID.
On Palm OS 3.X, the built-in applications always set their creator IDs in the target
field when sending data, causing the data to always be sent to that application. On Palm OS 4.0 and higher, the built-in applications still register to receive the same type of data, but they do not set the target
field when sending. This means that if your application is registered for the same data type and is the default application, it receives the data from devices running Palm OS 4.0 and higher as expected, but if the data is sent from a device running Palm OS 3.X, you still won't receive that data because it is specifically targeted for the built-in application.
To solve this problem, the ExgRegisterDatatype()
function supports registering for another application's creator ID. Listing 4.2 shows how an application that receives vCards might set the default application after allowing the user to select the default from a list, assuming the list is initialized with code similar to that in Listing 4.1.
Note that, as with all data types, your application won't receive the data targeted for the other application unless yours is the default application for that creator ID.
Listing 4.2 Setting the default application for vCards
uint32_t PilotMain (uint16_t cmd, void *cmdPBP, uint16_t launchFlags) { ... // Register for vCard MIME type, extension, and Address Book's creator ID. // At this point, we are not the default application so we do not receive // vCards. We still must register upon install so that our application // appears in the preferences list when the user chooses the default // application for vCards. case sysAppLaunchCmdSyncNotify: case sysAppLaunchCmdSystemReset: char addressCreatorStr[5]; // Create a string from Address Book's creator ID.MemMove(addressCreatorStr,
sysFileCAddress, 4);
address
CreatorStr[4] = chrNull; ExgRegisterDatatype(crID, exgRegTypeID, "text/x-vCard", "vCard", 0); ExgRegisterDatatype(crID, exgRegExtensionID, "vcf", "vCard", 0); ExgRegisterDatatype(crID, exgRegCreatorID, addressCreatorStr, NULL, 0); ... } static void PrefApply (void) { MemHandle h; FieldType *fld; ControlType *ctl; uint16_t listItem; // Set the default vCard app vif(appCnt && crIDs) { uint32_t crID; char addressCreatorStr[5]; // Create a string from Address Book's creator ID.MemMove(addressCreatorStr,
sysFileCAddress, 4);
address
CreatorStr[4] = chrNull; listItem = LstGetSelection(GetObjectPtr(PrefDefaultAppList)); crID = crIDs[listItem]; ExgSetDefaultApplication(crID, exgRegTypeID, "text/x-vCard"); ExgSetDefaultApplication(crID, exgRegExtensionID, "vcf"); ExgSetDefaultApplication(crID, exgRegCreatorID,addressCreatorStr
); } }
Registering to Receive Unwrapped Data
In rare circumstances, you can register to receive data that is sent enclosed in another object.
For example, suppose you have a stock quote application that wants to receive vStock objects. If the device is sent an email message that has the vStock object attached, your application may want to register to receive the vStock object directly rather than having the email application receive it. To do so, call ExgRegisterDatatype()
and pass one of the direct delivery constants (exgRegDirectCreatorID
, exgRegDirectExtensionID
, or exgRegDirectTypeID
) as the second parameter.
If you want to register to receive an object when it is sent as part of another object, you probably also want to receive it when it is sent by itself. This requires two calls to ExgRegisterDatatype()
: one with one of the direct delivery constants, and one without.
ExgRegisterDatatype(myCreator, exgRegDirectExtensionID, "TXT\tDOC",
"plain text", 0);
ExgRegisterDatatype(myCreator, exgRegExtensionID, "TXT\tDOC", "plain text", 0);
Thus, you might make four calls to ExgRegisterDatatype()
:
- one call to register for the file extensions
- one call to register for file extensions that are sent as part of another object
- one call to register for MIME types
- one call to register for MIME types that are sent as part of another object
As mentioned previously, it's rare for an application to register to receive unwrapped data directly. It's more common for one application (such as an email application) to receive the entire compound object and then unwrap and disperse the enclosed objects using the Local Exchange Library. See "Sending and Receiving Locally" and "Attachment Support Guidelines" for more information.
Sending Data
This section describes how to send data using the Exchange Manager. It discusses the following topics:
For information about sending data as an attachment from a messaging application such as email or SMS, see "Attachment Support Guidelines."
Sending a Single Object
The most common use of the Exchange Manager is to send or receive a single object. To send an object, do the following:
- Create and initialize an
ExgSocketType
data structure with information about which library to use and the data to be sent. See "Initializing the Exchange Socket Structure" for more information. - Call
ExgPut()
to establish the connection with the exchange library. - Call
ExgSend()
one or more times to send the data.In this function, you specify the number of bytes to send. You may need to call it multiple times if you don't send all the data in the first call.
- Call
ExgDisconnect()
to end the connection.A zero (0) return value indicates a successful transmission. However, this doesn't necessarily mean that the receiver kept the data. If the target application for an object doesn't exist on the receiving device, the data is discarded; or the user can decide to discard any received objects.
Note that the ExgSend()
function blocks until it returns. However, most libraries provide a user interface dialog that keeps the user informed of transmission progress and allows them to cancel the operation.
The Exchange Manager automatically displays error dialogs as well, if errors occur. You must check for error codes from Exchange Manager routines, but you don't need to display an error dialog if you get one because the Exchange Manager handles this for you.
For example, Listing 4.3 shows how to send the current draw window from one Palm Powered handheld to another Palm Powered handheld.
Listing 4.3 Sending data using Exchange Manager
status_t SendData(void) { ExgSocketType exgSocket; uint32_t size = 0; uint32_t sizeSent = 0; status_t err = 0; BitmapType *bmpP; // copy draw area into the bitmap SaveWindow(); bmpP = PrvGetBitmap(canvasWinH, &size, &err); // Is there data in the field? if (!err && size) { // important to init structure to zeros... MemSet(&exgSocket,sizeof(exgSocket),0); exgSocket.description = "Beamer picture"; exgSocket.name = "Beamer.pbm"; exgSocket.length = size; err = ExgPut(&exgSocket); if (!err) { sizeSent = ExgSend(&exgSocket,bmpP,size,&err); ExgDisconnect(&exgSocket,err); } } if (bmpP) MemPtrFree(bmpP); return err; }
Sending Multiple Objects
If the exchange library supports it, you can send multiple objects in a single connection. To send multiple objects, do the following:
- Create and initialize an
ExgSocketType
data structure with information about which library to use and the data to be sent. See "Initializing the Exchange Socket Structure" for more information. You might also supply a value for thecount
field to specify how many objects are to be sent. - Call
ExgConnect()
to establish the connection with the exchange library. - For each object, do the following:
- Call
ExgDisconnect()
to end the connection.A zero (0) return value indicates a successful transmission. However, this doesn't necessarily mean that the receiver kept the data. If the target application for an object doesn't exist on the receiving device, the data is discarded; or the user can decide to discard any beamed objects.
The ExgConnect()
call is optional. Some exchange libraries, such as the IR Library, support the sending of multiple objects but do not support ExgConnect()
. If ExgConnect()
returns an error, the first call to ExgPut()
initiates the connection. You should only continue to send objects if the first ExgPut()
call succeeds. See Listing 4.4. Libraries that support the ExgConnect()
call also support sending multiple objects without using ExgConnect()
.
Listing 4.4 Sending multiple objects
Boolean isConnected = false; err = ExgConnect(&exgSocket); //optional if (!err) isConnected = true; if (!err || err == exgErrNotSupported) { while (/* we have objects to send */) { err = ExgPut(&exgSocket); if (!isConnected && !err) isConnected = true; //auto-connected on first put. sizeSent = ExgSend(&exgSocket,dataP,size,&err); if (err) break; } } if (isConnected) ExgDisconnect(&exgSocket, err);
Implementing the Send Command
The built-in applications support a Send menu command. The purpose of this command is to allow the user to send data using any available transport mechanism.
The Exchange Manager defines a _send URL scheme. The intent is that any exchange library that supports sending is registered for the _send scheme. Currently, the Bluetooth, HotSync, SMS, and Mobile Mail libraries are registered for this scheme on release ROMs. The IR Library is not registered for the _send scheme.
To implement the Send command in your application, construct a URL that has the prefix exgSendPrefix
, and send the data in the normal manner. You can also use the exgSendBeamPrefix
instead so that the user can select from all exchange libraries registered for either sending or beaming (which includes the IR Library). Both of these prefixes begin with a question mark, causing the Exchange Manager to display a dialog if it finds more than one exchange library registered for the specified schemes.
For an example of how to implement the Send command, see the Memo application example code distributed with the Palm OS SDK.
Receiving Data
To have your application receive data from the Exchange Manager, do the following:
- Register for the type of data you want to receive. See "Registering for Data" for more information.
- Handle the launch code
sysAppLaunchCmdExgAskUser
if you want to control the user confirmation dialog that is displayed. See "Controlling the Exchange Dialog" for more information. - Handle the launch code
sysAppLaunchCmdExgReceiveData
to view and/or receive the data. See "Receiving the Data" for more information on receiving the data, and see "Viewing Attachments" for more information about viewing the data; it's best to follow the guidelines in "Put with View Mode." - If you want, handle
sysAppLaunchCmdGoTo
to display the record.
Controlling the Exchange Dialog
When the Exchange Manager receives an object and decides that your application is the target for that object, it sends your application a series of launch codes. The first launch code your application receives, in most cases, is sysAppLaunchCmdExgAskUser
.
NOTE: The Exchange Manager allows the exchange library to turn off the user confirmation dialog. In this case, your application does not receive the
sysAppLaunchCmdExgAskUser
launch code.
The Exchange Manger sends this launch code because it is about to display the exchange dialog, which asks the user to confirm the receipt of data. The launch code is your opportunity to accept the data without confirmation, reject the data without confirmation, or replace the exchange dialog.
Responding to this launch code is optional. If you don't respond, the Exchange Manager calls ExgDoDialog()
to display the exchange dialog.
The ExgDoDialog()
function allows you to specify that the dialog display a category pop-up list. This pop-up list allows the user to receive the data into a certain category in the database, but the pop-up list is not shown by default. If you want the exchange dialog to display the pop-up list, you must respond to sysAppLaunchCmdExgAskUser
and call ExgDoDialog()
yourself. Pass a pointer to an ExgDialogInfoType
structure. The ExgDialogInfoType
structure is defined as follows:
typedef struct { uint16_t version; DmOpenRef db; uint16_t categoryIndex; } ExgDialogInfoType;
-
→ version
- Set this field to 0 to specify version 0 of this structure.
-
→
db
- A pointer to an open database that defines the categories the dialog should display.
-
←
categoryIndex
- The index of the category in which the user wants to file the incoming data.
If db
is valid, the function extracts the category information from the specified database and displays it in a pop-up list. Upon return, the categoryIndex
field contains the index of the category the user selected, or dmUnfiledCategory
if the user did not select a category.
If the call to ExgDoDialog()
is successful, your application is responsible for retaining the value returned in categoryIndex
and using it to file the incoming data as a record in that category. One way to do this is to store the categoryIndex
in the socket's appData
field (see ExgSocketType
) and then extract it from the socket in your response to the launch code sysAppLaunchCmdExgReceiveData
. See Listing 4.5 for an example.
Listing 4.5 Extracting the category from the exchange socket
uint16_t categoryID = (ExgSocketType *)cmdPBP->appData; /* Receive the data, and create a new record using the received data. indexNew is the index of this record. */ if (category != dmUnfiledCategory){ uint16_t attr; status_t err; err = DmRecordInfo(dbP, indexNew, &attr, NULL, NULL); // Set the category to the one the user specified, and // mark the record dirty. if ((attr & dmRecAttrCategoryMask) != category) { attr &= ~dmRecAttrCategoryMask; attr |= category | dmRecAttrDirty; err = DmSetRecordInfo(dbP, indexNew, &attr, NULL); } }
Some of the Palm OS built-in applications (Address Book, Memo, and ToDo) use this method of setting the category on data received through beaming. Refer to the example code provided in the Palm OS SDK for these applications for a more complete example of how to use ExgDoDialog()
.
When you explicitly call ExgDoDialog()
, you must set the result
field of the sysAppLaunchCmdExgAskUser
launch code's parameter block to either exgAskOk
(upon success) or exgAskCancel
(upon failure) to prevent the system from displaying the dialog a second time.
Getting the Object Description
The user might need more information about the object being received, so the Exchange Manager displays information about the object in the exchange dialog. Some exchange libraries do not transmit information for the exchange socket's description
field, so the Exchange Manager must provide another means of supplying the user with information about the data being received.
The Exchange Manager displays the first item that it locates in the following list:
- The data's description from the exchange socket's
description
field - The filename in the socket's
name
field - The receiving application's description as stored in the exchange registry (you pass this description to
ExgRegisterDatatype()
when registering) - The MIME type in the socket's
type
field - The file extension in the socket's
name
field
If you want to support viewing the data in an application, the Exchange Manager can launch a display application with the launch code sysAppLaunchCmdExgReceiveData
. Display applications should register both file extension(s) and MIME type(s) of data that they can handle. Ideally, display applications should register for receiving data in view mode by registering with one or more of the view mode data type constants: exgRegViewExtensionID
, exgRegViewCreatorID
, or exgRegViewTypeID
. Refer to "General Registration Guidelines."
For detailed information about supporting data viewing, see "Viewing Attachments"; particularly, you should follow the guidelines in "Put with View Mode." This information applies not only to email attachments, but to any incoming data.
Receiving the Data
If the Exchange Manager receives exgAskOk
in response to the exchange dialog or the sysAppLaunchCmdExgAskUser
launch code, the next step is to launch the application with sysAppLaunchCmdExgReceiveData
. This launch code tells the application to actually receive the data.
To respond to this launch code, do the following:
- Call
ExgAccept()
to accept the connection. - Call
ExgReceive()
one or more times to receive the data.In this function you specify the number of bytes to receive, and
ExgReceive()
returns the number of bytes that were received. You may need to call it multiple times if data is remaining to be received after the first and subsequent calls.Note that in the socket structure, the
length
field may not be accurate, so in your receive loop you should be flexible in handling more or less data thanlength
specifies. - If you want your application launched again with the
sysAppLaunchCmdGoTo
launch code, place your application's creator ID in theExgSocketType
'sgoToCreator
field and supply the information that should be passed to the launch code in thegotoParams
field. (TheExgSocketType
structure is the parameter block for thesysAppLaunchCmdExgReceiveData
launch code.) - Call
ExgDisconnect()
to end the connection.A zero (0) return value indicates a successful transmission.
After your application returns from sysAppLaunchCmdExgReceiveData
, if the goToCreator
specifies your application's creator ID and if the exchange library supports it, your application is launched with sysAppLaunchCmdGoto
. In response to this launch code, your application should launch, open its database, and display the record identified by the recordNum
field (or matchCustom
field) in the parameter block. The Exchange Manager always does a full application launch with sysAppLaunchCmdGoto
, so your application has access to global variables; however, if you also use this launch code to implement the global find facility, you may not have access to global variables in that instance. The example code in Listing 4.6 checks to see if globals are available, and if so, calls StartApplication
to initialize them.
Listing 4.6 Responding to sysAppLaunchCmdGoto
case sysAppLaunchCmdGoto: if (launchFlags & sysAppLaunchFlagNewGlobals) { err = StartApplication(); if (err) return err; GoTo(cmdPBP, true); EventLoop(); StopApplication(); } else { GoTo(cmdPBP, false); }
Not all exchange libraries support using the sysAppLaunchCmdGoto
launch code after the receipt of data.
Because Palm OS supports multiple object exchange, there is no guarantee that your application is the one that is launched at the end of a receipt of data. If multiple objects are being received, it is possible for another application to receive data after yours and to set the goToCreator
field to its own creator ID. In this case, the last application to set the field is the one that is launched.
Listing 4.7 shows a function that receives a data object and sets the goToCreator
and goToParams
.
Listing 4.7 Receiving a data object
status_t ReceiveData(ExgSocketPtr exgSocketP) { status_t err; MemHandle dataH; uint16_t size; uint8_t *dataP; int16_t len; uint16_t dataLen = 0; if (exgSocketP->length) size = exgSocketP->length; else size = ChunkSize; dataH = MemHandleNew(size); if (!dataH) return -1; // // accept will open a progress dialog and wait for your receive commands err = ExgAccept(exgSocketP); if (!err){ dataP = MemHandleLock(dataH); do { len = ExgReceive(exgSocketP,&dataP[dataLen], size-dataLen,&err); if (len && !err) { dataLen+=len; // resize block when we reach the limit of this one... if (dataLen >= size) { MemHandleUnlock(dataH); err = MemHandleResize(dataH,size+ChunkSize); dataP = MemHandleLock(dataH); if (!err) size += ChunkSize; } } } while (len && !err); MemHandleUnlock(dataH); ExgDisconnect(exgSocketP,err); // closes transfer dialog if (!err) { exgSocketP->goToCreator = beamerCreator; exgSocketP->goToParams.matchCustom = (uint32_t)dataH; } } // release memory if an error occured if (err) MemHandleFree(dataH); return err; }
Sending and Receiving Databases
It's common to want to send and receive an entire database using the Exchange Manager. For example, you might want to allow your application's users to share their versions of the PDB file associated with your application by beaming that file to each other.
Sending and receiving a database involves the extra steps of flattening the database into a byte stream when sending and un-flattening it upon return.
In addition to the process documented in this section, you can now also use the Data Manager function DmBackupUpdate()
to flatten a database into a bye stream, and DmRestoreUpdate()
to restore a database from a byte stream. These functions are more flexible than the Exchange Manager functions.
Sending a Database
To send a database, do the following:
- Create and initialize an
ExgSocketType
data structure with information about which library to use and the data to be sent. See "Initializing the Exchange Socket Structure" for more information. - Call
ExgPut()
to establish the connection with the exchange library. - Call
ExgDBWrite()
and pass it a pointer to a callback function in your application that it can use to send the database. You make the call toExgSend()
in that function. - Call
ExgDisconnect()
to end the connection.
The ExgDBWrite()
function takes as parameters the local ID of the database to be sent and a pointer to a callback function. You may also pass in the name of the database as it should appear in a file list and any application-specific data you want passed to the callback function. In this case, you would pass the pointer to the exchange socket structure as the application-specific data. If you need any other data, create a structure that contains the exchange socket and pass a pointer to that structure instead.
The write callback function is called as many times as is necessary to send the data. It takes three arguments: a pointer to the data to be sent, the size of the data, and the application-specific data passed as the second argument to ExgDBWrite()
.
Listing 4.8 shows an example of how to send a database. The SendMe()
function looks up the database creator ID and passes it to the SendDatabase()
function. The SendDatabase()
function creates and initializes the exchange socket structure and then passes all that information along to the ExgDBWrite()
function. The ExgDBWrite()
function locates the database in the storage heap, translates it into a stream of bytes and passes that byte stream as the first argument to the write callback function WriteDBData()
. WriteDBData()
forwards the exchange socket and the data stream to the ExgSend()
call, sets its size parameter to the number of bytes sent (the return value of ExgSend()
), and returns any error returned by ExgSend()
.
Listing 4.8 Sending a database
// Callback for ExgDBWrite to send data with Exchange Manager status_t WriteDBData(const void* dataP, uint32_t* sizeP, void* userDataP) { status_t err; *sizeP = ExgSend((ExgSocketPtr)userDataP, (void*)dataP, *sizeP, &err); return err; } status_t SendDatabase (LocalID dbID, CharPtr nameP, CharPtr descriptionP) { ExgSocketType exgSocket; status_t err; // Create exgSocket structure MemSet(&exgSocket, sizeof(exgSocket), 0); exgSocket.description = descriptionP; exgSocket.name = nameP; // Start an exchange put operation err = ExgPut(&exgSocket); if (!err) { err = ExgDBWrite(WriteDBData, &exgSocket, NULL, dbID); err = ExgDisconnect(&exgSocket, err); } return err; } // Sends this application status_t SendMe(void) { status_t err; // Find our app using its internal name LocalID dbID = DmFindDatabase(0, "Beamer"); if (dbID) err = SendDatabase(dbID, "Beamer.prc", "Beamer application"); else err = DmGetLastErr(); return err; }
Note that there is nothing about ExgDBWrite()
that is tied to the Exchange Manager, so it may be used to send a database using other transport mechanisms as well. For example, if you wanted to transfer a database from your Palm Powered handheld to your desktop PC using the serial port, you could use ExgDBWrite()
to do so.
Receiving a Database
The Launcher application receives databases with the .prc
or .pdb
file extension. If you want your application to be launched when the database is received, you can use a different extension and handle receiving the database within your application. For example, a book reader application might want to be launched when the user is beamed a book. In this case, the book reader application might use an extension such as .bk
for the book databases.
You receive a database by responding to the same launch codes that you do for receiving any other data object (see "Receiving Data"); however, your response to the sysAppLaunchCmdExgReceiveData
launch code is a little different:
- Call
ExgAccept()
to accept the connection. - Call
ExgDBRead()
and pass it a pointer to a callback function in your application that it can use to read the database. You make the call toExgReceive()
in that function. - Call
ExgDisconnect()
to end the connection.
The ExgDBRead()
function takes as parameters two pointers to callback functions. The first callback function is a function that is called multiple times to read the data. The second function is used if the database to be received already exists on the device.
Requesting Data
This section describes how to use the Exchange Manager to request data. It covers:
- Sending a Get Request for a Single Object
- Responding to a Get Request
- Two-Way Communications
- Requesting a URL
Some exchange libraries may allow you to request data from a remote device through a call to ExgGet()
. If supported, you can use ExgGet()
to implement two-way communications between two Palm Powered devices.
NOTE: The only standard exchange library that supports
ExgGet()
is the Local Exchange Library; currently there are no transports that support remote get requests.
For information on using ExgGet()
to attach a document to a message from a messaging application, see "Sending an Attachment from a Messaging Application."
Sending a Get Request for a Single Object
To request data from a remote device, do the following:
- Create and initialize an exchange socket structure (
ExgSocketType
) as described in "Initializing the Exchange Socket Structure"section. The data structure should identify the exchange library and the type of data that your application wants to receive. - Call
ExgGet()
to establish the connection and request the data.In response, the exchange library establishes a connection with the remote device, and upon return has data that your application should receive. If the remote device is a Palm Powered device, the exchange library obtains this data from an application on the remote side using the process described in the "Responding to a Get Request" section.
- Call
ExgReceive()
one or more times to receive the data. - Call
ExgDisconnect()
to end the connection.
Responding to a Get Request
When the Exchange Manager receives a get request, it launches the appropriate application with the launch code sysAppLaunchCmdExgGetData
. Applications can register their support for the Get mechanism by registering to handle the _get
scheme.
NOTE: Since no standard transports support remote get requests, this section describes how to support a local get request.
Your response to the sysAppLaunchCmdExgGetData
launch code should be to send the requested data:
- Present a document selection screen so that the user can choose an object to send.
- Set the name, type, and description fields in the socket.
- Call
ExgAccept()
. (Do not callExgPut()
.) - Call
ExgSend()
one or more times. - Call
ExgDisconnect()
when finished.
For more information on supporting the Get mechanism, see "Sending an Attachment from a Messaging Application."
See the "Sending a Single Object" section for more information on sending objects.
Two-Way Communications
You can use ExgGet()
and ExgPut()
in combination with the ExgConnect()
call to have your application perform two-way communication. For example, you may want to implement two-way communication in a multiuser game.
In such a situation, one device acts as a client and the other acts as a server. The client calls ExgConnect()
, which tells the exchange library that a connection is established to perform multiple operations, such as the sending of multiple objects. The client then calls ExgGet()
or ExgPut()
repeatedly and calls ExgDisconnect()
when finished. On the server device, the appropriate application is launched for each of these requests. The server also calls ExgDisconnect()
when it is done sending or receiving each object. The swapping of client and server roles is not supported.
Remember that not all exchange libraries support ExgConnect()
and ExgGet()
. If either one of these returns an error, your application should assume that this feature is not available.
Getting the Sender's URL
For some applications, you might need to know the URL that addresses the remote device from which you are receiving data. This is especially useful for games and other two-way communications. You can get the URL after calling ExgAccept()
by calling ExgControl()
and passing the exgLibCtlGetURL
operation code.
Not all exchange libraries support this operation. The Bluetooth exchange library does support it, and you can find more information in Chapter 12, "Bluetooth Exchange Library Support," in Exploring Palm OS: Low-Level Communications.
Requesting a URL
In addition to requesting data with an ExgGet()
call, you can request a URL with a ExgRequest()
call. The idea behind the ExgRequest()
call is to follow the model of pull technology. You could, for example, implement a web browser if you had an exchange library that supported the HTTP protocol. You could then send an ExgRequest()
call with an exchange socket containing a URL such as http://www.palmos.com
and receive the web page in response.
The fundamental differences between ExgRequest()
and ExgGet()
are:
-
ExgRequest()
does not automatically send the data back to the application that requested it. WithExgRequest()
, when the exchange library receives the requested data, it has the Exchange Manager send it to the default application for that data type. - Applications can register for URLs sent using
ExgRequest()
.ExgRequest()
first looks for an exchange library that handles the URL scheme. If it cannot find one, it looks for an application instead. If it finds an application, it launches it with thesysAppLaunchCmdGoToURL
launch code.For example, suppose an application that handles email registers for the
mailto
URL scheme. If another application wants to implement an email command, it could do so by callingExgRequest()
and passing an exchange socket with a URL that begins withmailto
. In response to this command, the Exchange Manager launches the application that handles email, allowing the user to compose the email.
For information on another method of implemented email and attaching a document to a message, see "Sending an Attachment from a Display Application."
Sending and Receiving Locally
Most of this chapter has described how to use the Exchange Manager to send data to a remote device and receive data from a remote device.
You may also use the Exchange Manager to exchange data with other applications on the local device. To do so, use the Local Exchange Library. You might want to do so in the following circumstances:
- You might have an application that creates some sort of event in the Datebook application. Your users might have an application that they use in place of the built-in Datebook. To ensure that the appointment is sent to the user's chosen application, you can send that data as a vCalendar object using the Local Exchange Manager. This way, whichever application is the default in the Exchange Manager registry is the one that receives your vCalendar.
- Your application receives compound data objects, such as email messages that contain attachments intended for other applications. As described in the "Registering to Receive Unwrapped Data" section, exchange libraries can "unwrap" a compound object and deliver the objects it contains directly; however, doing so is the exception the rule.
It's much more common for the email message to be sent to the email application and have the attachments delivered to the appropriate applications only when the user requests it. In response to a user request, the email application extracts the attached object and uses the Local Exchange Library to send it to the application that should receive it, for viewing and/or storage. For detailed guidelines on handling attachments, see "Attachment Support Guidelines."
- Your application exchanges data with a remote device, and you want to debug the code that interacts with the Exchange Manager. In this case, using the Local Exchange Library causes your application to send data in loopback mode, where it is also the recipient of the data.
To use the Local Exchange Library, do the following:
- Use a URL in the
name
field of theExgSocketType
structure to identify the Local Exchange Library. Begin the URL with the constant stringexgLocalPrefix
. - If you want to suppress the exchange dialog, create and initialize an
ExgLocalSocketInfoType
structure and assign it to the socket'ssocketRef
field.typedef struct { Boolean freeOnDisconnect; Boolean noAsk; ExgPreviewInfoType *previewInfoP; ExgLocalOpType op; FileHand tempFileH; } ExgLocalSocketInfoType;
Determines whether the structure is freed when the |
|
Set to |
|
A pointer to an |
All other fields are set by the Local Exchange Library. If you don't create this structure, the library does it for you; therefore, you only need to create this structure if you want to supply non-default values for the noAsk
or previewInfoP
fields.
- You can suppress the display of the progress dialogs that the exchange libraries typically display by setting the
noStatus
field of theExgSocketType
structure totrue
. - Send and receive data in the normal manner. See "Sending Data" and "Receiving Data" for details.
Interacting with the Launcher
When you beam an application from the Launcher, other databases can be automatically beamed with it. If the application has an associated overlay database, the overlay is beamed along with the application. You do not have to perform any extra work to allow this to happen. This bundling behavior is available only when beaming from the launcher, not if an application manually beams an application.
In addition to beaming overlays, you can set up a record database so that the Launcher beams it along with the application database and the overlay. For example, a dictionary application might have its dictionary data in an associated database. When a user beams the dictionary application to another user, the dictionary data should be beamed along with the application itself. To allow this to happen, you set the bit dmHdrAttrBundle in the database's attributes.
If you beam an application plus databases to a device running Palm OS 4.0 or higher, the user sees a single confirmation message. If you beam the application to a device running Palm OS 3.X, the device receives only the application database and displays an alert saying that it cannot receive the other databases.
HotSync Exchange
HotSync Exchange allows a Palm OS Cobalt device and a desktop computer running the Palm Desktop to exchange files in their native formats. For example, HotSync Exchange enables installation of JPEG (.JPG) files to a handheld image viewer via the standard HotSync desktop install tool and the HotSync exchange library, provided the viewer application has registered with the Exchange Manager for the .JPG extension. This feature eliminates the need for the viewer application developer to write a custom conduit to pack JPEG data into the Palm OS database format.
Similarly, the viewer application can send JPEG files via the Exchange Manager directly to the desktop where HotSync stores them in standard .JPG format.
HotSync Exchange also supports bundled install, which is the installation of an application and its data files in a single HotSync session. Bundled install requires the newly installed application to register for its data types with the Exchange Manager when it receives the sysAppLaunchCmdSyncNotify
launch code. This allows the HotSync exchange library to deliver the data files when it receives the subsequent sysNotifySyncFinishEvent
.
For more information about the desktop side of HotSync Exchange, refer to the book Introduction to Conduit Development.
Note that HotSync Exchange is supported only by Palm OS devices running Palm OS Cobalt.
Sending Files with HotSync Exchange
Applications use the HotSync exchange library to send files to a HotSync desktop. The HotSync exchange library supports the following Exchange Manager schemes:
- The desktop scheme (_desktop). This scheme supports direct exchange of a file to a HotSync desktop.
- The _send scheme. This scheme allows users to send data using any transport that supports this scheme, such as the HotSync exchange library.
These schemes support the exchange of files during a HotSync operation to a directly connected desktop.
Neither scheme supports the specification of a target desktop in the Exchange URL, so the file will, by default, be sent during the next HotSync operation to any desktop. However, the user may select a specific target desktop for each file pending HotSync Exchange via the HotSync client user interface, if desired (see below). This will cause the file to be sent during the next HotSync operation with the selected desktop.
Example
The following example illustrates the data flow involving the HotSync exchange library and the desktop. Say that a device application wants to transfer palmuser.id to the desktop. The user also wants to install the picture mountain.jpg to the handheld to view on a registered JPEG picture viewer.
Figure 4.2 HotSync Exchange example

Prior to the HotSync Operation
Before the HotSync operation the following operations are performed:
The user queues the file mountain.jpg for install to the handheld during a subsequent HotSync. The file is queued in a user-specific download folder on the desktop.
The device application uses the Exchange Manager API to do the following (represented by red lines in the figure):
- Initialize the
ExgSocketType
structure with the file name palmuser.id. - Call
ExgPut()
. This causes the HotSync exchange library to allocate a temporary cache to store the data. It also stores information about the pending transaction in a catalog of pending desktop exchanges. - Call
ExgSend()
to fill the database with the data. - Call
ExgDisconnect()
to close the cache. The data is then queued until it can be successfully sent during a HotSync operation.
During the HotSync Operation
During the HotSync Exchange operation, the conduit performs several actions, represented by the black lines in the figure.
The HotSync Exchange conduit first checks if there are any pending handheld-to-desktop transfer requests for the local desktop by examining the handheld exchange catalog mentioned above. Since the conduit finds an entry, it proceeds to create a desktop file with the associated file name (palmuser.id) in the user's directory on the desktop that contains the contents of the associated temporary cache. Afterwards, the conduit deletes the catalog entry and the temporary cache from the handheld.
The conduit then checks to see if there are any files to be installed to the device. It finds mountains.jpg and creates a cache named mountains.jpg on the handheld.
After the HotSync Operation
After the HotSync operation the following operations are performed (represented by blue lines in the figure):
The system launches newly installed applications and applications whose data has been modified by the HotSync operation. At this point newly installed applications can register supported file types with the Exchange Manager. (So, if the HotSync operation had installed a JPEG viewer, it would now register for .JPG files). When the HotSync exchange library receives the sysNotifySyncFinishEvent
notification, it searches for temporary HotSync caches. On finding mountains.jpg, it opens the cache and calls ExgNotifyReceive()
. This causes the Exchange Manager to launch the viewer for JPEG files and transfer the file mountains.jpg to it. The application may choose to convert and store it in a Palm OS database. When the application calls ExgDisconnect()
, the HotSync exchange library deletes the temporary cache created by the conduit.
The HotSync exchange library disables the confirm receipt dialog that is normally displayed when data is sent via the Exchange Manager. Thus there is no user interface on the handheld device during a successful desktop to handheld exchange.
Attachment Support Guidelines
This section outlines how Palm OS applications should interoperate to exchange email attachments. On other platforms attachments are stored intermediately on a file system for the handover between a messaging application (email, instant messaging, etc.) and a display application (word processor, image viewer, etc.). On Palm OS, which doesn't provide a file system, the Exchange Manager enables data exchange between applications.
The following sections describe how applications should use the Exchange Manager to handle attachments. These guidelines were designed with the following goals:
- Leveraging existing capabilities of today's applications.
- Ensuring backwards compatibility with Palm OS 4 by using existing standard mechanisms.
- Providing a good user experience.
Application providers are strongly encouraged to follow these guidelines to enable a consistent user experience on Palm OS.
The following topics are covered:
- Viewing Attachments
- Sending an Attachment from a Messaging Application
- Sending an Attachment from a Display Application
- Email Application Guidelines
The Attachment Support sample code shows how to implement the guidelines covered in this section. It is available in the Developer Knowledge Base at http://kb.palmsource.com/
Viewing Attachments
Messaging applications should leverage dedicated display applications already available on the device rather than implementing their own content viewers. Passing data from the messaging application to a display application is facilitated by the Exchange Manager.
NOTE: The data viewing mechanism described here can be used for more than just viewing email attachments. It can be used as a general purpose mechanism to view any data incoming via the Exchange Manager. Follow the guidelines for display applications to support data viewing in a display application.
There are two methods of exchanging attachments:
- Regular Put: This is the standard put mechanism (using
ExgNotifyReceive()
orExgPut()
). It is backwards compatible with older applications that don't know about attachment support. - Put with View Mode: This method defines an enhanced view mode. It enables display applications to distinguish between data sent for temporary viewing versus data sent to be accepted into the database.
Additionally, this method defines a return mechanism to the messaging application. This allows display applications to execute a full launch of one or more other applications before returning control to the messaging application.
Regular Put
This method, which has been around for several years, enables an application to send data to another application. Older display applications, which are not attachment aware, will simply accept the data into their database and not return to the messaging application. (The user needs to return via the launcher). Although this behavior doesn't present an optimal user experience, it provides a way to take advantage of older applications.
Newer applications, which follow the guidelines outlined in this section, provide the user with the option to return to the messaging application (for example, via a Done button). The recommended method is that the display application simply exits. The system will automatically launch the previous application (implicit launch of the messaging application).
The interaction between the messaging application, Exchange Manager, and the display application for a regular Put operation is shown in Figure 4.3. Specific guidelines for messaging applications and display applications follow the figure.
Figure 4.3 Regular Put operation

Guidelines for Messaging Applications
To handle attachment viewing with the regular Put method, messaging applications should follow these guidelines:
- Messaging applications are strongly encouraged to implement their own exchange library to support the Put mechanism (minimal implementation of accept/receive/disconnect).
Although Put can be implemented without an exchange library (by using
ExgPut()
,ExgSend()
, andExgDisconnect()
), this implementation is slow, especially for large attachments, because the Exchange Manager first reads and copies all the data before handing it over to the display application. - Messaging applications can query the Exchange Manager registry to determine if a dedicated application is available to handle a specific content type (use
ExgGetRegisteredTypes()
). If no application can handle the attachment, the messaging application may convert the content into a different format that can be displayed on the device. The conversion might take place either on the client side or, in the case of a distributed email solution, on a server or desktop computer. For example, if no application has registered with the Exchange Manager to handle HTML content, the email application could convert it to text and display it itself. - Whenever possible, messaging applications should include the MIME type information (besides the file extension) when sending data to the Exchange Manager. File extensions do not uniquely identify the content of a document. In some cases, the same file extension has been used for different file formats (for example, ".doc"). Refer to IANA (http://www.iana.org/assignments/media-types/) for the official list of registered MIME types.
Some notes on MIME types: MIME type information in the Content-Type field of email messages isn't always reliable. Some email programs use non-registered MIME types (for example, application/powerpoint instead of application/vnd.ms-powerpoint) or use a generic MIME type (for example, application/octet) when attaching documents. It is recommended that email applications analyze the Content-Type field carefully (including file extensions), and map it to the correct MIME type before passing this information to the Exchange Manager. Developers of messaging applications are encouraged to present a list of applications that can handle the attachment, instead of simply using the default application. (The
ExgGetRegisteredApplications()
function allows messaging applications to query for applications that have registered for a specific MIME type or file extension). - Messaging applications should send only one data object (document) at a time to a document application in a single connection. Although the exchange library is capable of handling multiple objects in a single connection, the assumption is that a display application can display only one document at a time.
- For regular Put, the default Exchange Manager dialog ("Do you want to accept...") should not be disabled. (Use
ExgNotifyReceive()
(...,0)
in the exchange library). - Messaging applications are responsible for transport-related encoding and decoding of the content. All content exchanged with a display application happens in binary format.
Guidelines for Display Applications
To handle attachment viewing with the regular Put method, display applications should follow these guidelines:
- Display applications should register both file extension(s) and MIME type(s) of data that they can handle. Refer to "General Registration Guidelines."
- Applications should be prepared to receive invalid data and deal with this situation gracefully.
- Applications that accept data or documents into their databases should avoid unnecessary duplication. For instance, if a user views an attachment several times, the data should not be duplicated.
- Applications should provide the user with an option to return to the messaging application (for example, a Done button).
- Display applications and messaging applications exchange data in its normal binary format. Messaging applications will encode/decode the data according to their transport requirements.
Put with View Mode
This method defines an extension to the standard Put mechanism. It allows display applications to implement a special view mode where data is displayed, but not automatically added to the application's database. During view mode, the default Exchange Manager "Accept..." dialog can be disabled, which saves the user an extra step.
Moreover, view mode defines a mechanism to return to the messaging application across an arbitrary number of nested launches of other applications. This is useful, for instance, when a messaging application hands a .zip or .tar file to a decompression utility application that, after the user chooses a specific document, sends the content to the appropriate display application.
Implementation of the view mode requires collaboration of both the messaging and display applications. Display applications indicate support for view mode by using the following exchange registry IDs during registration:
// New Exchange registry IDs for View registry. Don't change values! #define exgRegViewExtensionID 0xff8d // filename ext. registry for View #define exgRegViewTypeID 0xff8e // MIME type registry for View ExgRegisterDatatype(...,exgRegViewExtensionID,...,...,...); ExgRegisterDatatype(...,exgRegViewTypeID,...,...,...);
These two exchange registry IDs, one for file extensions and the other for MIME types, allow display applications to support view mode only for a subset of the content they usually accept.
Before a messaging application calls ExgNotifyReceive()
, it must first check if the receiving application supports view mode for the content that is to be sent. If the display application supports view mode, the messaging application must add its own GoTo information to the ExgSocketType
structure. Figure 4.4 shows the interaction between the applications and the Exchange Manager in more detail.

Guidelines for Messaging Applications
Messaging applications are strongly encouraged to support view mode.
In addition to the guidelines defined in "Regular Put," messaging applications that want to take advantage of display applications with view mode support must follow these guidelines:
- Messaging applications must check if the receiving application supports view mode, before adding their own GoTo information. The default "Accept" dialog can be disabled only if the target application supports view mode, resides on the same device, and if GoTo information is added.
ExgGetRegisteredApplications(..., ..., ..., exgRegViewExtensionID,...) ExgGetRegisteredApplications(..., ..., ..., exgRegViewTypeID,...) ... if (supportsView) { add_my_GoTo_info(); ask = exgNoAsk; } ExgNotifyReceive(..., ask);
- If the receiving application does not support view mode, the
gotoCreator
field and thegoToParams
structure fields in theExgSocketType
structure passed toExgNotifyReceive()
(orExgPut()
) must be set to zero and the "Accept" dialog must not be disabled. The reason for this is that some applications (for example, certain built-in PIM applications) that don't support view mode, use somegoToParams
fields to determine certain states. Supplying wrong information could lead to unwanted behavior. - When a messaging application is relaunched after view mode, it should return to the same state it was in when the display application was launched. Especially, the same message should be displayed and any splash screens should be skipped.
Guidelines for Display Applications
In addition to the guidelines defined in "Regular Put," display applications that want to implement view mode support must follow these guidelines:
- Support for view mode must be indicated by registering with the Exchange Manager like this:
// New Exchange registry IDs for View registry. Don't change values! #define exgRegViewExtensionID 0xff8d // filename extension ID #define exgRegViewTypeID 0xff8e // MIME type registry ExgRegisterDatatype(...,exgRegViewExtensionID,...,...,...); ExgRegisterDatatype(...,exgRegViewTypeID,...,...,...);
- Always check if your application is called in view mode by checking if
goToCreator
information is available (in theExgSocketType
structure). - When applications receive data in view mode, the data should be stored temporarily and not automatically accepted into the application database. Instead, the user should be given the option to save the data. To save memory space, temporary data should be removed before the application exists.
- Applications that support view mode must provide an option to return to the messaging application (for example, a Done button). Returning to the messaging application must be implemented by actively launching the messaging application (with
SysUIAppSwitch()
or theAppLaunchWithCommand()
macro), using the GoTo information provided by the messaging application.
Sending an Attachment from a Messaging Application
Traditionally, when the user composes a message, messaging applications provide an option to select a document and attach it to the outgoing message. This has not been straightforward on Palm Powered devices in the past, since the Palm OS doesn't provide a file system. These guidelines define a standard way to implement this feature using the Exchange Manager's Get mechanism. This mechanism isn't limited to attachment support, but rather defines a general import mechanism.
The process of selecting an attachment includes two steps:
- Let the user select the application where the data is stored.
- Launch this application and let the user pick from a list of data objects.
The idea is to enable users to perform a data lookup by application (in contrast to a path lookup on other platforms). This fits the Palm OS model where data is associated with one particular application. The application that stores the data is responsible for providing the user interface in step 2. This makes it possible to present a user interface that is optimized for that particular data type. For instance, a calendar application can present information in an appropriate calendar context rather then as a simple list, allowing for a better user experience.
The Get mechanism requires implementation for both the messaging application as well as the display application. Although the Get mechanism has been available since Palm OS 4, it hasn't been widely used yet by applications, due to lack of guidelines and usage scenarios. However, with more and more applications supporting the exchange of native file formats across different platforms, this situation will change rapidly.
To leverage the existing Get mechanism for the purpose of supporting attachments, a new _get
exchange scheme has been defined (similar to _local
or _send
). Display applications must register this scheme with the Exchange Manager to let other applications know that they support the Get mechanism.
Figure 4.5 shows the interaction between the applications and the Exchange Manager.
Figure 4.5 Sending attachment from messaging application

NOTE: There are bugs in some versions of Palm OS that prevent using the Get mechanism as documented here. The Attachment Support sample code shows how to work around these problems. It is available in the Developer Knowledge Base at http://kb.palmsource.com/
Guidelines for Messaging Applications
To handle attachment sending, messaging applications should follow these guidelines:
- Messaging Applications must use the
_get
scheme to identify the available display applications that implement attachment support. - Messaging applications should offer a way to add multiple attachments to a message by repeating the attachment selection process.
- Messaging application should never try to read/write directly from/to the databases of other applications. Database formats might change or databases might be encrypted. Using the Exchange Manager not only prevents database corruption by other applications but also ensures interoperability between 68K and ARM applications.
- Before calling
ExgGet()
, messaging applications must:
Guidelines for Display Applications
To handle attachment sending from a messaging application, display applications should follow these guidelines:
- Applications must register the
_get
scheme with the Exchange Manager if they implement attachment support. Refer to "General Registration Guidelines." - Applications must not send more then one data object for every
ExgGet()
request. - When responding to a
sysAppLaunchCmdExgGetData
launch code, an application should copy the file name, type, and description information of the content into the suppliedexgSocket.name
,exgSocket.type
, andexgSocket.description
fields. Memory for these fields has been allocated by the calling application. The usable size of these fields is:-
name
:exgMaxTypeLength
(same as type) -
type
:exgMaxTypeLength
-
description
:exgMaxDescriptionLength
Applications should first check if memory was allocated (check for NULL pointers) before writing to the buffers. An application should never allocate or reallocate memory for these fields itself.
If the
exgSocket.name
field contains a scheme (for example,"_local:"
), this scheme information should not be overwritten. Rather, name information should be appended to the scheme (for example,"_local:myname.txt"
).
-
- Display applications should provide a familiar document selection screen, similar to the document list users might see when they usually launch the display application.
- When responding to a
sysAppLaunchCmdExgGetData
launch code, applications may support requests for a specific record (for example, via an application-specific URL scheme passed in thename
field of theExgSocketType
structure). Such a request should be handled without a user interface.
A display application may be launched with a full launch in response to a get request. This implementation is shown in detail in the Attachment Support sample code. It is available in the Developer Knowledge Base at http://kb.palmsource.com/
Sending an Attachment from a Display Application
Any display application should be able to send data to another device using any messaging application as a transport. For instance, a user could send a JPEG image from an image viewer to another person via email. This feature is implemented via the Exchange Manager using the _send
URL scheme. Because the send capability is has been available since Palm OS 4, many existing display applications already support it.
Guidelines for Messaging Applications
To handle attachment sending from a display application, messaging applications should follow these guidelines:
- Messaging applications must provide an exchange library that supports the
_send
URL scheme and register the scheme with the Exchange Manager (see "General Registration Guidelines."). Email applications will prompt the user for additional information (recipient information, subject line, etc.) and add the received data as an attachment to the message. - Messaging applications should be able to accept any content type to act as a transport mechanism.
Guidelines for Display Applications
To handle attachment sending, display applications should follow these guidelines:
- Display applications must use the
_send
URL scheme to send data to the Exchange Manager. The Send mechanism is a general mechanism that provides the user with a choice of all the transport mechanisms available on the device that support the_send
scheme (for example, Bluetooth, email, etc.).The sample code below shows how to send or beam data. The question mark in the
name
field means that on OS 4.0 and higher, it'll display a dialog to let the user choose which transport to use (for example, IR, Bluetooth, SMS, etc.).status_t err; ExgSocketType exgSocket; // Fill out exgSocket with the description of the data and the // package's "address" MemSet(&exgSocket, sizeof(exgSocket), 0); exgSocket.description = "SuperApp data"; exgSocket.name = "?_send;_beam:SuperAppData.sad"; exgSocket.type = "application/x-superappdata"; err = ExgPut(&exgSocket); // open the connection ExgSend(&exgSocket, theData, theDataSize, &err); // send the data err = ExgDisconnect(&exgSocket, err); // that's all!
- Display applications must set at least the type information (
exgSocket.type
). Name information (exgSocket.name
), including file extension and description information (exgSocket.description
), should also be provided. This allows messaging applications to format outgoing messages correctly, with the proper MIME content-type fields.
Email Application Guidelines
Email applications should follow these guidelines to support the mailto
scheme and the helper APIs.
Support for Mailto URL Scheme
Applications like a web browser must be able to launch an email application to start composing a new message. In contrast to the _send
scheme, the mailto
URL automatically implies email as a transport medium and allows applications to provide additional information, like recipients, subject line, etc.
- Email applications must implement the
mailto
URL scheme and register the scheme with the Exchange Manager. For more information on themailto
scheme, see RFC 2368 at http://www.ietf.org/rfc/rfc2368.txt - The application must display the message content before a message is sent. This prevents malicious applications from sending uncontrolled spam without the user's knowledge.
Support for Helper API
Messaging applications should register their services with the helper API as described in "Helper Notifications" in Exploring Palm OS: Programming Basics. In particular, email applications should support the mail service class.