Device provisioning with XML

I guess this post is loosely related to deployment – I’ve been working on another customer question today around pre-configuring a VPN connection to use IPSec pre-shared keys. One of the really useful features of Smartphone that made it to Pocket PC 2003 is the Configuration Manager feature. This lets you configure pretty much any aspect of your device using simple wap-provisioning XML through the Configuration Manager on the device. There are several well defined areas such as pocket IE favourites, dial-up networks, WiFi networks, VPN, GPRS, proxies and so on. In addition to the well defined configuration settings, you can also just go ahead and party all over the registry. On the device, Configuration Manager examines the XML and uses registered Configuration Service Providers (CSPs) modules to do the dirty work of changing settings. The list of CSP’s is, of course, extensible.

So what does this xml look like? This is the piece I built for creating the VPN entry:

<wap-provisioningdoc>

  <characteristic type="CM_VPNEntries">

  <characteristic type="NEWVPN">

         <parm name="SrcId" value="{436EF144-B4FB-4863-A041-8F905A62C572}"/>

         <parm name="DestId" value="{A1182988-0D73-439e-87AD-2A5B369F808B}"/>

         <parm name="Phone" value="vpn.customer.com"/>

         <parm name="UserName" value="user123"/>

         <parm name="Password" value="test"/>

         <parm name="Domain" value="mydomain"/>

       <!-- Determins the type of authentication e.g. IPSec vs PPTP -->

   <parm name="Type" value="1"/>

 <!-- Determins the type IPSec encryption, either pre shared key or cert based -->

 <parm name="IPSecAuth" value="1"/>

   <!-- pre shared key can be 256 chars long, but must be ASCII -->

  <parm name="PresharedKey" value="1234567890"/>

       <parm name="Enabled" value="1" />

      </characteristic>

   </characteristic>

</wap-provisioningdoc>

Let me take you through it briefly (the docs are pretty reasonable around this feature so go look it up in Pocket PC SDK docs for more detail):

The first characteristic defines the time of CSP used – in this case VPN configuration.

Next is the name of this entry, so when you look in setting on the device you will see this name on the VPN tab.

VPN connections in general provide a bridge from one network type to another e.g. Internet to Work. SrcId and DestId are GUID’s that refer to a list of network types held in the device (again extensible) and denote what networks this VNP bridges between. In this case SrcId refers to the pre-defined Internet value and DestId refers to the pre-defined Work value.

Then there is the Phone setting denoting the entry point URL, user name, domain and password which are all pretty self explanatory.

Type denotes if the VPN connection uses PPTP (value 0) or IPSec (value 1).

IPSecAuth denotes either cert based authentication (0) or pre-shared key authentication (1).

PresharedKey denotes the value of the key. My customer question was how long the key can be: the docs indicate 256 ASCII chars and the screen dialog is limited to that size as well. For practicality I guess this key could accept a base64 encoded key of about 170 bytes.

Enabled indicates that this setting is available.

Once you have your XML file how do you throw it at Configuration Manager? Fortunately there are lots of ways:

Check out the RapiConfig tool that comes with Pocket PC 2003 SDK (and the Smartphone SDK as well). Standard install puts it here: \program files\windows ce tools\WCE420\Pocket PC 2003 SDK\Tools. Attach a device via USB / Serial and setup and ActiveSync connection. Run RapiConfig /P <myxml.xml> and it will apply the settings. Quite a useful tip when writing your XML, try running a query against the device first to see what settings are there already – it’s a great way to get started. Queries are formed with <characteristic-query> or <parm-query> xml for example:

<wap-provisioningdoc>

   <characteristic-query type="CM_VPNEntries"/>

</wap-provisioningdoc>

And running them is exactly the same. This example gives a full list of VPN settings.

All that RapiConfig is doing it to call a system API remotely and extract the results to the desktop. The DMProcessConfig api can be used directly buy your code in the device but there is one small gotcha! If you want to call this api from managed code, be aware the API allocates the return buffer using the C++ “new” function so your code is in sever danger of leaking unless you can call the C++ delete operator (or the ‘free’ runtime function as delete defers to free in its implementation). Here is a sample (see left bar for disclaimer for this code):

using System;

using System.IO;

using System.Runtime.InteropServices;

using System.Windows.Forms;

using System.Text;

namespace XMLConfig

{

      /// <summary>

      /// Summary description for DMProcessConfig.

      /// </summary>

      public class DMProcessConfig

      {

            [DllImport("aygshell.dll")]

            private static extern int DMProcessConfigXML(string pszWXMLin, int dwFlags, IntPtr ppszwXMLout);

            [DllImport("coredll.dll")]

            private static extern void free(int buffer);

            public DMProcessConfig()

            {

            }

            unsafe static public bool ProcessXML(string Filename)

            {

                  StreamReader sr = new StreamReader(Filename, Encoding.ASCII);

                  string XML = sr.ReadToEnd();

                  fixed (int * OutPtr = new int[1])

                  {

                        IntPtr outptr = (IntPtr)OutPtr;

                        try

                        {

                              int result = DMProcessConfigXML(XML, 1,outptr);

                              if (result !=0)

                              {

                                    MessageBox.Show("Failed");

                              }

                              else

                              {

                                    free(*OutPtr);

                              }

                        }

                        catch(Exception e)

                        {

                              MessageBox.Show(e.Message);

                        }

                  }

                  return true;

            }

      }

}

 

There are a couple more ways to get XML running on the device. The first is over the air (OTA) provisioning but I haven’t done anything with OTA so let’s leave that for a bit. The second is through the new “.cpf” file. A CPF file is simply a CAB file that contains just one file _setup.xml. The CPF extension is associated with WCELoad.EXE (just like a standard CAB file), when a CPF file is opened the xml is extracted and thrown at Configuration Manager. The whole operation is silent except for a notification mail that appears in the user’s inbox indicating success or failure.

Building a CPF is pretty straight forward:

1> Take your xml file and rename it to _setup.xml

2> Go into the Pocket PC tools directory as above

3> Type MakeCab.exe /D COMPRESS=OFF _setup.xml myOutCpf.

The COMPRESS=OFF is needed for Pocket PC because WCELoad doesn’t support compressed cab’s (yet!). Next copy your CPF to a device nearby and click on it in explorer. Hey presto, XML is applied.

There are some things not quite perfect about configuration manager with probably the most annoying being lack of WiFi WEP key provisioning, but it is a great feature that I use lots for application deployment.

Marcus