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ý.
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.
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.
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.
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.
opkg update
opkg remove kmod-input-gpio-buttons
opkg install kmod-w1-gpio-custom
opkg install kmod-w1-slave-therm
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í
lsmod | grep w1 w1_gpio 704 0 w1_gpio_custom 864 0 w1_therm 1808 0 wire 13776 2 w1_gpio,w1_therm
/sys/devices/w1 bus master/10-000801d38936/w1_slave /sys/devices/w1 bus master/10-000801d2652c/w1_slave ...
34 00 4b 46 ff ff 0e 10 69 : crc=69 YES 34 00 4b 46 ff ff 0e 10 69 t=25875
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.
cd pjproject-1.8 patch -p2 -i ../pj.patch
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
./configure --disable-speex-codec --disable-speex-aec --disable-tls
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.
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.
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.
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