GPS Programming Tips for Windows Mobile - Part 1
NETCF: Memory leak... now what??
Supporting Kiosk-Applications on Windows Mobile (Technically achievable vs. supported)
Wireless Programming on Windows Mobile: supported or not supported?
Establishing GPRS Connection on Windows CE and Windows Mobile: Sample Codes
Disable WebBrowser's Context-Menu in NETCF applications
MAPI on Windows Mobile 6: Programmatically retrieve mail BODY (sample code)
Microsoft released a HotFix for NETCF v3.5 on Windows Mobile 6.1.4 onwards, to address basic functionalities of WebBrowser control
The right approach to get a Contact’s last communication (IItem’s PIMPR_SMARTPROP)
Remote Desktop Mobile (RDP Client) disconnects after 10 minutes of inactivity
Support Boundaries for Windows Mobile Programming (Developing Drivers, for example... Or even WiFi Programming)
Miei post in italiano sul team-blog del Supporto Tecnico agli Sviluppatori
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:
{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
while on those WM6 devices where the RIL is already implemented as NDIS Miniport driver
therefore it's no longer distinguished from for example the WiFi connection:
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!
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.
"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,