Около полугода назад мне достался миниатюрный видеосервер, применение которому я нашёл в арендуемом для мотоцикла гараже, где он всё это время благополучно работал в связке с двумя китайскими NoName IP-камерами, худо-бедно поддерживающими ONVIF, и 3G-модемом, что позволяло мне удалённо посмотреть видео с камер при оповещениях о детекции движения, к счастью совпадавшими пока только с моим приходом в гараж. Не дал этому микросерверу спокойно работать дальше я сам, так как, ещё когда только получил его в руки, из любопытства разобрал и неожиданно для себя обнаружил, что построен он на одноплатнике Orange Pi PC, который незадолго до этого, благодаря низкой цене, широко освещался в интернете, в том числе и на Geektimes, поэтому я примерно представлял его возможности.
Собственно, спустя полгода использования, в дополнение к основным функциям видеосервера мне захотелось задействовать гребёнку GPIO на его борту для подключения датчика дыма, датчика открытия двери и реле для включения сирены. Самым интересным и, на мой взгляд, сложным этапом этого хобби-проекта, я решил поделиться с сообществом, надеясь получить советы по дальнейшему развитию. Внимание: описанные дальше действия, скорее всего, лишили меня гарантии на устройство, я производил их на свой страх и риск и привожу лишь как пищу для ума, но не руководство к действию.
Исследование прошивки
Первым делом, в надежде, что видеосервер использует полноценный дистрибутив, я попробовал подключить монитор и клавиатуру к плате, но никакого сигнала на выходе HDMI не было, похоже, порт просто никак не задействован в прошивке, о чём, впрочем, и говорят разработчики, заявляя, что это устройство класса MicroNVR (Network Video Recorder), не подразумевающее никакого взаимодействия пользователя с сервером, кроме удалённого доступа. Вторая цель — ssh, порт которого на устройстве открыт, но сервер поддерживает только авторизацию по ключу, который мне никак раздобыть не удалось.
К счастью для меня, устройство базируется на той версии одноплатника, которая идёт без eMMC, и загрузка осуществляется с обычной MicroSD-карты, выступающей с торца платы. Собственно, всё что нужно для получения доступа к содержимому прошивки — вставить карту в кардридер. На 8Gb SanDisk'е расположено 3 раздела:
/dev/sdb1 on /media/user/disk type squashfs
/dev/sdb2 on /media/user/UBOOT type vfat
/dev/sdb3 on /media/user/07836191-ddf8-45ab-b02b-1103320c2e5b type ext4
Размеры разделов:
/dev/sdb1 25M 25M 0 100% /media/user/disk
/dev/sdb2 16M 2.2M 14M 14% /media/user/UBOOT
/dev/sdb3 58M 9.4M 45M 18% /media/user/07836191-ddf8-45ab-b02b-1103320c2e5b
Раздел «UBOOT», судя по всему, используется только загрузчиком U-Boot. Раздел с ext4 содержит логи (/log) основных подсистем (kern, lighttpd, line, netcfgd, syslog) и настройки сервервера видеонаблюдения, доступные изменению пользователем (/lib/line). А на разделе «disk» со squashfs (compressed read-only) расположены уже все файлы ОС и программ. Получается, операционная система и логическая часть со всеми «Аналитиками» и «Облаками» умещена разработчиками в 25 Мб, что совпадает с размером обновлений на их сайте, т.е. заменяется вся прошивка целиком, а не только ПО видеонаблюдения.
Основной раздел содержит привычный набор директорий:
bin dev factory media root sbin tmp var
boot etc lib proc run sys usr
В целом, ничего необычного в дереве каталогов нет, всё на своих местах. Запускаемые runit-сервисы лежат в /etc/service:
dropbear hwclock-fix lighttpd line netcfgd socklog-klog socklog-unix
Увидев в списке lighttpd, я решил проверить, смогу ли использовать его для своих целей. Запускается он с конфигурацией:
server.modules += ( "mod_cgi" )
$SERVER["socket"] == ":19587" {
include_shell "/usr/share/adm/lighttpd-gencert"
server.document-root = "/usr/share/adm/www"
cgi.execute-x-only = "enable"
cgi.assign = ( "" => "" )
}
Содержимое /usr/share/adm/www:
datetime firmware password profiles sysinfo timezones
factory-reset locale profile settings timezone
По набору скриптов понятно, что HTTP-сервер предоставляет возможности для утилиты, позволяющей изменить системные настройки устройства и обновить прошивку, получается, всё это можно сделать и без её участия по протоколу HTTP. Например, получить архив со сведениями о системе можно и через браузер:
https://192.168.1.2:19587/sysinfo
Сервер использует генерируемый самоподписанный сертификат и стандартную авторизацию с возможностью поменять пароль (на устройстве хранится только хэш). Готовый HTTPS-сервер с авторизацией и очень простой возможностью добавить свой скрипт сэкономил мне кучу времени и я приступил непосредственно к GPIO.
Доработка прошивки
Простой запрос в гугле «Orange Pi PC GPIO» сразу вывел меня на команды:
echo 0 > /sys/class/gpio_sw/PA1/data
echo 1 > /sys/class/gpio_sw/PA1/data
Найти имена портов тоже не было проблемой:
Посмотрев на имеющиеся скрипты, я создал по их примеру новый с именем alarm и содержимым:
#!/bin/sh
set -e
. ../lib/devline/http.sh
. ../lib/devline/auth.sh
is_auth || http_err_unauth
[ "$REQUEST_METHOD" = "PUT" ] || http_err_method PUT
value="$(head -c "$CONTENT_LENGTH" | tr -d '.')"
echo $value > /sys/class/gpio_sw/PA3/data
echo "Content-Type: text/plain"
echo
echo OK
Обновление прошивки
Мне оставалось только добавить новый файл на устройство, что нельзя сделать обычным копированием, т.к. целевая файловая система работает только на чтение. Наверное, существуют разные способы внесения изменения в squashfs, но я пошёл самым простым, на мой взгляд. Первым делом я считал образ раздела в файл:
dd if=/dev/sdb2 of=sdb2.img
Затем распаковал squashfs в обычную директорию:
unsquashfs sdb2.img
Скопировал скрипт alarm по нужному пути в squashfs-root и собрал из неё новый squashfs образ:
mksquashfs squashfs-root sdb2-new.img
Который потом залил обратно на флешку:
dd if=sdb2-new.img of=/dev/sdb2
Итог
На данный момент я могу по защищённому каналу замкнуть реле:
curl -X PUT -k --data '1' https://admin:j3ks92ls8f@192.168.1.2:19587/alarm
и разомкнуть его:
curl -X PUT -k --data '0' https://admin:j3ks92ls8f@192.168.1.2:19587/alarm
По большому счёту, лично для меня это было просто оценкой технической возможности реализации задумки. Оценка положительная: у меня есть доступ к портам ввода-вывода и я могу добавить свою логику в прошивку устройства. Бонусом я получил готовый к использованию HTTPS-сервер.
По моему мнению, это была самая интересная часть разработки, дальше по большей части остаётся только рутина, и я не уверен закончу ли всё задуманное в полном объёме. В любом случае, если кто-то решит повторить что-то подобное, вот пара идей по дальнейшему развитию текущего результата:
- Написать скрипт службы, которая будет отслеживать состояние входов с датчиками и реагировать на сработку (оповещать, включать сирену). Тут всё понятно, сложностей ни со службой ни с оповещением не предвидится, даже исполняемый файл curl уже есть на устройстве, т.е. для оповещений есть несколько вариантов: SMTP и получение сообщений по IMAP, готовые сервисы отправки SMS, свой сервер;
- Добиться работы через интернет без прямого IP-адреса. Дело в том, что через облако работает только основной софт видеосервера, а lighttp-сервер, реализующий системные настройки, доступен только прямо, что, конечно, не плохо само себе. По этому пункту я не так уверен в простоте реализации, мои идеи пока ограничиваются двумя вариантами: ssh-тунель (надо добавить свой публичный ключ на устройство) или свой сервер и long polling со стороны устройства.
Буду благодарен за ваши идеи.
Комментарии (22)
Vladimir_Sklyar
15.09.2016 18:42Через какой сервис формируется защищенный канал управления реле? И насколько он «защищенный»?
XLOR
15.09.2016 19:28А что за система такая?
Можно ссылку на производителя, прошивку?
25Мб — это хорошо.
А то у меня валяется OrangePi PC как раз, превращу ка я её в систему наблюдения, без свистелок и пр.motorcycle
15.09.2016 20:44Система называется «Линия».
XLOR
16.09.2016 07:08А можете поделиться образом microSD? Тоже хочу поковырять.
motorcycle
16.09.2016 09:34У меня сейчас нет полного образа с загрузочным разделом. Сервер пока опять в гараже, вечером или завтра сдамплю, поделюсь.
motorcycle
16.09.2016 17:14Кинул ссылку личным сообщением. Это образ флешки сразу после factory-reset, сделал его, чтобы не было моих логинов/паролей к облаку «Девлайн» и моему FTP, просто не уверен, что знаю все места их хранения. Сервер с такой флешкой нормально работает, просто все настройки по дефолту, IP-камеры заново цепляются без проблем.
climp
16.09.2016 09:34Не знаю, можно ли размещать прямые ссылки, но гуглите devline. Кстати, на мой взгляд, довольно годный софт. И ценообразование вменяемое.
vanomel
15.09.2016 19:55Все, сейчас я вас поломаю, потому как вы выдали свой айпи и пароль!
Шучу.
Думаю, что если ваш провайдер выдает вам статический внешний ip адрес, то вы может поднимать средствами ОС туннель до маршрутизатора и общаться с веб-сервером через него.motorcycle
15.09.2016 21:09Статика на 3G — роскошь.
ferrozer
16.09.2016 08:54Зачем изобретать велосипед? Настройте любой из бесплатных dynamic dns сервисов.
motorcycle
16.09.2016 09:40Белый IP тоже денег стоит. Чуть уточню: в гараже только 3G-модем, локалки между квартирой и гаражом нет. Т.е. единственная связь с сервером — серый IP-адрес мобильного оператора. Сам софт видеонаблюдения работает и так, у них есть бесплатный сервис, позволяющий для подключения использовать доменное имя вида myserver.devline.tv, но, как я написал в статье, служебный lighttpd-сервер, который я дорабатывал, таким образом в мир не смотрит.
BurlakovSG
16.09.2016 10:24Сейчас в основном у мобильных операторов выдаётся внутренний IP-адрес, т.е. за NAT — в таком случае dynamic dns работать не будет.
BurlakovSG
16.09.2016 10:13Скорее всего имелось ввиду статика у провайдера домашнего интернета.
motorcycle
16.09.2016 10:41Да, наверное, я не так понял. Белый адрес на проводе получить, конечно, проще. Именно про такой туннель я писал в своих вариантах.
sergio_deschino
16.09.2016 09:26первое, что приходит в голову — распознавать лицо, загонять его на внешний сервис и если оно совпадает с лицом владельца, то игнорировать алерт.
Сам в виде хобби, тестового проекта делаю подобную штуку для сети наших магазинов на малинке, которая считает посетителей, определяет лица и потом, если необходимо, помечает их для всех сети, как тревожных покупателей для всей сети, с оповещением на тг. Как допилю — выложу статью.
kalobyte
странно… прошивка в 25мб
а на сайтах лежит прошивка в 450мб
есть какой дистрибутив мелкий под эту плату с драйверами всеми? без исксов и всякого хлама?
motorcycle
Это не родная прошивка от Orange Pi, а прошивка от разработчиков этого конкретного NVR на его базе. В ней нет ничего лишнего, но и ничего полезного для общих нужд тоже, она заточена конкретно под сервер видеонаблюдения этого производителя и очень неудобна для доработки. Посмотрите в сторону Armbian, если хочется готовый дистрибутив «без исксов и всякого хлама».
romanjoe
25мб это прошивка видеосервера — устройства на базе этой платы, а не дистрибутив
crackedmind
Ничего странного, берем билдрут и на основе бизибокса собираем, маленькую компактную систему для нужд.