Click here to Skip to main content
Email Password   helpLost your password?
Wami Screenshot

Introduction

Where am I (Wami) is a Windows Mobile application suite that tells you where you are in the middle of a trip, without GPS and without connecting to the internet, using cell broadcast and cell tower information and a pre-recorded route file instead. It works by recording cell broadcast and tower information along a route into a route file and then using the current cell broadcast/tower information to index into the route file and find out the relative location within the route.

Motivation

I regularly travel to my hometown and I usually take the night train, preferring to sleep during the 9-10 hour journey. If I woke up during the journey, I had no way of knowing where I was and how long it would take to reach my hometown - I'd have to wait for the next major junction to find that out. Wami was written to solve that problem. With my train route recorded, I can now know my location and the estimated time of arrival at my destination with just a glance at my mobile phone. Along the way, I also added the ability to automatically respond to SMSes from configured numbers with the location and ETA information, and the ability to sound an alarm when I'm close to the destination.

Using Wami 

The Wami suite has three executables.

  1. RouteLogger - Runs on the phone and records all cell broadcast and tower information into a route file. Closing the app saves the recorded route into a location that will be probed by Wami.

    Route Logger Screenshot

  2. Wami - Main application which reads in the route file recorded by RouteLogger and shows you the current location and ETA at destination. When launched, Wami presents you with a list of route files recorded by Route Logger (from Application Data\wami\Routes) from which you can choose the appropriate route. Wami then loads the route file and shows the following screen:

    Wami UI description

  3. RouteEditor - Desktop application that lets you edit route files. The best way to edit the route files generated by RouteLogger is to:
    1. Clear All existing location groups.
    2. Add new location group, with a meaningful name.
    3. Expand the range of cell towers covered by the location group, by clicking on Expand Right (Alt+r) or Expand Left (Alt+e).
    4. Keep adding new location groups, until you have covered all locations.
    5. Save the modifications.

Route Editor Screenshot

If you are taking a trip for the first time, launch RouteLogger and keep it running until you reach your destination. RouteLogger uses text that is broadcast by your cellphone provider to associate a name to a cell tower, and that might not always be accurate or useful. RouteEditor lets you edit the route file to rename and group locations into more meaningful location groups.

Next time onwards, launch Wami and load the appropriate route file, that's all there is to it. You don't even need to have cell broadcast turned on for Wami to work, it can use the cell tower information in conjunction with the information in the route file to give you location names.

How It Works

The heart of the Wami suite is wamilib.dll, an assembly that houses all the core data structures and classes in the suite.

Click to enlarge image

LocationChangeNotifier

This class triggers location change events, with the current cell broadcast text and the cell tower id values as event parameters. It does this by:

RouteTracker

RouteTracker subscribes to the raw notifications from LocationChangeNotifier and translates it into a higher level LocationChanged event, using the information from the route file to look up Location objects for the given cell broadcast text and tower ids. It also keeps track of the current location along the route.

private void ProcessCellLocationChange(string newLocationName, string cellTowerId)
{
    newLocationName = newLocationName.Trim();
    currentLocationName = newLocationName;

    if (currentRoute != null)
    {
        Location location = 
		GetLocationForNameAndCellTowerId(newLocationName, cellTowerId);
        if (location != null)
        {
            ProcessKnownLocation(location);
        }
        else
        {
            ProcessUnknownLocation(newLocationName);
        }
    }
}

RouteManager, RoutePoint and Route

RouteManager acts as a single point interface for loading and saving routes. A Route is a collection of RoutePoints, with each route point representing a distinct location along the route. The RoutePoint also carries the time taken to reach the current route point from the previous route point, so finding the time to destination becomes the simple matter of adding all such time spans from the current point to the destination point.

Location and LocationGroups

A LocationGroup is simply a bunch of locations grouped under a recognizable name. For e.g. locations like San Francisco, Fremont and Sacramento can be grouped under California. LocationGroups exist because any decent city, at least in India, has multiple cell towers. Those towers will obviously have different cell ids/broadcast text, and it helps to organize them into a single identifiable entity, say Chennai.

Auto SMS Response

The Auto SMS response feature lets people chosen by you know your whereabouts. The Configure Auto SMS allows you to add contacts and specify a specific message. Wami will respond with your location and ETA to destination only if an incoming SMS message is from one of your chosen contacts and the message text matches the configured message. The SMSHandler class handles response to SMS requests. It uses the MessageInterceptor class from the Compact Framework to listen for incoming messages with the same body text as the configured message.

private void InitializeInterceptor()
{
   if (interceptor == null)
   {
      interceptor = new MessageInterceptor(InterceptionAction.NotifyAndDelete, true);
   }
   else
   {
      interceptor.Dispose();
      interceptor = new MessageInterceptor(InterceptionAction.NotifyAndDelete, true);
   }

   if (currentConfiguredMessage != null)
   {
      interceptor.MessageCondition = new MessageCondition
		(MessageProperty.Body, MessagePropertyComparisonType.Equal,
                        currentConfiguredMessage, false)
   }

   if (interceptor != null)
      interceptor.MessageReceived += new MessageInterceptorEventHandler
				(interceptor_MessageReceived);
}

The MessageInterceptor unfortunately does not provide a way to look for specific contacts, so that's handled by NotificationManager. NotificationManager maintains a list of triggers and the corresponding notifications - receiving an SMS with the configured body text is a trigger, and that trigger causes it to execute the corresponding notification action, i.e. replying to the SMS with the current tracking information.

private void ProcessTrigger(NotificationTrigger trigger)
{
   List<string> usersToNotify = new List<string>();

   foreach (var pair in userPredicateMap)
   {
      if (pair.Value(trigger))
      {
         usersToNotify.Add(pair.Key);
      }
   }

   if (usersToNotify.Count == 0)
      return;

    var message = GetMessage();

    if (message != null)
       notifier.Notify(usersToNotify.ToArray(), message);
}

Location Based Alarm

The CustomSoundPlayer class is used to play sound files on the device. It P/Invokes methods on aygshell.dll to asynchronously start and stop playing sounds.

public static class CustomSoundPlayer
{
        static IntPtr soundHandle;
        static object lockObject = new object();

        public static event EventHandler PlayingSound;
        public static event EventHandler StoppedPlaying;

        public static void PlaySound(string path)
        {
            lock (lockObject)
            {
                if (soundHandle != IntPtr.Zero)
                    return;

                SndOpen(path, ref soundHandle);
                SndPlayAsync(soundHandle, 0x1);
            }

            if (PlayingSound != null)
                PlayingSound(new object(), new EventArgs());
        }

        // Not threadsafe
        public static void StopPlaying()
        {
            lock (lockObject)
            {
                if (soundHandle == IntPtr.Zero)
                    return;

                SndStop((int)SndScope.Process, IntPtr.Zero);

                SndClose(soundHandle);
                soundHandle = IntPtr.Zero;
            }

            if (StoppedPlaying != null)
                StoppedPlaying(new object(), new EventArgs());
        }

       [DllImport("aygshell.dll")]
       internal static extern uint SndOpen(string file, ref IntPtr phSound);

       [DllImport("aygshell.dll")]
       internal static extern uint SndPlayAsync(IntPtr hSound, uint flags);

       [DllImport("aygshell.dll")]
       internal static extern uint SndStop(int soundScope, IntPtr hSound);

       [DllImport("aygshell.dll")]
       internal static extern uint SndClose(IntPtr hSound);
}

The LocationAndETAWatcher class subscribes to LocationChanged and TimeChanged methods of RouteTracker and provides the ability to execute single shot actions when the appropriate location/time change occurs. The location based alarm feature works by hooking up CustomSoundPlayer's PlaySound to LocationAndETAWatcher. The user can configure Wami to sound an alarm if:

LocationAndETAWatcher can watch both location changes and ETA changes, so the UI simply creates appropriate predicates for the above two conditions and sets up LocationAndETAWatcher to execute CustomSoundPlayer's PlaySound method.

watcher.Initialize(routeTracker);

if (!string.IsNullOrEmpty(s.SoundPlayLocationGroupName))
{
   watcher.AddSingleShotActionForLocationChange
	(locationGroup => locationGroup.Name == s.SoundPlayLocationGroupName,
           () => PlaySound(s.SoundFilePath));
}

var timeSpanToDestinationConfiguration = s.TimeSpanToDestination;
if (timeSpanToDestinationConfiguration != TimeSpan.Zero)
{
   watcher.AddSingleShotActionForETA
	(liveTimeSpanToDestination => liveTimeSpanToDestination <= 
           timeSpanToDestinationConfiguration, () => PlaySound(s.SoundFilePath));
}

Challenges

I have to say that writing a UI application for mobile devices is much more difficult than writing one for a desktop. Besides the obvious limitation in space and availability of controls, there's also orientation and wildly different aspect ratios to consider. Not something I enjoyed doing. The other hard thing is unit testing of the code. Without mocking, I'd be broke by now, having sent thousands of SMS messages from my phone to test the Auto SMS response feature:). I mocked everything I could, trying to avoid finding bugs when running on the phone. Cellular Emulator helped a great deal too.

References

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generalquestion
laus8
4:27 7 Jul '09  
i have been looking at your post and was wondering:
at the point that the wami application polls the cell towers to get the cell iD's , does one have to get the recommendations of the service provider owning the cell tower or it just happens behind scenes?
stans.

stans
QuestionCan't load RouteLogger and Wamilib
Sreejith Thampy.R
1:33 27 Mar '09  
hello Senthil,
Im using the VS 08 version 9.0.21022.8 RTM .I tried u r project(WAMI) to run but i came across a problem that 'RouteLogger and WamiLib ' are unable to add into the the project . Only 3 projects r loaded into the solution explorer.I know it has 5 projects to be loaded.I tried 'add existing projects' but that sh*t out of it.It cant be loaded by displaying an error that the project already exist.I tried every thing (re-naming ,add referencing,deleting ,etc..).And when i again and again tried to load ,the motherfucker error popping out.As im very curious to solve the problem and very eager to run this project,im looking for a gud solution from u r side as u r the master ..I appreciate if it solves .Looking forward for u r replay.
your friend
AnswerRe: Can't load RouteLogger and Wamilib
S. Senthil Kumar
1:49 27 Mar '09  
1. Did you try downloading the code from http://wami.codeplex.com?
2. Does your VS have Windows mobile 6 Standard SDK?

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

GeneralRe: Can't load RouteLogger and Wamilib
Sreejith Thampy.R
2:14 27 Mar '09  
yup,i tried the code from http://wami.codeplex.com and i have win mob 6 sdk and the active sync.Im getting that same problem bro. .{[(my IM id avenger_str07@yahoo.com)]}.
QuestionHelp Needed ..Urgent
sijinkumars
20:17 22 Mar '09  
hi Senthil,


I have a doubt in your project. Without having any internet connectivity and the gps system ,how this project actually works??For example if a person moves from one tower location to the other ,how it tracks the change in tower location??

With regards
Sijin
AnswerRe: Help Needed ..Urgent
S. Senthil Kumar
22:38 22 Mar '09  
sijinkumars wrote:
how it tracks the change in tower location??

There is no event available, the code polls the current cell tower id by using a timer and reports a location change if it is different from the previous cell tower id. Bear in mind that this application doesn't need the absolute location, only the location relative to the selected route.

I suggest you look at the code for more details.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

QuestionURGENT HELP NEEDED
sijinkumars
21:09 11 Mar '09  
hey senthil,
I just wondering abt u r project that i cant open u r project in the 2005 version of VS ,so would u mind help me out in which version did u complied the project .Im looking forward to see u r reply

Thank u
AnswerRe: URGENT HELP NEEDED
S. Senthil Kumar
21:53 11 Mar '09  
You need VS 2008 to build the solution.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

GeneralHow to set and run the program
ravanth
18:29 29 Jan '09  
Dear senthil,


plz explain how to set the program my PC.. i need some brifly explain


regards
kannan

Sir/Mam,

I'm Kannan.I Like very much for the coding for the project
THANKNG YOU

KANNAN

GeneralError msg on RouteLogger: cell broadcast doesn't seem to be enabled in your phone ...
kedanz
4:22 23 Jan '09  
I had a PDA phone with Window Moble 6 OS. I download the routelogger into my phone and after start I got the error message "Cell broadcast doesnot seem to be enabled in your phone. Do you still want to continue?" I type
"YES" and got string ";51872_2969;00:00:00" displayed at bottom. Do I need to set up something before start the app or I miss something?

Thanks
GeneralRe: Error msg on RouteLogger: cell broadcast doesn't seem to be enabled in your phone ...
S. Senthil Kumar
2:25 24 Jan '09  
kedanz wrote:
Do I need to set up something before start the app or I miss something?

If you want a location name to be recorded in Wami, you need to turn on cell broadcast. Cell broadcast is text that your cellular service provider broadcasts to all phones using the service.

To turn on cell broadcast on a WM 6 smartphone (non-touchscreen), click Start->Settings->Phone->Channels-. Check both the Enable Channels checkbox and the Receive Channel List checkbox. Click Menu->Edit Channels->Menu->Add. The channel number varies, depending on the service provider, but 50 usually works fine, atleast in South India.

To enable cell broadcast on WM 6 Professional, take a look at this[^] blog post.

Just so you know, Wami will work without cell broadcast - it will use generic location names (1,2,3...), and tell your relative position within a route, ETA to destination etc... You just won't get usable location names.

Hope this helps.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

QuestionRe: Error msg on RouteLogger: cell broadcast doesn't seem to be enabled in your phone ... [modified]
Abu Abdillah
4:18 26 May '09  
Fisrt, Thanks for this wonderful idea.
I live in Morocco and I just set the broadcast to be enabled but when i launch RouteLogger I see : Pause and then Currently: Recording and nothing else!

Since you said that the broadcast is just to get friendly tower names, why I receive nothing from the nearby tower?

Do you have any idea?

PS : does the channel 50 work for Morocco? If not, where should I find the correct number?

Thanks again.

Best regards,
Abu Abdillah
modified on Tuesday, May 26, 2009 9:25 AM

GeneralMy vote of 1
Kant
17:15 14 Jan '09  
Not original.
GeneralRe: My vote of 1
S. Senthil Kumar
19:01 14 Jan '09  
It's ok if you meant that the idea is not original, although I would disagree - I haven't seen seen any mobile apps that use location information to index into pre-recorded routes.

But if you voted 1 because of the previous comment that suggested that I plagiarized - then please do read my response to the comment.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

GeneralRe: My vote of 1
Kant
6:36 15 Jan '09  
I changed my vote after you updated the article.

You should have done that in first place.

I appreciate your effort.

రవికాంత్

GeneralOriginal Code
Acoustic
10:47 14 Jan '09  
A lot of your code looks surprisingly like code I wrote for my article on the same topic...

If your code is 100% original, that's great. But if not, give credit and citation where it's due, especially when it appears you're submitting a last minute entry for the competition.
GeneralRe: Original Code
S. Senthil Kumar
10:59 14 Jan '09  
Well, I copied the P/Invoke signatures for calling RIL_GetCellTowerInfo from http://dalelane.co.uk/blog/post-images/080312-rilcode.cs.txt[^]. I don't know if you are the same guy, but I don't think P/Invoke signatures require citation.

Did you even download and look at the source code? I also have a project running on codeplex (http://www.codeplex.com/wami[^]) that I started way before the competition was even announced.

If you're the guy who voted 1, I feel really sorry for you.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

GeneralRe: Original Code
Joel Ivory Johnson
11:37 14 Jan '09  
I actually use Dalelane's P/Invokes to after being directed to his site by OpenCellID.org. I ended up de-emphasizing the Cell Tower location functionality in the item I put out after seeing Acoustic's article. And by odd coincident Skyhook Wireless (the company from which I got the WiFi location info) updated their SDK and published it today[^], which takes care of aggregating WiFi, Cell Tower, and GPS information through what they are calling XPS.

I think that location services are just extremely popular right now. I was posting my article as a new verion of something I had posted here last year[^]. I had decided to call that program "FindMe." But Erica Sadun at TUAW.com also posted an iPhone program called FindME [^]that did the same thing, only it posted location information to twitter instead of sending it via SMS. Her program was posted close to the same time as mind. A company called Vito software also released a program called FindMe [^]that did the same thing. And just today msmobiles.com posted an article on a program called LocateMe[^]. While the three programs named FindMe were posted in close proximity to each other I am pretty sure that none of us saw the other's work before posting.

I'm not so much addressing whether or not any plagerism has occurred as much as pointing out that a lot of us are aiming for the same goals.

Wth Skyhook Wireless's update it looks that I'll have to go through my article[^] and rip out a lot of code that is no longer necessary.

Joel Ivory Johnson
My site: J2i.net
Twitter: J2iNet

GeneralRe: Original Code
S. Senthil Kumar
20:22 14 Jan '09  
Joel Ivory Johnson wrote:
Skyhook Wireless (the company from which I got the WiFi location info) updated their SDK and published it today[^], which takes care of aggregating WiFi, Cell Tower, and GPS information through what they are calling XPS.

Interesting. It's a pity that mobile internet access is still relatively expensive in India.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

GeneralRe: Original Code
Joel Ivory Johnson
3:07 15 Jan '09  
There's actually an option in the SDK to download all of the router data for the routers in your area so that no further internet access is required to get your location as long as you stay within the area that the router data was downloaded. I don't know if they do the same thing for cell tower data or not.

Joel Ivory Johnson
My site: J2i.net
Twitter: J2iNet

GeneralRe: Original Code
Acoustic
11:38 14 Jan '09  
You don't think you need a citation? Seriously? You're posting an article, and as a contest submission no less, under the pretense that it's your original work!

I downloaded your project and scoured the code prior to my comment, which is how I noticed it uses my code. I also looked at your codeplex project... but even there you didn't add the tower ID until January 12th according to your comments. The fact is that you borrowed from other sources, but you don't list them. That's just poor form and shameful in the context of a competition submission.

And no, I haven't voted a 1 for you. I haven't voted at all yet. I would at least give you the benefit of an explanation. Nonetheless, you'll need to update the article with the appropriate citations before I'll vote at all... or favorably.
GeneralRe: Original Code
S. Senthil Kumar
19:43 14 Jan '09  
Ok, I've added a reference to the web page from which I copied the RIL P/Invoke signatures.

Acoustic wrote:
which is how I noticed it uses my code

Which part are you talking about? If it's the code related to RIL_GetCellTowerInfo, there's plenty of code in the internet which shows how to get cell tower information, see here[^] and here[^], for example.

Even otherwise, code for getting the cell tower information is nearly insignificant when compared to the amount of code in the application, and I had a working version without cell tower id (Codeplex[^]. I don't understand how you came to the conclusion that "A lot of your code looks surprisingly like code I wrote for my article on the same topic"...

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro

GeneralRe: Original Code
Nishant Sivakumar
12:48 14 Jan '09  
S. Senthil Kumar wrote:
I don't know if you are the same guy, but I don't think P/Invoke signatures require citation.

That's not correct, Senthil. If you copied it from somewhere (as in copy/paste) you do require to credit the source unless there's a license that explicitly allows you to reuse it without mentioning where you got it from.

If I were you, I'd update the article to reflect this.

And good luck with the competition too Smile


GeneralRe: Original Code
S. Senthil Kumar
19:21 14 Jan '09  
Nishant Sivakumar wrote:
If I were you, I'd update the article to reflect this.

Done. I would have added a reference right away if I had copied actual code - I thought it was not necessary because it was just P/Invoke signatures.


Nishant Sivakumar wrote:
And good luck with the competition too

Thanks..

Regards
Senthil [MVP - Visual C#]
_____________________________
My Home Page |My Blog | My Articles | My Flickr | WinMacro


Last Updated 15 Feb 2009 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010