Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 124, АПРЕЛЬ 2009 г.

Навигация без GPS. Как определить свои координаты по IP, GSM/UMTS и Wi-Fi

Степан «Step» Ильин (step@gameland.ru)




Тысячи лет назад о такой штуке, как GPS, никто не мог даже мечтать. Но моряки и путешественники отлично справлялись с навигацией, используя компас и карты, солнце и звезды. Сейчас – век цифровой, но тоже есть немало способов определить месторасположение без всяких там систем глобального позиционирования.

Спору нет, GPS - классная штука, но что делать, если приемника под рукой нет? Далеко не у каждого есть встроенный чип в мобиле. Да и владелец автомобиля совсем не обязательно успел обзавестись устройством навигации. Так как же быть? Если не брать в расчет редкие и экзотические варианты, то основных способа три:

  1. Определить IP и с помощью специальной базы данных определить город, в котором находишься, и нередко - долготу и широту.
  2. Определить расположение по находящимся рядом базовым станциям GSM/UMTS. Это возможно при наличии базы данных с идентификаторами вышек и их координатами.
  3. Использовать для вычисления широты и долготы информацию о находящихся рядом точках доступа Wi-Fi, передав запрос с их характеристиками на специальный сервер.

Итак, начнем с самого простого.

IP нам в помощь

Когда мне нужно проверить свой внешний IP, чтобы убедиться, например, что я включил VPN или прокси, я всегда использую сервис ip2location.com. Приятно, что помимо самого IP-адреса выводится информация о провайдере, его месторасположении (город, страна, штат), а зачастую… еще и координаты. Само собой, в базе не будут указаны широта и долгота для самого обычного клиента интернет-услуг. Как правило, данные указываются для провайдера, реже - для крупных компаний, имеющих большие диапазоны статических IP. Получается, что, подключившись к сети (например, через любой открытый hotspot или просто воспользовавшись компьютером), можно с большой долей вероятности определить примерное место, где ты находишься. Конечно, способ примитивный - и более того, самый неточный из всех представленных в этой статье. С другой стороны, это реальный шанс определить месторасположение, всего лишь открыв страничку в интернете. А если сварганить специальный трекер, установить его на КПК и отслеживать IP-шники, которые он получает при коннекте к открытым WiFi-сетям, то реально вычислить передвижения девайса.

Использовать сервис в чистом виде, а именно – переходя браузером по ссылке ip2location.com, скучно и беспонтово. Месторасположение на карте не увидеть, лог не сохранить, а сама страница слишком тяжелая для мобильного инета - короче, это не наш путь. От сервиса нам нужно только одно - база соответствий разных IP-адресов их расположению, которую ip2location предлагает приобрести за довольно разумные деньги. Само собой, подобные базы быстро расплываются по варезным порталам и торрентам, причем в двух вариантах: .cvs (текстовом) и .bin (бинарном). С такой базой несложно заточить любое приложение под себя. Правда, IP-адрес в базе хранится в специальном цифровом виде без точек и разделения на октеты, но следующая PHP-функция поможет привести обычный IP-шник к нужному виду:

function Dot2LongIP ($IPaddr)
{
if ($IPaddr == "") {
return 0;
} else {
$ips = split (".", "$IPaddr");
return ($ips[3] + $ips[2] * 256 + $ips[1] * 256 * 256 + $ips[0] * 256 * 256 * 256);
}
}

Имея такой ключ для адреса, ничего не стоит найти соответствующие ему координаты в текстовой базе. Если же в распоряжении будет база в BIN-формате, то задача еще проще. Для Perl, C, Python, PHP, Ruby, C#, VB.NET, Java, Visual Basic сервисом подготовлены готовые модули (http://www.ip2location.com/developers.aspx), которые легко использовать в своем проекте. В случае с PHP достаточно закинуть на сайт модуль IP2Location.inc.php и создать несложный скриптик:

<?php
include("IP2Location.inc.php");
$ip = IP2Location_open("samples/IP-COUNTRY-SAMPLE.BIN", IP2LOCATION_STANDARD);
$record = IP2Location_get_all($ip, "_IP-АДРЕС_");
echo "$record->country_long : " . $record->country_long;
echo "$record->city : " . $record->city;
echo "$record->isp : " . $record->isp;
echo "$record->latitude : " . $record->latitude;
echo "$record->longitude : " . $record->longitude;
IP2Location_close($ip);
?>

Можно просто вывести на экран, залогировать или отобразить на карте с помощью Google Maps, передав широту и долготу в качестве параметра:

http://maps.google.com/maps?f=l&hl=en&q='+query+'&near='+str(lat)+','+str(lng)+'&ie=UTF8&z=12&om=1

Используем мобильные вышки!

Старая байка о том, что спецслужбы могут найти человека по сигналу от его мобильника - один из тех случаях, когда на самом деле все так и есть. Да чего там спецслужбы, если на это способна даже совершенно бесплатная программа Google Maps (www.google.com/gmm).

По сути, это удобная оболочка для доступа к одноименному веб-сервису, позволяющему смотреть фотографии местности со спутника, рельеф и – во многих случаях – карты с возможностью проложить маршруты. Думаю, рассмотреть крышу своего дома через maps.google.com пробовали все. Работать с таким сайтом через браузер на мобильном телефоне (даже если это сверхскоростная Opera Mini) крайне сложно, поэтому в Google, подсуетившись, сделали удобную оболочку для просмотра карт. Оформили ее в виде приложения для самых разных платформ – от обычных мобильных, поддерживающих Java, до смартфонов и коммуникаторов на Windows Mobile и Symbian S60 3rd Edition, престижных BlackBerry, а теперь еще и Android, к которой мы пока не привыкли, но очень скоро будем воспринимать как одну из основных платформ для телефона. В том же iPhone Google Maps встроена по умолчанию. Так вот, помимо удобного просмотра этих самых карт и спутниковых снимков, у утилиты есть одна замечательная кнопка «Мое месторасположение». Один клик - и на карте отмечается нахождение телефона. Да, для владельцев трубок с GPS это сущая ерунда: нашли чем удивить! Но надо видеть лица тех пользователей, которые видят на экране свое месторасположение, хотя никаких навигационных приблуд у них не было и в помине! Впрочем, это только так кажется.

Телефонная трубка всегда находится в зоне действия, по меньшей мере, одной базовой станции сотовой сети. Ну, или не находится - но в этом случае от нее толку не более чем от кирпичика. Любая из базовых станций имеет некоторый набор параметров, которые получает телефон - благодаря этому каждую БС можно распознать. Один из таких параметров – CellID (сокращенно CID) - уникальный номер для каждой соты, выданный оператором. Зная его, ты можешь распознать базовую станцию, а зная расположение базовой станции, можешь, понять где находишься. Точность варьируется от нескольких сотен метров и до нескольких километров, но это неплохая отправная точка, чтобы разобраться с координатами.

Получается, имея в наличии табличку, где в соответствии с каждой базовой станцией будет сопоставлены ее координаты, можно примерно вычислить положение абонента. А раз Google Maps может так лихо определять месторасположение человека, то у него такая база данных есть. Но откуда? Расположение базовых станцией различных операторов – пускай и не секретная, но вряд ли открытая информация. Даже учитывая масштабность проектов Гугла, с трудом можно поверить, что тот договорился со всеми операторами сотовой связи - определение местоположения работает в любом месте (забегая вперед, скажу, что правильнее говорить «может работать в любом месте»). Ответ скрывается в лицензионном соглашении во время установки программы, на который мы, конечно же, забили и сразу нажали «Я согласен» :). А ведь там черным по белому написано, что, принимая соглашение, мы разрешаем программе анонимно передавать на сервер информацию о текущем расположении и информации о сотовых вышках поблизости. Да! Базу данных с примерными координатами базовых станций составляют для Google сами пользователи Google Maps, имеющие на борту своих телефонов и коммуникаторов встроенный приемник GPS. И что самое классное: даже при полном отказе от использования как официальных, так и неофициальных (собранных энтузиастами с помощью специальных сканнеров - подробнее читай во врезке) баз с расположением станций, функция для определения месторасположения работает на «ура». Проверь сам.

GSM-навигация своими руками

Возможность посмотреть в программе свое расположение - само по себе здорово, но разве ж можно отказаться от соблазна использовать базы Google'а в корыстных целях? Как тебе, например, идея создать собственный трекер, который определял бы текущее расположение БС и передавал его на наш сервер? Эдакий жучок средствами самого телефона, который работает везде и всегда!

Компания не разглашает протокол взаимодействия Google Maps, не публикуя API, однако его легко вскрыли, просто проснифав трафик и реверснув часть кода. Помимо http-запросов на загрузку карт, отчетливо видно, что программа отправляет запросы по адресу http://www.google.com/glm/mmap, причем именно тогда, когда пользователь желает получить текущее месторасположение. Вот и попался наш скриптик – в качестве параметров ему передаются технические значения базовой станции: MCC, MNC, LAC и CellID.

  • MCC - код страны (для России - 250)
  • MNC - код сети (МТС - 01, Мегафон - 02, Билайн - 99 и т.п.)
  • LAC - код локальной зоны (другими словами, совокупности базовых станций, обслуживаемых одним контроллером)
  • CellID (CID) - идентификатор, состоит из номеров базовой станции и сектора

Зная, куда посылать данные, осталось эти значения получить! Наиболее простой способ - прямо в программе Google Maps перейти в «Справку», там щелкнуть «Общие сведения», и в самом конце этой странички будет строка с параметрами в формате myl:MCC:MNC:LAC:CellID. Куда больший простор для деятельности предоставляют специальные программы netmonitor'ы: с их помощью можно логировать параметры при переключении от одной станции к другой, извлекать параметры «соседей» (находящихся в поле зрения других БС), да и просто получать куда более подробную информацию. Для каждой платформы есть свои реализации нетмониторов с различными возможностями - ты можешь выбрать программу под себя, воспользовавшись врезкой.

Теперь, когда все необходимые параметры получены, можно обратиться на сервер и попробовать получить ответ. Приведу для этого несложный скрипт на Python'е, который написал наш соотечественник Skvo и опубликовал на форуме forum.netmonitor.ru:

net, cid, lac = 25002, 9164, 4000
import urllib
a = '000E00000000000000000000000000001B0000000000000000000000030000'
b = hex(cid)[2:].zfill(8) + hex(lac)[2:].zfill(8)
c = hex(divmod(net,100)[1])[2:].zfill(8) + hex(divmod(net,100)[0])[2:].zfill(8)
string = (a + b + c + 'FFFFFFFF00000000').decode('hex')
try:
data = urllib.urlopen('http://www.google.com/glm/mmap',string)
r = data.read().encode('hex')
if len(r) > 14:
print float(int(r[14:22],16))/1000000, float(int(r[22:30],16))/1000000
else:
print 'no data in google'
except:
print 'connect error'

Для запуска, естественно, потребуется интерпретатор Python'а (обязательно 2-й ветки, потому как на 3-й не запустится), который можно скачать с сайта http://python.org/download/releases. В первой строке скрипта, как несложно догадаться, необходимо подставить NET (MCC и MNC, написанные слитно), CID, LAC. В результате скрипт сформирует запрос на сервер http://www.google.com/glm/mmap и отправит его. Если базовая станция с этими параметрами есть в базе, то на экран выведутся координаты, например, «59.200274 39.836925». В противном случае скрипт выдаст ошибку: «no data in google».

Любителям программировать не составит труда добавить пару строчек, например, по указанным NET и LAC перебрать все варианты CID (от 1 до 65536), и, посмотрев, какие сектора имеются у Гугла, узнать их примерные координаты. Если тебе неохота морочить голову скриптами, на наш диск мы выложили GUI-программу, написанную на C# (исходники прилагаются). В этом случае ты автоматически получишь еще и ссылку, отображающую координаты на сайте Google Maps. Ссылки на реализации на других языках смотри в боковом выносе.

Интересно, что на сервер передаются всего лишь три параметра, причем ключевыми являются только значения LAC и CellID. А MCC/MNC необходимы на тот случай, если в базе есть несколько пар с одинаковыми LAC, CellID. При этом телефон может получать намного больше информации о текущей станции – взять хотя бы мощность сигнала, однако эти параметры в расчетах не используются. Получается крайне простой алгоритм. Один сектор - одна координата, независимо от того, находится ли пользователь в 100 метрах от базовой станции или в километре от нее, координата будет одинаковая!

Отдельно хочу сказать, что замечательный проект «Яндекс.Карты», который я особенно люблю за возможность отображения точек, имеет точно такой же функционал. И ровно так же, как и Google, предоставляет своей программе данные о точке по запросу с указанием Cell ID, LAC, NET параметров:

http://mobile.maps.yandex.net/cellid_location/?&cellid=%d&operatorid=%d&countrycode=%d&lac=%d

Единственное отличие в том, что ответ сервис «Яндекса» возвращает в XML-формате, который легко и удобно парсится для извлечения любых параметров.

Как заставить работать навигационные программы

Какой бы замечательной ни была программа Google Maps, использовать ее в качестве навигационного инструмента, мягко говоря, затруднительно. Было бы здорово, пускай и примерные, но все-таки координаты скормить нормальной программе навигации, с хорошими картами, подробной адресацией и проработанными алгоритмами прокладки маршрута. Некоторые программы, например, «Навител» и «Автоспутник» имеют еще один плюс: они умеют подгружать информацию о пробках и учитывать ее при составлении маршрута. Чисто теоретически, ничего не стоит написать подобное приложение самому. Алгоритм прост:

  1. Получаем текущие координаты при каждой смене базовой станции;
  2. Отправляя запрос на спутник, получаем примерные координаты;
  3. Эмулируем в системе последовательный порт и в простом формате NMEA, который используют GPS-навигаторы, транслируем туда текущие координаты.

Именно этот принцип лежит в программе VirtualGPS (www.kamlex.com), предназначенной для устройств на платформе Windows Mobile 2003, WM 5, WM 6, WM 6.1. Бесплатная lite версия программы определяет текущее расположение по вышкам сотовой связи и эмулирует GPS. После запуска прога создает в системе новый порт, который нужно указать в настройках любимой навигационной программы - и та, ничего не подозревая, будет считать, что подключена к настоящему GPS-приемнику.

На что способен Wi-Fi

Будучи раздосадован тем, что большинство WiFi-точке в городе либо закрыты, либо платные, подумай о том, что и им можно найти применение. Полагаю, не надо говорить для чего :). Принцип точно такой же: определив все точки доступа поблизости, отправляем информацию о MAC-адресах (добавляя при желании идентификатор сети SSID) на специальный сервис. Тот проверяет их координаты и выдает тебе твое примерное расположение. Такая технология давно функционирует в Штатах, где покрытие Wi-Fi зашкаливает настолько, что скрыться от него уже, похоже, негде. WPS (Wi-Fi Positioning System) предоставляет компания SKYHOOK Wireless (www.skyhookwireless.com), разработавшая клиентские приложения для разных платформ и собрав первоначальную базу с точками доступа. Быстро появились и альтернативные приложения, которые, используя API-сервиса, получают координаты пользователя. Среди них - замечательный плагин для Firefox'а Geode (http://labs.mozilla.com/geode_welcome), который подставляет информацию о текущем местоположении на любом веб-сайте (во время создания нового поста в блог, например).

Увы, в России хоть как-то заставить работать SKYHOOK мне так и не удалось. Зато наши соотечественники вплотную взялись за реализацию подобной идеи, воплотив в жизнь сервис Wi2Geo (wi2geo.ru), который мне почему-то очень хочется назвать Wi2Go :). Ребята уже сейчас предоставляют приложения для Windows Mobile, Symbian, Windows и Mac OS X, а для навигации используют базу IP-адресов, информацию о ячейках GSM и, собственно, точках доступа Wi-Fi. Базы никому не запрещено использовать в своих целях, воспользовавшись открытым API (http://labs.wi2geo.ru/basicapi.php). Огорчает только, что проект будет развиваться только в тех городах, где большое покрытие Wi-Fi. А таковым пока можно назвать только Москву.

А как же трекинг?

Выше мы говорили о трекинге пользователя - системе, позволяющей в реальном времени отследить положение пользователя на карте. Неплохо, если бы подобную штуку установили на свои телефоны все друзья. Тогда ничего бы не стоило узнать, кто где, и при необходимости - договориться о встрече. Ребята из Google реализовали это в функции Google Latitude, с недавнего времени доступной опять же пользователям мобильных Google Maps. К сожалению, через браузер просмотреть расположение друзей можно только в Штатах, но ведь ничего не мешает использовать американский прокси?

Есть и другой вариант. На сайте http://forum.xda-developers.com/showthread.php?t=340667 совершенно бесплатно можно скачать специальную программу для трекинга, клиентская часть которой устанавливается на коммуникатор на базе WM, а серверная - на любой веб-сервер. Далее положение объекта можно просмотреть через программу Google Earth. Реально работающее решение для бизнеса, которое с учетом открытых исходников несложно доработать под себя!

Программы NetMonitor

Чтобы понимать, какую базовую станцию телефон использует в текущий момент, и получить ее параметры, понадобятся специальные программы. К сожалению, универсальной программы нет, поэтому для каждой платформы придется найти подходящий инструмент!

  • Symbian: FieldTest, CellTrack, Best GSMNavigator
  • Windows Mobile 2005: GPS Cell
  • Windows Mobile 5.0/6.0: NetMonitor32, WMCellCatcher, CellProfileSwitcher (замечу, что не все программы работают со всеми радио-прошивками)

О базовых станциях сотовых сетей

В статье я упоминал о неофициальных базах данных с расположением вышек различных сотовых сетей. В интернете существует немало проектов, где энтузиасты делятся собранной нетмониторами информацией. Из иностранных это – celldb.org/aboutapi.php, www.opencellid.org/api, http://gsmloc.org/code, cellid.telin.nl. Каждый из них имеет простой API для получения координат с помощью обычного HTTP-запроса, при этом в качестве параметров указываются традиционные MCC, MNC, Cell ID и LAC.

Отдельно хочу упомянуть наш русский проект Netmonitor.ru, в котором собрана инфа о большом количества БС Мегафона, МТС, Билайна, ТЕЛЕ2 и даже Skylink. К тому же, на сайте располагается еще и крупнейший форум для исследователей сотовых сетей.

WWW

Реализация работы с базой данных Google Maps

DVD

Все описанные скрипты, утилиты для трекинга и навигации ты найдешь на нашем диске.

Содержание
ttfb: 5.9499740600586 ms