Programmatically getting the CellID from your Windows Mobile phone

I’m still on paternity leave at the moment, so time near a computer is limited to 20 or 30 minute periods in the rare occasions while Faith is asleep!

But in the last few days, I’ve still been playing with a few new geeky things. One of these is FindMe – a Windows Mobile application from Electric Pocket.

screenshot of FindMeThe basic idea is:

  • it gets the CellID of the GSM transmitter that your mobile phone is currently talking to
  • if it hasn’t seen this CellID before, it displays “You are in a new place” and prompts you to type in a name for where you are
  • if it has seen this CellID before, it uses the name you last entered for it

Then it uploads your name for the CellID (your description for where you are) to your Facebook profile.

Hey presto – location tracking without the need for GPS.

It works quite well.

I’ve played with location based stuff on my phone before but never tried to use GSM cell id before. I did consider it, but after failing to find a free database that could transform the cell id string into a location I could plot on a map, I didn’t really pursue it any further.

Playing with FindMe encouraged me to give it a try.

I don’t know how the FindMe app is implemented, but after a little bit of playing tonight, it seems fairly easy to grab something similar to the “Cell” string they are using from the RIL_GetCellTowerInfo function in the Radio Interface Layer (RIL) API.

  1. Call RIL_Initialize to get a RIL handle
  2. Call RIL_GetCellTowerInfo to get the information about the cell tower the phone is connected to

    The “Cell” string that FindMe displays seems to be a combination of the dwCellID, dwLocationAreaCode and dwMobileCountryCode fields

  3. Call RIL_Deinitialize to release the RIL handle

It seems to work okay.

Well… 150 or so lines of C# hacked together while Faith naps, generates the same strings that FindMe displays for the two cells my phone can bounce between in my house. Not exactly conclusive testing 🙂

I’ve put my code here in case it is useful to anyone. Usual disclaimers and provisos apply (i.e. it may be gibberish).

I’m not sure what I’m going to do with it. The biggest problem is still the lack of a database to be able to translate the cell tower info you get into an actual geographical location. But if – as with FindMe – you’re willing to invest the time to “train” an app and build up your own cell id database of locations, then there is some potential for interesting apps.

I might try writing a location based reminder app – could be interesting to extend the Outlook Tasks db to have something that reminds you of a task when you’re in a specific location. For example, it’d be good if your phone prompted you with things you want to remember to buy when you’re at the shops. The Tesco garage on my drive home from work is far enough away from anything else I go to that it’d probably have a cell ID that I wouldn’t otherwise be in. Likewise, once I work out the cell ids for Hursley, I could have something that can remind me of something when I get to work.

Or, I could use this as an excuse to play with Fire Eagle. I’ve had the invite for that for a while and still haven’t got around to giving it a try. It could be cool to write something that lets you update your Fire Eagle location using Cell ID info.

Tags: , , , , , , , , , , , , , , ,

115 Responses to “Programmatically getting the CellID from your Windows Mobile phone”

  1. dale says:

    For people who are seeing 0 for MNC and MCC – someone did post a comment with a possible answer:

    Hope that helps!

  2. spocky says:

    Hi, I have the exact opposite problem : my RilCellTowerInfo has the following parameters set :
    every other parameter is 0
    Any tips so that I can make it work ?

  3. I’m searching a way to use the RIL API with VB.Net, I got some ideas with your post, but I couldn’t work now… thanks for your info

  4. ASD2003ru says:

    Eten x900 (WM 6.1) MCC and MNC = 0 🙁

  5. dale says:

    @ASD2003ru – Someone did post a comment with a possible answer:

    Hope that helps!

  6. kozkan says:


    after calling GetCellTowerInfo() method with hp ipaq 514; its hangs up and not return any value or exception. is it hw or configuration issue or do i need anything else except calling GetCellTowerInfo()?



  7. dale says:

    @kozkan – It’s worth trying the addition posted in a comment mentioned a few times above:

    Hope that helps!

  8. tobbbie says:

    Did you have a look at cell profile switcher by maniac at:
    Very elaborate 🙂

  9. […] on WM device ? "knopper" wrote: > thanks ! Hi, there is a nice blog entry on to this topic Greets […]

  10. grant says:

    Can you send the ” ril.dll ” to me
    Because i want to get cell ID number
    i want to do some experiment.

  11. grant says:

    How to catch Cell-ID’s RSSI and other Cell-ID ??
    Can you tell me how to do ??

  12. Tili says:

    The biggest issue I see is that RIL is not part of windows mobile Pro SDK. If you have to get your application Microsoft signed, you cannot use any API that is not part of SDK.

    Is there any official way? How does google’s app on windows mobile do it?

  13. dale says:

    @Tili – I agree – this approach works for my purposes as independent hobbyist developer playing with what is possible, but if you wanted to create a commercial application, it’s not suitable. I don’t know what the “correct” way to do this is.

  14. Technovia says:


    I am totally not a C programmer! Can somebody point me in the right direction on calling these functions from within VB.NET ??

    I find loads of examples on the web for accessing RIL from C but not from VB and this code looks like it will work for my needs 🙂

    Thanks for any pointers!

  15. Chintan Fafadia says:


    Thanks for the guidance man!!! Was able to use this code to run on a Windows mobile phone, but I keep getting the cell-id and the LAC as 0. Any idea what could be the solution for that?

    Also as I have been reading comments on the blog, is there a way to use this to create an application or you have to getting it approved by Microsoft? I read about p\invoke on a another forum about RIL, has anyone tried that?


  16. dale says:

    @Chintan – did you try this?

  17. Chintan says:


    Thanks for the reply…i am getting the MCC and the MNC alright. My problem is with the cellid, location area code etc…all the other fields are coming up blank, however the same code worked for a friend of mine in a different city, however we both got other celltowerinfo parameters like RxLev, RxQual as zeros…any idea what could be the reason?

    Thanks again…

  18. Vik says:

    How do I import this code into Visual basic.NET?

  19. Mike says:

    I have built an application that collects the cell ID information returned by RIL_GetCellTowerInfo and the GPS location and stores it in a spatial database. When I look at the resulting data on a map I observe that the cell ID information is frequently bogus. It appears that the cell ID gets “stuck” sometimes and remains the same value over a long distance (up to 10 miles or so sometimes). I have observed this behavior on more than one phone including a HTC Touch Diamond and HTC Fuze. I noticed a couple posts on here describing similar behavior. Can anyone explain this behavior? Is it a bug in the radio driver? Is there a work around?

  20. Mike says:

    Vik, you can use .NET interop to call the RIL library. Another approach is to wrap RIL in a COM layer and then call that from .NET. I had weird stability problems with the interop approach so I switched to the COM wrapper approach.

  21. Mike says:

    I did a test of RIL_GetCellTowerInfo last night on a pair of HTC Touch Diamonds; one running Windows Mobile 6.0 and the other 6.1. Both phones reported 0’s for all 6 Rx fields. I believe the reason is that RIL is just an interface written by Microsoft, it is up to the OEMs to implement the interface, and the OEMs don’t implement everything. Thus the behavior is likely to vary by OEM/phone. Isn’t mobile development fun?

  22. Mike says:

    I did a further experiment where I reset the RIL library before calling RIL_GetCellTowerInfo by calling RIL_Deinitialize then RIL_Initialize. This made no difference. RIL_GetCellTowerInfo still frequently returned stale data. My next theory is that the problem has to do with the power state of the phone. It might be that RIL_GetCellTowerInfo only returns a valid value when the phone is in the fully on state. If this is the case, I am hoping I can “trick” it by insuring that a particular device on the phone is powered on in the unattended power state. I challenge is finding the proper device.

  23. TheSun says:

    RIL_GetCellTowerInfo work in unattended power state. But now the problem is FIL functions use battery. I don’t now if using RILNotifyCallback will be better. I test RilNotifyCallback but it’s doesn’t work. I create a c++ wrapper but I have error when calling RIL_DevSpecific(26) or RIL_DevSpecific(24). Anyone have already test with notification ??

    Some references : and

  24. Getting Cell id in windows mobile …?? developer can do just a try but everything is depends on OEM…..!

    My fight with WM devices to get CellID is very old (nearby from last 3 years) 🙂

    i tried with many approaches like.. TAPI….RIL and one Secret one (i will talk u later about this….)

    the conclusion of all that RIL is first approach if it doesn’t work the use last one approach.

    In between this i want to tell about one interesting conversion between me and one WM PDA OEM… ASUS… yes regarding Cellid 🙂

    i was working on Asus P535 device (we bought 4 devices) but no luck to get cell id…. so what to do… i started to go in deep… some assembly code, memory , driver debug etc anything that came in way… 🙂

    At last i got the reason…and here someting was missing…!! here i am writing the small part of email conversion i had done with asus people……

    I got the POI(actual cause of problem) after lot of struggle ….. 🙂

    In the OEM RIL driver that sends the AT commands to modem (I think name may be ‘Galaxy’ in this Asus P535 device) has to initialize the modem boot time of the modem ,so that time it send the initialize string (a series of AT commands) to modem in Asus P535 the init string is following …


    Here the value for ‘CREG ‘ is ‘+CREG=1’ it should be ‘+CREG=2’

    // +CREG=1 enables short +CREG notifications

    // +CREG=2 enables extended +CREG notifications (w/ and )

    So after initialization of modem …

    1. if in initialize string the value for ‘CREG ‘ is ‘+CREG=2’ ,now if the driver sends ‘AT+CREG? ’ to the modem ,then modem responds with “+CREG: 2,1,”0005″,”00000EF7” here ‘0005’ is Lac value and ‘00000EF7’ is cell id’s value for connected GSM tower.

    2. if in initialize string the value for ‘CREG ‘ is ‘+CREG=1’ ,now if the driver sends ‘AT+CREG? ’ to the modem ,then modem responds with “+CREG: 1, 10” here Lac value and ‘cell id’s value are not returned by modem, because the driver had set it to ‘short +CREG notifications’ at the time of modem initiation.

    So if in the modem initialize string the value of for ‘CREG ‘ is ‘+CREG=2’, then MS’s RIL standard API “RIL_GetCellTowerInfo” will work fine( because internally this API is converted to ‘AT+CREG? ’ and go to GSM modem by the OEM RIL driver(rilgsm.dll) .

    >>> Means fix/replace of rilgsm.dll (and it can be done with Asus signed CAB file)

    Sorry ….for lot of theory about RIL internal things…

    Conclusion : till now they didn’t solve it (i don’t know why??)

  25. radhoo says:

    Besides RIL_GetCellTowerInfo/polling mechanisms that waste a lot of battery power, you can use direct Cell ID network notifications, as a callback, using this library:

    It works for GSM networks, and provides the CellID on devices where GetCellTowerInfo fails or is unimplemented, since this is a network notification.

  26. dale says:

    @radhoo – Thanks for the comment. This certainly sounds like a useful library – anything that makes it easier to use this information is a good thing for developers.

    I think the battery power argument sounds a little odd though – as by the looks of it, your library is just a wrapper for RIL, so I don’t see that you save much battery life by letting a wrapper do the polling for you rather than an app.

  27. Steven says:

    hi dale,

    i’m interested when you mention writing a location based reminder. i find it useful when i need to get something from the market i pass by on my way home from work.

    Have you started anything on that? if yes, that will be great as i would like to see how it’s coded

  28. dale says:

    Sorry – it’s not really packaged or tidied up in a way that would be ready for sharing.

    Since I wrote this post, this idea seems to have become much more common. ‘Locale’ for Android, for example, is a great example of how to do location-based notifications well.



    This library will not work on WM phones where RIL is not implemented in std way, as i told in details above, as well as RIL notification will also not work.

    Use your library on Asus P535 , it will not work…:-)

  30. radhoo says:


    thanks for your answer.

    the library doesn’t do polling. as I said it receives the Cell ID as notifications. some of this is explained here:

    so this is why it is optimized for power consumption.

    ps: the forum code is incomplete, but it gives the idea.

  31. dale says:

    @radhoo – I had a quick look at the C# samples provided with your library, and I think I must be missing something, because they do seem to poll.

    For example:

    namespace RILClass
        /// Summary description for RILClass.
        public class RILClass
            //instead of a callback we will use a timer to gather data, as C# sucks bigtime
            private Timer timer1;
            public RILClass()
                //setup timer - for callback replacement
                this.timer1 = new System.Windows.Forms.Timer();
                timer1.Interval = 200;
                this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            private void timer1_Tick(object sender, EventArgs e)
                string s1=null, s2=null, s3=null, s4=null;
                UInt32 uTimeStamp = 0; //ms elapsed from Start()
                if (ReadData(out s1, out s2, out s3, out s4, ref uTimeStamp) != -1)
                    //interpret and use data
                    MessageBox.Show(s1 + " " + s2 + " " + uTimeStamp.ToString());

    So I’m not sure what power consumption benefits there would be from using it.

  32. Ankur says:

    Hi Dale,
    Thank you for the wonderful code…

    Can you plz help me out in finding the latitudes and longitudes using the cell id of the mobile ?

    I am getting the cell id successfully using your code, & my requirement further is to obtain my global position (BOTH WITH & WITHOUT GPS)
    So, for without GPS I will find my Lat’s Long’s through cell id…

    Plz help

    Thanks in advance,

  33. dale says:

    @Ankur – There are many ways to identify a lat/lon coordinate from a given Cell ID. I’ve played with Fire Eagle (Yahoo’s database), Google, and OpenCellId. They are all worth reviewing.

  34. Ankur says:

    Hi Dale,

    Oh that’s gr8 then…
    As for now I am playing with google’s database.

    So can you, by the way, tell me which one would be the best to use for obtaning Lat Lon ?
    Yahoo ? OpenCellId ? which one ?
    I think nothing beats google. M I right ?

    Thanks in advance,

  35. andy says:

    Dear Dale

    is it any chance you can change your code to i am really new to the programming world.
    i have tried several code converters but i keep getting error messeges in my compiler.

    many thanks

  36. dale says:

    @andy – No, sorry.

  37. Ankur says:

    Hi Dale,

    I have obtained an apikey from OpenCellId tp get the Lat Lon,
    and this is working well. I just wanted to ask you whether this apikey of opencell id is lifelong or not ?

    I mean will it keep working for ever? I hope there is no expiry for such keys. Please let me know about all this.

    Thanks in advance

  38. dale says:

    Ankur – I don’t know, sorry. To be honest, I never really pursued this OpenCellId stuff much further beyond an early stab at a client app.

  39. Ankur says:

    Hi Dale,

    ok no Probs.

    neways, I just needed one more favour from you…

    I have to obtain, along with the Cell Id & LAC, the current area in which the windows mobile is currently present- that same area which the service provider displays for us on the mobile screen.

    I have to obtain it from the api, & the info that we get from the RIL api is as follows (as such you know this): –

    public uint cbSize;
    public uint dwParams;
    public uint dwMobileCountryCode;
    public uint dwMobileNetworkCode;
    public uint dwLocationAreaCode;
    public uint dwCellID;
    public uint dwBaseStationID;
    public uint dwBroadcastControlChannel;
    public uint dwRxLevel;
    public uint dwRxLevelFull;
    public uint dwRxLevelSub;
    public uint dwRxQuality;
    public uint dwRxQualityFull;
    public uint dwRxQualitySub;
    public uint dwIdleTimeSlot;
    public uint dwTimingAdvance;
    public uint dwGPRSCellID;
    public uint dwGPRSBaseStationID;
    public uint dwNumBCCH;

    Can you please tell me how can I get the area ?
    which parameter from above list is giving me the area ?

    Thanks in advance,

  40. dale says:

    Ankur – Sorry, I don’t know. Would be interesting to find out, actually – I can see how that might be useful information to have.

  41. Ankur says:

    Hi Dale,

    Thanks for the reply.

    Well, I will be really thankful if you can please try to find out the way to get the area.

    I need the area since I have to display it on the mobile in my app.

    Neways, what I believe is that the api must be having that area, the api must be returning the area. It is then only that the service providers display it.

    So why can’t we do it …
    Yes surely we can

    Looking forward for to it…

    Thanks in advance,

  42. Javed says:

    Hi Dale,

    I have been following your discussion for very long time, but havn’t had courage to do the coding myself. As per the requirment have with me I am doing this codeing myself and stuck at CellID. I am using WM and successfully getting the label displayed CID-LAC-MCC-Time, but when I am tring to split the text in order to have Lat/long values I am unable to get the result (I am using VC#). Being a dummy user I have tried to find out IndexOfAny of “-” I am getting “-1” as a value. Not being a C# programming background (I know little bit!) I am not able to proceed futher.

    Any help in this regards would be great. Looking forward for a reply.
    Thank you in advance

  43. dale says:

    Javed – getting back -1 from IndexOf means that the substring you are searching for is not present in the string. Step 1 would be to check what the text you are trying to search is.

    Good luck


  44. Febiyan says:

    Hi Dale,

    I’m new at Windows Mobile Programming using C#, I just want to try your wrapper to make a LBS application for my Thesis (thanks a lot!).
    I tried to add your code to my app, and here is the code when a button is clicked:

    string cellTowerInfo = “”;
    cellTowerInfo = RIL.GetCellTowerInfo();
    //and the rest is to send the cellTowerInfo value to other variables

    The problem is, when I click the button, the software freezes, but the phone doesn’t. When I traced the error, the line causing the freeze is this line:

    // wait for cell tower info to be returned

    If I remove that line, the software doesn’t freeze but cellTowerInfo contains nothing. 🙁 Do you have any clue?

    Sorry for the bad English. 🙁


    BINUS University Student

  45. Javed says:

    Hi Dale,

    I have been searching for the text ‘-‘ in the return value of cellid where the text is being displayed correctly and successfully getting the label displayed ‘CID-LAC-MCC-Time’ After getting this value I am tring to split the value by the hyphen ‘-‘. But unable to get the return yet. still I am getting -1 the length is 1 that means “”-Timestamp. I can see the label value correctly but unable to proceed further. Snippet of code as follows

    Cursor.Current = Cursors.WaitCursor;
    string cellid = RIL.GetCellTowerInfo();
    string txt = cellid + “-” + DateTime.Now.ToString();
    lblCellID.Text = txt;
    //Getting correct cellid Info
    string[] cellidFields =
    //The message box shows 1
    if (cellidFields.Length == 2)
    // I am unable to get in IF loop here

    Thank you in advance for the help

  46. Pablo says:

    Hi, i was wondering how can i get the RxLev, and RxQuality, from the GetCelltowrinfo, as many ppl here, they get a lot of zero’s why is that, plz i appreciate the help. thxs.

    PS: nice Work Dale, Nice code.

  47. Louis says:

    Hello Dale,
    many thanks for releasing your code to the community.

    BTW, do you have any idea how to know the TimingAdvance parameter?
    Also, how to know the id/lac/mcc/mnc of neighbour cells?


  48. Louis says:

    you can use more sophisticated ril.cs file inside this zip file:
    There is a function to retrieve the reception strength.

  49. Richard says:

    For another cell-ID database to use to get the position of a cell check out:
    Global coverage and around 3.9M cells in the DB.