На­вер­няка у тебя где‑то завалял­ся ста­рый смар­тфон на Android, а может, даже и не один. Я рас­ска­жу, как сде­лать из него надеж­ную сиг­нализа­цию для тво­его велоси­педа, да и вооб­ще для любого дви­жимо­го и нед­вижимо­го иму­щес­тва. Прог­рамми­ровать будем на Python 3, при этом набор фун­кций при­ложе­ния без тру­да может быть изме­нен и рас­ширен для решения дру­гих насущ­ных задач.

Не­дав­но я закон­чил сбор­ку сво­его элек­тро­вело­сипе­да. Теперь я могу не толь­ко колесить в близ­лежащих пар­ках, но и исполь­зовать его в качес­тве пол­ноцен­ного средс­тва перед­вижения. Ско­рость до 55 км/ч поз­воля­ет уве­рен­но дер­жать­ся в город­ском потоке машин, а бес­шумность, отсутс­твие запаха бен­зина плюс неболь­шая мас­са — спо­кой­но ездить по пар­кам и тро­туарам, а так­же хра­нить тран­спорт дома. В общем, сплош­ные плю­сы. Ког­да надо при­пар­ковать­ся и пой­ти по делам, на раме моего велоси­педа защел­кива­ется U-образный замок Kryptonite. Одна­ко мотор и новень­кий акку­муля­тор уже не дела­ют раму самой дорогой частью велоси­педа. И поэто­му остро вста­ет воп­рос защиты тран­спортно­го средс­тва от тех, кто тоже сле­дует за прог­рессом, но не жела­ет на него тра­тить­ся. Короче говоря, от воров.

Име­ющиеся в про­даже сиг­нализа­ции для велоси­педов прос­то отпу­гива­ют воришек гром­ким зву­ком. Поэто­му я решил сде­лать собс­твен­ное устрой­ство с обратной связью. Пер­вое, что приш­ло в голову, — раз­работать сиг­нализа­цию на мик­рокон­трол­лере. Но затем я подумал: почему бы не исполь­зовать ста­рый смар­тфон, который лежит без дела? Ведь у него на бор­ту уже есть все необ­ходимое, что­бы решить пос­тавлен­ную задачу: мобиль­ный интернет, GPS для опре­деле­ния мес­тополо­жения, раз­личные дат­чики для обна­руже­ния внеш­них воз­дей­ствий, камера и сен­сорный экран. В общем, воп­рос с железом был решен, оста­лось толь­ко реали­зовать прог­рам­мную часть. Что­бы луч­ше понять прин­цип работы опи­сан­ного в статье устрой­ства, можешь сра­зу пос­мотреть демонс­тра­цию его работы.

 

Termux

Ес­ли ты еще не слы­шал про Termux, то сроч­но отправ­ляй­ся изу­чать мат­часть. «Хакер» уже пи­сал на эту тему. Termux — это эму­лятор тер­минала для опе­раци­онной сис­темы Android. Но пус­кай тебя не сму­щает сло­во «эму­лятор», весь код выпол­няет­ся натив­но.

Как ты зна­ешь, в осно­ве Android — ядро Linux. Termux добав­ляет к ядру минималь­ное окру­жение в виде набора ути­лит и интер­пре­тато­ра Bash. Этот набор может быть лег­ко рас­ширен хорошо извес­тной поль­зовате­лям Linux коман­дой apt install <package> (или pkg install <package>). При этом спи­сок пакетов дос­таточ­но обширный: от кон­соль­ного редак­тора Vim до окон­ной сис­темы X11 и сре­ды рабоче­го сто­ла Xfce. Все это работа­ет без прав супер­поль­зовате­ля!

Кро­ме того, всег­да есть воз­можность написать свою прог­рамму на С или даже язы­ке ассем­бле­ра. Ком­пилятор GCC так­же мож­но уста­новить из пакетов. Если есть пра­ва root, все ста­новит­ся еще инте­рес­нее: мож­но под­клю­чить репози­торий root-repo и получить дос­туп к таким прог­раммам, как tcpdump или Aircrack-ng. Для наших же целей root-пра­ва не пот­ребу­ются: все, что нам нуж­но, — это уста­новить интер­пре­татор язы­ка Python 3. К счастью, нуж­ный пакет уже име­ется в репози­тории.

Termux я рекомен­дую уста­новить из магази­на соф­та с откры­тым исходным кодом F-Droid. Если у тебя в телефо­не еще нет это­го магази­на, отправ­ляй­ся на сайт f-droid.org и ска­чивай соот­ветс­тву­ющее при­ложе­ние. Далее в самом F-Droid в стро­ке поис­ка напиши Termux и уста­нови сле­дующие при­ложе­ния: Termux, Termux:API и Termux:Widget. Если Android на тво­ем телефо­не ниже седь­мого, то тебе понадо­бит­ся уже архивная вер­сия. Ее ты можешь взять тут. Пос­ле уста­нов­ки запус­кай Termux и инстал­лируй необ­ходимые пакеты и модули питона, которые нам понадо­бят­ся. Для это­го в открыв­шемся тер­минале набери сле­дующие коман­ды:

pkg update
pkg install termux-api
pkg install openssh
pkg install qrencode
pkg install python
pkg install pip
pip install pystun3

Об­рати вни­мание, что pystun3 в пос­ледней стро­ке — это модуль питона, поэто­му мы уста­нови­ли его коман­дой pip install, а не pkg install.

 

Termux:API

Ко­ман­дой pkg install termux-api мы уста­нови­ли под­дер­жку Termux-API, что поз­воля­ет вза­имо­дей­ство­вать с сис­темой Android из коман­дной стро­ки: делать фото, записы­вать и вос­про­изво­дить звук, подавать виб­росиг­нал, получать информа­цию с дат­чиков телефо­на, выводить диало­говые окна и про­чее. Что­бы изу­чить все воз­можнос­ти Termux-API, набери в коман­дной стро­ке termux-, наж­ми два раза Tab, и уви­дишь все дос­тупные ути­литы. Фун­кци­ональ­нос­ти впол­не дос­таточ­но, что­бы орга­низо­вать вза­имо­дей­ствие с поль­зовате­лем с помощью всплы­вающих сооб­щений (termux-toast), диало­говых окон (termux-dialog) и уве­дом­лений (termux-notification).

Для сиг­нализа­ции нам понадо­бит­ся информа­ция с дат­чика уско­рения — аксе­леро­мет­ра. Для это­го пос­мотрим сна­чала, какие дат­чики при­сутс­тву­ют в телефо­не:

termux-sensor -l

В получен­ном спис­ке дат­чиков ищи тот, в наз­вании которо­го есть сло­во accelerometer. Нап­ример, в моем телефо­не име­ется BMI160 Accelerometer и Linear Acceleration. Теперь мож­но поп­робовать опро­сить дат­чик такой коман­дой:

termux-sensor -s "BMI160 Accelerometer" -n 1

В моем слу­чае вывод этой коман­ды име­ет сле­дующий вид:

{
"BMI160 Accelerometer": {
"values": [
0.35223388671875,
0.20556640625,
9.873580932617188
]
}
}

Об­рати вни­мание на две вещи. Во‑пер­вых, вывод информа­ции по одно­му изме­рению занима­ет девять строк. В даль­нейшем мы исполь­зуем это для пар­синга выход­ного потока с дат­чика уско­рения. Во‑вто­рых, уско­рение выводит­ся в виде его ком­понен­тов по трем прос­транс­твен­ным коор­динатам. Если ты еще не забыл школь­ный курс физики, то уже сооб­разил, что сум­ма квад­ратов этих величин даст нам квад­рат уско­рения. Его‑то мы и будем вычис­лять для опре­деле­ния дви­жения телефо­на.

Ес­ли в пре­дыду­щей коман­де опус­тить параметр -n, то дан­ные с дат­чика будут выводить­ся неп­рерыв­но с интерва­лом в одну секун­ду. Интервал, в свою оче­редь, мож­но изме­нить, добавив ключ -d <число миллисекунд>. Этим мы и вос­поль­зуем­ся в прог­рамме. Дат­чик уско­рения дос­таточ­но чувс­тви­тель­ный, что­бы опре­делить не толь­ко переме­щение тво­его девай­са, но и виб­рацию от лег­кого уда­ра по сто­лу, на котором лежит устрой­ство.

 

Предварительная подготовка

Пи­сать код мож­но пря­мо на телефо­не, уста­новив любой тек­сто­вый редак­тор, нап­ример Vim или Nano. Но про­ще делать это на компь­юте­ре, а затем отпра­вить прог­рамму по SSH на телефон. Для это­го в файл ~/.ssh/authorized_keys нуж­но положить свой ключ SSH. Пос­ле чего в кон­соли Termux запус­тить демон sshd, вве­дя одно­имен­ную коман­ду. Учти, что демон sshd слу­шает нес­тандар­тный порт 8022, пос­коль­ку у него нет при­виле­гий супер­поль­зовате­ля.

Те­перь мож­но с ПК получить дос­туп к телефо­ну коман­дой ssh <IP-адрес телефона> -p 8022. Обра­ти вни­мание, что имя поль­зовате­ля мож­но не ука­зывать, Termux при­мет любое. Узнать IP-адрес телефо­на в тво­ей локаль­ной сети мож­но, вве­дя коман­ду ifconfig в кон­соли Termux. Если ты поль­зователь Windows, то для под­клю­чения исполь­зуй кли­ент Putty. Для пересыл­ки фай­ла прог­раммы из текуще­го катало­га на компь­юте­ре в Termux дос­таточ­но в тер­минале на ком­пе ввес­ти такую коман­ду:

cat program.py | ssh <IP-адрес телефона> -p 8022 "cat > program.py"

для Linux или такую для Windows:

set PATH=C:\путь\до\папки\putty;%PATH%
pscp -P 8022 program.py <IP-адрес телефона>

Ес­ли телефон под­клю­чен к домаш­ней сети Wi-Fi, Termux не очень отзывчив при соеди­нении по SSH. По всей видимос­ти, это свя­зано с перехо­дом передат­чика в телефо­не в энер­госбе­рега­ющий режим. Если ты тоже стол­кнешь­ся с такой проб­лемой, ее мож­но решить коман­дой iw dev wlan0 set power_save off, выпол­ненной от рута. А если таких прав нет, ты можешь под­клю­чить­ся к телефо­ну либо по USB-кабелю, вклю­чив режим USB-модема, либо по Wi-Fi, переве­дя телефон в режим точ­ки дос­тупа.

 

Пишем код

Прог­рамма сос­тоит из двух час­тей: кли­ент­ской и сер­верной. Кли­ент будет работать на телефо­не, зак­реплен­ном на велоси­педе, и пери­оди­чес­ки отправ­лять UDP-пакеты сер­веру — телефо­ну, который находит­ся рядом с тобой. В содер­жимом пакета может быть либо KNOCK, либо ALARM. Получив сооб­щение KNOCK, сер­вер будет знать, что кли­ент работа­ет штат­но и не име­ет проб­лем с сетью. В слу­чае сооб­щения ALARM будем про­игры­вать заранее под­готов­ленный файл со зву­ком сирены.

Итак, прис­тупа­ем к написа­нию кли­ент­ской час­ти прог­раммы, которую назовем client_alarm.py. Сна­чала сде­лаем импорт необ­ходимых модулей.

#!/data/data/com.termux/files/usr/bin/env python3
import socket
import json
from subprocess import Popen, PIPE
import os
import time
from nat import nat_traversal

Пер­вая стро­ка — это шебанг. Что­бы каж­дый раз не писать такой длин­ный путь, можешь исполь­зовать стан­дар­тный для Linux /usr/bin/env python3, а потом выз­вать ути­литу termux-fix-shebang client_alarm.py. Она испра­вит путь до прог­раммы env на под­ходящий для Termux. Далее зададим необ­ходимые кон­стан­ты.

AVERAGE = 10
KNOCK_DELAY = 5
SENSOR_NAME = 'BMI160 Accelerometer'
ACCELEROMETER_DELAY = 20
ACCELERATION_THRESHOLD = 0.1
DELAY_AFTER_ALARM = 1
RPORT = 0
RHOST = ''

Здесь AVERAGE — чис­ло изме­рений уско­рения, по которым мы будем вычис­лять сред­нее зна­чение. Усредне­ние нуж­но для более ста­биль­ной работы, что­бы исклю­чить лож­ные сра­баты­вания сиг­нализа­ции. KNOCK_DELAY — задер­жка в секун­дах меж­ду «отсту­кива­нием» на сер­вер. ACCELEROMETER_DELAY — задер­жка в мил­лисекун­дах, которая будет переда­на коман­де termux-sensor. ACCELERATION_THRESHOLD — важ­ный параметр, который опре­деля­ет порог сра­баты­вания сиг­нализа­ции. Если сде­лать его слиш­ком малень­ким, то чувс­тви­тель­ность воз­растет, но при этом мож­но получить лож­ные сра­баты­вания. Рекомен­дую подоб­рать этот параметр экспе­римен­таль­но так, что­бы добить­ся нуж­ной тебе чувс­тви­тель­нос­ти. DELAY_AFTER_ALARM — пауза пос­ле каж­дого сра­баты­вания сиг­нализа­ции. Она нуж­на, что­бы не «засыпать» сер­вер пакета­ми с сиг­налом ALARM. RHOST и RPORT — адрес, куда будем отправ­лять пакеты.

И тут воз­ника­ет проб­лема: что­бы орга­низо­вать ком­муника­цию двух устрой­ств по сети, хотя бы одно из них дол­жно иметь пуб­личный (еще говорят «белый») IP-адрес. Для это­го нуж­но либо арен­довать VPS-сер­вер, либо заказать соот­ветс­тву­ющую услу­гу у тво­его интернет‑про­вай­дера. Пос­ле чего мож­но обес­печить пря­мую видимость устрой­ств, под­клю­чив их к собс­твен­ному сер­веру, нап­ример через OpenVPN или Wireguard. Как это сде­лать, «Хакер» писал здесь. Имен­но так я и сде­лал. Но если у тебя еще нет арен­дован­ного сер­вера, то не спе­ши расс­тра­ивать­ся. Я рас­ска­жу, как соеди­нить два находя­щих­ся за NAT устрой­ства по сети нап­рямую.

 

Проходим сквозь стену

NAT (network address translation) — это механизм тран­сля­ции сетевых адре­сов, который поз­воля­ет нес­коль­ким устрой­ствам под­клю­чать­ся к хос­там в интерне­те, исполь­зуя один общий IP-адрес. На сегод­няшний день имен­но тех­нология NAT дает воз­можность более чем 20 мил­лиар­дам устрой­ств по все­му миру иметь дос­туп в гло­баль­ную сеть, при том что «белых», то есть мар­шру­тизи­руемых в интерне­те, IPv4-адре­сов все­го чуть более четырех мил­лиар­дов.

У раз­ных про­вай­деров NAT может быть нас­тро­ен по‑раз­ному. Для соеди­нения устрой­ств мы будем исполь­зовать STUN (Session Traversal Utilities for NAT) — спе­циаль­ный сетевой про­токол, который поз­воля­ет кли­енту за NAT узнать свой внеш­ний IP-адрес, а так­же спо­соб тран­сля­ции пор­та во внеш­ней сети. В дан­ном слу­чае за нас все сде­лает фун­кция get_ip_info() модуля pystun3, который мы уста­нови­ли ранее.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


rexby

В 2009 году окончил МГТУ им. Баумана по направлению "Техническая физика". Более 10 лет работал научным сотрудником в Институте радиотехники и электроники им. Котельникова РАН, а также преподавал математику и физику школьникам. Среди увлечений - электроника и программирование. Сторонник открытого ПО и ОС Linux.

Check Also

Номер триста. Колонка главреда

О приближении трехсотого номера коллеги начали мне напоминать примерно два года назад: ког…

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    9 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии