Превращаем ADSL-модем в Ethernet-шилд для Arduino/CraftDuino



0x0 — введение
0x1 — разбираем 🙂
0x2 — знакомимся с программной частью
0x3 — формат прошивки
0x4 — модифицируем файловую систему
0x5 — пишем первую программу
0x6 — последовательный порт
0x7 — заключение
Превращаем ADSL-модем в Ethernet-шилд

Возможно кто-нибудь помнит, как на новогодних каникулах мы проводили исследования ADSL-модема на базе Linux — ZTE ZXDSL831AII (подобен D-link DSL-2500U) и при выводе последовательного интерфейса я обмолвился о возможности превращения модема в своеобразный Ethernet-шилд.
Чтож, настала пора это сделать!

В принципе, задача выглядит просто, но при её решении я столкнулся с несколькими подводными камнями, которые неплохо отняли время на своё решение 🙂

Основная идея превращения модема в Ethernet-шилд очень проста — нужно всего-лишь запустить на модеме программу, которая будет слушать определённый сетевой порт и при подключении выдавать в него данные из последовательного порта и наоборот, передавать принятые данные в последовательный порт.
Разумеется, настоящий Ethernet-шилд позволяет Arduino/CraftDuino работать не только в режиме сервера, но и клиента ( слать запросы в google и писать в twitter) — этого данное решение пока не позволяет, хотя, думаю всё зависит от программы, которую вы запустите на ADSL-модеме 😉
Данное же решение подойдёт, если вам требуется управлять своим контроллером через Ethernet. Например, на базе этого решения можно построить настоящий умный дом 🙂 Короче, всё ограничивается вашей фантазией 😉

А если у вас есть под рукой Wi-Fi-роутер D-Link DIR-320, то всё вообще становится намного проще. На него можно установить прошивку от Олега (http://wl500g.info), OpenWRT (http://openwrt.org) или dd-wrt (http://www.dd-wrt.com)
и превратить свой роутер в настоящего робота!
Идея остаётся та же — на роутере запускается программа трансляции пакетов из сети в последовательный порт, который слушает контроллер и управляет двигателями и прочими робо-прибамбасами. Причём всё это через беспроводное Wi-Fi-соедеинение. Самое удобное, что у D-Link DIR-320 есть USB-порт, к которому можно подлкючить web-камеру (поддерживающую UVC) и с помощью mjpeg-streamer передавать видеокартинку!

Итак, нам нужна программа-прокси слушающая сокет и передающая принятые данные в последовательный порт.

Такая программы уже есть:
http://ser2net.sourceforge.net — Serial to Network Proxy
но я воспользуюсь утилитой suart, написанной участником робофорума — Dead

Пересобираем программу под наш модем. У меня уже установлен toolchain для ADSL модема D-link 2500U

собираем программу

./bin/mips-linux-gcc -o suart suart.c

однако, при попытке запустить программу на модеме она последовательно выдавала ошибки:

/usr/bin/suart: can't resolve symbol 'cfmakeraw'
/usr/bin/suart: can't resolve symbol 'cfsetispeed'
/usr/bin/suart: can't resolve symbol 'tcflush'

так что, пришлось немного модифицировать программу.
Скачать исходник и готовую программу можно здесь:
suart-DSL-2500.zip

По-умолчанию, программа слушает 3000-й порт и перебрасывает данные на /dev/ttyS0 на скорости 115200.
Эти значения можно изменить с помощью параметров командной строки:

./suart -?
Suart is tool that allow you to tunnel a local serial connection over a network

Usage: suart [-s] [-p] [-b] [-d] [-?]

   -s Set serial port, default is /dev/ttyS0
   -p Set socket address, default is 3000
   -b Set serial port baudrate (9600/19200/38400/57600/115200), default is 115200
   -d Show debug info - transferred data
   -w wait seconds befor run, default is 0
   -? (-h) Show this help page

Example: suart -s/dev/ttyS1 -p3005 -b9600 -d

но для нашего модема всё подходит и программу можно запускать без параметров.

Итак, у вас уже есть программа, которую нужно запихнуть в модем. Для этого нужно модифицировать его файловую систему.

Распаковываем корневую файловую систему (можно взять файл rootfs из предыдущих примеров например, вот этот — sq7.bin).

Напоминаю, что распаковку нужно делать под суперпользователем root 😉

У нас появляется директория
squashfs-root
копируем нашу программу suart в каталог /usr/bin/
(туда же скопируйте программу sleep, которая принимает в качестве параметра число секунд на которые нужно уснуть системе — она нам пригодится )
sleep-DSL-2500.zip

Но так как мы запихнули аж две дополнительных программы — размер корневой файловой системы вырастет и прошивка на модеме скорее всего не запустится. Всё просто — нужно удалить что-нибудь ненужное.
Например, картинки из веб-интерфейса!
переходим в /webs/ и видим много gif-ок
выполним команду

for i in *.gif; do > $i; done;

файлы никуда не делись, но теперь имеют нулевой размер.

Однако, если просто запустить программу на модеме — достучаться до 3000-го порта не получится! Всё дело в файрволе(!!!) iptables, который работает на модеме.

если проверить порт с помощью nmap-а:

nmap -v 192.168.1.1 -p 3000

то он выдаст, что порт открыт, но фильтруется и подключиться к нему не получится 🙁

Окончательно проверить догадку относительно файрвола просто — можно убить http (командой kill -9) и запустить suart на 80-м порту

# /usr/bin/suart -p80

и всё заработает 🙂

Придётся разбираться с iptables. Как звучит-то: настроить файрвол на модеме :)))

Посмотреть существующие настройки можно командой:

# /bin/iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere            udp dpt:5100
ACCEPT     udp  --  anywhere             anywhere            udp dpt:1900
ACCEPT     udp  --  anywhere             anywhere            udp dpt:5431
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:5431
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTAB
LISHED
ACCEPT     udp  --  anywhere             anywhere            udp dpt:tftp
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:telnet
ACCEPT     icmp --  anywhere             anywhere            icmp echo-request
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ftp
DROP       all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Ага - в цепочке INPUT видим последнюю инструкцию
DROP       all  --  anywhere             anywhere

В принципе, можно просто очистить всю таблицу командой:

/bin/iptables -F 

Но это не наш метод 🙂

Узнаем номер DROP-а, чтобы его удалить:

# /bin/iptables --list --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     udp  --  anywhere             anywhere            udp dpt:5100
2    ACCEPT     udp  --  anywhere             anywhere            udp dpt:1900
3    ACCEPT     udp  --  anywhere             anywhere            udp dpt:5431
4    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:5431
5    ACCEPT     all  --  anywhere             anywhere            state RELATED,
ESTABLISHED
6    ACCEPT     udp  --  anywhere             anywhere            udp dpt:tftp
7    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:telnet

8    ACCEPT     icmp --  anywhere             anywhere            icmp echo-requ
est
9    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
10   ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ftp
11   DROP       all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

Удаляем DROP (11-е правило в цепочке INPUT):

/bin/iptables -D INPUT 11

Остайтся открыть 3000-й порт:

/bin/iptables  -A OUTPUT -p tcp -m tcp --dport 3000 -j ACCEPT
/bin/iptables  -A INPUT -p tcp -m tcp --sport 3000 -j ACCEPT

Проверяем — работает!
Запихнём эти команды в файл /usr/bin/mytest

#!/bin/sh

echo "[i] RoboCraft is cool!"

echo "[i] edit iptables ..."
/bin/iptables -D INPUT 11
/bin/iptables -A OUTPUT -p tcp -m tcp --dport 3000 -j ACCEPT
/bin/iptables -A INPUT -p tcp -m tcp --sport 3000 -j ACCEPT
echo "[i] iptables done!"

Остаётся прописать выполнение этих команд и последующий вызов suart-а в автозагрузку.

Сначала я пробовал запихнуть это дело в /etc/init.d/rcS
мучал его и так и эдак, пробовал ставить в конце & — чтобы программа запускалась в фоновом режиме.
Добавлял в suart параметр w который вызывал задержку(в секундах), вставлял в suart fork() — ни в какую!

В итоге, последняя редакция rcS

#! /bin/sh

PATH=/sbin:/bin
export PATH

mount -t proc proc /proc
/bin/mount -a
#/sbin/inetd

echo "[i] Start..."
#/usr/bin/suart -w30
#echo "[i] Ok. Wait 30 sec..."

А где же вызов программы? Всё просто — обратите внимание на лог загрузки модема, который можно посмотреть через последовательный порт.

Если использовать вышеприведённый rcS, то строчка
[i] Start…
будет сразу после строчки
Algorithmics/MIPS FPU Emulator v1.5

а iptables, похоже стартуют позже

обратите внимание на строчку

==>   Bcm963xx Software Version:

она отыскалась в здоровущем (аж целый мегабайт!) файле
/bin/cfm

Я решил сделать ход конём — переименовываем файл /bin/cfm в /bin/cfm0
а на его место запихнул скрипт следующего содержания:

#! /bin/sh

echo "[i] CFM..."
/bin/cfm0 &
echo "[i] my start..."
/usr/bin/sleep 30 && /usr/bin/mytest
/usr/bin/suart

Как видим, он запускает оригинальный /bin/cfm0 в фоновом режиме, а потом ждёт 30 секунд и запускает /usr/bin/mytest, который прописывает дополнительные настройки iptables, а затем и наш /usr/bin/suart

Не забудем сделать скрипт исполняемым и… всё! Можно паковать прошивку!

выполняем команду упаковки корневой файловой системы:

./mksquashfs squashfs-root/ sq8.bin -be  -no-fragments -noI -all-root -noappend -lzma -b 65536

получаем sq8.bin

далее используем мою утилиту packImage.exe из набора
ParseImage

и генерируем файл прошивки.
для ZTE ZXDSL831AII:

packImage.exe bcm.bin cfe.bin sq8.bin kernel.bin
move result.bin result-sq8-suart.bin

получаем result-sq8-suart.bin

Заходим в веб-интерфейс модема, вкладка Management -> Update firmware
указываем наш файл result-sq8-suart.bin и ждём.

Если смотреть на последовательно порту лог загрузки то мы увидим следующее:

...
init started:  BusyBox v1.00 (2008.01.31-12:18+0000) multi-call binary
Algorithmics/MIPS FPU Emulator v1.5
[i] Start...


BusyBox v1.00 (2008.01.31-12:18+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.


Loading drivers and kernel modules...

bcm_enet: module license 'Proprietary' taints kernel.
Broadcom BCM6338A2 Ethernet Network Device v0.3 Jan 31 2008 20:15:18
Config Internal PHY Through MDIO
BCM63xx_ENET: 100 MB Full-Duplex (auto-neg)
eth0: MAC Address: 00:D0:D0:86:86:B5
Broadcom BCM6338A2 USB Network Device v0.4 Jan 31 2008 20:15:20
usb0: MAC Address: 00 D0 D0 86 86 B6
usb0: Host MAC Address: 00 D0 D0 86 86 B7
[i] CFM...
[i] my start...
eth0 Link UP.
BcmAdsl_Initialize=0x800EDB88, g_pFnNotifyCallback=0x801A48C4
AnnexCParam=0x7FFF7EB8 AnnexAParam=0x00000980 adsl2=0x00000000
pSdramPHY=0xA07FFFF8, 0x9D701 0xDEADBEEF
AdslCoreHwReset: AdslOemDataAddr = 0xA07F8054
AnnexCParam=0x7FFF7EB8 AnnexAParam=0x00000980 adsl2=0x00000000
dgasp: kerSysRegisterDyingGaspHandler: dsl0 registered
ATM proc init !!!
ip_tables: (C) 2000-2002 Netfilter core team
ip_conntrack version 2.1 (61 buckets, 0 max) - 376 bytes per conntrack
ip_conntrack_pptp version 2.1 loaded
ip_nat_pptp version 2.0 loaded
ip_conntrack_rtsp v0.01 loading
ip_ct_h323: init success
ip_nat_h323: init success
insmod: cannot open module `/lib/modules/2.6.8.1/kernel/net/ipv4/netfilter/ip_co
nntrack_tftp.ko': No such file or directory
insmod: cannot open module `/lib/modules/2.6.8.1/kernel/net/ipv4/netfilter/ip_na
t_tftp.ko': No such file or directory
ip_nat_irc: Unknown symbol needs_ip_conntrack_irc
insmod: cannot insert `/lib/modules/2.6.8.1/kernel/net/ipv4/netfilter/ip_nat_irc
.ko': Success (2): Success
ip_nat_rtsp v0.01 loading

==>   Bcm963xx Software Version: ZXDSL 831AIIV4.1.0a_E09_RU   <==

device usb0 entered promiscuous mode
br0: port 1(usb0) entering learning state
br0: topology change detected, propagating
br0: port 1(usb0) entering forwarding state
...
br0: port 3(nas_0_1_92) entering learning state
br0: topology change detected, propagating
br0: port 3(nas_0_1_92) entering forwarding state
CONSOLED launched
exit
CONSOLED exited
CONSOLED launched
exit
CONSOLED exited
CONSOLED launched
exit
br1: port 1(usb0) entering disabled state
[i] RoboCraft is cool!
[i] edit iptables ...
[i] iptables done!

полный лог - suart_loading_log.txt

Обратите внимание - когда стартует /etc/init.d/rcS (строчка [i] Start...)
и когда /bin/cfm (строчка [i] CFM... )

проверяем порт с помощью nmap-а:

nmap -v 192.168.1.1 -p 3000

и видим:

Host 192.168.1.1 appears to be up ... good.
Interesting ports on 192.168.1.1:
PORT     STATE SERVICE
3000/tcp open  ppp

отлично! порт открыт!

Пробуем подключиться:

telnet 192.168.1.1 3000

Работает!!!!

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

Программы:
suart-DSL-2500.zip
sleep-DSL-2500.zip
sq8.bin
result-sq8-suart.bin
ParseImage

Далее: Исследование Wi-Fi-роутера TP-LINK TL-MR3020

Ссылки
Что нам стоит «умный дом» построить. Делаем фарш из микроконтроллеров и роутера
http://roboforum.ru/wiki/DIR-320
http://roboforum.ru/forum10/topic9534.html
http://roboforum.ru/forum88/topic9793.html
iptables:
http://www.posix.ru/network/iptables/
http://www.opennet.ru/docs/RUS/iptables/
http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html
программирование под Linux:
http://www.advancedlinuxprogramming.com
http://www.opennet.ru/docs/RUS/serial_guide/

Автор: Vladimir (noonv), 2011

Эксклюзивно для robocraft.ru
копирование на другие ресурсы и публикация
без разрешения автора запрещены.


11 комментариев на «“Превращаем ADSL-модем в Ethernet-шилд для Arduino/CraftDuino”»

  1. Если есть полноценный процессор, крос-компилятор и внешние порты, то нафига козе баян микроконтроллер? Прогу то можно прямо линуховую написать.
    Но шилд то конечно своеобразный получился — работающий на последовательном порту. SPI здесь бы лучше смотрелся бы:)

    • Какое количество внешних портов доступно у данного модема? Светодиоды?

  2. ЗдОрово! Спасибо за статью. А как бы вообще заменить CFM скриптами? Broadcom и вендоры как правило не дают его исходники, а этот монстр управляет всем в роутере.

    • почему же — на сайте Broadcom есть исходники их CFM 😉

    • Правда? А вы не путаете CFM с CFE? Может быть ссылочку дадите?

  3. подскажите, плиз, уважаемые Гуру) можно ли заставить br1 — выделенный в отдельную группу интерфейс — получать сетевые настройки по DHCP? через ifconfig можно настроить фиксированный ip и gw, а если выполнить команду

    dhcpc -i br1

    , то вылазиет ошибка

    /proc/var/fyi/wan/br1/daemonstatus: cannot create

    , что понятно, т.к в папке /proc/var/fyi/wan нет ничего про br1.. Если создать ADSL подключение, то его имя появляется в папке wan — типа nas_0_8_35.
    Может есть способ создать там и папку br1? Или можно запустить dhcpc в обход использования этой папки? Или может можно переименовать br1 в nas_0_8_35.

    Машинка — DLink dsl-2640u/bru/c2, fw:2.05

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

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Arduino Bluetooth CraftDuino DIY Google IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение