Spotlight on Connection Manager

clip_image002

Windows Mobile provides a very powerful, but often misunderstood, abstraction layer called Connection Manager. Connection Manager is responsible for managing all the possible networks a device may expose and transparently brokering them out to applications. On a mobile device, connections come and go… and when they come, they do so various forms …cellular, WiFi, Desktop-Pass-Through (via USB or Bluetooth), etc. The possibilities are vast because we have a very flexible platform and device makers are free to integrate all kinds of communication sources. Even if we consider a single cellular network, there may be multiple network paths an application uses to make network requests…that’s where thing can get a little confusing and developers (as well as end users) often start asking questions. Consider that an operator may use multiple APNs to secure or control communications… or that they may have a generic mobile portal for content that is filtered through a WAP proxy. How does all this work transparently to a connected application like Internet Explorer or custom ISV application? Developers shouldn’t have to write code to deal with all the scenarios… and that’s why we have Connection Manager. In a perfect world, you never even know it’s there… it “just works”.

Connection Manager is too complex to cover in any single post, but I wanted to touch on a couple of things. Marcus Perryman has written several excellent articles on the topic and blogs about it every so often.

My first experience with Connection Manager was like many developers. I was utterly perplexed. I came from the world of desktop/server computing where networks were fairly consistent. I setup TCP/IP, maybe a proxy, and that was it. Most desktop apps can now safely assume a connection is going to be there. Mobile apps are not so lucky, but the good news is that Connection Manager does a lot of the work for you.

The more I thought through the connectivity challenges of a mobile device, the more I began to appreciate what CM provides. How do you transparently broker a bunch of potential networks to applications? One could assume that there may be multiple valid networks to get to an internet resources, so priority might be one approach. Another factor might be that specific types of requests would need to be use specific networks… for instance, maybe all wap:// or mms:// requests would need to be bound to a specific operator network. Another requirement might be that you would want to bind intranet requests to a local network and extranet requests to an external network.

To understand how CM approaches these problems on any specific device, you just have to look into the CM plumbing. That’s all the configuration data that tells CM how to make decisions based on configured networks. The problem… well, it’s mostly invisible. Only a very small percentage of configuration info is exposed in the WM user interface (networks, proxies, etc.). Most of the important stuff (mapping, plans, etc.) is only configured and exposed via CSPs. I should emphasize that in most cases, you never need to know about how it all works. Operators generally configure connection behavior of a device before it goes to market via Provisioning Connectivity Settings. It would take a while to go through all of these and how they play into things, but there are a few key questions that come in development scenarios that will lead you into all of this…

· How does the platform differentiate what routes to a “Work” connection vs. an “Internet” connection?

· When do I have to establish a connection in my code vs. letting the platform do it?

· Why can my application make a successful network request after I use Internet Explorer but fails otherwise?

· When I configure a connection exception in the UI, what really happens?

· Why does my internet application behave strangely and fail on some devices and operator networks?

· How does WM prioritize networks?

I said earlier that Connection Manage is an abstraction layer, so it hides the physical network hardware from you and exposes everything via virtual networks, or “meta-networks”. The Windows Mobile SDK provides quite a bit of documentation on Connection Manager. It’s not terrible easy to read since it’s totally abstract, but it’s a start. A few things you will want to look at to make sense of all this…

The CM_Networks CSP configures metanetworks, destination networks to which multiple connectivity objects and proxy or Virtual Private Network (VPN) connections can connect. This is basically the end of the plumbing path for network requests on a WM device. These represent the networks that are available to the device… everything else in the CM plumbing is designed to help your app get here easily and do so transparently.

 

The CM_Planner CSP sets/queries the “preferred” connections for Connection Manager. Suppose you have multiple networks that can get you to a destination… CM_Planner configures criteria and sets the “default” selection to help CM make a good decision when there are several comparable paths.

 

The CM_Mappings CSP is how CM determine which types of request go to a specific network. It does this by pattern matching the request string against a wildcard filter string that you attach to a network GUID. This is how a device differentiates a “Work” request from an “Internet” request. By default, anything with a “.” (dot) in it gets routes to the “Internet” GUID. This is done by a mapping that is added for any string that matches the wildcard “*://*.*/*”. This is also how we make decisions about which requests to route to the “Work” meta-network…simply adding a mapping for “*://*/*” and mapping it to the “Work” GUID. Sometimes a device make have a filters to route MMS, WSP, WAP, etc. If you find a scenario where requests always seem to be routing to the a network you don’t expect, check the mappings.

CM_Mappings is also how CM handles network “exceptions”. This comes up quite a bit when someone wants to use a device on a corporate intranet (typically the “Work” network) with fully qualified domain names. Remember, by default, anything with a “.” in the name/URL gets sent to the Internet. If you are using FQDNs on your intranet, then you won’t want that. When you add “Work URL Exception”, you are actually adding a mapping for the fully qualified name to use the “Work” GUID. For example if we queried the mappings for a device with a URL exception for “expenses.mycorp.com”, it might look like this:

clip_image004

The query <wap-provisioningdoc>
<characteristic-query type="CM_Mappings" recursive="true"/> </wap-provisioningdoc>

 

The result

<wap-provisioningdoc>

  <characteristic type="CM_Mappings" recursive="true">

    <characteristic type="16777216">

      <parm name="Pattern" value="*://expenses.mycorp.com/*"/>       <parm name="Network" value="{A1182988-0D73-439E-87AD-2A5B369F808B}"/>     </characteristic>

    <characteristic type="536870912">

      <parm name="Pattern" value="wsp://*/*"/>

      <parm name="Network" value="{7022E968-5A97-4051-BC1C-C578E2FBA5D9}"/>

    </characteristic>

    <characteristic type="553648128">

      <parm name="Pattern" value="wsps://*/*"/>

      <parm name="Network" value="{F28D1F74-72BE-4394-A4A7-4E296219390C}"/>

    </characteristic>

    <characteristic type="570425344">

      <parm name="Pattern" value="*://*.*/*"/>       <parm name="Network" value="{436EF144-B4FB-4863-A041-8F905A62C572}"/>     </characteristic>

    <characteristic type="587202560">

      <parm name="Pattern" value="*://*/*"/>

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

    </characteristic>

  </characteristic>

</wap-provisioningdoc>

You could take it a step further and query CM_Networks on the emulator to examine the available networks, we would see that the Work GUID matches the GUID we mapped the requests to in the mappings exceptions. Similarly, you would see that the mapping for *.* (fully qualified domain names) maps to the Internet GUID. All we’ve done is to map specific URL requests to specific networks.

<characteristic type="CM_Networks" recursive="true">

    <characteristic type="My Work Network">

      <parm name="DestId" value="{18AD9FBD-F716-ACB6-FD8A-1965DB95B814}"/>

      <parm name="Secure" value="0"/>

      <parm name="ReadOnly" value="0"/>

    </characteristic>

    <characteristic type="My ISP">

      <parm name="DestId" value="{ADB0B001-10B5-3F39-27C6-9742E785FCD4}"/>

      <parm name="Secure" value="0"/>

      <parm name="ReadOnly" value="0"/>

    </characteristic>

    <characteristic type="Work">       <parm name="DestId" value="{A1182988-0D73-439E-87AD-2A5B369F808B}"/>       <parm name="Secure" value="0"/>

      <parm name="ReadOnly" value="0"/>

    </characteristic>

  <characteristic type="Secure WAP Network">

      <parm name="DestId" value="{F28D1F74-72BE-4394-A4A7-4E296219390C}"/>

      <parm name="Secure" value="0"/>

      <parm name="ReadOnly" value="0"/>

    </characteristic>

    <characteristic type="The WAP Network">

      <parm name="DestId" value="{7022E968-5A97-4051-BC1C-C578E2FBA5D9}"/>

      <parm name="Secure" value="0"/>

      <parm name="ReadOnly" value="0"/>

    </characteristic>

    <characteristic type="The Internet">       <parm name="DestId" value="{436EF144-B4FB-4863-A041-8F905A62C572}"/>       <parm name="Secure" value="0"/>

      <parm name="ReadOnly" value="0"/>

    </characteristic>

  </characteristic>

 

Connection Manager FAQs and “Gotchas”

 

How does the platform differentiate what routes to a “Work” connection vs. an “Internet” connection?

It’s just a URL mapping. Anything with a “.” (dot) in it is considered an “Internet” request and will route to the Internet connection GUID. Anything without a “.” (dot) is considered “Work” and routes to the Work connection GUID. You can define exceptions to route FQDN request to the Work network. This is all configured in the CM_Mapping CSP and is designed as a simple way to separate intranet traffic from internet traffic.

 

When do I have to explicitly setup a connection in my code?
Managed applications (e.g. - Compact Framework) generally setup connections for you if you use higher level classes like HttpWebRequest…just make your request. This is not the case for lower level managed socket classes like TcpClient and UdpClient. In those scenarios, you would need to P/Invoke to make it happen. If you write a native application, you always need to make sure you establish a connection in your code to ensure connectivity. Check out Jim Wilson’s How-Do-I series for managed apps with Connection Manager and see the CMHELPER SDK sample application for more guidance with native apps.

Why can my application make a successful network request after I use Internet Explorer but fails otherwise?
When any application successfully establishes a connection to a destination network using Connection Manager, the connection is typically kept alive for a period of time and made available to other applications. Internet Explorer uses Connection Manager to establish its connection and that’s why other connected apps will be able to make network requests as long as this connection is still alive.

When I configure a connection exception in the UI, what really happens?

You are just adding a mapping for a specific URL to a specific destination network.

Keep in mind that URL Exceptions only appear in the user interface if the exception ID falls into a specific range. This is documented in the WM SDK under “Using Connection Manager URL Mappings”. 16777216-16842751 Manually entered URL exceptions, sequentially numbered from 0x01000000. There can be up to 65536 entries. Hidden mappings serve as a way to protect the config from end users. This is useful in corporate environments to lock down devices, but tricky for developers who may not know they are there. You can query the CSP to get a full listing of mappings.

Why does my internet application behave strangely and fail on some devices and operator networks?
In most cases, things should “just work”…however, I have seen several scenario where network communication was hampered by operator specific configurations. Most notably, operators like to route all Internet communication through their WAP proxies which can create variety of communication issues if apps don’t expect to be limited.

A recent example….I helped a developer who was reporting a problem with a number of Windows Mobile phones by users attempting to sign in using Live ID on a major web portal. The error?

JavaScript required to sign in

Windows Live ID requires JavaScript to sign in. This web browser either does not support JavaScript, or scripts are being blocked.

Clearly, WM supports Javascript so something else must be going on. On the problem devices, a quick change to disable to WAP proxy instantly resolved the errors. From Internet Explorer, go to Menu->Tools->Options->Connections and disable “Auto-Detect Network” and enable “The Internet”. This tells IE to bypass the automatic mappings that were added by the operator to use WAP for internet requests and route directly to the Internet destination network instead.

If you run into communication errors on a device, it’s always a good idea to test with the emulators first using a cradled connection. This is a very simplistic, clean configuration and removes many of the operator and device variables from the mix. If connections work in the emulator, you can start comparing some of the differences in the CM plumbing to see what is going on.

How does WM prioritize networks?

There are a number of factors that play into how one network is prioritized over another. The greatest factor is probably the concept of security level. In general, if multiple network paths are available, CM will use what it perceives as the “most secure”. Desktop Pass-Through (DTPT) connections are considered the most secure connection, followed by NIC, WiFi, and then cellular network connections. For more information, you can read up Connection Manager Security.

 

Can I tell my application to use a specific connection if I don’t want to CM make all the decisions?

Yes, see Configuring an Application to use a Specific Network

 

When I cradle my device on my desktop, it imports my desktop Proxy and messes up my connections. How do I avoid that?

See Vik’s post here.

Do you have other Connection Manager questions? Let me know…

Cheers,
Reed