Wednesday, February 18, 2009

Enable/disable WiFi with the .NET Compact Framework

In my first compact framework blog entry I want to show you how to programmatically enable and disable wifi on your device.
When I started programming for Windows Mobile I was surprised how much isn't directly available in the .NET compact framework but has to be accessed with function calls in the coredll.dll. I thought that something basic like controlling the volume or enabling/disabling the phone/bt or wifi is easily to do... but it isn't.

Here are the steps you have to perform to control the wifi device:
1. Get the name of the wifi device. It is located in the registry: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\State
Because there are more than just one values we are looking for the first subkey in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\State\Suspend which is on my device "{98C5250D-C29A-4985-AE5F-AFE5367E5006}"
Now, to get the complete name, let's find the first value in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\State which contains {98C5250D-C29A-4985-AE5F-AFE5367E5006}. This is on my Diamond "{98C5250D-C29A-4985-AE5F-AFE5367E5006}\TNETW12511"
This may sound a bit unreliable but it worked on all devices I saw ;-)
2. If we have found the correct name we call the coredll function SetDevicePower
3. Because on iPAQ devices everything works different, we have to call some other functions as well: iPAQSetWLANRadio which is located in ipaqutil.dll

Now here is the example:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32;
 
namespace WifiTest
{
    public class WiFiCtrl
    {
 
        #region PInvokes
        [DllImport("ipaqutil.dll", SetLastError = true)]
        private static extern bool iPAQSetWLANRadio(ref int status);
 
        [DllImport("iPAQUtil.dll", SetLastError = true)]
        private static extern bool iPAQGetWLANRadioStatus(ref int val);
 
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern int SetDevicePower(string pvDevice, int dwDeviceFlags, DevicePowerState DeviceState);
 
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern int GetDevicePower(string pvDevice, int dwDeviceFlags, ref DevicePowerState DeviceState);
        #endregion
 
        private enum DevicePowerState : int
        {
            Unspecified = -1,
            D0 = 0, //Full power
            D1,
            D2,
            D3,
            D4, //Unpowered
        }
 
        private const int POWER_NAME = 1;
        private const int POWER_FORCE = 4096;
        
        private static string GetDeviceName()
        {
            //Get the device name from the registry
            string target = "";
            RegistryKey TheKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Power\\State\\Suspend", false);
            if (TheKey != null)
            {
                string[] subkey = TheKey.GetSubKeyNames();
                target = subkey.GetValue(0).ToString();
                TheKey.Close()
            }
            RegistryKey rk = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Power\\State");
            if (rk != null)
            {
                foreach (string items in rk.GetValueNames())
                {
                    if (items.Replace(target, "") != items)
                    {
                        rk.Close();
                        return items;
                    }
                }
                rk.Close();
            }
            return "";
        }
        
        public static bool IsEnabled()
        {
            //Checks if the WiFi is enabled or disabled
            try
            {
                int i = -1;
                if (iPAQGetWLANRadioStatus(ref i))
                {
                    if (i == 1)
                        return true;
                    else if (i == 0)
                        return false;
                }
            }
            catch { }
            string tmp = GetDeviceName();
            if (tmp.Length > 0)
            {
                DevicePowerState x = new DevicePowerState();
                GetDevicePower(tmp, POWER_NAME | POWER_FORCE, ref x);
                if (x == DevicePowerState.D0)
                    return true;
                else
                    return false;
            }
            return false;
        }
        
        public static void ToggleWifi()
        {
            //Enables/Disables the WiFi device
            
            //Default values -> Enable WiFi
            int NewI = 1;
            DevicePowerState DevP = DevicePowerState.D0;
            if (IsEnabled())
            {
                //WiFi is already enabled -> disable it
                NewI = 0;
                DevP = DevicePowerState.D4;
            }
            try
            {
                iPAQSetWLANRadio(ref NewI);
            }
            catch
            { }
            string tmp = GetDeviceName();
            if (tmp.Length > 0)
            {
                SetDevicePower(tmp, POWER_NAME | POWER_FORCE, DevP);
            }
        }
    }
}

Labels: , , ,

Tuesday, February 17, 2009

My new blog

Welcome!
Yesterday I opened my own forum, today I'm starting my own blog.

I just wanted to do some Windows Mobile blogging which contains help for PocketPC developers. I know there are tons of blogs out there but if you're doing Windows Mobile programming it's so hard to find all the necessary information. For some problems I even needed months to find a solution...

So basically this is a collection of my collected and own knowledge about doing some deeper interaction with Windows Mobile...

Have fun with it! It will be filled soon!

Labels: ,