Mobile Development - 'Support Side Story'

Broadcasting technical support to Windows Mobile\CE Application Developers to help realizing their potential

Broadcasting technical support to Windows Mobile\CE Application Developers to help realizing their potential

February, 2009

  • Mobile Development - 'Support Side Story'

    Wireless Programming on Windows Mobile: supported or not supported?

    • 10 Comments
    • I can’t take WZC for granted… but, at least, can I programmatically turn WiFi on and off?
    • ossvcs.dll’s Wireless Device Power Management Functions
    • WiFi driver is a Power Manager-controllable NDIS Miniport Driver
    • Introducing: RIL Driver and IP Helper APIs on WM6

    As I mentioned in one of my first posts, WiFi Programming is something that depends so much on the WLAN driver developed by the OEM, that an ISV can’t take for granted some interfaces and develop a WiFi-based application that is device-independent. But if a WLAN driver implements the WZC interfaces, then an ISV developer may technically use WZC APIs, even if this is not supported by Microsoft as it is something OEM-dependent. For example, if you want to do so with managed code, then you must read the MSDN article I had already mentioned Building a Wi-Fi Discovery Application with the .NET Compact Framework 2.0 that Chris Tacke wrote some years ago. Also, make sure not to forget that many settings can be done through the Wi-Fi Configuration Service Provider, *IF* the OEM’s WiFi stack properly integrates with the standard WiFi architecture (i.e. it’s WZC-compatible). Note: I’m saying so because I recently worked on a case where querying the Wi-Fi CSP didn’t return anything even if the driver was loaded and even if there was an open connection, and in this case the relevant OEM had to provide the developer with a specific solution.

    The issue is the following… ok, ISVs are not supported by Microsoft on controlling the WiFi connection by using WZC APIs because Microsoft can’t know what the OEM did with its WLAN driver: but… can at least ISVs use whatever API to even simply do very basic stuff such as programmatically turn it off and on? Does this simple task really depend on how the OEM developed the driver?

    Looking for a solution over the web, you’d find 2 possible approaches, which seem to be OEM-independent:

    1. Use some undocumented APIs exposed by a DLL that is inside every \Windows folder of a WM device (this would also allow to interact with the other wireless radios of the device)
    2. Use Power Manager APIs with the WiFi driver, which is a NDIS Miniport driver controllable by Power Manager (valid for WiFi only)

    {SIDE NOTE. Interestingly… while looking for those, I came across the following post: “The most useful iPhone app I can't release”. I honestly don’t know the Apple iPhone SDK, therefore can’t express myself on it and didn’t know that it “specifically prohibits using private framework API” (assuming that’s true, based on all the comments of that post): it’s simply interesting to know that WiFi Programmers have similar “non-technical” problems with iPhone platform as well. And I’m sure that Android ones benefit from the “oversights” of the other platforms! That’s the beauty of the competition in a market… (side-by-side note: remember that on Windows Mobile you can programmatically control Bluetooth through the Bluetooth CSP).}

    Let’s go back to Windows Mobile and examine the 2 approaches above.

     

    1. Use some undocumented APIs exposed by a DLL that is inside every \Windows folder of a WM device (this would also allow to interact with the other wireless radios of the device)

    This is an incredibly powerful approach, because it gives you the power of controlling the power state of all the wireless “devices”: Bluetooth, WiFi and Radio (i.e. the RIL = “Radio Interface Layer”: it’s the driver responsible for radio data connection (GPRS\EDGE\UMTS\..)). And it’s quite well known in the Mobile Community, we all know that \Windows\ossvcs.dll exposes some APIs (GetWirelessDevices, ChangeRadioState, etc, namely the “Wireless Device Power Management Functions”) that allow to develop your own Comm Manager (or Wireless Manager). And using those functions from within a managed application is even easier than on native applications, where you have to dynamically load the library and get the address of the function exposed with a particular ordinal: with managed apps, you can simply use the EntryPoint element of the DllImportAttribute.

    Now, let’s pose the usual question: IS THIS SUPPORTED BY MICROSOFT TECHNICAL SUPPORT? The answer is simple here… Is it documented in the SDK? No: ergo it’s not officially supported… Or not? Those APIs are there: if the Dev Team didn’t want ISVs to use them then it wouldn’t develop a DLL which exposes them. Since the solution is well known in the Community and proved to work correctly in most cases, my personal opinion is that the problem is with the documentation here, which is simply missing for those APIs. I’ve asked the Product Group to consider adding the documentation in the public WM SDK… let’s see what that’ll sort out.

    Just to be clear, even if one day those Wireless Device Power Management APIs will be fully documented and ready to be used by ISVs, what more can Microsoft Technical Support do after verifying that an ISV used the functions correctly? If those Wireless Device Power Management Functions don’t work correctly with one of the wireless drivers, chances are that the problem is with the driver, not with the functions (considering that the same APIs work correctly in other cases). And who develops the driver and technically has the ability to give support about it? Only the OEM…

     

    2. Use Power Manager APIs with NDIS Miniport driver (valid for WiFi only)

    If you look at pm.h header file of the WM5\6 SDKs, you’ll find a constant, which is is even public for 5.0 here and for 6.x here:

    #define PMCLASS_NDIS_MINIPORT           TEXT("{98C5250D-C29A-4985-AE5F-AFE5367E5006}")

    If you examine the registry contents at [HKLM\System\CurrentControlSet\Control\Power\State], you’ll see “devices” whose power-state can be controlled thru Power Manager APIs, accordingly to the SDK Documentation. One of those devices is the WiFi driver, described as “{98C5250D-C29A-4985-AE5F-AFE5367E5006}\<device name chosen by the OEM>” (The name can be seen also for example in the IPConfig section of the log generated by the Windows Mobile Network Analyzer PowerToy). Since the device appears under that registry key, an ISV can programmatically control its power state by using the documented Power Manager API SetDevicePower():

    [DllImport("coredll.dll", SetLastError = true)] 
    private static extern int SetDevicePower(string pvDevice, int dwDeviceFlags, DevicePowerState DeviceState); 
    
    private enum DevicePowerState : int 
    { 
        Unspecified = -1, 
        D0 = 0, // Full On: full power, full functionality 
        D1, // Low Power On: fully functional at low power/performance 
        D2, // Standby: partially powered with automatic wake 
        D3, // Sleep: partially powered with device initiated wake 
        D4, // Off: unpowered 
    }
    
    private const int POWER_NAME = 0x00000001;

    So, to turn the WiFi ON:

    string driver = Utilities.WiFi.FindDriverKey(); 
    SetDevicePower(driver, POWER_NAME, DevicePowerState.D0);

    And OFF:

    string driver = Utilities.WiFi.FindDriverKey(); 
    SetDevicePower(driver, POWER_NAME, DevicePowerState.D4);

    Utilities.WiFi.FindDriverKey() is simply a function that returns the whole registry key name of the key containing the NDIS MINIPORT class GUID defined in the SDK’s pm.h:

    private static string FindDriverKey() 
    { 
         string ret = string.Empty; 
    
         //#define PMCLASS_NDIS_MINIPORT           TEXT("{98C5250D-C29A-4985-AE5F-AFE5367E5006}") 
         //(From "c:\Program Files (x86)\Windows Mobile 6 SDK\PocketPC\Include\Armv4i\pm.h") 
         string WiFiDriverClass= "{98C5250D-C29A-4985-AE5F-AFE5367E5006}";  
    
         foreach (string tmp in Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Power\\State", false).GetValueNames()) 
         { 
             if (tmp.Contains(WiFiDriverClass)) 
             { 
                 ret = tmp; 
                 break; 
             } 
         } 
    
         return ret; 
    }

    This proved to work on some devices I’ve tested it with, after reboots and also consistently with the Wireless Manager\Comm Manager of the device. I’ve found a forum post stating that on iPAQ devices this approach doesn’t work (and this is in line with the fact that HP provided a DLL within its private SDK exposing specific APIs to interact with their driver), however I tested this approach on an iPAQ Smartphone and it worked as well.

    Now, the usual question: IS THIS SUPPORTED OR NOT BY MICROSOFT TECHNICAL SUPPORT? Every single detail an ISV uses in this approach is documented, hence supported. Cool! But… again, as before… what more can Microsoft Technical Support do after verifying that the ISV used the functions above correctly? If a Power Manager API doesn’t work correctly with a driver, chances are that the problem is with the driver, not with the PM API (considering that the same API works correctly in other cases). And who develops the driver and has technically the ability to give support about it? Again, the OEM…

     

    I hope things are a bit clearer now… just let me know in case that’s not true!

     

    Cheers,

    ~raffaele

     

    P.S.: There’s an interesting point about NDIS Miniport drivers. On WM5, Microsoft's recommendation to OEMs was to implement the RIL Driver as PPP Adapter. Among other things, that allowed developers using IP Helper APIs to easily retrieve the related adapter information because the string "[Cellular Line]" was contained in the Adapter's name, for example thru the GetAdaptersInfo() API. Now, starting on WM6 Microsoft encourages OEMs to implement the RIL as NDIS Miniport driver, because this way the device will be ready to support simultaneous data calls (with PPP you can’t do that): "[...] One advantage of using WWAN-based GPRS connections is the ability to establish multiple GPRS connections simultaneously" (Establishing a WWAN-based GPRS Connection).

    Note that not every single WM6.x device has already the RIL implemented as NDIS Miniport driver, demonstrating once again how OEMs have complete power on this. So, if you use IP Helper APIs or simply look the ipconfig report of the Windows Mobile Network Analyzer PowerToy, on WM6 devices where the OEM hasn’t yet “upgraded” the RIL you’ll still see

    • PPP Adapter [Cellular Line]:
      • Adapter Name ...... : Cellular Line

    while on those WM6 devices where the RIL is already implemented as NDIS Miniport driver

    • Ethernet adapter Local Area Connection:
      • Adapter Name ...... : WWAN1-IBOX.TIM.IT-1 (for example)

    therefore it's no longer distinguished from for example the WiFi connection:

    • Ethernet adapter Local Area Connection:
      • Adapter Name ...... : TNETW12511 (for example)

    At TCP\IP Protocol level (e.g. by using IP Helper API GetAdaptersInfo), on those WM6 devices where the OEM followed Microsoft's recommendations for the RIL there’s no way to distinguish if a connection is WLAN (=WiFi) or WWAN (=RIL). In future I plan to post about another approach, probably based on NDISUIO (“NDIS User-mode I/O”)… I firstly need to be sure I’ll talk about something “SUPPORTED”… (that’s always my #1 priority! Or not? :-)

     

    P.P.S.: Happy birthday to this blog!! THANK EVERYONE FOR READING\COMMENTING\CONTACTING ME, I couldn’t absolutely imagine the success it had in our Community (does it really deserve it? :-), so thanks again!! If you have any suggestion on anything, just let me know!

  • Mobile Development - 'Support Side Story'

    Yet Another Technical Support’s added value: Architectural Guidelines

    • 2 Comments
    • Advisory Services vs Problem\Resolution
    • Architectures for dynamic forms in NETCF

    Many developers out there don’t know the full potential provided by the experts at Microsoft Technical Support… and I really want to do some marketing here!! For example, a typical scenario is as follows: you’ve just taken ownership of a project and don’t know where to start as it’s the first one targeting NETCF and Windows Mobile (just to use a beloved example…). A good investment at this point is to use some Advisory hours your Technical Support contract may have (you may need to be a Partner, probably – just check the //microsoft.com/support website).

    Advisory Services are used to provide suggestions, guidelines, recommendations about how to possibly achieve a goal, so that ISVs can do a conscious choice; those services are something different from “My Visual Studio \ NETCF application doesn’t work as expected: help me on finding what’s wrong”-kind of requests (these are called “Problem\Resolution Services”. The 2 kinds of services are defined as follows:

    "Problem Resolution Services" definition: Microsoft Problem Resolution Services provide assistance for problems with specific symptoms encountered while using a Microsoft product, where there is a reasonable expectation that the problem is caused by the Microsoft product. A Problem Resolution incident is defined as a single support issue and the reasonable effort needed to resolve it. A single support issue is a problem that cannot be broken down into subordinate issues. If a problem consists of subordinate issues, each shall be considered a separate incident. If a problem is determined by Microsoft to be the result of a defect in a Microsoft product, the customer will not be charged for that incident.

    "Advisory Services" definition: Microsoft Advisory Services provides short-term advice and guidance for problems not covered with Problem Resolution Service and requests for consultative assistance for design, development and deployment issues.

    So I really appreciated some time ago a .NET desktop developer asking for initial suggestions about how to develop his form-based NETCF application, where he needed to dynamically create forms and controls. I ended up with the following list of generic suggestions (just to start…, which may be useful for other NETCF Developers out there!

     

    1. Shell Application

    On large applications you might create a shell application: the main functionality is then created as separate applications. This minimizes the amount of memory being consumed by the active applications, which you know is a very scarce resource for NETCF apps. The shell would act as a guardian and kill background applications if it decided that too much memory is being consumed. Protect the shell and make sure it’s always available; then, make sure the foreground application the user is using is always running.

     

    2. Microsoft Mobile Client Software Factory (July 2006) and Windows Mobile Accelerator (March 2008)

    Microsoft Mobile Client Software Factory – This is a set of sample codes provided by Microsoft to Smart Devices developers: you would find various blocks (DataAccess, OrientationAware, and so on) that I would recommend you having at least on the dev machine to index the source files, so that when you want to search for a class’ usage you can use that sample. NOTE: some time ago I handled a case where the developer followed the pattern about dynamic form creation shown by the Mobile Client Software Factory, called *"Composite UI"*, and claimed that the perceived performances of dynamically creating\destroying controls (which is the base of the "Composite UI" pattern) were really bad. Indeed this was a pretty common complaint about the Mobile Client Factory (July 2006) and one of the reasons for the publishing of the

    Mobile LOB Accelerator (March 2008) – where Composite UI block is NOT included.

    Mobile Client Factory is a great idea once devices have lots of memory and processing power, as for desktops: but until then you are better off using Forms the way they were originally intended basically like the LOB Accelerator does.

    So, pay much attention on dynamic creation of forms and controls.

     

    3. MVC Pattern and NETCF

    Just read all the MVC-related posts written by the NETCF guru Alex Yakhnin. He also posted the project to codeplex.

     

    4. Mobile Application Architecture Pocket Guide

    You must read “Mobile Application Architecture Pocket Guide”: as Rob Tiffany said, “[…] This is the first patterns & practices update to this guide since 2002 so it's a welcome sight to to have it out there for all our Windows Mobile developers.

     

    HTH,

    ~raffaele

Page 1 of 1 (2 items)