2015-12-14

WebRTC a PBX Asterisk pro VoIP

Tentokráte jsem se pustil do zpracování školního projektu na téma zprovoznění komunikace mezi pobočkovou ústřednou Asterisk a klientem založeným na WebRTC technologii. Ačkoliv se předmět samotný zabývá spíše klasickým VoIP, zvolil jsem si zajímavý úkol zprovoznění Asterisku se SIPml5 klientem.



Nejprve seznámení se s pojmy: Asterisk je zástupcem digitálních telefonních pobočkových ústředen (neboli protikus k drátu od kancelářského telefonu) pracujících na protokolu SIP, H.323 a dalších, což je opět evoluce dříve známých principů klasických telefonů, tak jak je známe posledních 140 let.

Naproti tomu je Web Real-Time Communication teprve 4 roky stará novinka postavená na Javascriptu do webových prohlížečů. Funguje jako peer-to-peer komunikace klientů na aplikační úrovni a portu 80 a proto nevyžaduje speciální podporu ze síťové strany.
Umí přenášet hlas, video, zprávy, hry či soubory v reálném čase. Dále se budu zabývat uplatněním WebRTC jako přenosového média pro hovory, co se s WebRTC dá dělat naleznete i s demonstaracemi na webu.

Klasické řešení VoIP telefonů se SIPem a RTP je dostatečně robustní v intranetu či kdekoliv, kde máte ve správě infrastrukturu. Můžete například ovlivňovat firewallová pravidla nebo specifikovat druh nasazeného klienta na počítačích a tím zajišťovat kvalitní telefonní služby.

Výborné video popisující ve 30 minutách, proč je WebRTC docela fajn:


Kde nebude tento přístup vyhovovat je současný trend v mobilitě uživatelů, různorodosti zařízení a módnosti mít všechnu funkcionalitu ve webovém prohlížeči. WebRTC je v tomto směru úžasný, protože nenutí k instalaci pluginů, což je jedna z největších výhod pro uživatele i programátory. A když to jednou umí prohlížeč, tak to pravděpodobně funguje nativně přes celý internet. Hurá!

Teď jak to využít? Můj projekt se zaměřuje na použití SIPml5 klienta, který využívá WebRTC pro přenos médií. Samotný klient se přihlásí k PBX pomocí běžných SIP zpráv přenášených přes protokol websocket.

Největší komplikace je zde s přenášenými médii. WebRTC správně vyžaduje šifrování "hlasu" mezi koncovými stanicemi za použití DTLS/SRTP. které se musí dohodnout v rámci vyjednávání o kodecích v rámci protokolu SDP a to bohužel klasičtí B2BUA a VoIP klienti neumí.


Proto vznikla doplňující proxy RTCWeb Breaker, která vystupuje jako B2BUA a umožňuje sestavit zabezpečené i běžné RTP spojení do SIP světa či PSTN. Bohužel se mi ji nepodařilo zkompilovat a tedy vyzkoušet, což také ovlivnilo samotný projekt. Zanedbatelnou výhodou je to, že kontrolní signalizace funguje, takže telefonátu chybí jen hlas, hm drobná vada.

Schéma zapojení:
  • PC1: phonerlite-portable <111>
  • PC1: simpl5 <888> Mozilla
  • PC2: phonerlite-portable <222>
  • PC2 simpl5 <999> Chrome
Jak se tedy klienti chovají při hovoru?
  • 111 na 222: standardně včetně médií
  • 222 na 111: Failed to receive SDP offer/answer with required SRTP crypto attributes for audio
  • 111 na 888: Failed to receive SDP offer/answer with required SRTP crypto attributes for audio
  • 888 na 111: Remote host can't match request ACK to call
  • 111 na 999: Failed to receive SDP offer/answer with required SRTP crypto attributes for audio
  • 999 na 111: Spojeno bez médií
  • 222 na 888: Failed to receive SDP offer/answer with required SRTP crypto attributes for audio
  • 888 na 222: Spojeno bez médií
  • 222 na 999: Failed to receive SDP offer/answer with required SRTP crypto attributes for audio
  • 999 na 222: Spojeno bez médií
Co na to konzole Asterisku? (klienti při prvotní registraci)

  • Registered SIP '222' at 192.168.124.1:5075
    • Saved useragent "SIPPER for PhonerLitePortable" for peer 222
  • Registered SIP '111' at 192.168.124.137:5080
    • Saved useragent "SIPPER for PhonerLitePortable" for peer 111
  • Registered SIP '888' at 192.168.124.137:49478
    • WebSocket connection from '192.168.124.137:49478' for protocol 'sip' accepted using version '13'
    • Saved useragent "IM-client/OMA1.0 sipML5-v1.2015.03.18" for peer 888
  • Registered SIP '999' at 192.168.124.1:22470
    • WebSocket connection from '192.168.124.1:22470' for protocol 'sip' accepted using version '13'
    • Saved useragent "IM-client/OMA1.0 sipML5-v1.2015.03.18" for peer 999
Analýza toku ve Wiresharku: (zdroj)
příkaz tcpdump -w ~/zaznam.pcap -i eth0 na PBX




Všechny analýzy nám vlastně říkají to, co už víme, nedaří se navázat zabezpečené spojení a proto je komunikace odmítnuta. V screenshotech nějak chybí volání 888 na 111 a zároveň je mi podezřelé, proč klient 111 odmítá komunikovat, protože mi již v minulosti telefonovat a konfiguraci má stále stejnou a dokonce identickou s klientem 222. Podrobím tento nesoulad dalšímu zkoumání...

Použité konfigurační soubory
Čím si nejsem jistý je chování Asterisku při tomto patchi. Nevysledoval jsem žádnou změnu. Ta by měla dle dokumentace pouze potlačit nevhodné chování Chrome a ICE, jenže vzhledem ke stáří zmíněného patche bych vše považoval za již vyřešené.

Závěr

Tento projekt mě seznámil s docela zajímavými technologiemi, trochu to kazí to, že mi vlastně nefungují, ale docela bych věřil, že to bude chybou mezi klávesnicí a židlí. V principu se mi také líbí fakt, že minimální implementace vyžaduje šifrování, což je pro tyto technologie dobře. Nadruhou stranu mi to způsobilo asi 3 týdenní zpoždění s odevzdáním a i tak jsem si hraním s Asteriskem a SIPm5 strávil asi 2 celé víkendy, čímž notně utrpěly jiné projekty, které jsem v průběhu semestru povinen odevzdávat. Doufám, že se mi podaří nějakou konzultací zmíněné nedostatky odstranit a článek tak aktualizovat na funkční tutoriál.


Dotazy, tipy a nápady přijímám jako vždy do komentářů.


2015-12-13

WebRTC2SIP neúspěšná kompilace

Toto je neúspěšný pokus o kompilaci projektu WebRTC2SIP, který jsem zamýšlel využít v projektu. Mělo jít o spuštění se všemi závislostmi na Ubuntu Server 14.04.3 LTS x64. Vycházel jsem při tom z oficiálních tutoriálů 1 a 2, bohužel jsem se zasekl na knihovně tinyNET obsaženou ve frameworku Doubango, kterou nejsem schopný bez hlubších znalostí opravit. Vzhledem k tomu, že se Doubango již dále nevyvíjí, tak nevím, jak dále odstranění problému směřovat. 

Každopádně spousta dílčích problémů byla úspěšně vyřešena, takže pokud se této problematice věnujete a přijdete na nějaký update, dejte mi vědět v komentáři pod textem. Děkuji. Teď už ale k samotnému postupu:

#programové závislosti a prerekvizity
apt-get install -y make libtool autoconf subversion git cvs wget gcc

apt-get install -y libxml2-dev

#solution for E: Unable to locate package libogg-devel
apt-get install -y libogg-dev 

#solution for E: Unable to locate package gcc-c+
apt-get install -y g++

#solution for E: Unable to locate package pkgconfig
apt-get install -y pkg-config

#solution for E: Unable to locate package libvpx-devel
apt-get install -y libvpx-dev

#solution for E: Unable to locate package speex-devel
apt-get install -y libspeex-dev



#libspeex (audio codec) an libspeexdsp (audio processing and jitter buffer) are optional.
wget http://downloads.xiph.org/releases/speex/speex-1.2beta3.tar.gz
tar -xvzf speex-1.2beta3.tar.gz
cd speex-1.2beta3
./configure --disable-oggtest --without-libogg 
make && make install



#libsrtp nezbytné pro zabezpečené RTP
cd /usr/src/
git clone https://github.com/cisco/libsrtp/
cd /usr/src/libsrtp
CFLAGS="-fPIC" ./configure --enable-pic 
make && make install
make runtest
#error fixing



#OpenSSL nutné pro zabezpečení 
cd /usr/src/
wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz
tar -xvzf openssl-1.0.1c.tar.gz
rm openssl-1.0.1c.tar.gz
cd /usr/src/openssl-1.0.1c
make install_sw
./config shared --prefix=/usr/local --openssldir=/usr/local/openssl 
make && make install

#cms.pod around line 474: Expected text after =item, not a number
#POD document had syntax errors at /usr/bin/pod2man line 71.
#make: *** [install_docs] Error 255

#solution:
git clone https://github.com/openssl/openssl
cd /usr/src/openssl
./config shared --prefix=/usr/local --openssldir=/usr/local/openssl 
make && make install



#kodek OPUS
wget http://downloads.xiph.org/releases/opus/opus-1.0.2.tar.gz
tar -xvzf opus-1.0.2.tar.gz
cd opus-1.0.2
./configure --with-pic --enable-float-approx 
make && make install
cd ..
rm opus-1.0.2.tar.gz



#Yasm Modular Assembler Project používá kodek VP8
wget http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
tar -xvzf yasm-1.2.0.tar.gz
cd yasm-1.2.0
./configure && make && make install
cd ..
rm yasm-1.2.0.tar.gz



#podpora H.264 video codec vyžadována FFmpegem
wget ftp://ftp.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar -xvjf last_x264.tar.bz2
cd x264-snapshot-*
./configure --enable-shared --enable-pic && make && make installcd ..
rm last_x264.tar.bz2



#FFmpeg is solution to record, convert and stream audio, video.
git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
git checkout -b n1.2
./configure --extra-cflags="-fPIC" --extra-ldflags="-lpthread" \
--enable-pic --enable-memalign-hack --enable-pthreads \
--enable-shared --disable-static --disable-network --enable-pthreads \
--disable-ffmpeg --disable-ffplay --disable-ffserver --disable-ffprobe \
--enable-gpl --disable-debug
make && make install



#framework Doubango
cd /usr/src/
svn checkout http://doubango.googlecode.com/svn/branches/2.0/doubango doubango
cd /usr/src/doubango 
./autogen.sh 
./configure --with-ssl --with-srtp --with-speexdsp --with-ffmpeg

#configure: error: You requested SRTP (requires libsrtp) but not found...die
#solution: reinstall SRTP

#configure: error: You requested SSL (requires OpenSSL) but not found...die
#solution: upgrade OpenSSL above
#documented

#configure: error: You requested SPEEX DSP but not found...die
#solution: install: speex-1.2beta3.tar.gz above

make && make install

#E: make[2]: *** [src/tls/libtinyNET_la-tnet_dtls.lo] Error 1
#E: make[2]: Leaving directory `/usr/src/doubango/tinyNET'
#E: make[1]: *** [all-recursive] Error 1
#E: make[1]: Leaving directory `/usr/src/doubango'
#E: make: *** [all] Error 2

#unsuccessful solution
cd /usr/src/
wget http://www.kostecky.cz/doubango/doubango.patch --no-check-certificate
#there is antispam: check content of file!
cd doubango
patch -p0 < ./../doubango.patch

#Error patch: **** Only garbage was found in the patch input.
#solution: check content of the patch

#E: patching file rce (read from tinyNET/test/test_ice.h)
#E: Hunk #1 FAILED at 58 (different line endings).
#E: 1 out of 1 hunk FAILED -- saving rejects to file rce.rej
#E: patching file rce (read from tinyNET/src/tnet_utils.c)
#E: Hunk #1 FAILED at 200.
#E: Hunk #2 FAILED at 215.
#E: 2 out of 2 hunks FAILED -- saving rejects to file rce.rej
#E: patching file rce (read from tinyNET/src/tinynet_config.h)
#E: Hunk #1 FAILED at 88.
#E: 1 out of 1 hunk FAILED -- saving rejects to file rce.rej

make && make install
#WITHOUT SUCCESS!



#tutorial continues by this commands
svn co http://webrtc2sip.googlecode.com/svn/trunk/ webrtc2sip
export PREFIX=/etc/webrtc2sip
cd webrtc2sip 
./autogen.sh 
./configure --prefix=$PREFIX
make && make install

#E: mp_object.h:23:23: fatal error: tsk_debug.h: No such file or directory
#E: make[1]: *** [webrtc2sip-mp_c2c.o] Error 1
#E: make[1]: Leaving directory `/usr/src/webrtc2sip'
#E: make: *** [all] Error 2

cp -f ./config.xml $PREFIX/sbin/config.xml
webrtc2sip --help



#Doubango ./configure final screen
**************************************************************************
*                               CONGRATULATIONS
**************************************************************************
Cross Compilation:    no
Target OS:            Linux
Host setup:           x86_64-unknown-linux-gnu
Install prefix:       /usr/local
Compiler:             gcc
Build Type:           doubango

Enable GPL:           yes
Enable Non Free:      yes

FFmpeg:               yes
VP8 video codec:      yes
OpenH264 video codec: no
OPUS audio codec:     yes
ILBC audio codec:     no
G.729 audio codec:    no -> yes
GSM audio codec:      yes
AMR audio codec:      no -> yes
SPEEX audio codec:    yes
G.722 audio codec:    yes
G.711 audio codec:    yes

YUV:                  no
JPEG:                 no
SPEEX DSP:            yes

SSL:                  yes
DTLS-SRTP:            yes
DTLS:                 yes
SRTP:                 yes

WebRTC:               Enabled(no): AEC(no), NS(no)

Monotonic timers:     yes
RESOLV:               no
ALSA (audio):         no
OSS (audio):          yes
V4L2 (video):         yes
DEBUG:                no

DEBUG_LEVEL:          error


Co s tím dále nevím... Nejvíce jsem se zdržel na kompilaci libtinyNET_la-tnet_dtls.lo, nicméně patchování mi nepomohlo a dále nevím, budu rád za případnou pomoc.

LibSRTP: make: *** [runtest] Error 255

Toto je řešení problému s knihovnou librsrtp při kompilaci na Ubuntu Server 14.04.3 LTS x64 v neprodukčním prostředí. Je to útržek z práce na projektu.

cd /usr/src/
cd /usr/src/libsrtp
CFLAGS="-fPIC" ./configure --enable-pic 
make && make install
make runtest
#E: ./rtpw: couldn't open file /usr/share/dict/words
#E: make: *** [runtest] Error 255 

#solution
cd /usr/share/dict
tar zxvf linuxwords.1.tar.gz
rm linuxwords.1.tar.gz
mv linuxwords.1/linux.words ./words
rm -r linuxwords.1
cd /usr/src/libsrtp 

make runtest
#libsrtp2 test applications passed.

Nic více, nic méně, ale snad to adminům hledajícím na Google pomůže. 

2015-12-01

Soutěž s ČSOB šťastná chvilka

Tak jsem na sociální síti narazil na soutěž Cool kalendáře nebo také Šťastná chvilka od ČSOB jejíž podstatou je ve správnou chvíli vložit odpověď na nějakou triviální otázku a v případě, že se odpověď uloží v ideální moment stáváte se výhercem nějaké ceny. 

V prvním kole, které ani nebylo zašifrované se mi podařilo získat kávovar. Pravidla už nedovolují mou další účast a tak mohu další mnou vypočtené termíny pustit do světa.

V pravidlech totiž zjistíte, že šťastná chvilka je definována poměrně pěkně rafinovaným způsobem práce s časem, nicméně není to nic, co by nezvládnul Excel za pár minut:
  •  1.12.15 14:32:29  1. Šťastná chvilka
  •  2.12.15 10:13:48  2. Šťastná chvilka
  •  3.12.15 16:34:32  3. Šťastná chvilka
  •  4.12.15 21:11:22  4. Šťastná chvilka
  •  5.12.15 09:06:35  5. Šťastná chvilka
  •  6.12.15 22:34:14  6. Šťastná chvilka
  •  7.12.15 14:44:23  7. Šťastná chvilka
  •  8.12.15 12:39:25  8. Šťastná chvilka
  •  9.12.15 16:26:06  9. Šťastná chvilka
  • 10.12.15 09:30:58 10. Šťastná chvilka
  • 11.12.15 18:52:12 11. Šťastná chvilka
  • 12.12.15 17:20:34 12. Šťastná chvilka

Konkrétně je to tedy zapsáno takto:
  • 1. Šťastná chvilka = 1.12.2015 14:32:29
  • 2. Šťastná chvilka = 1. Šťastná chvilka + 70 879,12 vteřin
  • 3. Šťastná chvilka = 2. Šťastná chvilka + 109 244,18 vteřin
  • 4. Šťastná chvilka = 1. Šťastná chvilka + 283 132,89 vteřin
  • 5. Šťastná chvilka = 4. Šťastná chvilka + 42 912,56 vteřin
  • 6. Šťastná chvilka = 3. Šťastná chvilka + 280 782,22 vteřin
  • 7. Šťastná chvilka = 1. Šťastná chvilka + 519 113,89 vteřin
  • 8. Šťastná chvilka = 6. Šťastná chvilka + 137 111,30 vteřin
  • 9. Šťastná chvilka = 8. Šťastná chvilka + 100 001,16 vteřin
  • 10. Šťastná chvilka = 2. Šťastná chvilka + 688 630,19 vteřin
  • 11. Šťastná chvilka = 10. Šťastná chvilka + 120 074,10 vteřin
  • 12. Šťastná chvilka = 11. Šťastná chvilka + 90 792,94 vteřin – 9 890,56 vteřin

Takže už si stačí jen včas vzpomenout... Pokud si chcete ověřit výpočty, XLS soubor sdílím zde.

Pokud chcete vědět, jaký je čas serveru, tedy ten, podle kterého se rozhoduje, nastavte si synchronizaci času na některý ze serverů: (web jede na Google hostingu)
  • time1.google.com 
  • time2.google.com 
  • time3.google.com 
  • time4.google.com
Hodně štěstí, pokud budete také úspěšní a něco vyhrajete, dejte mi vědět do komentářů!