Implementing Network Detection for Mobility

Submit New Article

December 21, 2009 11:00 PM PST


by Fred Cooper


Introduction

The mobile PC frees people from the confines of their offices and dens, but presents new challenges for application developers wanting to exploit this platform. A true mobility-enabled application must adapt to the changing network connectivity of the mobile PC. Today, most mobile PCs with Intel® Centrino® mobile technology have both wired and wireless network capabilities. Multiple network adapters may be connected to the network at the same time. The same mobile PC could have a high speed wired network connection at one moment and a lower speed wireless LAN (802.11), wireless WAN (GPRS), or modem connection a moment later. The mobility aware application must know the status, type and speed of the network connection. Fortunately, we can implement several network detection methods using the Microsoft Windows* SDK and Microsoft Windows Platform SDK functions.

The intended audience of this white paper is architects, designers and developers writing applications for recent Microsoft Windows* operating systems including: Windows Server 2003* and Windows XP*. The paper also provides beneficial details of network detection for validation engineers and technical-marketing.


Network Detection Fundamentals

Network Connections

The mobile platform may have multiple network connections at the same time.  In some cases the system may have access to the servers the software desires through multiple connections, but at different speeds.  The server, for example, may be available on the internet through a GPRS network adapter, a wired network adapter connected to a cable modem, or a wireless LAN adapter.   The question is, which connection does the program actually use?

Alternatively, adapters can have connections to separate networks, such as a wired LAN card on a private network and a GPRS card on a public network.  In this paper we will discuss how to determine which adapter is actually being used to communicate to the desired location and how to determine the state and speed of that connection.

Interfaces and Adapters

The implementation method we will discuss in this paper make use of the IP helper API provided in the Microsoft* Platform SDK.  This helper API provides access to many networking functions, including the networking interface and adapter tables. 

There is a one-to-one correspondence between the interfaces and adapters on a given system.  Interfaces are protocol level abstractions (e.g. Ethernet, PPP, Token Ring), while adapters can be thought of as an abstraction of the hardware (although there can be software adapters like the loop-back interface, for example).  For the purposes of this paper, both of these abstractions contain some information we are going to need to determine the state of the adapter and intern the state of the connection.

Routing Tables

The routing table provides the key to determining which adapter will be used on a system that has more than one adapter.  The routing table manager controls the central repository of routing information for IP and IPX protocols (plus any routing protocols that operate under Routing and Remote Access Service).  The manager determines the best route to each network for which it is aware by matching the most specific destination address table entry with the target destination address, the connection with the best metrics, and protocol priorities.  In Microsoft Windows* XP, wireless connections automatically receive a higher (slower) interface metric than a wired LAN connection.  This setting can be manually adjusted in the Advanced settings tab of the TCP/IP network properties dialog in the Windows* XP operating systems.  Only Windows XP automatically sets the interface metric.  All previous versions of the Windows operating system must be manually configured to give wired connections a higher priority.

For example a simplified routing table may look like this:

 

 Network Destination  Mask  Interface  Metric
 0.0.0.0  0.0.0.0 Wired LAN Network card  20
 127.0.0.0  255.0.0.0 Loopback Interface  1
 0.0.0.0  0.0.0.0 Wireless Network card  30
 134.135.96.122  255.255.255.255  Loopback Interface  1

 

To send data to 134.231.112.90, the routing table manager will first look at the most specific table entry (the mask with the most bits filled in), in this case 134.135.96.122.  If this does not match, the routing table manager will then apply the mask 255.0.0.0, and determine if the first part of the IP address is 127, which it is not.  Now the routing table manager must look at the two least specific (general usage) interfaces, the Wired and Wireless network cards.  A Windows XP system, automatically configures these adapters so that the metric for the wireless is greater than the metric for the wired.  In this case the Wired card has a metric  of 20, which is less than 30, so the routing table manager will use the wired LAN card.

To view the routing table on your computer, from the command prompt type: route print


Libraries and Services Available

The easiest way to implement network detection is not to implement it yourself.  Microsoft and Intel provide services and libraries that already implement most of the features discu ssed in this paper.  If these tools suit your needs, you can avoid the time and effort of having to implement your own solution.

System Event Notification Service (SENS)

Microsoft Windows 2000* includes the System Event Notification Service (SENS) to solve many mobile application issues.  The SENS API, distributed with the Platform SDK, provides a simple function call for checking if the network connection is alive and another that will ping a specified address for you.  In addition to these simple functions, you can also register with the service to receive events when a connection is made or lost, a destination can be pinged, or when the system changes power state (battery on, AC ON, or battery low).

For reference the API’s for SENS are:

 

   IsNetworkAlive   (lpdwFlags)
   IsDesitinationReachable (lpszDestination, pQualityOfSeviceInfo)



The event objects are:

   ISensLogon:   Logon, Logoff, display locked, display unlocked, screen saver on, screen saver off
   ISensLogon2:   Fast user switching (sessions) logon/logoff.
   ISensNetwork:  Connection Made / Lost, Destination reachable, Destination reachable no QOS
   ISensOnNow:  AC Power ON, Battery ON, Battery Power Low

 

There is a very good sample for implementing a network detection application at:
http://support.microsoft.com/?id=321381*

The SENS API’s are easy to use and provide a lot of good functionality for the mobile developer. It does have a few limitations that should be considered before using this API.

  • SENS is a Windows service and as such, must be running to function properly. On a default Windows XP system this service should be installed and running. However, a user can disable the service if they wish.
  • IsDestinationReachable pings the specified remote address. This API will not work through a firewall or for sites that do not respond to ping requests. If an address is not reachable, the function will not return for 7 seconds. This API provides the only method for determining the initial connection speed until the state changes and you receive a notification.
  • SENS can take as long as 5 minutes to report connection state changes. VPN connect/disconnect and unplugging of network cable reporting is instantaneous.
  • SENS has no method for distinguishing a wireless connection from a wired connection.

 

Intel Network Detection Library

Available with a Non-Disclosure Agreement (NDA) with Intel, the Intel Network Detection Library provides a simple C interface API for determining the state, type (wireless, wired LAN, modem), and speed of the network connection.

For reference some of the API’s available in this library include:

  • INetGetConnectionSpeed(pulSpeed) : Returns the network connection speed of the current active Internet connection.
  • INetGetConnectionInfo(strDestIPAddress, pInfo) : Returns information about a the network connection that would be used to reach the provided IP address.
  • INetIsConnectionAvailable(strDestIPAddress) : Returns true if an adapter is connected and the route table will use that adapter for the specified IP address.

 

The information returned about the connection includes:

The Intel Network Detection Library involves only a few simple C-style API calls to get a lot of information about the network connection. The library does have a few limitations that should be considered before using this API.

  • It does not provide any notification infrastructure to notify your application when the connection state changes. It can only tell you state of the connection at the time the functions are called. An application could implement this functionality internally by calling the Intel Network Detection Library APIs from a thread that polls the network.
  • It does not actually ping the network. It tests the status of the adapter and verifies the route table for the address, but the remote server can still be unavailable, and hence a connection with that server will not be possible.

 


Implementing Network Detection

This section describes how to implement your own network detection code in your application using the Windows Platform SDK and Microsoft’s IP Helper API. Note that to simplify the code in this document, buffer allocations and a lot of basic good programming practices are not shown. For example: return value error checking, NULL pointer checking, ASSERTs, etc.

Finding the right adapter

The first step in network detection is to identify the correct adapter and connection. This process begins by getting a list of all adapters and interfaces on the system:

 

    // Get Adapter Table
    GetAdaptersInfo(pAdapterTable, &ulAdapterTableSize);
    
    // Get the network Interface Table
        GetIfTable(pIfTable, &dwIfTableSize, TRUE);

 

We now have a lot of information about all the network adapters and their associated interfaces on the system. Next, we ask the routing table manager to determine the best interface for the specified IP address by making a call to IP Helper function GetBestInterface:

 

	unsigned long dwBestIfIndex = 0;

	IPAddr dwDestAddr = (IPAddr) inet_addr(strDestIPAddress);

	// Get the route table information
	if (GetBestInterface(dwDestAddr,&dwBestIfIndex) != NO_ERROR)
		return false;

 

On a Windows XP system, GetBestInterface will by default prefer wired connections over wireless. So we have the preferred interface index now (dwBestIfIndex), but we still need to find that interface associated with that index in the interface table:

 

MIB_IFROW * pCurInterface = NULL;
for (DWORD dwArrayIndex = 0; dwArrayIndex < dwIfTableSize; dwArrayIndex++)
{
    if (pIfTable->table[dwArrayIndex].dwIndex == dwBestIfIndex)
    {
    pCurInterface = &pIfTable->table[dwArrayIndex];
    break;
    }
}

if (!pCurInterface)
     return false;

 

Now that we have the best interface, we need to locate the adapter that belongs to that interface. Note that there is a one-to-one relationship between adapters and interfaces, so the next step just requires a bit of searching:

 

IP_ADAPTER_INFO * pCurAdapter = &pAdapterTable[0];
while (pCurAdapter && (pCurAdapter->Index != dwBestIfIndex))
{
	pCurAdapter = pCurAdapter->Next;
}

if (!pCurAdapter)
	return false;

 

Getting the Connection Status and Speed

In the previous section we saw how to locate the adapter and interface. In this section we will extract the information. Begin with the easy ones:

Connection speed: It is ether the maximum speed of the network card or the actual speed of serial (modem) connection.

dwSpeed= pCurInterface->dwSpeed;

Connection Status:

 dwStatus= pCurInterface->dwOperStatus;

The interesting status values are:

 

   MIB_IF_OPER_STATUS_OPERATIONAL This is what most LAN adapters return when they are connected and functioning properly 
   MIB_IF_OPER_STATUS_DISCONNECTED  This is what you will see if the network cable is disconnected for LAN adapters, or for a modem when it receives a NO CARRIER.
   MIB_IF_OPER_STATUS_CONNECTED This is the state a functioning modem connection will be in. All other states are not connected.  
  All other states are not connected.  

 

Getting the Connection Type 

The connection type requires a bit more work, because the information reported in the interface and adapter tables may not be sufficient to distinguish between a wired and wireless LAN connection. To get the most accurate data we have to ask the device driver for the adapter itself. This can be done using the function DeviceIoControl to send the OID_GEN_PHYSICAL_MEDIUM request to the driver. Most wireless network cards, and certainly the Intel® PRO/Wireless cards, will return the NdisPhysicalMediumWirelessLan value from this call. Here is an example of obtaining the adapter type:

HANDLE hDevice = INVALID_HANDLE_VALUE;

// Build the path to the device
char szDevPath[MAX_ADAPTER_NAME_LENGTH + 8];
wsprintf( szDevPath, ".\%s", &pCurAdapter->AdapterName[0] );

// Open the device for reading
hDevice = CreateFile(   szDevPath,  0, FILE_SHARE_READ,
                (LPSECURITY_ATTRIBUTES) NULL,

                           _EXISTING, 0, (HANDLE) INVALID_HANDLE_VALUE);

if (hDevice == INVALID_HANDLE_VALUE)
    return false;

// Query the device for its type
NDIS_OID    OidCode = OID_GEN_PHYSICAL_MEDIUM;    
ULONG       ulOidPhysicalMedium=0;
ULONG       ulBytesReturned=0;
bool bResult = (bool) DeviceIoControl( hDevice, 
                IOCTL_NDIS_QUERY_GLOBAL_STATS,
                &OidCode,
                sizeof(NDIS_OID),
                &ulOidPhysicalMedium,
                sizeof(ULONG),
                &ulBytesReturned, NULL );

// Close the device
CloseHandle(hDevice);

 

In this sample code, if the command succeeded, ulOidPhysicalMedium will be set to one of the following values:

 

NdisPhysicalMediumWirelessLan
NdisPhysicalMediumCableModem
NdisPhysicalMediumPhoneLine
NdisPhysicalMediumPowerLine
NdisPhysicalMediumDSL
NdisPhysicalMediumFibreChannel
NdisPhysicalMedium1394
NdisPhysicalMediumWirelessWan

 


Conclusion

Determining the network connection state can be as simple as making a single function call or may require a bit more coding if more detail about the connection is needed. On mobile platforms, the speed and type of the network connection can change in an instant. To provide the best user experience possible, application developers must design applications to be aware of their network environment and to adapt to the changes in the network communications.


Resources