Router WR741ND

1.0

Tento krátký text neberte prosím jako úplný návod, jak nainstalovat OpenWrt na router. Je to spíš inspirace pro bastlíře - je ovšem vyžadována poměrně dobrá znalost operačního systému Linux. A hlavně mám zde poznamenáto to, co jsem dělal a až to budu někdy opakovat, nemusím to hledat po celém Webu. A ta dokumentace k OpenWrt také není nic moc, i když vlastní systém je velice dobrý.

Úvod

Na pokusy s Ethernetem jsem si koupil router WR741ND od firmy TP-Link. Vybral jsem ho především proto, že byl levný ale má i dostatek dynamické paměti (32 MB), WiFi zatím nepoužívám. A jako správný alchymista jsem se rozhodl nainstalovat si na něj vlastní Linux. Volba byla celkem jasná : OpenWrt - distribuce, která je na tento typ zařízení přímo určena, ale je to plnohodnotný systém, na němž se dají vyvíjet vlastní aplikace.

Instalace OpenWrt

Na Webu jsou sice hotové obrazy systému, které budou asi pro běžného uživatele použitelné, ale protože budeme chtít sestavit vlastní programy, je nutné zkompilovat celý systém. Není to sice žádné drama, ale je to docela moloch - zabere na disku přes 3 GB místa a trvá to několik hodin. Takže to chce trochu trpělivost a rychlé připojení k Internetu.

  1. Stáhneme základní balík Backfire a rozbalíme ho. Kompilaci nelze dělat jako root a je to tak dobře, instalace je docela složitý skript a chyba by mohla mít vážné následky.
  2. Konfigurace je podobná, jako když kompilujeme Linuxové jádro (make menuconfig). Jako konfigurační soubor lze načíst můj WR741ND.config nebo použít default. Já jsem zatím konfiguraci moc neměnil, ale je možné to poněkud ořezat. Pak dáme make a můžeme jít spát.
  3. Výsledkem je binární soubor openwrt-ar71xx-tl-wr741nd-v1-squashfs-factory.bin - ten nahrajeme do flash routeru. Pokud je nový, jde to lehce přes webové rozhraní - menu upgrade firmware, vybereme uvedený soubor a je to.
  4. Teď už je možné (ze strany LAN, nikoli WAN) připojit se telnetem jako root, změnit heslo a pak už používat pouze ssh. Adresa je 192.168.1.1

Úpravy

Tento systém je použitelný, ale já jsem si přidal USB podle tohoto návodu. Upozorňuji, že je to na hranici možností pájecího pera. Nakonec jsem musel vývody procesoru pomocí 2 jehel odtrhnout od plošného spoje (resp. šlo to i s mědí) a přihnout směrem vzhůru - trefit se drátkem přesně na vývod (a nepřipájet i okolní piny) jsem nedokázal. Podruhé už bych to dělat nechtěl. Napájet to lze z 7805, zbyde na ní tak 3V, takže ani moc netopí. Nicméně po zapatchování jádra (usb.patch) a nové kompilaci to funguje. Asi by bylo lepší patch umístit přímo do systému patchů backfire a kompilace by proběhla hned napoprvé včetně USB, ale nechtělo se mi s tím experimentovat, oprava případné chyby trvá moc dlouho. Lze si i vyvést sériový port (ve 3.3V úrovních) ale není to potřeba, nový systém je možné nahrát i přes ssh. Obraz openwrt-ar71xx-tl-wr741nd-v1-squashfs-factory.bin přejmenujeme například na image.bin, aby se s tím lépe pracovalo, pak provedeme (na PC):

scp image.bin root@192.168.1.1:/tmp/image.bin
ssh root@192.168.1.1
mtd -e firmware write /tmp/image.bin firmware -r

a mělo by být hotovo. Ta metoda se sériovým portem a tftp je asi jen projev zoufalství, když se něco nepovede. Nicméně, pokud nabouráme u-boot, tak nepomůže ani svěcená voda. Ale hardware je udělané docela vtipně - flash má sice jen 4MB ale je sériová (8 nožiček) a v procesoru je asi nějaký bootloader, který z ní umí načíst kód do DRAM a tam spustit. Škoda, že k procesoru není na webu datasheet.

Konfigurace

Celkem není co konfigurovat. WAN rozhraní dostane IP z DHCP naší vesnické sítě, na LAN běží defaultně použitelný DHCP server, který přidělí připojenému počítači adresu v rozsahu 192.168.1.100 až 192.168.1.250. Na routeru je použita maškaráda (NAT). To na pokusy stačí. Pro instalaci vlastních balíčků je nutné zprovoznit na PC připojeném do LAN HTTP server. Použil jsem boa, protože je jednoduchý. V souboru /etc/opkg.cfg na routeru pak nastavíme IP adresu PC a cestu k balíčkům. Pak můžeme nainstalovat do routeru další balíčky (příkazy na routeru):

opkg update
opkg install kmod-usb-ohci
opkg install kmod-usb-audio
opkg install libpthread

Systém si závislosti vyřeší sám.

Testovací aplikace - teploměr s DS18S20

  1. Pro první pokusy jsem vzal kód, který mi tu zbyl z něčeho jiného a trochu ho upravil. Mělo to fungovat tak, že po stisknutí tlačítka na routeru odešle tento e-mail a na to konto mi přijde SMS zpráva. Prostě takové jednoduché hlídátko. Jenže se mi nepovedlo nějak rozumně číst stavy vstupů a tak zůstala jen kostra SMTP klienta. Nicméně se tím podařilo ověřit, že křížová kompilace není zase tak velká věda a programy zkompilované na PC lze v routeru bez problémů spustit.
  2. 23.12.2010 - Pod vlivem bývalého kolegy jsem do routeru doplnil teploměr s jednodrátovou sběrnicí Dallas se dvěma čidly DS18S20. Fakt je, že podpora pro tato čidla v jádře je dobrá, ale bohužel dost špatně dokumentovaná. Hardware je jednoduché - master sběrnice je vytvořen GPIO pinem, použil jsem tlačítko QoS především proto, že se na něj líp pájí než na ledku. Ale na pinu ledky to asi bude fungovat také. Je tu malý problém - GPIO piny procesoru pracují s úrovněmi 2.5V, čidla potřebují pro svou správnou činnost alespoň 3.3V napájení, přičemž 2.5V logické úrovně by měly být dostatečné. Takže nejčitší řešení je propojit čidla trojdrátově asi takto:
    propojeni.png
    Žádné pull-up odpory pak nejsou potřeba. Software pro obsluhu je víceméně v jádře, je nutné nainstalovat balíky:
    opkg update
    opkg remove kmod-input-gpio-buttons
    opkg install kmod-w1-gpio-custom
    opkg install kmod-w1-slave-therm
    
    Protože master sedí na pinu butonu, je nutné odstranit modul gpio-buttons. Problémem je i správné pořadí zavádění modulů do jádra (viz /etc/modules.d/). Pořadí je následující:
    rmmod gpio-buttons    # tohle je nutné, bohužel modul se zavádí zřejmě už v základním obraze,
                          # takže pouhé odinstalování nepomůže
    #insmod wire                       # obecný driver 1-wire bus, je už v jádře (viz /etc/modules.d/50-w1)
    insmod w1-gpio-custom bus0=0,12,0  # připojí na GPIO12, což je tlačítko QoS.
    insmod w1-gpio                     # to je master
    insmod w1_therm                    # slave pro DS18S20 a jiné teploměry
    sleep 15                           # počkej, až se systém ustálí
    ./therm &>/dev/null &              # spuštění měření
    
    Původně jsem chtěl dát pořadí tak, jak to má být do /etc/modules.d/. Jenže modul gpio-buttons nejde nějak rozumně odstranit a protože je asi součástí základního image, nejde ho ani jednoduše smazat v /lib/modules/. Nepomůže ani dát zaváděcí příkazy na začátek v /etc/modules.d/ (vyzkoušeno). Takže jedině dát to do skriptu, jímž se spouští měřící software. Příkaz rmmod gpio-buttons je důležitý, bez něj se to na pin butonu nepřipojí. Z /etc/modules.d/ je třeba odebrat mimo 50-w1 vše, co s w1 souvisí (rm *-w1-*) Funkční výsledek je pak takovýto:
    lsmod | grep w1
      w1_gpio                  704  0 
      w1_gpio_custom           864  0 
      w1_therm                1808  0 
      wire                   13776  2 w1_gpio,w1_therm
    
    Data je pak možné číst ze souborů
    /sys/devices/w1 bus master/10-000801d38936/w1_slave
    /sys/devices/w1 bus master/10-000801d2652c/w1_slave
    ...
    
    Adresáře s tím divným dlouhým číslem se dynamicky mění podle S/N připojených čidel. Formát dat je následující a asi nepotřebuje komentář (teplota ve st.C je ve skutečnosti t/1000, zde tedy 25.875 st.C):
    34 00 4b 46 ff ff 0e 10 69 : crc=69 YES
    34 00 4b 46 ff ff 0e 10 69 t=25875
    
    Data se mění každých 10 sekund. Program v sekci download tato data čte, parsuje a zaznamenává do souboru. Ve 24:00h UTC je odešle emailem jako přílohu a soubor smaže (pokud se to povedlo). Parametry jsou zašity do zdrojáků natvrdo, takže pokud bude mít někdo zájem, musí si je upravit v ./smtp/therm.c. Výsledky v grafické podobě (snad to budu průběžně aktualizovat) jsou zde. Červeně je čidlo těsně vedle krbu, modře čidlo venku, pod oknem. Grafy jsou generovány postskriptovým souborem (což je vlastně program) přímo čtením z datových souborů a následně převedeny pomocí ps2pdf.

IP telefon, založený na protokolu SIP

To bylo vlastním cílem experimentů - možnost alespoň převzít hovor z IP, aby nebylo nutné mít zapnuté PC. Je fakt, že lze vzít hotové řešení a je to bez problémů, ale pro řádného bastlíře je to výzva. A když jsem viděl, že v OpenWrt je implementována i IP ústředna asterisk, napadlo mě, že telefon snad půjde taky. Jenže co použít ? Nabízí se samosebou linphone, ale odradila mě složitost rozhraní a množství externích knihoven. Tak jsem hledal dál a našel jsem docela dobré API - PJSIP. Je dobře komentované, externí knihovny si to vleče s sebou, takže jsou staticky přilinkovány do aplikace. Pro tento účel je to lepší než spousta sdílených knihoven, které pak stejně nikdo nepoužívá. I když v popisu je, že to lze použít v embedded aplikacích - tedy spolu s knihovnou uClibc, kterou používá i OpenWrt, zjevně to není pravda - konstrukce snprintf (p, l, "%.*s", 0, NULL), v kódu hojně používaná, dává ve spojení s glibc p="" , ale ve spojení s uClibc p="(null)", což je špatně. Autoři vtipně radí opravit to přímo v uClibc a to je blbost - zajímalo by mě, co všechno by pak přestalo v OpenWrt chodit. Takže jsem to zalepil na těch pár kritických místech - soubor pj.patch a je pokoj.

Kompilace PjSIP stacku

  1. Stáhneme si zdrojáky a rozbalíme.
  2. Zazáplatujeme chybky
    cd pjproject-1.8
    patch -p2 -i ../pj.patch
    
  3. Nakonfigurujeme pro router (cesta je jen příklad, cílový adresář musí obsahovat mips-openwrt-linux-uclibc-gcc)
    export PATH=$PATH:/PathTo/backfire_10.03/staging_dir/toolchain-mips_r2_gcc-4.3.3+cs_uClibc-0.9.30.1/usr/bin/
    ./configure --host=mips-openwrt-linux-uclibc --disable-speex-codec \
    --disable-speex-aec --disable-tls
    
    nebo případně pro běh na PC
    ./configure --disable-speex-codec --disable-speex-aec --disable-tls
    
    Kodek speex a potlačení echa je možné zakázat už při kompilaci, procesor routeru takovou zátěž nestíhá tak proč to vláčet s sebou. TLS v OpenWrt stejně není použito.
  4. Zkompilujeme pomocí make dep, make, instalovat není třeba.

Instalace vlastního telefonu

Stáhneme si zdrojáky ze sekce Download a rozbalíme je. Je potřeba upravit Makefile v adresáři phone podle účelu - jestli chceme testovat software na PC nebo kompilovat pro router. Makefile je relativně jednoduchý a pochopilelný, takže jsem nepoužil konfigurační skript. Dál je nutné upravit v main.c (na začátku) parametry pro registraci na serveru. Pak už jen make a je hotovo. Jak to funguje - pokud pustíme program phone s nějakým parametrem (jakýmkoli), spustí se na pozadí, výpisy na konzoli skončí v /dev/null. Ale je možné démonu předat příkazy přes pojmenovanou rouru - je tedy nutné jí napřed vytvořit - příkazem

mkfifo -m 0666 /root/phone.pipe

Do roury pak můžeme poslat příkaz (například)

echo sip:adresa@server.domena > /root/phone.pipe

Ten vyvolá odchozí hovor na adresu sip:adresa@server.domena. Dál jsou podporovány jen příkazy "h" - hangup (ukončení hovoru) a "q" - řádné ukončení programu. Pokud program spustíme bez parametru, jsou příkazy čteny z konzole a na konzoli jsou vypisovány kontrolní výpisy. Příchozí hovor je převzat automaticky, bez zásahu obsluhy (prostě zatím neumím to tlačítko). Během hovoru by měla svítit LED QoS (ledky umím). Zatím je zprovozněno jen spouštění programu v adresáři /tmp routeru, protože má 1,4MB a jinde není místo. Takže po výpadku napájení se program ztratí. Bude to chtít vyházet z image systému zbytečnosti jako je HTTP server, ppp, pppoe. Pak to snad vleze do flash. To počká, až k tomu dodělám nějaké ovládání po sériové lince aby se daly dělat nějak rozumně i odchozí hovory.

Zvuk

Použil jsem nějakou levnou USB zvukovku, která se mi tu válela v šuplíku bez užitku. Vrstva ALSA je sice v OpenWrt obsažena, ale není nutné jí používat. PjSip používá ještě navíc mezivrstvu portaudio - to je daň za multiplatformnost. Nicméně 8kHz to zvládne a telefon víc nepotřebuje.

Závěr

Router WR741ND je za pětikilo docela dobrá hračka. IP telefon na tom zprovoznit jde, chodí kodeky uLaw (použit default, připojení je rychlé, tak co), ALaw, gsm, G722. Speex je prý lepší (spíš novější), ale to už procesor zjevně nestíhá. IP telefon je už docela složitý software, ani se nedivím, že jsem v původním OpenWrt nic použitelného nenašel (no, možná tam něco je ale chybí mi metoda jak to najít). Pro domácí automatizaci docela vhodná volba - pokud stačí sériový port. Ale pokud je potřeba USB bude lépe se poohlédnout po něčem, co to má už vyvedeno. S USB lze rozjet třeba WEB server nebo FILE server (no, nic moc, ale nehučí to). Nakonec před pár lety 486 rozhodně rychlejší nebyla a 32 MB paměti bylo dost i na serveru. A síť chodila, lidi na tom dělali docela spokojeně. Jenže od tý doby přibyly obrázky, videa a jiné blbiny... A 3 GB dat co zabírá OpenWrt na disku nikoho nazarazí i když výsledný obraz systému zabírá tak 1/1000 tohoto objemu.

Download

17.10.2010 - přidáno vyzvánění a vstup pomocí buttonů na zvukovce. Tento vstup je další démon, který čte vstupní eventy a podle toho sype data do roury. Roura pro ovládání je tedy zachována, přibyl příkaz "a" pro zvednutí hovoru. Source tarball - zatím beta

Licence

GPL

 Vše Třídy Soubory Funkce Proměnné Definice typů Definice maker

Generováno Thu Feb 3 20:03:15 2011 pro projekt RouterWR741ND programem  doxygen 1.6.1