Documentation  |   Table of Contents   |  < Previous   |  Next >   |  Index

2    Using the Telephony API

Telephony and SMS

Exploring Palm OS®

This chapter describes how to use the Telephony API.

Note that the only network supported in this release is GSM/GPRS.

Opening the Telephony Manager Library ^TOP^

Before you can use the Telephony Manager library, you must open it by calling TelOpen() or TelOpenPhoneProfile(). The library is automatically loaded by the system upon the first telephony function call.

When opened, the Telephony Manager library uses the Connection Manager to open an internal component known as the Telephony Server, which interfaces to the phone drivers. The Telephony Server retrieves information about the needed drivers through the Connection Manager profile.

The particular Connection Manager phone profile that is used depends on how you open the Telephony Manager:

  • If you call TelOpen(), the phone profile is automatically selected by the Telephony Manager via a call to CncProfileFindFirst(). This finds the first telephony profile that is usable and available in the list of telephony profiles.
  • If you call TelOpenPhoneProfile(), you select the phone profile by passing its identifier to this function.

Closing the Telephony Manager Library ^TOP^

When you are done with the library, you should close it by calling the TelClose() function, which releases any resources associated with your use of the Telephony Manager.

Using Synchronous and Asynchronous Calls ^TOP^

Almost all of the telephony functions can be called either synchronously or asynchronously. If you call a function synchronously, it blocks until it completes or an error occurs.

If you call a function asynchronously, it returns immediately and your application receives an event to notify it that the function has completed. The event that you receive contains status and other information returned by the function. For more information about telephony events, see "Telephony Events."

You can cancel an asynchronous function call that is in progress by calling TelCancel().

This section provides a simple example of calling the TelNwkGetStatus() function both synchronously and asynchronously to illustrate the difference.

When you call a function synchronously, you need to test the result value returned by the function to determine if the call was successful. For example, the code in Listing 2.1 calls the TelNwkGetStatus() function synchronously.

Listing 2.1  Calling a function synchronously


status_t err = errNone; 
int32_t sTelDescId; 
uint8_t sNetworkStatus; 
err = TelNwkGetStatus(sTelDescId, &sNetworkStatus, NULL) 
printf("Result of getting network status is %d", err); 

To call the same function asynchronously, you specify a transaction ID in the call, instead of specifying NULL as the last argument. The transaction ID (sNwkStatusTransId in Listing 2.2) is a pointer to an unsigned integer value that is filled in by the Telephony Manager with a value associated with the asynchronous operation that is begun. This same ID value is found in the transId field of the event you receive when the operation completes.

Listing 2.2  Calling a function asynchronously


status_t err = errNone; 
int32_t sTelDescId; 
uint8_t sNetworkStatus; 
uint16_t sNwkStatusTransId = kTelInvalidTransId; 
err = TelNwkGetStatus(sTelDescId, &sNetworkStatus, &sNwkStatusTransId) 
... 
// Telephony application event handler; called from event loop 
static void MyProcessTelephonyEvent(TelEventType *eventP) 
{ 
  switch( eventP->functionId ) 
  { 
... 
    case kTelNwkGetStatusMessage: 
      printf("Result of function call is %d", eventP->returnCode); 
      printf("Network status is %d", eventP->paramP); 
      break; 
... 
  } 

Using Data Structures With Variably-sized Fields ^TOP^

Many of the telephony functions use data structures that have variably-sized buffer fields. For example, the TelNwkGetLocation() function uses the TelNwkLocationType structure, which contains two such fields.


typedef struct _TelNwkLocationType { 
  char *areaCodeP; 
  size_t areaCodeSize; 
  char *cellIdP; 
  size_t cellIdSize; 
} TelNwkLocationType; 

The areaCodeP and cellIdP buffers are variable-sized strings that you allocate in the heap. When you initialize one of these structures to pass to the TelNwkGetLocation() function, you must preallocate the buffers and store the allocated size in the corresponding size fields.

The following code sample initializes a TelNwkLocationType data structure and passes it to the TelNwkGetLocation() function to retrieve the network location.


#define maxAreaCodeSize 5 
#define maxCellIdSize 30 
TelNwkLocationType myLoc; 
 
myLoc.areaCodeP = MemPtrNew(maxAreaCodeSize); 
myLoc.areaCodeSize = maxAreaCodeSize; 
myLoc.cellIdP = MemPtrNew(maxCellIdSize); 
myLoc.cellIdSize = maxCellIdSize; 
err = TelNwkGetLocation(sTelDescId, &myLoc, NULL); 

Upon return from the function, the buffer fields are filled in, and the size fields contain the actual number of bytes that were stored into the buffer fields.

If the allocated size of a buffer is not large enough to contain the entire value, the function does the following:

  • Returns the telErrBufferSize error.
  • Fills the buffer with as much data as it can, and truncates the data that does not fit. If the data ends with a null terminator and is truncated, the null terminator is retained.
  • Sets the value of the size field to the actual size required to contain all of the data.

Note that for string buffers, the size includes the byte required for the null terminator character.


NOTE: When you call a function asynchronously, the telErrBufferSize error is returned in the returnCode field of the event you receive upon completion of the function's execution.

Also, when you call a function asynchronously, it is your responsibility to ensure that any data structures used by the function remain in memory until you receive the completion event. At that time, you are responsible for freeing the memory for any buffers you allocated.

Testing the Telephony Environment ^TOP^

Before running your application, you need to verify that the environment in which it is running (the Palm Powered device and the telephone) supports the facilities that your application needs. The Telephony Manager allows you to determine if a specific service set is available with TelIsServiceAvailable(), and also allows you to determine if a specific function call is supported with TelIsFunctionSupported().

Alternatively, there are a series of macros that you can use to check if a service is available (TelIsServiceNameServiceAvailable()), or if a function is available (TelIsFunctionNameSupported()).

The code excerpt in Listing 2.3 shows how to use the macros to verify that the environment supports particular phone book capabilities. The code first tests for the availability of the phone book service set, and then determines if several specific functions are supported.

Listing 2.3  Testing for the presence of specific capabilities


// Test if phone book capabilities are present 
err = TelIsPhbServiceAvailable(sTelDescId); 
if (err != errNone) 
  return err; 
 
// Check that this phone supports adding entries 
err = TelIsPhbAddEntrySupported(sTelDescId); 
if (err != errNone) 
  return err; 
 
// Check that this phone supports selecting a phone book 
err = TelIsPhbSetPhonebookSupported(sTelDescId); 
if (err != errNone) 
  return err; 
 
// Check that this phone supports getting entries list 
err = TelIsPhbGetEntriesSupported(sTelDescId); 
if (err != errNone) 
  return err; 
 
// Check that this phone supports getting an entry 
err = TelIsPhbGetEntrySupported(sTelDescId); 
if (err != errNone) 
  return err; 
 
// Check that this phone supports deleting an entry 
err = TelIsPhbDeleteEntrySupported(sTelDescId); 
return err; 

Telephony Events ^TOP^

The Telephony Manager sends telephony events to an application through its event loop or via notifications sent by the Notification Manager.

Events sent via the event loop are mainly for the completion of asynchronous function calls. Applications can call TelEvtGetEvent() to receive both system events and telephony events in the main event loop. To receive only telephony events, use TelEvtGetTelephonyEvent(). Telephony events have the event type kTelTelephonyEvent.

Events sent via notifications are for many other kinds of telephony events such as an incoming SMS message, a call connection, battery status change, etc. These are communicated via a notification of the type kTelTelephonyNotification. Applications that want to receive such telephony notifications must register with the Notification Manager.

Sleep and Wake ^TOP^

When the Telephony Server exchanges data with the mobile phone, the device is prevented from sleeping (EvtResetAutoOffTimer() is called internally). This means that the device won't go to sleep when data is being sent or received.

If the user switches off the device during data exchange, the connection is stopped, and all of the pending commands are canceled.