Chris Tacke
OpenNETCF Consulting
July 24, 2005
In today’s world of mobile and embedded devices, wireless Ethernet (or Wi-Fi) network adapters are becoming commonplace, and wireless hotspots are nearly ubiquitous in most technology savvy locations.
Unfortunately being able to discover or “sniff out” available wireless networks on a Windows Mobile device with the standard user interface isn’t straightforward, and Windows CE’s built-in Wireless Zero Configuration (WZC) API set is completely undocumented.
So what are we as embedded developers to do? In this article I’ll show you how we can leverage a robust shared-source (not Open Source) library from OpenNETCF.org to write a feature-rich application for displaying network adapter properties and discovering nearby wireless access points (APs) with only about 200 lines of hand-typed code – and that includes comments, white spaces and brackets.
Any time you introduce third-party software into your solution you must do some analysis of the benefits and risk of usage, so before we look at the application let’s take a quick look at OpenNETCF.org, the Smart Device Framework and the OpenNETCF Shared Source License.
First, OpenNETCF.org is a project run by OpenNETCF Consulting, LLP. It was started “in the spirit of the Open Source Movement” to provide solutions to problems that the Compact Framework development community began running into from the first beta releases.
The primary product of the OpenNETCF.org project is known as the Smart Device Framework or SDF, which is an extensive set of classes that complement the .Net Compact Framework (version 1.0 and 2.0 compatible). It provides many of the classes, properties and methods that are available in the full .Net framework, plus a large complement of classes that are specific to the Windows CE environment.
Essentially it’s a framework that allows Compact Framework developers to provide more feature-rich solutions with less time to market than with the Compact Framework alone. Best of all you get the full source code, it’s 100% free and the distribution license is very friendly.
As I said, the OpenNETCF Shared Source License is very friendly. I won’t cover it in detail here – just the highlights. However it’s only one page long, written in very simple language, and has been reviewed by legal teams of multi-billion-dollar companies and found to be acceptable for use. I highly encourage you to review the license yourself (www.opennetcf.org/license) but if you were to distill it down further it would read something like this:
“You are free to use and distribute the OpenNETCF Smart Device Framework with your application provided you add some significant value to the end product. You can use as much or little as you would like. You can distribute the OpenNETCF assemblies as provided or take the source and roll it into your own product. We simply ask that somewhere in the documentation for the product you state that you used it. About the only restriction is that you cannot simply compile and sell the framework as a stand-alone product. You also can’t hold us responsible for problems due to usage.”
The SDF has been downloaded nearly 200,000 times, is nearly 2 years old and in complete form is nearly as large as the Compact Framework 1.0. This means it’s been tested to a degree, but keep in mind it’s a community project so it’s unlikely to be bug-free and some areas have gotten more development attention than others.
Now that we’ve covered the risks (what there are of them anyway), let’s look at the huge benefits the SDF provides.
For our application we’ll be using only a single namespace from the SDF: OpenNETCF.Net. The source code is roughly 3800 lines, so immediately we can see that if the code works (we’ll see that it does), then if we use most of it (and we will) then using it could potentially save weeks of development.
The namespace contains a large number of classes for network usage, including FTP, network statistics and Bluetooth but for this article we’re going to focus on four classes: the Adapter and the AccessPoint plus the AdapterCollection and AccessPointCollection, which are, as their names imply, collection classes of the previous two.
Figure 1 is a simple class diagram of the classes.

Figure 1 – The Adapter, AccessPoint and Associated Collection Classes
The Adapter class represents any Ethernet-compatible network adapter in the system. This can be a wired or wireless network card or anything else that presents an Ethernet layer to NDIS, such as an active ActiveSync connection over USB, serial or IrDA.
As you can see in Figure 1, the Adapter class presents a large number of properties, most of which describe either IP configuration items (like IP address, Gateway and Subnet Mask) or wireless connection information such as signal strength.
In our sample we’ll use the Adapter class to present the commonly used adapter configuration information for any adapter – wireless or not.
The AdapterCollection is simply a CollectionBase-derived class that provides a container for Adapters returned by a call to Networking.GetAdapters. Let’s take a look at how this works.
First, we need to get a list of all NDIS adapters the device has, which comes in the form of an AdapterCollection returned from Networking.GetAdapters. When the test application starts up, we get a list by calling UpdateAdapters, which gets the AdapterCollection and populates a ComboBox with the Adapter Names:
void UpdateAdapters()
{
// get the available adapters
m_adapters = Networking.GetAdapters();
// clear the combo
cboAdapters.Items.Clear();
// add the adapters
foreach (Adapter adapter in m_adapters)
{
cboAdapters.Items.Add(adapter);
}
}
Every time the user changes the selected (or current) Adapter,
the UI is updated with the selected Adapter’s configuration information by a
call to UpdateConfig
void UpdateConfig()
{
tabConfiguration.SuspendLayout();
// update the adapter's configuration info
lblMACAddress.Text =
BitConverter.ToString(m_currentAdapter.MacAddress);
lblIPAddress.Text = m_currentAdapter.CurrentIpAddress;
lblSubnet.Text = m_currentAdapter.CurrentSubnetMask;
lblGateway.Text = m_currentAdapter.Gateway;
// wireless info
bool wireless = m_currentAdapter.IsWireless;
if (wireless)
{
lblIsWireless.Text = "True";
lblWZCCompat.Text =
m_currentAdapter.IsWirelessZeroConfigCompatible.
ToString();
}
else
{
lblIsWireless.Text = "False";
lblWZCCompat.Text = "N/A";
}
// DHCP info
bool dhcpEnabled = m_currentAdapter.DhcpEnabled;
if (dhcpEnabled)
{
lblDHCPEnabled.Text = "True";
lblLeaseObtained.Text =
m_currentAdapter.LeaseObtained.ToShortDateString();
lblLeaseExpires.Text =
m_currentAdapter.LeaseExpires.ToShortDateString(); ;
mnuRenew.Enabled = true;
}
else
{
lblDHCPEnabled.Text =
"False";
lblLeaseObtained.Text =
"N/A";
lblLeaseExpires.Text = "N/A";
mnuRenew.Enabled = false;
}
tabConfiguration.ResumeLayout();
}
Figure 2 shows the Configuration Tab of our sample application running on an iPAQ H5555 device. The selected Adapter is the built-in 802.11b controller. When connected via ActiveSync, the ActiveSync connection itself is done through TCP/IP and will also enumerate as an Adapter.

Figure 2 – Adapter configuration info for the built-in 802.11b adapter in my HP iPAQ H5555
For our WiFi discovery goal, the important Property here is IsWirelessZeroConfigCompatible. If a wireless adapter in not WZC compatible, then most of its properties are accessed through proprietary API calls, that are often not documented or published, leaving us as developers largely out of luck as far as custom implementations or software. However, if an adapter is WZC compatible (more and more are any more) then we can use a standard set of Windows APIs to get a large amount of information about the adapter and the network access points it “sees.”
As I mentioned before, the WZC APIs are not formally documented, but Microsoft Platform Builder comes with the source code for the default network UI that connects to WZC-compatible adapters, and as such it provides a way – albeit non-trivial – to see how the APIs work and these APIs are available in a friendly form through the OpenNETCF.Net.AccessPoint class.
The primary node of interest in a wireless network is the access point (AP), and when working with APs for a specific adapter there are two general categories that they fall into: APs that the adapter can see right now, and APs that it has seen in the past and that it will give preferential treatment if it sees them again. These lists are usually different, but will often contain some of the same APs in both. In the AccessPoint class, these are defined as NearbyAPs and PreferredAPs (often referred to as “available”) respectively. The third term for an AP of importantance is the Associated AP, which is the AP we’re currently running our network traffic through. It’s quite possible to have no AssociatedAP, for instance if we’re not in range of any AP, but if we are associated then the AssociatedAP, obviously, is always in the list of NearbyAPs.
In our sample we get and display both lists, Preferred and Available. For those
APs that our currently selected adapter sees, we list the signal strength in decibels (SSID) as well as a friendlier text version like “Excellent”, “Good”, “Fair” or “Poor”.
You can see in Figure 3 that right now in my house I have two available access points, both of which have excellent strength (being less than a foot from the APs helps). The AccessPoint class also has a few other properties to provide information on its capabilities and privacy.

Figure 3 – Available (nearby) wireless networks
The whole idea behind the Compact Framework and managed code in general is developer productivity. High productivity means faster time to market and richer feature sets. It means lower cost solutions, lower opportunity costs and more resource availability for other projects.
While the sample application we covered here isn’t as robust as a full-up wireless application could be – for example it doesn’t have nice icons for the AP infrastructure and the ability to change AP associations – it does prove the point of productivity. By leveraging a free shared-source library we’ve created a pretty nice WiFi discovery application with less than 200 lines of typing. It shows all adapters available, for wireless adapters it shows all available and preferred access points, along with the signal strength of them, and as a bonus “nugget” I’ve included the seven lines of code to renew any adapter’s DHCP address (and it would have been only one if I hadn’t added some UI niceties).
Managed code isn’t the solution to every business problem, and C/C++ definitely has its place, but in today’s fast paced business climate we, as developers, must always work to provide our customers more for less. Managed code, coupled with the Rapid Application Development tools available with Visual Studio 2005, provides a solid base for us to successfully compete in the marketplace.