Сбор данных GSM сети с MikroTik RB951G-2HND

Автор: | 2017-01-04

Маршрутизаторы MikroTik RB951G-2HND обладают портом USB, к которому можно подключить 3G/4G-модем для подключения к Интернет.
С USB-модемом, как и с любым другим, можно работать при помощи AT-команд. GSM-модемы, как правило, поддерживают команды получения данных о сети.
Эта заметка о нюансах работы с AT-командами на маршрутизаторах MikroTik.

На MikroTik, доступ к модему осуществляется командой /system serial-terminal channel=chnum, работа с которой в чём-то похожа на программу cu. Но фатальным недостатком данного метода, является то, что работа возможна только в интерактивном режиме, что не способствует автоматизации.

Собираем инфу для работы
Если в настройках PPP-соеденения нажать «Advanced Mode», то можно увидеть поля Data Channel и Info Channel. Это каналы модема отвечающие за, соответственно, передаваемые данные и информацию о статусе. Если подключиться к каналу информации при помощи команды /system serial-terminal usb1 channel=3, то на экран будет бесконечно сыпаться техническая информация о текущем статусе модема вот какого, малоинформативного вида:

Выполним команду /interface ppp-client info ppp-out1
Вывод будет следующим:

Команда опять же интерактивна и передать данные в скрипт не позволяет.
Не сдаёмся и выполним /interface ppp-client info ppp-out1 do={ :global modemsn $»serial-number»;}
Команда запустилась в бесконечном цикле и создала глобальную переменную $modemsn, в которую положила значение, идущее после serial-number:. После завершения команды по Ctrl-C переменная остаётся.
Также можно заметить, что команда позволяет передать пользовательские данные через параметр user-command, правда разметка вывода несколько поедет, но это не беда.
Открываем справочник AT-команд и ищем те, которые нас интересуют, а именно:

      AT+CIMI — информация об IMSI номере SIM карты
      AT+CREG? — тип регистрации сети
      AT^ICCID? — информация о серийном номере SIM карты

Чтобы команда AT+CREG выдавала инфу о базовых станциях, предварительно нужно выполнить AT+CREG=2. Выполняем /interface ppp-client info ppp-out1 user-command=»AT+CIMI\r\nAT+CREG\?\r\nAT^ICCID\?» do={ :global imsi $»manufacturer»; :global cell $»model»; :global iccid $»revision»; :global signal $»signal-strengh» }, что даст следующий вывод:

а в соответствующие переменные упадут нужные данные, различной степени сырости.
Теперь, вооружившись полученными знаниями, напишем скрипты, которые будут получать данные за нас.

Скрипты
Т.к. у разных модемов, номер канала данных может различаться, то нам нужен скрипт, который будет выполняться при старте маршрутизатора и производить инициализацию ppp-соединения.

По непонятной мне причине, при первом старте маршрутизатора после сброса, правило планировщика, помеченного как start-up, не срабатывает, хотя при последующих запусках отрабатывает как положено. В связи с этим, добавляем в шедулер правило c интервалом 20 сек., которое вызовет скрипт, устанавливающий этому правилу интервал в start-up, в результате, при первом старте скрипт выполнится по таймеру, а во все последующие по событию start-up. Попутно, скрипт проходит все соединения и для каждого получает количество каналов модема, по очереди, от 1 до MAX_CHANNELS, ставит в качестве канала информации в ppp-соединении, пытается получить данные и если данные получены, то оставляет текущий канал и разрешает это соединение. В качестве строки инициализации устанавливает AT+CREG=2 (см. выше зачем).

Теперь можно собирать данные.
Добавим задание в планировщик, которое будет выполнять скрипт раз в час.

Скрипт создает фоновое задание с командой /interface ppp-client info …, которая, как мы помним, является интерактивной, ждёт 10 секунд, завершает задание, парсит полученные данные и выполняет запрос к серверу, в котором передаёт параметры.

Сервер
Ставим web-сервер, поддержку cgi и СУБД. В моём случае это nginx, PHP и SQLite. Также рекомендую поднять на сервере SLL, хотя бы самоподписанный — 2017 год как-никак, безопасность и всё такое…
На web-сервере кладём файл cellstat.php следующего содержания:

Находясь в папке со скриптом, выполним sqlite cellstat.sqlite и создадим таблицу, в которую будут складываться данные и не забудем назначить права на запись пользователю www:

Скрипт выбирает последнюю запись с переданным серийным номером маршрутизатора и если новые данные совпадают со старыми, то обновляет время записи, дабы не раздувать базу, иначе добавляет новую запись.

Имея данные о базовых станций и уровне сигнала, можно получить координаты устройства через API геолокации Яндекса или Google. К стати, в моём случае Яндекс отрабатывал лучше, да и отечественный производитель опять же, что улучшает карму. И это вполне себе работает в местах более-менее близких от населённых пунктов. Где-нибудь по среди тайги, в гефтегазоносных местах нашей необъятной Родины, конечно же — нет, но как правило координаты этих мест обычно сообщаются при заезде и ничего не мешает не получать, а отсылать данные о БСках и уровне сигнала, дабы внести свой вклад в гоолокацию, за что + в карму, опять-таки.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *