thoughts scribbles images from silicon plateau
RSS icon Home icon
  • Google cell tower mapping with Python on S60

    Posted on July 11th, 2008 jebu Comments

    I have had my N95 for some days now. I’ll just say that the device is all I could ask for in a smart phone for, now. iPhone 3G, yeah, lets just say my take on it is clear from my choice of the N95. So the best part of this being the Python for S60 and the location API’s available via Python.

    I came across this piece of beauty which uses a hidden Google API for location detection based on cell tower information. Now what better way to start learning Python than getting this piece working on my phone with Python. I’m fed up of writing Hello Worlds to start learning a language. Here is a python version of the poor mans GPS.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    from httplib import HTTP
    import location
     
    latitude = 0
    longitude = 0
     
    def doLookup(cellId, lac, host = "www.google.com", port = 80):
      from string import replace
      from struct import unpack
      page = "/glm/mmap"
      http = HTTP(host, port)
      result = None
      errorCode = 0
     
      content_type, body = encode_request(cellId, lac)
      http.putrequest('POST', page)
      http.putheader('Content-Type', content_type)
      http.putheader('Content-Length', str(len(body)))
      http.endheaders()
      http.send(body)
      errcode, errmsg, headers = http.getreply()
      result = http.file.read()
      # could need some modification to get the answer: here I just need
      # to get the 5 first characters
      if (errcode == 200):
        (a, b,errorCode, latitude, longitude, c, d, e) = unpack(">hBiiiiih",result)
        latitude = latitude / 1000000.0
        longitude = longitude / 1000000.0
      return latitude, longitude
     
    def encode_request(cellId, lac):
      from struct import pack
      content_type = 'application/binary'
      body = pack('>hqh2sh13sh5sh3sBiiihiiiiii', 21, 0, 2, 'in', 13, "Nokia N95 8Gb", 5,"1.3.1", 3, "Web", 27, 0, 0, 3, 0, cellId, lac, 0, 0, 0, 0)
      return content_type, body
     
    (mcc, mnc, lac, cellId) = location.gsm_location()
    (latitude, longitude) = doLookup(cellId, lac, "www.google.com", 80)
    print latitude
    print longitude

    Download
    Beware this does not work from all IP’s, from my wifi connection at home this threw an error while on the GPRS connection this worked well.

    • marcorivero
      Hi its very useful, that is posible on Symbian c++
    • ashen
      I was looking for something like this..
      Thank you very much!!
    • Very nice work!

      It actually works perfectly! Thank you very much :)
    • ben9732
      Hi, i tried to use your script, but i got the following errors:

      File "default.py", line 107, in menu_action
      f()
      File "default.py", line 70, in query_and_exec
      script_namespace.namespace)
      File "e:\python\google_locate.py", line 37, in <module>
      (mcc, mnc, lac, cellId) = location.gsm_location()
      TypeError: 'NoneType' object is not iterable

      I've got the latest v1.9.7 python installed, my phone is hacked, Capabilities Present: ('NetworkServices', 'LocalServices', 'ReadUserData', 'WriteUserData', 'UserEnvironment')

      thank you for your time and help.
    • haojian
      (connect...)it installed successfully.what's wrong?is there anything i forgot?symbian c++ has a concept of capability,will python for s60 need so too? looking forward to reply,thank you.
      英语能力有限,希望已经表述清楚了我的问题。O(∩_∩)O~
    • yes you will need to sign you app (.sis) with elevated privileged by going thru the symbian signed process.

      http://blog.jebu.net/2008/07/google-cell-tower-...

      我不知道中國 (via google translate)
    • haojian
      so happy to receive your reply.yes,i've signed my app via a self-signed process with my own certificate.i've tried it on the other apps,and it runs well on my mobilephone.this time,it failed.i tried the python script on emulator,and i got this mistake:"python error(-50)""unpack non-sequence"
      does this matter?O(∩_∩)O哈!
      i'm so sorry you do not know China.
    • most probably the google webservice is not able to lookup the location for your cell tower
    • haojian
      hi,thanks for your code.now i use the following codes to get cellid and lac information from my nokiaN95:
      -------------
      import appuifw,location,e32
      def getcellid():
      mcc,mnc,lac,cellid=location.gsm_location()
      appuifw.note(u"cellid is %d--lac is %d"%cellid,lac)

      def quit():
      global script
      script.signal()

      appuifw.app.title=u"cellid and lac"
      appuifw.app.menu=[(u"test",getcellid)]
      script=e32.Ao_lock()
      appuifw.exit_key_handler=quit
      script.wait()
      -----------
      and i have packed it into a .sis file.so pity i got nothing since
    • Felipe Pontes
      Hi all!

      I need make requests for latitude and longitude using groovy. Where do I can find documentation about that google API? Jebu, could you help me to understand the pack parameters at line 34 of your code? I always get "Not implemented" response from google using a initial code in groovy. :(

      Thanks in advance,
      Felipe.
    • Good Script, i have do the same thing with PHP, but i have got a question:

      ok i give to google LAC & CellID, and i respond me a binary code, where i can thing inside LAT & LONG of the cell, but for MNC & MCC code? do you think i can retrieve this value from the Binary response of /glm/mmap of Google?
    • MCC and MNC are identifiers of your cell tower, so ideally you should be providing it to google not the other way. there is an example of using the api with all the 4 parameters of the cell tower here .
    • nick
      Ok... it sounds easy, and I know it's easy.
      However :( I'm just too new to python to make something not stupid.
      (gawd isn't php nicer for beginners!)

      Anyway.. I've tried urllib (since apparently there is no urllib2 for pys60) and httplib

      At some point it seemed to work with urllib. Seemed to. but I had a bad response from the server (Error 400).

      So I tried again with httplib but now I'm flooded with error messages from python shell itself and server doesn't receive any message.

      I just want to open a php page that says "hello world, your latitude is XX and your longitude is YY".

      from httplib import HTTP
      import httplib
      import location

      latitude = 0
      longitude = 0

      def doLookup(cellId, lac, host = "www.google.com", port = 80):
      from string import replace
      from struct import unpack
      page = "/glm/mmap"
      http = HTTP(host, port)
      result = None
      errorCode = 0

      content_type, body = encode_request(cellId, lac)
      http.putrequest('POST', page)
      http.putheader('Content-Type', content_type)
      http.putheader('Content-Length', str(len(body)))
      http.endheaders()
      http.send(body)
      errcode, errmsg, headers = http.getreply()
      result = http.file.read()

      # could need some modification to get the answer: here I just need
      # to get the 5 first characters
      if (errcode == 200):
      (a, b,errorCode, latitude, longitude, c, d, e) = unpack(">hBiiiiih",result)
      latitude = latitude / 1000000.0
      longitude = longitude / 1000000.0
      return latitude, longitude


      def encode_request(cellId, lac):
      from struct import pack
      content_type = 'application/binary'
      body = pack('>hqh2sh13sh5sh3sBiiihiiiiii', 21, 0, 2, 'in', 13, "Nokia N95 8Gb", 5,"1.3.1", 3, "Web", 27, 0, 0, 3, 0, cellId, lac, 0, 0, 0, 0)
      return content_type, body

      (mcc, mnc, lac, cellId) = location.gsm_location()
      (latitude, longitude) = doLookup(cellId, lac, "www.google.com", 80)
      print latitude
      print longitude


      latitude=str(latitude)
      longitude=str(longitude)
      the_url= 'script.php?lat='+latitude+'&lng='+longitude
      print the_url

      conn = httplib.HTTPConnection("http://myserver.com",80)
      conn.request("GET", the_url)
      conn.getresponse()
      conn.close()



      arrrrr I hate not seeing this.
    • I'm no python expert, but this code looks good and running the skeleton of your request works fine. Whats the sort of errors that you see? Might be better to continue this discussion on email, feel free to mail me [jebui at yahoo dot com]
    • nick
      Now that it works...


      Would you happen to know how it's possible to change

      print latitude
      print longitude

      by a function that would

      if I press 1 : open a url (not necessarily the webbrowser, just trigger a php script on a server) http://myserver.com/script.php?lat=latitude&...

      if I press 2 : open another url (same thing)

      ?
      thanks a lot !
    • Why not that should be pretty easy to setup, read from sys.stdin for the input and use either the httplib used in the scrupt or urllib to call out to the url that you want to.
    • nick
      That did the trick!

      Actually I don't know what exactly..
      But I uninstalled PyS60

      Signed PyS60 shell with all privileges
      AND
      installed it in the telephone memory instead of the SD

      Now it works but I don't know which of the two thing made it possible.

      Anyway thanks !!! :)
    • jojo
      Identical result (unpack non-sequence) as Nick on an N95 8GB. Have Py 1.4.5 for S60 3rd ed and sample scripts (ball, simplecube, snake etc) run fine. Appreciate any assistance.
    • @jojo that is strange i happen to have the exact same setup as you and it works fine for me. what does this simple script give you

      import location
      print location.gsm_location()

      this should print the gsm cell id details you are connected. If this does not give you that then try these.

      * Have you signed the python shell with the proper privileges? go thru https://www.symbiansigned.com/app/page/public/o... and have the shell signed with all the privileges. location is a privileged call and the app needs to have the privileges.

      * Try installing the python packages on the primary storage instead of the memory card.
    • @nick looks like location.gsm_location() is not returning the cell id as expected. have you tried sample scripts which do this call?
    • nick
      Hi

      I'm very new to all of this and I can't make it work on my e71..
      I use pys60 1.4.5.
      Traceback (most recent call last):
      File "E:\private\2000b1a5\default.py",line 81, in menu_action
      f()
      File "E:\private\2000b1a5\default.py",line 65, in query_and_exec
      execfile(script_list[index][1].encode('utf-8'), script_namespace.namespace)
      File ""e:\python\cell.py", line 37, in ?
      (mcc, mnc, lac, cellId) = location.gsm_location()
      TypeError: unpack non-sequence

      Name of your script is cell.py
      Any idea why it doesn't work ? Maybe I haven't installed pys60 properly (although all example scripts provided run well) ?
      Thanks for your help !
    • @johann thanks for the report, i will try to get a revised version out which does proper error reporting so it makes it a little bit clear where the issue is.
    • Johann Aman
      Sorry, @jebu, I checked it again, your script goes wrong, though that another script returns 39.504583 -0.356747, and this is correct, because I know those CellID data came from Valencia, Spain. I'm bad in Python:), so I can only report this. Thanks!
    • @sumanthmara, cant help you much this is a snippet for python on S60. I have not tried packaging it into a SIS. you could ofcourse use it from c++, its a plain http call, you have to marshal and unmarshal the arguments as per the format expected by the service, which is all that the code above does.
    • @johann I verified the script with the negative lat long and this works fine since the unpack is properly interpreting it as a signed integer. The CellID and LAC that you have mentioned give back a not found response from google. Check the script against CID=4995 LAC=6045 MNC=380 MCC=310 and it properly returns Lat = 37.871034 Lon = -122.273795. Its possible that because the script you pointed is using MCC and MNC its able to locate it, the script that I have able only uses the CID and LAC.
    • Johann Aman
      Hi! Your script crashes when running from my laptop (witout code location.gsm_location()) for e. g. this query: MCC=214, MNC=4, LAC=24601, CellID=30146631, though this data exists in Google database; this script: http://discussion.forum.nokia.com/forum/showthr... returns correct result (see comment about negative coords). Thanks!
    • SumanthMara
      Hi ALL,
      I download above source code and build sis file for it on symbian s60 3rd edition.but when I try to open to application it closes back in 2-3 secs of time.what would be the problem.And can I use this code into my symbian c++ application code..?If yes ..How?
    • Zea
      Thanks for you code!! It's so good!
    • suhail
      how to track mobile number with the help of google map in india. i have lost my number?
      waiting for reply.
      suhail
    • ninj4
      hi! i tried your python script but it doesn't work !
      i have this error
      error: unpack str size does not match format
      on line 26
    • snipe
      @jebu:

      I tried google maps on my mobile and it returned me "this location is currently unavailable". You have right ;) Thanks for the answer :)
    • @snipe, if the script threw an unpack error that usually means that the google tower lookup service does not have the lat long for the specific tower that you are querying for. Good check would be to try running google maps on your mobile and see if it shows you the location without turning on GPS.

      Yeah that script is bare bones i have not done error checks for handling these cases.
    • snipe
      @jebu:

      My phone returns mcc, mnc, lac and cid, but cid is > 65535 and script throw me an error :-/ I think because of pack/unpack format.
    • @snipe no idea of how this gel's with UMTS. This script essentially maps the cell tower to which your phone is currently connected to a physical location. On GSM networks this is identified by 4 numbers mcc (countyr) , mnc (network) , lac (location) and cid (cell id). If this information is available in a UMTS network this should work.
    • snipe
      Hi

      I have one question about this script. How to change something to work this with UMTS?
    • Hi Dario,

      I have no clue why mcc and mnc are not used but i'm not a GSM expert. If they can get a fix with lac and cid, that might be good enough. Most other cell tower mapping services do use all four of the parameters, Google is the only one that i have seen using just two of them.
    • Dario
      Hi jebu

      First, thanks for your answer.
      I have install now PYS60 1.4.4 and it works. Super;-)

      I have a last question about the code. If i look the code, i see just 2 parameter for the cell tower information (see doLookup(cellId, lac.....) But the other 2 parameters like "mcc, mnc" for country code etc. are not send to google. So i don't understand where google knows the country and Area code? Maybe you can explan me, i've want understand what's going on.

      Thanks, Dario
    • Hi Dario,
      It should work by default on other phones too as long as you have python and the location API on python available. I have tested on PyS60 1.4.3 and above. Do you have a specific error that you are getting? One thing that i have seen is that the google web service is blocked from some IP ranges so that might be one cause. But if you have the error trace from python that would definitely help to track it.

      --
      Jebu
    • Dario
      Google cell tower mapping with Python on S60
      Published by jebu on July 11, 2008 in Python

      Hi
      I've a Nokia 6110 Navigator and want to use the Python script "Google cell tower mapping with Python on S60", but it don't work. What i must change that would work on other Phone?

      Thanks for your answer.
      Dario
    • kael
      Thanks for this code !
    blog comments powered by Disqus