Previous Page Table of Contents Index Next Page

Palm OS Programmer's Companion


Palm Logo 11 Network Communication

Two different Palm OS® libraries provide network services to applications:

Net Library

The net library allows Palm OS applications to easily establish a connection with any other machine on the Internet and transfer data to and from that machine using the standard TCP/IP protocols.

The basic network services provided by the net library include:

You can implement higher-level Internet-based services (file transfer, e-mail, web browsing, etc.) on top of these basic delivery services.



IMPORTANT: Applications cannot directly use the net library to make wireless connections. Use the Internet library for wireless connections.


This section describes how to use the net library in your application. It covers:

About the Net Library

The net library consists of two parts: a netlib interface and a net protocol stack.

The netlib interface is the set of routines that an application calls directly when it makes a net library call. These routines execute in the caller's task like subroutines of the application. They are not linked in with the application, however, but are called through the library dispatch mechanism.

With the exception of functions that open, close, and set up the net library, the net library's API maps almost directly to the Berkeley UNIX sockets API, the de facto standard API for Internet applications. You can compile an application written to use the Berkeley sockets API for the Palm OS with only slight changes to the source code.

The net protocol stack runs as a separate task in the operating system. Inside this task, the TCP/IP protocol stack runs, and received packets are processed from the network device drivers. The netlib interface communicates with the net protocol stack through an operating system mailbox queue. It posts requests from applications into the queue and blocks until the net protocol stack processes the requests.

Having the net protocol stack run as a separate task has two big advantages:

One or more network interfaces run inside the net protocol stack task. A network interface is a separately linked database containing code necessary to abstract link-level protocols. For example, there are separate network interface databases for PPP and SLIP. A network interface is generally specified by the user in the Network preference panel. In rare circumstances, interfaces can also be attached and detached from the net library at runtime as described in the section "Settings for Interface Selection" later in this chapter.

Constraints

Because it's unclear whether all future platforms will need or want network support (especially devices with very limited amounts of memory), network support is an optional part of the operating system. For this reason, the net library is implemented as a system library that is installed at runtime and doesn't have to be present for the system to work properly.

When the net library is present and running, it requires an estimated additional 32 KB of RAM. This in effect doubles the overall system RAM requirements, currently 32 KB without the net library. It's therefore not practical to run the net library on any platform that has 128 KB or less of total RAM available since the system itself will consume 64 KB of RAM (leaving only 64 KB for user storage in a 128 KB system).

Because of the RAM requirements, the net library is supported only on PalmPilot Professional and newer devices running Palm OS 2.0 and later.

All applications written for Palm OS must pay special attention to memory and CPU usage because Palm OS runs on small devices with limited amounts of memory and other hardware resources. Applications that use the net library, therefore, must pay even more attention to memory usage. After opening the net library, the total remaining amount of RAM available to an application is approximately 12 KB on a PalmPilot Professional and 36KB on a Palm III.

The Programmer's Interface

There are essentially two sets of API into the net library: the net library's native API, and the Berkeley sockets API. The two APIs map almost directly to each other. You can use the Berkeley sockets API with no performance penalty and little or no modifications to any existing code that you have.

The header file <unix/sys_socket.h> contains a set of macros that map Berkeley sockets calls directly to net library calls. The main difference between the net library API and the Berkeley sockets API is that most net library API calls accept additional parameters for:

The macros in sys_socket.h do the following:

For... The macros pass...
reference number AppNetRefnum (application global variable).
timeout AppNetTimeout (application global variable).
error code Address of the application global errno.

For example, consider the Berkeley sockets call socket, which is declared as:

Int16 socket(Int16 domain, Int16 type, Int16 protocol);

The equivalent net library call is NetLibSocketOpen, which is declared as:

NetSocketRef NetLibSocketOpen(UInt16 libRefnum, NetSocketAddrEnum domain, NetSocketTypeEnum type, Int16 protocol, Int32 timeout, Err* errP)

The macro for socket is:

#define socket(domain,type,protocol) \
NetLibSocketOpen(AppNetRefnum, domain, type, protocol, AppNetTimeout, &errno)

Net Library Usage Steps

In general, using the net library involves the steps listed below. The next several sections describe some of the steps in more detail.

For an example of using the net library, see the example application NetSample in the Palm OS Examples directory. It exercises many of the net library calls.

1. Obtain the net library's reference number.

Because the net library is a system library, all net library calls take the library's reference number as the first parameter. For this reason, your first step is to obtain the reference number and save it. See "Obtaining the Net Library's Reference Number."

2. Set up for using Berkeley sockets API.

You can either use the net library's native API or the Berkeley sockets API for the majority of what you do with the net library. If you're already familiar with Berkeley sockets API, you'll probably want to use it instead of the native API. If so, follow the steps in "Setting Up Berkeley Socket API."

3. If necessary, configure the net library the way you want it.

Typically, users set up their networking services by using the Network preferences panel. Most applications don't set up the networking services themselves; they simply access them through the net library preferences database. In rare instances, your application might need to perform some network configuration, and it usually should do so before the net library is open. See "Setup and Configuration Calls."

4. Open the net library right before the first network access.

Because of the limited resources in the Palm OS environment, the net library was designed so that it only takes up extra memory from the system when an application actually needs to use its services. An Internet application must therefore inform the system when it needs to use the net library by opening the net library when it starts up and by closing it when it exits. See "Opening the Net Library."

5. Make calls to access the network.

Once the net library has been opened, sockets can be opened and data sent to and received from remote hosts using either the Berkeley sockets API or the native net library API. See "Network I/O and Utility Calls."

6. Close the net library when you're finished with it.

Closing the net library frees up the resources. See "Closing the Net Library."

Obtaining the Net Library's Reference Number

To determine the reference number, call SysLibFind, passing the name of the net library, "Net.lib". In addition, if you intend to use Berkeley sockets API, save the reference number in the application global variable AppNetRefnum.

err = SysLibFind("Net.lib", &AppNetRefnum);
if (err) {/* error handling here */}

Remember that the net library requires Palm OS version 2.0 or later. If the SysLibFind call can't find the net library, it returns an error code.

Setting Up Berkeley Socket API

To set up the use of Berkeley sockets API, do the following:

    AppNetTimeout = SysTicksPerSecond() * 10;

Setup and Configuration Calls

The setup and configuration API calls of the net library are normally only used by the Network preferences panel. This includes calls to set IP addresses, host name, domain name, login script, interface settings, and so on. Each setup and configuration call saves its settings in the net library preferences database in nonvolatile storage for later retrieval by the runtime calls.

In rare instances, an application might need to perform setup and configuration itself. For example, some applications might allow users to select a particular "service" before trying to establish a connection. Such applications present a pick list of service names and allow the user to select a service name. This functionality is provided via the Network preferences panel. The panel provides launch codes (defined in SystemMgr.h) that allow an application to present a list of possible service names to let the end user pick one. The preferences panel then makes the necessary net library setup and configuration calls to set up for that particular service.

Usually, the setup and configuration calls are made while the library is closed. A subset of the calls can also be issued while the library is open and will have real-time effects on the behavior of the library. Chapter 54, "Net Library" in Palm OS SDK Reference, describes the behavior of each call in more detail.

Settings for Interface Selection

As you learned in the section "About the Net Library," the net library uses one or more network interfaces to abstract low-level networking protocols. The user specifies which network interface to use in the Network preference panel.

You can also use net library calls to specify which interface(s) should be used:

Unlike most net library functions, these functions can be called while the library is open or closed. If the library is open, the specific interface is attached or detached in real time. If the library is closed, the information is saved in preferences and used the next time the library is opened.

Each interface is identified by a creator and an instance number. You need these values if you want to attach or detach an interface or to query or set interface settings. You use NetLibIFGet to obtain this information. NetLibIFGet takes four parameters: the net library's reference number, an index into the library's interface list, and addresses of two variables where the creator and instance number are returned.

The creator is one of the following values:

If you know which interface you want to obtain information about, you can iterate through the network interface list, calling NetLibIFGet with successive index values until the interface with the creator value you need is returned.

Interface Specific Settings

The net library configuration is structured so that network interface- specific settings can be specified for each network interface independently. These interface specific settings are called IF settings and are set and retrieved through the NetLibIFSettingGet and NetLibIFSettingSet calls.

For an example of using these functions, see the NetSample example application in the Palm OS Examples directory. The function CmdSettings in the file CmdInfo.c, for example, shows how to loop through and obtain information about all of the network interfaces.

Setting an Interface's Login Script

The netIFSettingLoginScript setting is used to store the login script for an interface. The login script is generated either from the script that the user enters in the Network preferences panel or from a script file that is downloaded onto the device during a HotSync® operation. The format of the script is rigid; if a syntactically incorrect login script is presented to the net library, the results are unpredictable. The basic format is a series of null-terminated command lines followed by a null byte at the end of the script. Each command line has the format:

<command-byte> [<parameter>]

where the command byte is the first character in the line and there is 1 and only 1 space between the command byte and the parameter string. Table 11.1 lists the possible commands.

Table 11.1 Login Script Commands 

Function Command Parameter Example
Send s string s go PPP
Wait for w string w password:
Delay d seconds d 1
Get IP g g
Prompt a string a Enter Name:
Wait for prompt f string f ID:
Send CR s string s ^N
Send UserID s string s jdoe
Send Password s string s mypassword
Plugin command1 sp string sp plugin:cmd:arg
1

See "Extending the Network Login Script Support."

The parameter string to the send (s) command can contain the escape sequences shown in Table 11.2.

Table 11.2 Send Command Escape Sequences 

$USERID substitutes user name
$PASSWORD substitutes password
$DBUSERID substitutes dialback user name
$DBPASSWORD substitutes dialback password
^c if c is `@' -> `_', then byte value 0 -> 31
else if c is `a' -> `z', then byte value 1 -> 26
else c
<cr> carriage return (0x0D)
<lf> line feed (0x0A)
\" "
\^ ^
\< <
\\ \

Note also that login scripts can be created on a desktop computer and then installed onto the device during synchronization. The script commands are inspired by the Windows dial-up scripting command language for dial-up networking. For documentation from Microsoft, search for the file Script.doc in the Windows folder. The Network preferences panel on Palm OS supports the following subset of commands:

set serviceName
set userName
set password
set phoneNumber
set primaryDNS
set secondaryDNS
set ipAddr
set closewait
set inactivityTimeout
set establishmentTimeout
set protocol
set dynamicIP
waitfor
transmit
getip
delay
prompt
waitforprompt
plugin "
pluginname:cmd[:arg]"

The plugin command is a Palm OS-specific extension used to perform a command defined in a plugin. See "Extending the Network Login Script Support" for more information on plugins.

Create a script file with the extension .pnc or .scp and place it in the user's install directory. The network conduit will download it to the device during the next HotSync operation. Each script file should contain only one service definition.

General Settings

In addition to the interface-specific settings, there's a class of settings that don't apply to any one particular interface. These general settings are set and retrieved through the NetLibSettingGet and NetLibSettingSet calls. These calls take setting ID, buffer pointer, and buffer size parameters.

Opening the Net Library

Call NetLibOpen to open the net library, passing the reference number you retrieved through SysLibFind. Before the net library is opened, most calls issued to it fail with a netErrNotOpen error code.

err = NetLibOpen(AppNetRefnum, &ifErrs);
if (err || ifErrs) {/* error handling here */}

Multiple applications can have the library open at a time, so the net library may already be open when NetLibOpen is called. If so, the function increments the library's open count, which keeps track of how many applications are accessing it, and returns immediately. (You can retrieve the open count with the function NetLibOpenCount.)

If the net library is not already open, NetLibOpen starts up the net protocol stack task, allocates memory for internal use by the net library, and brings up the network connection. Most likely, the user has configured the Palm OS device to establish a SLIP or PPP connection through a modem and in this type of setup, NetLibOpen dials up the modem and establishes the connection before returning.

If any of the attached network interfaces (such as SLIP or PPP) fail to come up, the final parameter (ifErrs in the example above) contains the error number of the first interface that encountered a problem.

It's possible, and quite likely, that the net library will be able to open even though one or more interfaces failed to come up (due to bad modem settings, service down, etc.). Some applications may therefore wish to close the net library using NetLibClose if the interface error parameter is non-zero and display an appropriate message for the user. If an application needs more detailed information, e.g. which interface(s) in particular failed to come up, it can loop through each of the attached interfaces and ask each one if it is up or not. For example:

UInt16 index, ifInstance;
UInt32 ifCreator;
Err err;
UInt8 up;
Char ifName[32];
...
for (index = 0; 1; index++) {
    err = NetLibIFGet(AppNetRefnum, index,
    &ifCreator, &ifInstance);
    if (err) break;

    settingSize = sizeof(up);
    err = NetLibIFSettingGet(AppNetRefnum,
    ifCreator, ifInstance, netIFSettingUp, &up,
    &settingSize);
    if (err || up) continue;
    settingSize = 32;
    err = NetLibIFSettingGet(AppNetRefnum,
ifCreator, ifInstance, netIFSettingName,
ifName, &settingSize);

    if (err) continue;

    //display interface didn't come up message
}
NetLibClose(AppNetRefnum, true);

Closing the Net Library

Before an application quits, or if it no longer needs to do network I/O, it should call NetLibClose.

err = NetLibClose(AppNetRefnum, false);

NetLibClose simply decrements the open count. The false parameter specifies that if the open count has reached 0, the net library should not immediately close. Instead, NetLibClose schedules a timer to shut down the net library unless another NetLibOpen is issued before the timer expires. When the net library's open count is 0 but its timer hasn't yet expired, it's referred to as being in the close-wait state.

Just how long the net library waits before closing is set by the user in the Network preferences panel. This timeout value allows users to quit from one network application and launch another application within a certain time period without having to wait for another network connection establishment.

If NetLibOpen is called before the close timer expires, it simply cancels the timer and marks the library as fully open with an open count of 1 before returning. If the timer expires before another NetLibOpen is issued, all existing network connections are brought down, the net protocol stack task is terminated, and all memory allocated for internal use by the net library is freed.

It's recommended that you allow the net library to enter the close-wait state. However, if you do need the net library to close immediately, you can do one of two things:

  • Set NetLibClose's second parameter to true. This parameter specifies whether the library should close immediately or not.

  • Call NetLibFinishCloseWait. This function checks the net library to see if it's in the close-wait state and if so, performs an immediate close.

Version Checking

Besides using SysLibFind to determine if the net library is installed, an application can also look for the net library version feature. This feature is only present if the net library is installed. This feature can be used to get the version number of the net library as follows:

UInt32* version;
err = FtrGet(netFtrCreator, netFtrNumVersion,
    &version);

If the net library is not installed, FtrGet returns a non-zero result code.

The version number is encoded in the format 0xMMmfsbbb, where:

MM major version
m minor version
f bug fix level
s stage: 3-release, 2-beta, 1-alpha, 0-development
bbb build number for non-releases

For example:

V1.1.2b3 would be encoded as 0x01122003

V2.0a2 would be encoded as 0x02001002

V1.0.1 would be encoded as 0x01013000

This document describes version 2.01 of the net library (0x02013000).

Network I/O and Utility Calls

For the network I/O and utility calls, you can either make calls using Berkeley sockets API or using the net library's native API.

Several books have been published that describe how to use Berkeley sockets API to perform network communication. Net library API closely mirrors Berkeley sockets API in this regard. However, you should keep in mind these important differences between using networking I/O on a typical computer and using net library on a Palm OS device:

For more information, see the following:

Berkeley Sockets API Functions

This section provides tables that list the functions in the Berkeley sockets API that are supported by the net library. In some cases, the calls have limited functionality from what's found in a full implementation of the sockets API and these limitations are described here.

Socket Functions

Berkeley Sockets Function Net Library Function Description
accept NetLibSocketAccept Accepts a connection from a stream-based socket.
bind NetLibSocketBind Binds a socket to a local address.
close NetLibSocketClose Closes a socket.
connect NetLibSocketConnect Connects a socket to a remote endpoint to establish a connection.
fcntl NetLibSocketOptionSet NetLibSocketOptionGet
(...,netSocketOptSockNonBlocking,...)
Supported only for socket refnums and the only commands it supports are F_SETFL and F_GETFL. The commands can be used to put a socket into non-blocking mode by setting the FNDELAY flag in the argument parameter appropriately -- all other flags are ignored. The F_SETFL, F_GETFL, and FNDELAY constants are defined in <unix/unix_fcntl.h>.
getpeername NetLibSocketAddr Gets the remote socket address for a connection.
getsockname NetLibSocketAddr Gets the local socket address of a connection.
getsockopt NetLibSocketOptionGet Gets a socket's control options. Only the following options are implemented:

  • TCP_NODELAY

    Allows the application to disable the TCP output buffering algorithm so that TCP sends small packets as soon as possible. This constant is defined in <unix/netinet_tcp.h>.

  • TCP_MAXSEG

    Get the TCP maximum segment size. This constant is defined in <unix/netinet_tcp.h>.

  • SO_KEEPALIVE

    Enables periodic transmission of probe segments when there is no data exchanged on a connection. If the remote endpoint doesn't respond, the connection is considered broken, and so_error is set to ETIMEOUT.

  • SO_LINGER

    Specifies what to do with the unsent data when a socket is closed. It uses the linger structure defined in <unix/sys_socket.h>.

  • SO_ERROR

    Returns the current value of the variable so_error, defined in <unix/sys_socketvar.h>

  • SO_TYPE

    Returns the socket type to the caller.
listen NetLibSocketListen Sets up the socket to listen for incoming connection requests. The queue size is quietly limited to 1. (Higher values are ignored.)
read, recv, recvmsg, recvfrom NetLibReceive
NetLibReceivePB
Read data from a socket. The recv, recvmsg, and recvfrom calls support the MSG_PEEK flag but not the MSG_OOB or MSG_DONTROUTE flags.
select NetLibSelect Allows the application to block on multiple I/O events. The system will wake up the application process when any of the multiple I/O events occurs.
This function uses the timeval structure defined in <unix/sys_time.h> and the fd_set structure defined in sys/types.h.
Also associated with this function are the following four macros defined in <unix/sys_types.h>:

  • FD_ZERO

  • FD_SET

  • FD_CLR

  • FD_ISSET

Besides socket descriptors, this function also works with the "stdin" descriptor, sysFileDescStdIn. This descriptor is marked as ready for input whenever a user or system event is available in the event queue. This includes any event that would be returned by EvtGetEvent. No other descriptors besides sysFileDescStdIn and socket refnums are allowed.
send, sendmsg, sendto NetLibSend
NetLibSendPB
These functions write data to a socket. These calls, unlike the recv calls, do support the MSG_OOB flag. The MSG_PEEK flag is not applicable and the MSG_DONTROUTE flag is not supported.
setsockopt NetLibSocketOptionSet This function sets control options of a socket. Only the following options are allowed:

  • TCP_NODELAY

  • SO_KEEPALIVE

  • SO_LINGER
shutdown NetLibSocketShutdown Similar to close(); however, it gives the caller more control over a full-duplex connection.
socket NetLibSocketOpen Creates a socket for communication.The only valid address family is AF_INET. The only valid socket types are SOCK_STREAM, SOCK_DGRAM, and in Palm OS version 3.0 and higher, SOCK_RAW. The protocol parameter should be set to 0.
write NetLibSend Writes data to a socket.

Supported Network Utility Functions

Berkeley Sockets Function Net Library Function Description
getdomainname NetLibSocketOptionGet(..,
netSettingDomainName,...)
Returns the domain name of the local host.
gethostbyaddr NetLibGetHostByAddr Looks up host information given the host's IP address. It returns a hostent structure, as defined in <netdb.h>.
gethostbyname NetLibGetHostByName Looks up host information given the host's name. It returns a hostent structure which is defined in <netdb.h>.
gethostname NetLibSettingGet(..,
netSettingHostName,
...)
Returns the name of the local host.
getservbyname NetLibGetServByName Returns a servent structure, defined in <netdb.h> given a service name.
gettimeofday glue code using TimGetSeconds Returns the current date and time.
setdomainname NetLibSettingSet(..,
netSettingDomainName,...)
Sets the domain name of the local host.
sethostname NetLibSettingSet(..,
netSettingHostName,
...)
Sets the name of the local host.
settimeofday glue code using TimSetSeconds Sets the current date and time.

Supported Byte Ordering Macros

The byte ordering macros are defined in <unix/netinet_in.h>. They convert an integer between network byte order and the host byte order.

Berkeley
Sockets
Macro
Description
htonl Converts a 32-bit integer from host byte order to network byte order.
htons Converts a 16-bit integer from host byte order to network byte order.
ntohl Converts a 32-bit integer from network byte order to host byte order.
ntohs Converts a 16-bit integer from network byte order to host byte order.

Supported Network Address Conversion Functions

The network address conversion functions are declared in the <unix/arpa_inet.h> header file. They convert a network address from one format to another, or manipulate parts of a network address.

Berkeley Sockets Function Net Library Function Description
inet_addr NetLibAddrAToIN Converts an IP address from dotted decimal format to 32-bit binary format.
inet_network glue code Converts an IP network number from a dotted decimal format to a 32-bit binary format.
inet_makeaddr glue code Returns an IP address in an in_addr structure given an IP network number and an IP host number in 32-bit binary format.
inet_lnaof glue code Returns the host number part of an IP address.
inet_netof glue code Returns the network number part of an IP address.
inet_ntoa NetLibAddrINToA Converts an IP address from 32-bit format to dotted decimal format.

Extending the Network Login Script Support

Beginning in Palm OS 3.3, you can write a plugin that extends the list of available script commands in the Network preferences panel. You might do so, for example, if:

The login script enhancement can also be installed on any device that already has network library support (that is, PalmPilot Professional and newer devices running Palm OS 2.0 or higher). To do so, you install a file named Network.prc along with a PRC file for the network interface you use (i.e., PPP or SLIP). These files provide the new Network preferences panel, which contains support for some new commands and support for the ability to write script plugins.

The sections below describe the basics of how to write a login script plugin. For more detailed information on the API you use to write a plugin, see the chapter "Script Plugin" in the Palm OS SDK Reference.

Writing the Login Script Plugin

To write a login script plugin, you create a project like you normally would; however, specify 'scpt' as the database type instead of 'appl'. (If you're using Metrowerks CodeWarrior, you specify the database type in the PalmRez post linker panel.)

In the PilotMain function, the plugin should respond to two launch codes:

Responding to scptLaunchCmdListCmds

The Network preferences panel sends the scptLaunchCmdListCmds launch code when it is constructing the pull-down list of available commands that it displays in its script view. The panel sends this launch code to all PRCs of type 'scpt'. It passes an empty structure of type PluginInfoType as its parameter block. Your plugin should respond by filling in the structure with the following information:

A given device might have multiple plugins installed. If so, the resulting pull-down list contains the union of all commands supported by all of the plugins installed on the device. For this reason, you should make sure the command names you supply are unique. You also should make sure the names are as brief as possible, as only 15 characters are allowed for the name.

Responding to scptLaunchCmdExecuteCmd

The scptLaunchCmdExecuteCmd launch code is sent when the login script is being executed. That is, the user has attempted to connect to the network service specified in the Network preferences panel, and the panel is executing the script to perform authentication.

The scptLaunchCmdExecuteCmd parameter block is a structure of type PluginExecCmdType. It contains:

Your plugin should execute the specified command. When a plugin is launched with this code, it is launched as a subroutine and as such does not have access to global variables. Also keep in mind that the network library and a connection application (such as the HotSync application) are already running when the plugin is launched. Thus, available memory and stack space are extremely limited.

To perform most of its work, the plugin command probably needs access to the network interface (such as SLIP or PPP) specified for the selected network service. For this reason, the plugin is passed a pointer to a callback function defined by the network interface. The plugin should call this function when it needs to perform the following tasks:

The callback's prototype is defined by ScriptPluginSelectorProc. It takes as arguments the handle to the connection-specific data passed in with the launch code, the task that the network interface should perform (specified as a pluginNetLib... constant), followed by a series of parameters whose interpretations depend on which task is to be performed.

For example, the following code implements the command "Send Uname", which sends the user's name to the host computer.

Listing 11.1 Simple Script Plugin Command


#define pluginSecondCmd "Send Uname"

UInt32 PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags) {
PluginExecCmdPtr execPtr;
UInt32 error = success;
Int16 dataSize = 0;
Char* dataBuffer = NULL;
ScriptPluginSelectorProcPtr selectorTypeP;

if (cmd == scptLaunchCmdExecuteCmd) {
    execPtr = (PluginExecCmdPtr)cmdPBP;
    selectorTypeP = execPtr->procP->selectorProcP;

    dataBuffer = MemPtrNew(pluginMaxLenTxtStringArg+1);
    if (!dataBuffer) {
    return failure;
    }
    MemSet(dataBuffer,pluginMaxLenTxtStringArg+1,0);

    if (!StrCompare(execPtr->commandName, pluginSecondCmd)) {

    /* get the user name from the network interface */
    error = (selectorTypeP)(execPtr->handle,
    pluginNetLibGetUserName, (void*)dataBufferP, &dataSize, 0,
    NULL);
    if (error) goto Exit;

    dataSize = StrLen((Char*)dataBufferP);

/* have the network interface send the user name to the host */
    error = (selectorTypeP)(execPtr->handle,
    pluginNetLibWriteBytes, (void*)dataBufferP, &dataSize, 0,
    NULL);

    return error;
    }
}


If your command needs to interact with the user, it must do so through the network interface. When the connection attempt is taking place, the user sees either the Network preferences panel or the HotSync application. Your plugin does not have control of the screen, so you cannot simply display a form. You have two options:

To use pluginNetLibCallUIProc, you must do the following:
Initialize the form using a form resource that you've created. Create a struct that contains your form's handle and any other values that you are going to need in your user interface routine. Call the network interface's callback function with the pluginNetLibCallUIProc command, the structure with the form's handle and other pertinent information, and the address of a function in your plugin that will perform the user interface routine. This function should take one argument--the struct you've passed to the network interface--and return void. When the call to the network interface returns, close the form.

For an example of using pluginNetLibCallUIProc, see the functions WaitForData and promptUser in the example code ScriptPlugin.c.

Internet Library

The Internet library provides Palm applications easy access to World Wide Web documents. The Internet library uses the net library for basic network access and builds on top of the net library's socket concept to provide a socket-like API to higher level internet protocols like HTTP and HTTPS.

Using the Internet library, an application can access a web page with as little as three calls (INetLibURLOpen, INetLibSockRead, and INetLibSockClose). The Internet library also provides a more advanced API for those applications that need finer control.

NOTE:  

The information in this section applies only to version 3.2 or later of the Palm OS on Palm VII devices. These features are implemented only if the Wireless Internet Feature Set is present.


WARNING!

In future OS versions, Palm Computing does not intend to support or provide backward compatibility for the Internet library API.

The Internet library is implemented as a system library that is installed at runtime and doesn't have to be present for the system to work properly.

This section describes how to use the Internet library in your application. It covers:

System Requirements

The Internet library is available only on version 3.2 or later of the Palm OS on Palm VII devices. Before making any Internet library calls, ensure that the Internet library is available. You can be sure it is available by using the following FtrGet call:

err = FtrGet(inetLibFtrCreator, inetFtrNumVersion, &value);

If the Internet library is installed, the value parameter will be non-zero and the returned error will be zero (for no error).

When the Internet library is present and running, it requires an estimated additional 1 KB of RAM, beyond the net library. More additional memory is used for the security library, if that is used (when accessing secure sites), and for opening a cache database, if that is used.

Initialization and Setup

Before using the Internet library, an application must call SysLibFind to obtain a library reference number, as follows:

err = SysLibFind("INet.lib", &libRefNum)

Next, it must call INetLibOpen to allocate an inetH handle. The inetH handle holds all application specific environment settings and each application that uses the Internet library gets its own private inetH handle. Any calls that change the default behavior of the Internet library affect environment settings stored in the application's own inetH structure, so these changes will not affect other applications that might be using the Internet library at the same time.

INetLibOpen also opens the net library for the application. In addition, the application can tell INetLibOpen the type of network service it prefers: wireline or wireless. INetLibOpen queries the available network interfaces and attaches the appropriate one(s) for the desired type of service. When the application calls INetLibClose, the previous interface configuration is restored. For more information on configurations, see the section "Internet Library Network Configurations" .

The Internet library gets some of its default behavior from the system preferences database, and some of these preference settings are made by the user via the Wireless preferences panel. The preferences set by this panel include the proxy server to use and a setting that determines whether or not the user is warned when the device ID is sent. Other settings stored in the preferences database come from Internet library network configurations (see "Internet Library Network Configurations" ). All these settings can be queried and/or overridden by each application through the INetLibSettingGet and INetLibSettingSet calls. However, any changes made by an application are not stored into the system preferences, but only take effect while that inetH handle is open.

Accessing Web Pages

In the Palm.Net environment, all HTML documents are dynamically compressed by the Palm Web Clipping Proxy server before being transmitted to the Palm device.

The procedure for reading a page from the network operates as follows. First, the application passes the desired URL to the INetLibURLOpen routine, which creates a socket handle to access that web page. This routine returns immediately before performing any required network I/O. Then the application calls INetLibSockRead to read the data, followed by INetLibSockClose to close down the socket.

Note that if no data is available to read immediately, INetLibSockRead blocks until at least one byte of data is available to be read. To implement asynchronous operation using events, see the next section, Asynchronous Operation.

If an application requires finer control over the operation, it can replace the call to INetLibURLOpen with other lower-level Internet library calls (INetLibSockOpen, INetLibSockSettingSet, etc.) that are described in the section "Using the Low Level Calls" .

Asynchronous Operation

A major challenge in writing an Internet application is handling the task of accessing content over a slow network while still providing good user-interface response. For example, a user should be able to scroll, select menus, or tap the Cancel button in the middle of a download of a web page.

To easily enable this type of functionality, the Internet library provides the INetLibGetEvent call. This call is designed to replace the EvtGetEvent call that all traditional, non-network Palm applications use. The INetLibGetEvent call fetches the next event that needs to be processed, whether that event is a user-interface event like a tap on the screen, or a network event like some data arriving from the remote host that needs to be read. If no events are ready, INetLibGetEvent automatically puts the Palm device into low-power mode and blocks until the next event occurs.

Using INetLibGetEvent is the preferred way of performing network I/O since it maximizes battery life and user-interface responsiveness.

With INetLibGetEvent, the process of accessing a web page becomes only slightly more complicated. Instead of calling INetLibSockRead immediately after INetLibURLOpen, the application should instead return to its event loop and wait for the next event. When it gets a network event that says data is ready at the socket, then it should call INetLibSockRead.

There are two types of network events that INetLibGetEvent can return in addition to the standard user-interface events. The first event is a status change event (inetSockStatusChangeEvent). This event indicates that the status of a socket has changed and the application may want to update its user interface. For example, when calling INetLibURLOpen to access an HTTP server, the status on the socket goes from "finding host," to "connecting with host," to "waiting for data," to "reading data," etc. The event structure associated with an event of this type contains both the socket handle and the new status so that the application can update the user interface accordingly.

The second type of event that INetLibGetEvent can return is a data-ready event (inetSockReadyEvent). This event is returned when data is ready at the socket for reading. This event tells the application that it can call INetLibSockRead and be assured that it will not block while waiting for data to arrive.

The general flow of an application that uses the Internet library is to open a URL using INetLibURLOpen, in response to a user command. Then it repeatedly calls INetLibGetEvent to process events from both the user interface and the newly created socket returned by INetLibURLOpen. In response to inetSockStatusChangeEvent events, the application should update the user interface to show the user the current status, such as finding host, connecting to host, reading data, etc. In response to inetSockReadyEvent events, the application should read data from the socket using INetLibSockRead. Finally, when all available data has been read (INetLibSockRead returns 0 bytes read), the application should close the socket using INetLibSockClose.

Finally, the convenience call INetLibSockStatus is provided so that an application can query the status of a socket handle. This call never blocks on network I/O so it is safe to call at any time. It not only returns the current status of the socket but also whether or not it is ready for reading and/or writing. It essentially returns the same information as conveyed via the events inetSockReadyEvent and inetSockStatusChangeEvent. Applications that don't use INetLibGetEvent could repeatedly poll INetLibSockStatus to check for status changes and readiness for I/O, though polling is not recommended.

Using the Low Level Calls

Applications that need finer control than INetLibURLOpen provides can use the lower level calls of the Internet library. These include INetLibSockOpen, INetLibSockConnect, INetLibSockSettingSet, INetLibSockHTTPReqCreate, INetLibSockHTTPAttrGet, INetLibSockHTTPAttrSet, and INetLibSockHTTPReqSend.

A single call to INetLibURLOpen for an HTTP resource is essentially equivalent to this sequence: INetLibSockOpen, INetLibSockConnect, INetLibSockHTTPReqCreate, and INetLibSockHTTPReqSend. These four calls provide the capability for the application to access non-standard ports on the server (if allowed), to modify the default HTTP request headers, and to perform HTTP PUT and POST operations. The only calls here that actually perform network I/O are INetLibSockConnect, which establishes a TCP connection with the remote host, and INetLibSockHTTPReqSend, which sends the HTTP request to the server.

INetLibSockHTTPAttrSet is provided so that the application can add or modify the default HTTP request headers that INetLibSockHTTPReqCreate creates.

INetLibSockSettingSet allows an application finer control over the socket settings.

Finally, the routine INetLibURLCrack is provided as a convenient utility for breaking a URL into its component parts.

Cache Overview

The Internet library maintains a cache database of documents that have been downloaded. This is an LRU (Least Recently Used) cache; that is, the least recently used items are flushed when the cache fills. Whether or not a retrieved page is cached is determined by a flag (inetOpenURLFlagKeepInCache) set in the socket or by INetLibURLOpen. Another flag (inetOpenURLFlagLookInCache) determines if the Internet library should check the cache first when retrieving a URL.

The same cache database can be used by any application using the Internet library, so that every application can share the same pool of prefetched documents. Alternately, an application can use a different cache database. The cache database to use is specified in the INetLibOpen call.

Generally, a cached item is stored in one or more database records in the same format as it arrives from the server.

In the cache used by the Clipper application, each record includes a field that contains the "master" URL of the item. This field is set to the URL of the active PQA, so all pages linked from one PQA have the same master URL. This facilitates finding all pages in a hierarchy to build a history list.

The Internet library maintains a list of items in the cache. You can retrieve items in this list, or iterate over the whole list, by calling INetLibCacheList. You can retrieve a cached document directly by using INetLibCacheGetObject.

You can check if a URL is cached by calling INetLibURLGetInfo.

Internet Library Network Configurations

The Internet library supports network configurations. A configuration is a specific set of values for several of the Internet library settings (from the INetSettingEnum type).

The Internet library keeps a list of available configurations and aliases to them. There are three built-in configurations:

You can also define your own configuration by modifying an existing one and saving it under a different name.

The Internet library also defines several configuration aliases (see "Configuration Aliases" in the Palm OS SDK Reference). An alias is a configuration name that simply points to another configuration. You can specify an alias anywhere in the API you would specify a configuration. This facilitates easy re-assignment of the built-in configurations and eliminates having duplicate settings. You assign an alias by using INetLibConfigAliasSet and can retrieve an alias by using INetLibConfigAliasGet.

For example, to change the default configuration used by the Internet library for a particular kind of connection, you can set up the appropriate values for a connection, save the configuration, and then set the Internet library's default alias configuration to point to your custom configuration. When an application specifies which configuration it wants to use, if it specifies the alias, it will use the custom settings.

If you use configurations at all, it will probably be to specify a specific configuration when opening the Internet library via INetLibOpen. The Internet library also contains an API to allow you to manipulate configurations in your application, but doing so is rare. You can list the available configurations (INetLibConfigList), get a configuration index (INetLibConfigIndexFromName), select (INetLibConfigMakeActive) the Internet library network configuration you would prefer to use (wireless, wireline, etc.), rename existing configurations (INetLibConfigRename), and delete configurations (INetLibConfigDelete).

The configuration functions are provided primarily for use by Preferences panels while editing and saving configurations. The general procedure is to make the configuration active that you want to edit, set the settings appropriately, then save the configuration using INetLibConfigSaveAs. Note that configuration changes are not saved after the Internet library is closed, unless you call INetLibConfigSaveAs.

Summary of Network Communication

Net Library Functions
Library Open and Close
NetLibClose
NetLibConnectionRefresh
NetLibFinishCloseWait
NetLibOpen
NetLibOpenCount
Socket Creation and Deletion
NetLibSocketClose NetLibSocketOpen
Socket Options
NetLibSocketOptionGet NetLibSocketOptionSet
Socket Connections
NetLibSocketAccept
NetLibSocketAddr
NetLibSocketBind
NetLibSocketConnect
NetLibSocketListen
NetLibSocketShutdown
Send and Receive Routines
NetLibDmReceive
NetLibReceive
NetLibReceivePB
NetLibSend
NetLibSendPB
Utilities
NetHToNL
NetHToNS
NetLibAddrAToIN
NetLibAddrINToA
NetLibGetHostByAddr
NetLibGetHostByName
NetLibGetMailExchangeByName
NetLibGetServByName
NetLibMaster
NetLibSelect
NetLibTracePrintF
NetLibTracePutS
NetNToHL
NetNToHS
Setup
NetLibIFAttach
NetLibIFDetach
NetLibIFDown
NetLibIFGet
NetLibIFSettingGet
NetLibIFSettingSet
NetLibIFUp
NetLibSettingGet
NetLibSettingSet

Network Utilities
NetUReadN NetUTCPOpen
NetUWriteN

Internet Library Functions
Library Open and Close
INetLibClose INetLibOpen
Settings
INetLibSettingGet INetLibSettingSet
Event Management
INetLibGetEvent
High-Level Socket Calls
INetLibSockClose
INetLibSockRead
INetLibURLOpen
Low-Level Socket Calls
INetLibSockConnect
INetLibSockOpen
INetLibSockSettingGet
INetLibSockSettingSet
INetLibSockStatus
HTTP Interface
INetLibSockHTTPAttrGet
INetLibSockHTTPAttrSet
INetLibSockHTTPReqCreate
INetLibSockHTTPReqSend
Utilities
INetLibCheckAntennaState
INetLibURLCrack
INetLibURLGetInfo
INetLibURLsAdd
INetLibWiCmd
Cache Interface
INetLibCacheGetObject INetLibCacheList
Configuration
INetLibConfigAliasGet
INetLibConfigAliasSet
INetLibConfigDelete
INetLibConfigIndexFromName
INetLibConfigList
INetLibConfigMakeActive
INetLibConfigRename
INetLibConfigSaveAs



Palm OS Programmer's Companion

  Previous Page Table of Contents Index Next Page  

This is page 80 of 85 in this book

Palm Computing Platform Development Zone
Copyright © 2000, Palm, Inc. All rights reserved.