J2i.Net

Nothing at all and Everything in general.

Gavin Jacke's HCCB Become's Microsoft's Tag

Gavin Jacke  is a Director of Engineering for Microsoft Research.  One of his inventions is the High Capacity Color Barcode. Microsoft's applied this technology to a new Windows Mobile product called "Tag."  In short a Tag is a color barcode that you can place on a product or in an ad, and some one with the client application on their phone can aim it at your tag to get referred to a website with more information, receive a vCard, or be connected to a phone number.  Pretty cool!

 

HttpGet and Web Services

I was creatting a proxy to make use of the OpenCellID web services.  There is no WSDL available for the service so I decided to create a web services solution that had the same interface as the OpenCellID proxy and then use the WSDL that it generated as a starting point for a proper WSDL file (which for me was much less effort then creating the WSDL from nothing).  After creating the initial WSDL I tried to use the WSDL command line tool to create the proxy.  I specified HttpGet protocol and to my surprise I received an empty class file.  I tried again specifying SOAP as the protocol and it worked!  Why the difference in behaviour?  After attempting to solve this for a while without success I decided to post a question on the MSDN forums and quickly received an answer.

As it turns out by default HttpGet (and HttpPost) protocol are disabled for web .Net web services. To enable them you must add them as approved protocols in the web.config file.  After adding the appropriate section things worked like a charm.

        <protocols> 
            <add name="HttpGet"/> 
            <add name="HttpPost"/> 
        </protocols> 

Placing Custom Icon in Task Bar

Every now and then a question pops up about how to place a custom icon in the task bar. Doing so is against the "Made for Windows Mobile" guidelines. But if you have no concerned with meeting those guidelines you can place a custom icon in the task barby creating a windows and making the task tray the window's parent.  Ofcourse you will need to get the handle to the task tray.  A call to the native function FindWindow("HHTaskBar",NULL) will return that handle.

Accessing the Skyhook Wireless SDK from C# - prerelease wrapper

I've got a working wrapper for the Skyhook Wireless SDK but it has some [known] bugs.  I am also working on an OpenCellID wrapper and a Virtual Earth example that will make use of both services so I can't concentrate on taking care of the bugs just yet, but I promised to make the wrapper available this week so I am uploading it with the disclaimer that it is in prerelease form.  I don't plan on changing the methods by much between this version and a proper release version.  This code is not production ready and it confers no rights or warranties.   In the attachment you will find the C wrapper (Which handles conversion between wide and ani characters among other things), the wrapper, and a simple client of the wrapper.

Using the wrapper is wasy.  You only need to create a Wps object and then ask for your location.

Known Bugs:

  • If you examine the WPSPROXY wrapper you will find that in some cases memory is allocaated for a wide character conversion but not released.
  • I noticed if I ask for location while periodic location is active then a lockup will occur.  This is either a but or something that I am not supposed to do.

 Remember to ensure that WSAPI.DLL and WPSPROXY.DLL are deployed with your application.

 

A few simple code examples:

 //Get Full Address (exception thrown if address is not available)
  WPS wps = new Wps("myUserName","MyRealm");
 WiFiLocation location = wps.GetWiFiLocation(StreetAddressLookupType.FullStreet);


 //Get Full Address (no exception thrown if address is not available)
  WPS wps = new Wps("myUserName","MyRealm");
 ResultCode  = wps.GetWiFiLocation(StreetAddressLookupType.FullStreet, out loc);
 if(rc!=ResultCode.OK)
 {
    Console.out.WriteLine("Could not acquire location");
 }

 

 Download Code Here

Upcoming Windows Mobile Webcast

The new year is around the corner and the upcoming presentations for "24 hours of Windows Mobile" are on the calendar.   After these presentations there should be able 8 more which puts the presentation series as completing in March.

 

OpenCellID for .Net

I made mention of OpenCellID.org in a post not long ago.  In that post I had stated that I probably would not use the service since it was Java oriented.  I've got to retract that statement as I've just made a simple C# class for accessing the functionality.  It will be in an upcoming article on codeproject.com.  If you wanted to see the OpenCellID portion of the code look below.

 

 

using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.Xml.XPath;


namespace J2i.Net.OpenCellID
{

    
    public class OpenCellClient : IDisposable
    {
        string _baseUrl = "http://www.opencellid.org/cell";
        string _appID = String.Empty;

        public OpenCellClient()
        {

        }
        public OpenCellClient(string appID):this()
        {
            _appID = appID;
        }

        public CellTowerLocation GetCellTowerLocation (uint mobileCountryCode, uint  mobileNetworkCode, uint  localeAreaCode, uint   cellID)
        {
            CellTowerLocation retVal = null;
            string requestAddress = String.Format("{0}/get?mnc={1}&mcc={2}&lac={3}&cellid={4}",
                _baseUrl,
                mobileNetworkCode, mobileCountryCode, localeAreaCode, cellID);
            WebRequest webRequest = HttpWebRequest.Create(requestAddress);
            WebResponse response = webRequest.GetResponse();
            using (Stream xmlSource = response.GetResponseStream())
            {
                XmlDocument xd = new XmlDocument();
                xd.Load(xmlSource );

                if(xd.GetElementsByTagName("rsp")[0].Attributes["stat"].Value.Equals("ok"))
                {
                    XmlNode cellNode = xd.GetElementsByTagName("cell")[0];
                    retVal = new CellTowerLocation();
                    retVal.cellid = cellID;
                    retVal.mcc = mobileCountryCode;
                    retVal.mnc = mobileNetworkCode;

                    retVal.lac = localeAreaCode;
                    retVal.lat = Double.Parse(cellNode.Attributes["lat"].Value);
                    retVal.lon = Double.Parse(cellNode.Attributes["lon"].Value);
                    retVal.nbSamples = Int32.Parse(cellNode.Attributes["nbSamples"].Value);
                    retVal.range = Int32.Parse(cellNode.Attributes["range"].Value);
                }
            }
            return retVal;

        }

        public CellTowerLocation GetCellTowerLocation()
        {

            RILCELLTOWERINFO towerInfo = RIL.GetCellTowerInfo();
            return GetCellTowerLocation(towerInfo.dwMobileCountryCode, towerInfo.dwMobileNetworkCode, towerInfo.dwLocationAreaCode, towerInfo.dwCellID);

        }

        public int AddMeasure(uint mobileCountryCode, uint mobileNetworkCode, uint localeAreaCode, uint cellID, double latitude, double longitude)
        {
            TestAppID();
            int retVal = 0;
            string requestAddress = String.Empty;

            requestAddress = string.Format("{0}/measure/add?key={1}?&mnc={2}&mcc={3}&lac={4}&cellid={5}&lat={6}&long={7}",
                _baseUrl,
                _appID, mobileNetworkCode,
                mobileNetworkCode,
                mobileCountryCode,
                localeAreaCode,
                cellID,
                latitude,
                longitude);
            WebRequest webRequest = HttpWebRequest.Create(requestAddress);
            WebResponse response = webRequest.GetResponse();
            using (Stream xmlSource = response.GetResponseStream())
            {
                XmlDocument xd = new XmlDocument();
                xd.Load(xmlSource);

                if (xd.GetElementsByTagName("rsp")[0].Attributes["stat"].Value.Equals("ok"))
                {
                    retVal = int.Parse(xd.DocumentElement.Attributes["id"].Value);
                }
            }
            return retVal;
        }

        public bool DeleteMeasure(int id)
        {
            TestAppID();
            bool retVal = false;
            string requestAddress = String.Format("{0}/measure/delete/{1}?key={2}", _baseUrl, id, _appID);
            WebRequest webRequest = HttpWebRequest.Create(requestAddress);
            WebResponse response = webRequest.GetResponse();
            using (Stream xmlSource = response.GetResponseStream())
            {
                XmlDocument xd = new XmlDocument();
                xd.Load(xmlSource);

                if (xd.GetElementsByTagName("rsp")[0].Attributes["stat"].Value.Equals("ok"))
                {
                    retVal = true;
                }
            }
            return retVal;
        }


        private void TestAppID()
        {
            if ((_appID == null) || (_appID.Equals(String.Empty)))
                throw new ArgumentException("An Application ID has not been set on the OpenCellClient object.  A key can be requested at http://opencellid.org/users/signup", "AppID");
        }

        #region IDisposable Members

        public void Dispose()
        {

        }

        #endregion
    }
}

Using Skyhooks WiFi Location Service from Managed Code

Skyhook Wireless (http://www.skyhookwireless.com) offers a WiFi based location service. The service is available for Windows and Linux desktops long with Symbian and Windows Mobile phones.  Looking specifically at what is packaged with the Windows Mobile SDKs (there are three, one for Windows Mobile Standard, one for Windows Mobile Professional, and one for Windows Mobile Classic) one will find a C++ header file, the DLL containing the client side Wireless Positioning Service (WPS) functionality, and some example C++ code. Managed developers need to use P/Invoke to get access to the functionality.

In reading through the Skyhook Wireless Discussion Group I've found that there are managed developers that have interest in using the SDK but they have not had success with creating a wrapper for the functionality.  I've been planning to make an attempt at creating a wrapper myself since June.  Right now I am going through a very breif quiet perid at work (and not to mention that I've completed my obligations with school) so I took a couple of days to give it a try.  I've run into what I believe to be be the challenge that other managed developers have encountered and I have a workaround for it.  Presently I have code that can successfully query the users location (for those familiar with the SDK that means I can called WPS_location, WPS_ip_location, and get automatic callbacks from WP_periodic_location with full address information) and I hope to get it out after Boxing day (December 26th).

The first challenge that I encountered is that the Skyhook WPS SDK makes use of ANSI (8-bit) characters while the Compact Framework only supports 16 bit characters.  One work around for this is to create your own string encoder to convert between the 16-bit and 8-bit character sets and pass the strings back and forth as byte-arrays. But this didn't help with the second problem I ran into.  With the compact framework I would receive NotSupported exceptions when trying to pass complex structures.  As long as a structure was flat (only contained primitive types such as integers, doubles, and so on) the type could be marshalled without conflicts.  As soon as that structure contained another more complex type that was not a primitive type the NotSupported Exception would occue.  And easy example is trying to marshal any structure that contains a string builder.  Seeing what worked for me and what didn't work I came up with a workaround.

I created a proxy unmanaged DLL.  This DLL has functions that only accept simple types: integers, doubles, and StringBuilders.  The functions in the DLL will build the more complex structures and handle the conversion from unicode to ANSI and then make calls against the SkyhookWireless DLL.  As the return values pass back through the proxy DLL they are converted from their complex types back to something easily passed back to the managed code.   Having experienced that success I am creating a wrapper for the entire SDK and plan to have it uploaded to the Skyhook Wireless Discussion Group after Boxing day.  As per usual there will also be an article on CodeProject.com after my work is complete.  This will enable C# and VB.Net developers to make use of the Skyhook Wireless SDK.

First Post

I'm a Software Engineer.  Developing on Windows Mobile is a small part of that and there's a lot of things not directly related to Windows Mobile about which I would like to speak.  So I decided to start another blog just for those topics.  This is my first post but I still have a lot to do to get my blog setup.  So the next time I post here I'll have something of substance to say.

24 Hours of Windows Mobile - Halfway Point

As of yesterday the 24 hours of Windows Mobile series has reached its halfway point. .  I thought this would be a good time to post the links to all of the recorded presentations for those that may have missed one. 

 

TitleLevelDescription
Introduction to Windows Mobile Development 200 High level introduction to developing managed applications for mobile devices
Interoperability Between Native and Managed Code 300 Basic's of P/Invoke and using COM objects
Creating Adaptive Applications 300 Creating applications that work with a wide variety of formfactors
Using Pocket Outlook Data within a Managed Application 300 Retrieving and manipulating data stored within Pocket Outlook
Live Update from PDC 300 Sharing news announced at PDC time and other demonstrations
Developing Battery Friendly Applications for Windows Mobile 300 Demonstration of the State and Notifications broker and other features of Windows Mobile that can assist in developing applications that consume less power
Unit Testing for Mobile Devices 300 Explore using the unit testing functionality of Windows Mobile for devices
Testing Your Mobile Applications 300 Strategies for testing your Mobile Application
IPC and True Push 300 Asynchronous programming techniques inside your managed application
Windows Mobile Networking 300 Negotiating and establishing a network connection
Location Awareness 300 Location services available for Windows Mobile
Windows Mobile Power Toys 200 Tools to assist you in diagnosing information about your running applications.