|
MSDN
Home > MSJ > May 1998
May
1998
Windows CE 2.0 Networking Offers Exciting Mobile Computing
Possibilities
|
Anthony Jones
Microsoft’s new Windows® CE operating system is designed for
small form factor devices. An appealing feature of these devices is
their robust networking capability. They support many types of
communications hardware, including serial links, modems, and
Ethernet cards. |
This article assumes you’re familiar with C++ and Network
Programming |
Anthony Jones is an engineer at Microsoft in
the Developer Support Networking Unit. He is an avid skier who is
perfecting the technique of sliding down the mountain on his
back.
|
Imagine you're on your way to the
airport for an important business trip when you realize you left the
heat on at your house. You pull your Handheld PC out of your
briefcase and dial up your ISP through your cellular phone. You then
bring up a Home Management app that shows the temperature in your
house, the thermostat setting, what lights are on, and the mode of
the security system, among other things. You turn the thermostat to
the off position and the problem is solved. Sound like science
fiction? Well, it's closer than you think! Microsoft's new Windows® CE operating system is designed for small form factor
devices, including Handheld PCs, automobile computers, and many
other embedded applications. Just recently, Microsoft and TCI
announced a deal to use Windows CE in set top cable boxes. Microsoft
has also unveiled plans for the Auto PC, a small computer running
Windows CE for use in automobiles. Several manufacturers have
already released plans to produce these devices with navigation
features that include a GPS (Global Positioning System) tracking
device and wireless communications. Of course, most people have heard of those tiny Handheld
PCs running the Windows CE operating system. These little devices
are amazing in their own right. Handheld PCs come with versions of
Microsoft Excel and Word, and their ability to synchronize with your
desktop PC via serial or infrared connections makes them the perfect
personal organizers. Another appealing feature of these devices is
their robust networking capability. They support many types of
communications hardware, including serial links, modems, and
Ethernet cards. They also support almost all of Microsoft's
networking APIs! Windows CE is taking off like wildfire, in large part due
to its strong networking features. In this article I will give a
detailed overview of the networking capabilities under Windows CE
2.0. I will emphasize the Winsock support and networking features
such as infrared socket support (IrSock) because these capabilities
open up exciting new possibilities in the world of mobile computing.
One important thing to note is that the communications
support in Windows CE is an operating system specification and not a
requirement for the hardware on which it runs. Handheld PC
manufacturers receive the operating system as a set of components,
some of which are tagged as optional. The manufacturer can choose
which optional features will be supported. When manufacturers leave
out a component, it's usually to save space for their own unique
features. In the discussion that follows, I will note those APIs
that I know are not implemented on Handheld PCs.
Communication Support There are three basic components to Windows CE
communications: serial I/O, telephony, and networking support.
Windows CE networking support includes:
- Winsock and IrSock APIs
- TCP/IP and IrDA protocols
- NDIS4.0 support for local area networking
- PPP and SLIP via serial or modem connections
- Remote file access (WNet API)
- Remote Access Client (RAS API)
- Browser support (WinInet API)
Serial Communication Serial communication is a fundamental feature of the
Windows CE architecture and should be available on virtually all
devices. Serial communication is performed either over a direct
cable connection or through the infrared transceiver. Direct cable
connections over a COM port are handled by the Win32® API serial functions. The API calls
CreateFile, ReadFile, and WriteFile can be used to open, read from,
and write to a COM port. Overlapped (asynchronous) I/O is not
supported under Windows CE and should not be used in any of the API
calls. The infrared port is assigned to a COM port so it is
possible to use the Win32 API serial functions to communicate. Since
this is raw I/O, there will be no collision detection, which can
lead to data corruption. The IrSock extension to Winsock provides
reliable communication over the infrared port. In addition, there is
IrComm, which emulates a serial connection but uses IrSock and the
IrDA protocol under the hood.
Telephony Windows CE also includes a telephony (TAPI) service
provider that supports AT command-based modems. This capability can
be used either with attached modems or PCMCIA modems. The purpose of
TAPI is to provide telephone communication services without
requiring detailed knowledge of the modem hardware. Currently,
Windows CE supports only outbound calls; inbound calls are not
supported. Windows CE provides a connection wizard to set up
multiple dial-up and direct cable connections.
Networking Communications The networking options available under Windows CE are
impressive for such a small device. Looking at Figure 1, you
can see that at the highest level of the network stack lies the
WinInet and WNet APIs. The WinInet API is for Internet browsing
support while the WNet API is used to access share drives on remote
computers. The WNet API will allow network printing in Windows CE
2.1. Both WinInet and WNet are implemented as a subset of their
Win32 counterparts and contain some limitations.
|
|
Figure 1
API and Protocol Stack |
There are some differences in the Windows CE implementation
of WinInet. First, most WinInet APIs are handled synchronously. Only
InternetReadFile and InternetQueryDataAvailable support both
synchronous and asynchronous modes. Second, Windows CE supports
Unicode by default. Last, before using any Internet functions, an
application must call InternetOpen to obtain a handle that points to
an Internet or Gateway object. This handle will be passed to other
functions that offer specific Internet services such as issuing an
HTTP request. Under Windows CE, WinInet is limited to client applications
using HTTP and FTP. Gopher, cookies, and persistent URL cache
functions are not presently supported. While the FTP APIs are
available as a Windows CE component, no Handheld PC currently
shipping supports them. The WNet API under Windows CE also contains some caveats.
Only the Microsoft network provider is supported, which means, for
example, you cannot connect to Novell share drives. Also, the
redirector was left out of Windows CE 2.0 for the Handheld PC, and
this cripples its ability to use any of the WNet functions
successfully. However, Microsoft has now made the missing files
available for download from their Web site. Next are the Remote Access Client and Winsock (along with
IrSock). Because Winsock and IrSock are the focus of this article, I
will discuss those in greater detail later. The Remote Access
Service (RAS) is a software-based multi-protocol router used to
connect Windows CE devices to a remote host. Windows CE only
provides support for RAS clients. Most of the Win32 RAS functions
are present, except those that deal with the server side of RAS. The
only other restriction is that RAS supports only one point-to-point
connection at any given time, but the connection can be either a
direct serial connection or a dial-up connection. It is important to note that some networking APIs are not
supported under Windows CE. None of the LAN Man API calls are
supported, and named pipes and mailslots are not implemented. For
further information on WinInet, WNet, and RAS capabilities and
limitations under Windows CE, consult the Platform SDK
documentation.
Winsock Support Windows socket support under Windows CE is a subset of the
Winsock 1.1 specification. All of the standard Winsock functions are
available except for the asynchronous calls (including the majority
of the WSAxxx functions). Some added features include support
for Secure Socket Layer (SSL) 2.0, SSL 3.0, and PCT 1.0 security
protocols. There is also a set of ICMP support functions used for
making "ping" requests. Winsock support has been extended to handle the IrDA
protocol. This extension is known as IrSock, and brings exciting new
capabilities to mobile devices. Applications using IrSock are very
similar to straight Winsock applications except that the addressing
scheme is new. The new addressing scheme was necessary because of
the nature of mobile computing. Handheld PCs frequently move in and
out of range of various resources, so a dynamic name resolution
scheme was required. I will discuss IrSock addressing in further
detail later on.
Handheld PCs on the Network Handheld PCs running Windows CE are designed to communicate
with other machines. This is perhaps its greatest strength. As
discussed earlier, there are several ways to get a Handheld PC
connected to other PCs. The first (and most common) method is to
connect to a desktop via the serial cable or the infrared serial
port. If you have the Windows CE Services installed, a relationship
is created between the Handheld PC and PC. These services, however,
are not required to use a serial connection. All that is needed is a
desktop with the RAS server installed. When connecting a Handheld PC to a desktop there are
certain limitations. First of all, a connected Handheld PC is not
registered with a WINS server unless the redirector components are
used. This means that any attempt to resolve the name of the
Handheld PC will fail. Second, the Handheld PC is assigned an IP
address, but in most cases this address is a local address that is
known only to the desktop. This makes it impossible for outside
machines to connect to the Handheld PC, but the RAS server will
forward the network packets from the Handheld PC to the correct
location. Of course, this scenario assumes the typical RAS server
setup. It is possible to configure RAS to hand out real IP addresses
and configure routing so that the Handheld PC can receive network
traffic, but that is beyond the scope of this article. A Handheld PC is capable of using an Ethernet card, in
which case it could be assigned a real IP address (statically or via
DHCP). This would allow a Handheld PC full access to reach and be
reached by other machines.
Writing Winsock Applications Because the asynchronous Winsock functions are not
available, developers must restructure their applications to use
regular blocking and nonblocking sockets. Programmers who grew up
with Windows sockets might have some trouble thinking of sockets
without the window messages and event notifications enabled by
WSAAsynchSelect and WSAEventSelect, respectively. I came from a BSD
socket background, but I have to admit that the asynchronous Winsock
model is rather elegant. It greatly simplifies socket programming
when receiving data asynchronously. In this section, I will describe
what you need to watch out for when coding blocking and nonblocking
sockets, and I will present strategies for efficiently using these
models. Socket programming must be proactive; that is, the
programmer must take into account the many possible actions that
could take place at each Winsock call. With asynchronous sockets,
reading and writing only take place when their respective events are
triggered. This leaves the programmer free to think about how to
perform some computation on the data. With synchronous sockets, the
programmer must think, "Okay, at this point I need to read 42 bytes,
but what happens if the data hasn't arrived yet?" As a result, the
programmer needs to develop a well thought out read/write scheme
with awareness of the data flow between the application and the
remote machine.
Blocking Sockets Blocking sockets cause concern because any Winsock API call
on a blocking socket may do just that—block for some period of time.
Most Winsock applications follow a producer-consumer model where the
application reads (or writes) a specified number of bytes and
performs some computation on that data. The code snippet in Figure 2 illustrates this model.
The problem with this code is that recv may never return if
there is no data pending because the statement says to return only
after reading bytes from the system's input buffer. Some programmers
might be tempted to peek for the necessary number of bytes in the
system's buffer by calling ioctlsocket with the FIONREAD option.
Peeking for data without actually reading the data (reading the data
actually removes it from the system's buffer) is considered bad
programming practice and should be avoided at all costs. The
overhead associated with peeking is great because there are possibly
several system calls just to check the number of bytes available.
Then, of course, there is the overhead of making the actual read
call that removes the data from the system buffer. What can be done to avoid this? The idea is to prevent the
application from totally freezing due to lack of data (either from
network problems or client problems) without continually peeking at
the system network buffers. One method is to separate the
application into a reading thread and a computation thread that
share a common data buffer. Access to this buffer would be protected
through the use of a synchronization object such as an event or
mutex. The purpose of the read thread is to continually read data
from the network and place it in the shared buffer. Once the reading
thread has read the minimum amount of data necessary for the
computation thread to do its work, it could signal an event which
would notify the computation thread to begin. The computation thread
would then remove a chunk of data from the buffer and perform
whatever calculations are necessary. Figure 3 illustrates this by
providing two functions, one responsible for reading network data
(ReadThread), and one for performing the computations on the data
(ProcessThread). One drawback to blocking sockets is that it makes life more
difficult if the app needs to communicate via more than one
connected socket at a time. The scheme shown in Figure 3 could be modified to have one read
and data processing thread per connected socket. This adds quite a
bit of housekeeping overhead, but it is a feasible solution. The
only drawback is that the solution does not scale very well once you
start dealing with a large number of sockets.
Nonblocking Sockets The alternative to blocking sockets is nonblocking sockets.
Nonblocking sockets are a bit more of a challenge to use, but they
are every bit as powerful as blocking sockets and offer a few
advantages. Figure 4 illustrates how to create
a socket and put it into nonblocking mode. Once a socket is placed into nonblocking mode, Winsock API
calls will return immediately. In most cases these calls will fail
with the error WSAEWOULDBLOCK, which means that the requested
operation did not have time to complete during the call. For
example, a call to recv for 20 bytes will return WSAEWOULDBLOCK if
there is no data pending in the system's input buffer. Often
additional calls to the same API are required until a successful
return code is encountered. Figure 5 describes the meaning for
various Winsock calls when WSAEWOULDBLOCK is returned. Because nonblocking calls frequently fail with the
WSAEWOULDBLOCK error, it is important to check all return codes and
be prepared for failure at any time. Many programmers fall into the
pitfalls of continually calling one API call until it returns a
success. For example, placing a call to recv in a tight loop to read
200 bytes of data is no better that polling a blocking socket with
the MSG_PEEK flag. To avoid this, the select API can be used to
detect whether there is data to be read or whether a socket can be
written to. This API call will block until the conditions the
programmer specifies are met. The function prototype for select is
as follows: |
int WINSOCKAPI select(int nfds,
fd_set *readfds,
fd_set *write_fds,
fd_set *except_fds,
const struct timeval
*timeout); |
You'll notice that there are three fd_set
parameters, one for checking readability, one for writeability, and
one for out-of-band data, respectively. An fd_set is a collection of
sockets. Winsock declares several macros for adding, deleting, and
clearing these sets. For example, Figure 6 illustrates how to check
whether socket s has any incoming data pending. A single call to select may also include the other fd_set
variables, and each fd_set may contain multiple sockets. To keep
things simple, it is probably best to call select with only one type
of fd_set at a time because select merely returns the number of
sockets that meet the given conditions. For example, if a read and a
write fd_set were used with each set containing three sockets, and
select returned four, all this means is that four sockets are
available for reading or writing. It is up to the programmer to
figure out which sockets correspond to which event. Each type of socket, blocking and nonblocking, has
advantages and disadvantages. Blocking sockets are easier from a
conceptual standpoint, but become difficult to use when dealing with
multiple connected sockets or when data is sent and received in
varying amounts and times. Nonblocking sockets require more code to
handle the possibility of receiving a WSAEWOULDBLOCK error on every
Winsock call, but the select function offers the ability to manage
multiple connected sockets in an organized manner.
Socket Options Because Windows CE Winsock is an entirely new and small
platform, not all of the socket options used by getsockopt and
setsockopt are useful, or even implemented. I'll detail the options
that are supported for each API call. Figure 7 enumerates the socket
options that are currently supported or will be supported in the
future. The first column, Level, shows for which level the option is
valid. The Option Name column lists the actual option. The Specific
API column notes whether the option applies to getsockopt,
setsockopt, or both. Finally, the Protocol column notes whether the
option is valid for traditional Winsock sockets, IrSock sockets, or
both. All of the options in Figure 7 are defined in the Winsock header
file, but not all are implemented. For setsockopt there are quite a
few options not implemented. First, none of the multicast options
(IP_MULTICAST_TTL, IP_MULTICAST_IF, IP_MULTICAST_LOOP,
IP_ADD_MEMBERSHIP, and IP_DROP_MEMBERSHIP) are implemented because
multicasts are not supported under Windows CE 2.0. Multicast support
is slated for Windows CE 2.1. Note that multicast support for IrSock
does not make sense since it does not support datagram sockets.
Also, SO_RCVBUF can be used to obtain the system receive buffer size
in getsockopt, but it cannot be used to change the buffer. If you do
try to change the receive buffer size, the error WSAEOPNOTSUPP will
be returned. Options related to the SOL_IRLMP family will be
discussed in further detail in later sections. The only WSAxxx function implemented under Windows
CE is WSAIoctl. Both WSAIoctl and ioctlsocket are used to set or
check various input and output options on a socket (see Figure 8). These differ from the
getsockopt and setsockopt functions in that they do not apply to any
particular socket family or protocol. They handle general options
such as blocking versus nonblocking mode and secure socket layer
options, and should apply to both Winsock and IrSock, although
secure socket options are not supported for IrSock. Windows CE includes three new Winsock API functions that
perform ICMP echo requests that are similar to the ping command.
These new API functions—ICMPCreateFile, ICMPSendEcho, and
ICMPCloseHandle—are simple and well documented in the SDK.
ICMPCreateFile is called first to return a valid ICMP handle that
you use in calls to ICMPSendEcho. This API function lets you send
data in an ICMP packet, and returns any ICMP responses from the
intended recipient (or returns an error if the network is
unreachable). You may also specify a timeout value to limit the
waiting time in case the destination is unreachable. ICMPCloseHandle
is called on the ICMP handle when communication is finished.
Unfortunately, the required header file (icmpapi.h) and static
library (icmplib.lib) were left out of the latest SDK, and this will
be remedied in newer releases of the SDK or possibly through a
Knowledge Base article.
Infrared Sockets Most Handheld PCs come equipped with an infrared serial
port for wireless communication. IrSock takes into account the
transient nature of portable computers. Because Handheld PCs are
likely to move about, traditional name resolution schemes (including
conventional Winsock) do not work well. These conventional methods
assume static resources such as name servers, which cannot be used
when a person is walking about with a Handheld PC that is running a
network client. To circumvent this problem, IrSock is designed to browse
in-range resources in an ad-hoc manner without the overhead of a
large network, and does not use standard Winsock name service
functions or even IP addressing. Instead, the name service has been
incorporated into the communications stream, and a new address
family has been introduced to support services bound to infrared
serial ports. The IrSock address structure includes a service name that
describes the application used in bind and connect calls, and a
device identifier describing the device on which the service runs.
This pair is analogous to the IP address—the port number tuple used
by conventional TCP/IP sockets. The IrSock structure is defined as:
|
struct sockaddr_irda {
u_short irdaAddressFamily;
u_char irdaDeviceID[4];
char irdaServiceName[25];
}; |
The irdaAddressFamily field is always set to
AF_IRDA. The irdaDeviceID field is a four-character string that
identifies the device on which a particular service is running. This
field is ignored when creating an IrSock server, but it is
significant for a client because it specifies the specific IrDA
device to connect to. Finally, the irdaServiceName field is the name
of the service that the application will either register itself as
or is looking for.
IrSock Name Resolution Addressing can be based on IrDA Logical Service Access
Point Selectors (LSAP-SELs) or on services registered with the
Information Access Service (IAS). The IAS abstracts a service from
an LSAP-SEL into a more friendly service name. You can think of this
as the difference between an Internet name such as www.microsoft.com
and its numeric IP address. Developers are discouraged from using the direct LSAP-SEL
"address" because the address space for IrDA services is limited.
Windows CE allows LSAP-SEL integer identifiers in the range of
1-127. IAS can be thought of as a WINS server. It associates an
LSAP-SEL with a service name. An actual IAS entry has three fields of importance: class
name, attribute, and attribute value. For example, a server wishes
to register itself under the service name of MyServer. This is
accomplished when the server issues the bind call with the
appropriate SOCKADDR_IRDA structure. Once this occurs, an IAS entry
is added with a class name of MyServer, an attribute of
IrDA:TinyTP:LsapSel, and an attribute value of, say, 3. The
attribute value is the next unused LSAP-SEL. The client, on the other hand, passes in a SOCKADDR_ IRDA
to connect. This initiates an IAS lookup for a service with the
class name MyServer and attribute IrDA:TinyTP:LsapSel. The IAS query
will return the value 3. It is possible to formulate your own IAS
query by using getsockopt with the IRLMP_IAS_QUERY option. I will
discuss this later. If you want to bypass IAS altogether (although this is not
recommended), you can specify an LSAP-SEL address directly for a
server name or an endpoint to which a client wishes to connect. This
should only be used to communicate with legacy IrDA devices that do
not provide any kind of IAS registration. Specifying the service
name in the SOCKADDR_IRDA structure as LSAP-SELxxx, where xxx is the
attribute value between 1 and 127, bypasses the IAS registration and
lookup. For a server, this would directly assign that server to the
given LSAP-SEL address (assuming that LSAP-SEL is unused). For a
client, this bypasses the IAS lookup and causes an immediate attempt
to connect to whatever service is running on that LSAP-SEL.
IrSock Server The coding principle behind a server running over IrSock is
analogous to the regular Winsock equivalent. To write an IrSock
server, first allocate a socket with the socket API call, using
AF_IRDA for the address format parameter and SOCK_STREAM for the
type. Next, bind the service name to the socket with the bind call,
passing a SOCKADDR_IRDA structure in for the address parameter.
Listen for incoming connections with the listen API call and accept
incoming connections with the accept API call. Use the send and recv
API calls to communicate with the client. Finally, close the socket
with the closesocket API call. Writing an IrSock client is slightly more complicated
because it is the job of the client to search for services in the
area. This search is a general search for IrDA devices in the
vicinity; it actually does not search for a particular service. I
will discuss this in more detail shortly. But first, here are the general steps necessary to write a
client using IrSock. Start by allocating a socket with the socket
API call, using AF_IRDA for the address format parameter and SOCK_
STREAM for the type. Then search for available IrSock servers with
getsockopt and the IRLMP_ENUMDEVICES option. Connect with the
service via the connect API, using a SOCKADDR_IRDA for the name
parameter that describes the particular service for which you are
looking. Use the send and recv API calls to communicate with the
server. Finally, close the socket with the closesocket API call.
The method for looking up IrSock services is
straightforward, but the significant differences from traditional
Winsock can cause a few problems. As I mentioned, the basis for
looking up available services is getsockopt with IRLMP_ENUMDEVICES.
This call will discover devices within the infrared range for
registered applications. If any services are found, they are
returned in a DEVICELIST structure, which is defined as follows:
|
typedef struct _IRDA_DEVICE_INFO
{
u_char irdaDeviceID[4];
char irdaDeviceName[22];
u_cahr Reserved[2];
} IRDA_DEVICE_INFO, *PIRDA_DEVICE_INFO, FAR *LPIRDA_DEVICE_INFO;
typedef struct _DEVICELIST
{
ULONG numDevice;
IRDA_DEVICE_INFO Device[1];
} DEVICELIST, *PDEVICELIST, FAR *LPDEVICELIST; |
The field of interest in a DEVICELIST is Device, which is
an IRDA_DEVICE_INFO structure. Within that structure is an
irdaDeviceID that corresponds to the field of the same name in the
SOCKADDR_IRDA structure. Any IrSock-capable device will have a
device ID associated with it, so a successful query will return one
or more IRDA_DEVICE_ INFO structures containing the device ID of
each device discovered. If no IrSock-capable devices are detected,
the query will return with the numDevice field set to zero. Once a
list of these device IDs are returned, a client can either attempt
to connect to each server or begin to query the server for services
it is running. To connect to the server, the client fills out a
SOCKADDR_IRDA with the device ID of the device in question and the
service name of the IrSock server to which it wants to connect.
You may have noticed that when searching for available
IrSock devices, a device ID and friendly name are returned. A client
is required to know both the device ID of the server and the name of
the IrSock service for which it is looking. Future releases may add
additional "hint" information to the structure returned by an
IRLMP_ENUMDEVICES call. This information will better associate a
particular server with a found IrDA device. To find the correct
server, it is necessary to attempt a connection to each device
returned, specifying the service name for which you are looking. Figure 9 illustrates a simple
IrSock client, irclient.c, that first searches for IrSock devices in
the area, and then attempts to connect to each one in search of a
particular server. Also included is code for a simple IrSock server
to which this client could connect.
IrSock Socket Options IrSock exposes a handful of socket options, only a few of
which are likely to get much use. The most commonly used option is
IRLMP_ENUMDEVICES, which I discus-sed earlier. This is used to
browse infrared traffic for available devices. The other commonly
used option is IRLMP_IAS_QUERY, which is used to query a device's
IAS service for registered services and service attributes. When
performing a query, an IAS_QUERY structure is passed into
getsockopt, defining the parameters for the search. The structure is
defined as follows: |
typedef struct _IAS_QUERY
{
u_char irdaDeviceID[4];
char irdaClassName[61];
char irdaAttribName[61];
u_short irdaAttribType;
union
{
int irdaAttribInt;
struct
{
int Len;
u_char OctetSeq[1];
u_char Reserved[3];
} irdaAttribOctetSeq;
struct
{
int Len;
u_char CharSet;
u_char UsrStr[1];
u_char Reserved[2];
} irdaAttribUsrStr;
} irdaAttribute;
} IAS_QUERY, *PIAS_QUERY, FAR *LPIAS_QUERY; |
An entry within the IAS_QUERY consists of the device ID,
class name, and attribute name. The attribute value associated with
the name can be an integer, a binary sequence, or a string, which is
the reason for the union within the structure. To perform a query,
fill in a valid device ID (returned from an IRLMP_ENUMDEVICES),
class name, and attribute name. The value returned will be the
attribute associated with that particular class and attribute on the
given device. For the most part, developers will use connect, which
will properly handle the query for the LSAP-SEL on which a service
is running. In this case, the device ID would be the device to
query, the class name would be the name associated with the service
in question, and the attribute would be IrDA:TinyTP:LsapSel.
Another option of some interest is IRLMP_IAS_SET, which is
used to change the attribute associated with a particular class
name. This option requires passing an IAS_SET structure into
setsockopt. The structure is exactly like the IAS_QUERY structure
minus the irdaDeviceID field. It is doubtful that one would actually
need to change the attributes associated with an IAS entry. The rest of the IrSock options are unlikely to be used, but
here are short descriptions of each to satisfy everyone's curiosity.
IRLMP_9WIRE_MODE is designed to talk to the Windows 95 IrComm. In
this mode, the IrLMP packet contains an additional one-byte IrComm
header. Related to this option is IRLMP_SEND_PDU_LEN, which
transmits the maximum PDU size of an IrLMP packet to the other side.
This is used to determine whether IRLMP_9WIRE_ MODE should be set.
IRLMP_EXCLUSIVE_MODE puts the IrLMP layer into exclusive mode, which
means only one LSAP-SEL will be active and communicating. For
further information about these options, consult the IrDA
specifications found at http://www.irda.org/.
Secure Socket Layer Support Windows CE provides support for SSL, including the SSL 2.0,
SSL 3.0, and PCT 1.0 security protocols. Secure sockets are
available from both the WinInet API and the Winsock API. To utilize
SSL from Winsock, the following steps need to be taken. First, create a callback function that will be called by
the Winsock security provider when a certificate is received from a
remote party. This function is responsible for ensuring the validity
of the certificate received. Next, create a socket with the socket
API. Set the socket options via the setsockopt API, with the level
parameter set to SO_SOCKET, the optname set to SO_SECURE, and the
optval (a DWORD), set to SO_SEC_SSL. Call the WSAIoctl API to
complete the setup. This includes calling WSAIoctl with the SO_SSL_
SET_VALIDATE_CERT_HOOK option to install the callback function
created in the first step. Finally, make a connection and use
Winsock calls in the normal fashion. The most involved step in the process is writing the
callback function for validating certificates. The purpose of the
callback is twofold. First, it ensures the certificate has not
expired. Second, it verifies that the identity contained within the
certificate matches that of the remote party. More in-depth
information on SSL callback functions can be found in the Platform
SDK.
TCP/IP Registry Options Traditional TCP/IP stacks are developed to work efficiently
on wired networks and do not address concerns introduced with
wireless networks. Settings appropriate to Ethernet, for example,
may waste bandwidth on wireless networks by unneeded retransmission
requests. To improve efficiency, some TCP/IP parameters can be tuned
to the characteristics of the supporting network. These parameters
are maintained on a per-adapter basis, so applications must
determine the appropriate adapter and change the associated
parameter settings in the registry. Two parameters are most relevant: Receive Window Size and
Initial Round Trip Time. The registry key for Receive Window Size is
Adapter Name\tcpip\parms \TcpWindowSize. In general, larger
receive windows work better with high-delay, high-bandwidth data.
For added efficiency, the receive window should also be an even
multiple of the TCP Maximum Segment Size (MSS) and should never
exceed the system maximum, which has its own key
(tcpip\parms\GlobalMaxTcpWindowSize). Currently there is a known
problem with this parameter that will be fixed in a later release of
Windows CE. The registry key for Initial Round Trip Time is Adapter
Name\tcpip\parms\TcpInitialRTT. Round trip times are generally
longer for wireless networks, and the recommended value is four
seconds. If no value is set, the default is three seconds.
Conclusion Windows CE offers many exciting new capabilities in the
world of mobile computing. The possible applications for this new
operating system are limitless. Because it is a new technology, its
specifications and capabilities are likely to change. A good place
to find the latest Windows CE news is on the Microsoft Windows CE
Web page at http://www.microsoft.com/windowsce/).
For programming information, consult the latest Platform SDK
documentation.
From the May 1998 issue of Microsoft Systems
Journal. Get it at your local newsstand, or better yet, subscribe.
|
|