Adding location to a non GPS phone : using OpenCellID

By admin • juin 26th, 2008

1) Introduction

In this two parts article, we will introduce mobile positioning with CellID, and the open source database of CellIDs: OpenCellID. We will see how to use it through a simple sample. The second part will demonstrate how to use OpenCellID with OpenStreeMap and the 8Motion library to create a full interactive mobile mapping experience in JavaME, each of these examples being less than 100 lines of code.

2) What is CellID

We all know that GPS will be deployed in the vast majority of phones in the future. But now, only a few high end handsets are GPS enabled.
An alternative, available since a long time, but gaining momentum recently is CellID based location. What is CellID? A CellID is the number given to a specific cell (the radio tower to which your handset is connected) . In most of the case, it’s the closest tower to your location. So by knowing this tower, you know where the user is. But a tower can cover a huge area: from a few hundred meters, in high density area, to several kilometers in lower density area. That’s why CellID accuracy is lower than GPS accuracy, but this present a very good alternative.

CellID has become recently more popular, mainly thanks to his nice integration into GoogleMap mobile.

3) OpenCellID

So this sounds great, let’s just get the phone cellID, so we will have his location. The issue is that the location of cells is not a public information. Operators keep this private, for many reasons:

  • They don’t want to give tower location to their competitors
  • They use this as an extra revenue income, as they provide paying services to retrieve cell location.

That’s why we have set up a service called “OpenCellID”. OpenCellID.org is an open source database of CellID, serving two purposes:

  • Everybody can create an application gathering information about cell locations, and send these information to the OpenCellID server, improving the coverage
  • The database can be used by other applications to get the location of a cell, according to his cell id.

How to use OpenCellID (http://www.opencellid.org/api )

The API is a simple REST api. There are only two relevant calls: measure/add and get/cell

measure/add to add a measure of cell. This is used to by application which wants to add information to the database. These application produce content for the OpenCellID database. To use it, you need to require a key to OpenCellID.org. The key is used to track applications providers, and ensure that no fake data are inserted into the system.

Examples:

http://www.opencellid.org/measure/add?key=myapikey&mnc=1&mcc=2&lac=200&cellid=234&lat=3.42&lon=3.12

Replace myKey with the key that you received while registering at OpenCellID. This will tell the serveur that a client found a cell of id 234, for mcc=1, mcc=2 and the position 3.42,3.12 …Be careful: all informations are in decimal, while some handsets (sonyericsson for instance) provides lac and cellid in hexa, so you will need to convert them before calling the API.

Cell/get is used to get the position associated with a cell. You just need to give mcc,mnc,cellid and optionnaly lac.

http://www.opencellid.org/cell/get?mcc=250&mnc=99&cellid=29513&lac=0

You need to provide at least mcc, mnc (mobile country code, and mobile network code of the operator), and cell id. Lac (location area code) is an optional parameter, and will help to find an alternate position if cell is not found.
In return, the API will return a simple XML, like this one:



<rsp stat="ok">
<cell lat="57.8240013122559" lac="0" lon="28.00119972229" mcc="250" nbsamples="38" range="0" cellid="29513" mnc="99">
</cell></rsp>

Lat and lon are the coordinate of the cell, based on 38 samples…

If needed, you can use the optional parameter “fmt” to specify an output format,:

http://www.opencellid.org/cell/get?mcc=250&mnc=99&cellid=29513&lac=0&fmt=txt

will return something like this:

57.8240013122559,28.00119972229,250,99,0,29513,100,38

Same informations than before, but in a much compact form (see the API description for a complete description).

Others API are under development, to retrieve operators from mcc/mnc for instance.

4) Sample program:

So let’s use OpenCellID to create a small program, written in JavaME, which will just get the CellID of the phone , do a request to the OpenCellID server and display the results.

First, let’s get the CellID:

We use SonyEricsson specific properties. There properties are non standard, and only available on some devices.

// These properties are implemented on latest SonyEricsson phone // This does not work on others (Nokia, etc...) String cellid=System.getProperty("com.sonyericsson.net.cellid"); String mcc = System.getProperty("com.sonyericsson.net.cmcc"); String mnc = System.getProperty("com.sonyericsson.net.cmnc"); String lac = System.getProperty("com.sonyericsson.net.lac");

Cellid is of course the cell id, mcc is mobile country code, mnc is mobile network code and identify the operator and the country (cmcc stands for current mcc). That’s all we need to find our location.

Then, verify if theses properties are supported:

String info="This phone does not support CellID"; if(cellid!=null){ info="Cell:"+cellid+" mcc:"+mcc+" mnc:"+mnc+" lac:"+lac; url="http://www.opencellid.org/cell/get?cellid="+Integer.parseInt(cellid,16)+ "&mcc="+mcc+"&mnc="+mnc+"&lac="+Integer.parseInt(lac,16)+"&fmt=txt"; cellInfo.setString(info); Thread t=new Thread(this); t.start(); posInfo.setString("Requesting position..."); }

In this part, we have created the URL to request information on the server, and start the fetch of the information in a separate thread:

public void run(){ try { HttpConnection cnx = (HttpConnection)Connector.open(url); InputStream is=cnx.openInputStream(); StringBuffer b=new StringBuffer(); int car; while( (car=is.read())!= -1){ b.append((char)car); } is.close(); cnx.close(); String res=b.toString(); if(res.startsWith("err")){ posInfo.setString("Cell not found!"); }else{ int pos=res.indexOf(','); String lat=res.substring(0,pos); int pos2=res.indexOf(',',pos+1); String lon=res.substring(pos+1,pos2); posInfo.setString(lat+" "+lon); } } catch (IOException ex) { ex.printStackTrace(); posInfo.setString(ex.toString()); } }

If the API call return something starting with err, we are probably in error. Otherwise, we will have our current cell id positioning.

And that’s done. The complete source code is available here.The compiled program is available here, with jad and jar.

So, what happens if the CellID is not in the database? Then the program will display an error. You can improve the accuracy of OpenCellID by discovering more cells. Check OpenCellID to know how to do it.

Next part will improve this first version, by creating an interactive program displaying the location on a map, using J2memap free component…

Comments

By Diego Guidi on juin 26th, 2008 at 10:20

Looks a promising project :)

Cool code, thanks.

Have you considered merging the OpenCellID database with the CellDB one ?

Also, you wrote “We use SonyEricsson specific properties. There properties are non standard, and only available on some devices”.

Does this mean that there are as many versions of an app as there are mobile devices ? I guess the code should contain specific parts depending on the device type.

What a pity CellID has no standardized API.

By thomas.landspurg on juin 29th, 2008 at 18:35

Regarding CellDB, yes, but the problem is for now celldb does not provide a way to export completely the database, as OpenCellID is doing….

Regarding CellID, that’s true that the app haves specific code according to the device, that’s life of mobile! And even, the real problem is not having specific code for this, it’s that only a few devices gives access to these informations

Looking at CellID, I thought that JSR 179: Location API was about CellID and then realized that it is not the case.

Wouldn’t it be possible to create a new Java API for CellID - unless it’s too late ?

How to know if a device supports CellID ? Is there an official or semi-official list of CellID capable devices ?

Looks like a great way to have some sort of location info on non-GPS phones.

I would also like to know how to find out if a device supports CellId?

What is the possibility of finding this on a Nokia phone as well?

Thanks!

By thomas.landspurg on juillet 1st, 2008 at 22:15

@kael, no JSR179 does not provides direct access to CellID, even if it could be theorically used or this…. Today, CellID are provided through specific properties and are unfortunately not standardized.

I came across this thread and discovered that JSR-179 does support CellID :

MTE_CELLID

public static final int MTE_CELLID

Location method Cell-ID for cellular (in GSM, this is the same as CGI, Cell Global Identity). MTE_CELLID = 0×00000008
:)
BTW, I have an idea of midlets : the goal is to be able to get “subscribed channels” informations always displayed on the screen or on the mini-screen of the mobile “in a standard manner”.

For example, I’d like to have always displayed the most close FON WiFi hotspot or the list of the most close Velib’ stations on the screen.

I was first thinking to Cell Info Display that appear on the screens. But it seems not possible for a midlet to emulate Cell Broadcast informations (apparently, only emulators like the WTK can), and even less to generate specific CBS informations like Cell Info Display.

So I’m now thinking to a midlet that would use the UI API specific to each class of devices to display those informations via the screensaver or in a similar manner using the screen (themes ?) API, but I don’t know if it’s possible.

There are very interesting mashups to do with CellID and POI databases using the calculation of the orthodromic distance, though.

Addendum : if it was possible, a SVG map could be displayed as a background screen and metadata as text.

By thomas.landspurg on juillet 6th, 2008 at 14:07

@kael : cazn you be more precise…Are you asking for an evolution of the location program? I will soon post a sample where background is displayed using OpenStreetMap, so I hope it will help you.
Regards

By thomas.landspurg on juillet 6th, 2008 at 14:12

@kael: Going back to your previous post, about JSR179: the issue with JSR179 proividing support for CellID, is that the CellID is hidden, and require access to an external server (OpenCellID could provide it). Very few handset have implemented this, as far as I know…

But your idea of providing home screen with information is nice…It could be possible to do it with SonyEricsson too, as it’s one of the few handsets which allows j2me app to run as background, in the idle screen.

You can easily do an app to display location based information! And to be honest, this is a very smart idea, I like it! Do you have plans to works on this?

I’m just starting to learn J2ME, so I may take some time to write midlets.

Actually, I wrote a Vélib XMPP bot that I use to check where to find available places (using a geocoding API amongst other things) with Bombus Mod. But to use it, I need to stop and write an address which is not very practical when riding a bike. What I’d like is to have relevant data always displayed on the mini-screen.

I have several ideas of weather forecasts, Vélib stations, FON WiFi hotspot, prices of gas stations or NAViTiA (SIEL) based midlets.

For static data, once the midlet listener get a CellID it would make a query to get and display relevant data.

For dynamic data (like from the NAViTiA or Vélib API), there should be a push mechanism which would allow to get real-time data, perhaps with XMPP Pubsub, and hence to avoid unnecessary polling requests.

For Vélib I doubt they would deliver data in real-time, but for NAViTiA I think it might possible.

Regarding the GUI, I wished to simulate CBS with its channels subscription mechanism. But apparently, a midlet can’t emulate CBS, so I’m searching for an alternative and thinking to the Nokia Themes SDK.

BTW, I tried to run a modified version of OpenCellIDTest.java for a Nokia Series 40 3rd Edition Feature Pack 1, following the S40 system properties description but the values appear as “null” because the midlet requires to be signed as mentioned here. So I either should learn to sign midlets or a get a S60 mobile.

Regarding JSR-179, apparently MTE_CELLID seems to be a constant so I’m not sure what it is used for. Could you explain how it could be used and what an external server would provide ?

Also, there seems to be several other LBS technics for mobiles like Enhanced Cell ID, Angle of Arrival (AOA) and Time of Arrival (TOA), and JSR-179 seems to provide some of those data.

Thomas, isn’t there a way to get cell ID in J2ME on Nokia?

By thomas.landspurg on juillet 10th, 2008 at 21:44

@martynas : unfortunatly, there is no way to acccess to cell id on nokia. The only possibility for now is to create a native process, on S60, which communicate locally with the java app

There’s a Vélib’ midlet that could be extended to support OpenCellID.

I gotta get a GPS to scan Paris cell towers and participate to the OpenCellID database. :)

Hi everyone

@kael : You’re right MTE_CELLID is a constant.
With JSR179 you define a criteria (see CRITERIA object) and the phone will choose the best type of location due to this criteria (GPS, CELL-ID, TOA).
You could analyse in the method LocationUpdated, location.getLocationMethod will give you an int that you could compare to MTE_CELLID or MTE_SATELLIT or …

@others
Did someone try to test application with JSR179 on real phones? I got a problem because in the method lcoationUpdated when I use the method isvalid() on the object Location I receive “False”… I can’t find why and so I can’t receive the location data!
Thanks for your help
Regards

Hi everyone

@kael : You’re right MTE_CELLID is a constant.
With JSR179 you define a criteria (see CRITERIA object) and the phone will choose the best type of location due to this criteria (GPS, CELL-ID, TOA).
You could analyse in the method LocationUpdated, location.getLocationMethod will give you an int that you could compare to MTE_CELLID or MTE_SATELLIT or …

@others
Did someone try to test application with JSR179 on real phones? I got a problem because in the method lcoationUpdated when I use the method isvalid() on the object Location I receive “False”… I can’t find why and so I can’t receive the location data!
Thanks for your help
Regards;…

 

Leave a Comment

« Lonely Planet API | Home | Interview for Telematicsupdate about OpenCellID »