< Home < Developers < Development Support < Documentation

## 6 Network Communication

Table of Contents | < Previous | Next > | Index

| Title - Palm OS® Programmer's Companion vol. II: Communications 6 Network Communication Net Library About the Net Library Net Library Usage Steps Obtaining the Net Library's Reference Number Setting Up Berkeley Socket API Setup and Configuration Calls Opening the Net Library Closing the Net Library Version Checking Network I/O and Utility Calls Berkeley Sockets API Functions Extending the Network Login Script Support Internet Library System Requirements Initialization and Setup Accessing Web Pages Asynchronous Operation Using the Low Level Calls Cache Overview Internet Library Network Configurations Summary of Network Communication |  |  |  | Two different Palm OS® libraries provide network services to applications: The net library provides basic network services using TCP and UDP via a socket API. This library is discussed in the section Net Library. The Internet library builds on the net library to provide a socket-like API to high-level Internet protocols such as HTTP. This library is discussed in the section Internet Library. ## 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: Stream-based, guaranteed delivery of data using TCP (Transmission Control Protocol). Datagram-based, best-effort delivery of data using UDP (User Datagram Protocol). 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 Net Library Usage Steps Obtaining the Net Library's Reference Number Setting Up Berkeley Socket API Setup and Configuration Calls Opening the Net Library Closing the Net Library Version Checking Network I/O and Utility Calls Berkeley Sockets API Functions Extending the Network Login Script Support ## 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: The operating system can switch in the net protocol stack to process incoming packets from the network even if the application is currently busy. Even if an application is blocked waiting for some data to arrive off the network, the net protocol stack can continue to process requests for other applications. 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 IIITM. #### 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: A reference number. All library calls in the Palm OS must have the library reference number as the first parameter. A timeout. In consumer systems such as the Palm OS device, infinite timeouts don't work well because the end user can't "kill" a process that's stuck. The timeout allows the application to gracefully recover from hung connections. The default timeout is 2 seconds. An error code. The sockets API by convention returns error codes in the application's global variable errno. The net library API doesn't rely on any application global variables. This allows system code (which cannot have global variables) to use the net library API. 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: Include the header file <unix/sys_socket.h>, provided with the Palm OS SDK. Link your project with the module NetSocket.c, which declares and initializes three required global variables: AppNetTimeout, AppNetRefnum, and errno. NetLibSocket.c also contains the glue code necessary for a few of the Berkeley sockets functions. As described in the previous section, assign the net library's reference number to the variable AppNetRefnum. Adjust AppNetTimeout's value if necessary. This value represents the maximum number of system ticks to wait before a net library call expires. Most applications should adjust this timeout value and possibly adjust it for different sections of code. The following example sets the timeout value to 10 seconds.
      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 62, "Net Library," in Palm OS Programmer's API 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: NetLibIFAttach attaches an interface to the library so that it will be used when and if the library is open. NetLibIFDetach detaches an interface from the library. NetLibIFGet returns an interface's creator and instance number. 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: netIFCreatorLoop (Loopback network) netIFCreatorSLIP (SLIP network) netIFCreatorPPP (PPP network) 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. The NetLibIFSettingGet call takes a setting ID as a parameter along with a buffer pointer and buffer size for the return value of the setting. Some settings, like login script, are of variable size so the caller must be prepared to allocate a buffer large enough to retrieve the entire setting. (NetLibIFSettingGet returns the required size if you pass NULL for the buffer. See the NetLibIFSettingGet description in the reference documentation for more information.) The NetLibIFSettingSet call also takes a setting ID as a parameter along with a pointer to the new setting value and the size of the new setting. If you're using NetLibIFSettingSet to set the login script, see the next section. 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 6.1 lists the possible commands. #####
Table 6.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 User ID | 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 6.2. #####
Table 6.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: You can open a maximum of four sockets at once in the net library. This is to keep net library's memory requirements to a minimum. When you try to send a large block of data, the net library automatically buffers only a portion of that block because of the limited available dynamic memory. The function call returns the number of bytes of data that it actually transmitted. You must check the return value and if there's more data to send, call the function again until the transmission is finished. If you expect to also receive data during a large transmission, you should send a smaller block, then read back whatever is available to read before sending the next block. In this way, the amount of memory in the dynamic heap that must be used to buffer data waiting to send out and data waiting to be read back in by the application is kept to a minimum. For more information, see the following: The next section, "Berkeley Sockets API Functions," provides tables that list the supported Berkeley sockets calls, the corresponding native net library call, and gives a brief description of what each call does. Chapter 62, "Net Library," of the Palm OS Programmer's API Reference provides detailed descriptions of each net library call. Where applicable, it gives the equivalent sockets API call for each net library native call. The NetSample example application in the Palm OS Examples directory shows how to use the Berkeley sockets API in Palm OS applications. ## 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: You are a corporate IT shop, system integrator, or a token card vendor and want the login script to properly respond to a range of different connection scenarios defined by the authentication server. You are a token card vendor and you want to create the Palm OS version of your password generator. You want to perform conditional tests and branching during the execution of the script. The login script enhancement can also be installed on any device that already has network library support (that is, PalmPilotTM 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 Programmer's API 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: scptLaunchCmdListCmds to inform the Network preferences panel of the commands your plugin implements. scptLaunchCmdExecuteCmd to execute one of your commands. #### 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: - The name of your plugin (the name of the PRC file) - The number of commands your plugin implements. No more than pluginMaxNumOfCmds is allowed. - An array containing the name of each command your plugin implements and a Boolean value that indicates whether your plugin takes an argument. 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: The name of the command to be executed The command argument, if it takes one A pointer to a network interface function A handle to information specific to the current connection 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: Read a number of bytes from the network Write a number of bytes to the network Get the user's name and password information Write a string to the connection log Prompt the user for information Check to see if the user pressed the Cancel button Display a form Obtain access to the serial library 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 6.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: The network interface can display a prompt for you and return the value that the user enters in response. It can also query the Network preferences panel to see if the user cancelled the connection attempt. If you want to do more than simply display a prompt or check the cancel status, you can use the command pluginNetLibCallUIProc to display a form and call your own user interface routine. To use pluginNetLibCallUIProc, you must do the following: 1. Initialize the form using a form resource that you've created. 2. Create a struct that contains your form's handle and any other values that you are going to need in your user interface routine. 3. 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. 4. 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 PalmTM 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, Inc. 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 Initialization and Setup Accessing Web Pages Asynchronous Operation Using the Low Level Calls Cache Overview Internet Library Network Configurations ## 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 Web Clipping Application Viewer 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: A wireless configuration that uses the Palm.Net wireless system and the Palm Web Clipping Proxy server. A wireline configuration that uses the wireline network configuration specified in the Network preferences panel and the Palm Web Clipping Proxy server. A generic configuration that uses the wireline network configuration specified in the Network preferences panel and no proxy server. 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 Programmer's API 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