<<< sicherheits-checkliste - übersicht - wie geht dem - vserver - virtuelle linux hardware >>>
installation von asterisk mit zaphfc
Wie mache ich eine mini-PBX mit ISDN?
Die aktuelle Version dieser Seite liegt unter http://verfaction.de/zaphfc.
Alle Copyrightrechte verbleiben beim Autor.
Zielsetzung
Hintergrund
Voice-over-IP ist zur Zeit im Kommen, das wird kaum jemand leugnen können. Aber warum wollen eigentlich alle dieses VoIP haben? Welche Vorteile bringt das, wenn man doch schon ein funktionierendes Telefon hat?
Nun, die einfachste aller Erklärungen ist wie immer die naheliegenste: Kosten. Wer mit VoIP nicht mehr auf Wählleitungen zurückgreifen muss, der legt schon einmal die Kosten für Telefon- und Internet-Anbindung zusammen. Sofern also auf der Internet-Leitung noch Bandbreite übrig ist, kann man diese für VoIP nutzen und damit ein Kostenersparnis durch Synergie erzielen. Wichtig hierbei ist allerdings, dass eine Überlastregelung den Telefonie-Datenverkehr bevorzugt behandeln muss, da sinnvolle Verzögerungen im Bereich <150ms gewählt bleiben müssen, um eine flüssige Unterhaltung zu gewährleisten. Überdies sollte die Varianz der Verzögerung minimal sein, da sonst die Software die Varianz noch als künstliche Verzögerung hinzufügen muss, um eine durchgängige Sprachverbindung zu gewährleisten. Für DSL-Kunden bedeutet dies, dass ohne Fastpath die Nutzung von VoIP nicht ernsthaft möglich ist. DSL-Endkunden mit z.B. 128kBit/s Upstream dürfen praktisch keine Uploads parallel zum Telefonie-Datenverkehr haben. Selbst Downloads können zu Störungen, wie Aussetzern oder Verzerrungen führen.
Implementierung
Um nun Telefonie mit anderen Teilnehmern über das Internet zu führen müssen grundsätzlich die beiden Welten miteinander verbunden werden. Dazu setze ich in diesem Beispiel eine ISDN-Karte im NT-Modus ein, um daran ein normales ISDN-Telefon anzuschliessen. Eine zweite ISDN-Karte stellt den Kontakt mit dem externen ISDN-Netz her. Somit kann ich mit meinem normalen Telefon weiterhin telefonieren und abgehend frei auswählen, ob ich über ISDN oder VoIP telefoniere. Eingehende Anrufe werden für den Benutzer transparent zum angerufenen Telefon durchgeleitet. Als Übergabe-Gateway kommen mein Linux-Router (für den Kontakt mit der Aussenwelt) und meine Workstation (für den internen ISDN-Anschluss) zum Einsatz. In dieser Konstellation wird zwischen den beiden Rechnern IAX2 als Protokoll eingesetzt. Es ist dabei unerheblich ob der "interne" Endpunkt im direkt angeschlossenen LAN sitzt, oder über das Internet erreicht werden muss.
Als Protokolle werden H.323, SIP und IAX2 benutzt. Die Umsetzung zwischen herkömmlichen Telefonnummern und VoIP-URIs geht über ENUM (im Speziellen 9.4.e164.arpa vom DENIC).
Anordnung:
ISDN --- Asterisk (extern, Voicemail, Fax, HFC als TE)
VoIP -/                        \------ [VoIP/IAX2] -- Asterisk (intern, HFC als NT)
                                                           \-- ISDN-Telefon
Fax-Support
Die Nutzung von Fax ist aktuell nur über ISDN-Verbindungen oder G.711 möglich. T.38-Unterstützung in asterisk is momentan nicht verfügbar.
Hardware
In meinem Fall habe ich 2 HFC-S Karten von Conrad gekauft und eine gebrauchte Gigaset 3060 über eBay. Parallel bleibt während der Übergangszeit mein normales ISDN-Telefon direkt angeschlossen, um nicht zu 100% abhängig von der neuen Konfiguration zu sein.
Bandbreite
Als überschlagsmäße Auslegung kann pro G.711 Kanal mit 80 kbps (Kilobit pro Sekunde) gerechnet werden, bei GSM mit ca. 30 kbps. Diese Zahlen beinhalten keine Video-Nutzung und sollten als Mindestanforderung verstanden werden. Immerhin müssen auch noch Lastspitzen abgedeckt werden, um verlorene Pakete wieder aufzuholen. Die Nutzung von G.711 bringt ISDN-gleiche Sprachqualität, G.726 und iLBC sind ebenfalls für Sprache sehr empfehlenswert. GSM stellt aber gängigerweise den "kleinsten gemeinsamen Nenner" dar. Eine detailliertere Übersicht zu benötigten Bandbreiten gibt es hier.
Benötigte Software
Aktuell eingesetzt werden:
Die Vermittlungsstelle und Kontrollzentrum zwischen allen Welten
Wird von Asterisk genutzt. Bringt die Funktionen, um Q.931 und Q.921 Signalisierung zu tätigen
Wird von Asterisk genutzt. Abstraktionsschicht für TDM (time division multiplex) Karten, wie z.B. ZapHFC ISDN.
Für Eilige: Die Blitzanleitung
Unter Debian lässt sich das wie folgt installieren:

root@host:~ # echo "deb http://pkg-voip.buildserver.net/debian sarge main" >>/etc/apt/sources.list
root@host:~ # apt-get update
root@host:~ # apt-get install asterisk asterisk-bristuff zaptel zaptel-source module-assistant dpatch
root@host:~ # echo <<EOF >/etc/zaptel.conf
# hfc-s pci a span definition
# most of the values should be bogus because we are not really zaptel
loadzone=nl
defaultzone=nl

span=1,1,3,ccs,ami
bchan=1-2
dchan=3
alaw=1-3
EOF
# echo <<EOF >/etc/asterisk/zapata.conf
;
; Zapata telephony interface
;
; Configuration file

[channels]
;
; Default language
;
;language=en
;
; Default context
;
;
switchtype = euroisdn
; p2mp TE mode
signalling = bri_cpe_ptmp
; ^^^^^^ this is for zaphfc modes=0
; p2p TE mode
;signalling = bri_cpe
; p2mp NT mode
;signalling = bri_net_ptmp
; ^^^^ this is for zaphfc modes=1
; p2p NT mode
;signalling = bri_net

pridialplan=local
prilocaldialplan=local
nationalprefix = 0
internationalprefix = 00

; trust user provided callerid (clip no screening)?
pritrustusercid = yes
callerid=asreceived

echocancel=yes
immediate=no
group = 1
context=inbound-isdn
channel => 1-2

EOF
# m-a update;m-a a-i zaptel
# vim /etc/default/asterisk
(hier jetzt RUNASTERISK=yes setzen)
Mit den passenden Kernel-Headern installiert, klappt das
module-assistant update;module-assistant auto-install zaptel
dann auch. Nach geglücktem Compilieren kann danach das generierte zaptel-modules Paket (mittels dpkg -i /usr/src/zaptel-modules*.deb;depmod -a;modprobe zaphfc) installiert werden. (Hilfe gibt's aktuell immer unter /usr/share/doc/zaptel-source/README.Debian)
Mittels modprobe zaphfc kann das Kernelmodul dann geladen werden. Sofern NT-Mode benötigt wird, muss mit modprobe zaphfc modes=1 gearbeitet werden und sehr wahrscheinlich muss die ztcfg-Ausführung von /etc/modprobe.d/zaptel und /etc/modutils/zaptel auskommentiert und update-modules laufen gelassen werden. Momentan gilt, dass ztcfg nur GENAU EINMAL nach dem Laden des zaphfc-Moduls ausgeführt werden darf. Alle weiteren Versuche, das Modul zu initialisieren, werden zwar nicht mit einem Fehler quittiert, aber dafür stellt die Karte jeglichen Dienst ein. Wenn also sämtliche Anrufe von und zu ISDN nicht klappen, dann als erstes die automagischen ztcfg Aufrufe ausbauen und nach dem Laden des Modules einmal händisch ausführen (rmmod zaphfc;modprobe zaphfc modes=1;ztcfg -vv). Wenn dann asterisk startet (asterisk -U asterisk -vvvvvvv), ist zumindest das Problem identifiziert (Lösungsvorschläge bitte an mich oder den Upstream).
Von hier kann es jetzt direkt zum Finetuning des Asterisk weitergehen (Überflüssige Module in modules.conf). Asterisk gestartet wird übrigends mit /etc/init.d/asterisk start
BRIstuff
(Vorausbemerkung an alle Debian-Nutzer: asterisk-bristuff hat bristuff bereits eincompiliert!) Eigenlich ist alles direkt im Paket bristuff von junghanns.net enthalten. Dort ist auch ein Script drin, dass direkt alles baut (zaptel, libpri und asterisk) und installiert, wenn man auf Pakete verzichten will. Ich habe für meine Installation die Debian Pakete gepatcht und somit aus dem bristuff nur das zaphfc Kernelmodul benötigt.
Asterisk, zaptel, libpri
Abgesehen von den BRIstuff-Patches ist meine Installation ein "normaler" Asterisk. Die Patches müssen wie gesagt auf libpri und zaptel angewendet werden und mit diesen Versionen der ebenfalls gepatchte Asterisk compiliert werden. Für weitergehende Fragen zu Asterisk sei an dieser Stelle auf das Voip-info Wiki verwiesen. Sobald ich meine Installation auf aefirion umgestellt habe, werde ich diese Seite updaten.
Ausgangssituation, Benötigte Hardware
Um ISDN sowohl intern als auch extern zu machen, benötigt man 2 HFC Karten (z.B. isdn.jolly.de hat eine Liste). Von diesen schaltet man eine in den TE und die andere in den NT-Modus. An die Karte im NT-Modus hängt man dann einen NTBA und ein handelsübliches ISDN-Telefon.
Diese beiden Asterisk laufen bei mir auf 2 Rechnern, die miteinander über IAX2 kommunizieren. Dabei ist es egal, ob dafür die Verbindung über LAN oder über das Internet geht. Wichtig ist die korrekte Einbindung in iax.conf. Vor allem bei Verbindung über LAN lohnt es sich aus Qualitäts und Latenzgründen "alaw" als Codec einzusetzen. Dies kann in der iax.conf auch für einzelne Endpunkte definiert werden.
Software-Installation
Das zaphfc Kernelmodul muss man aus dem bristuff Paket gegen den aktuellen Kernel übersetzen und installieren (u.U. reicht: make&&make install). Danach aus den bristuff/patches/ die Sourcen von libpri, zaptel und asterisk patchen, falls man nicht bereits gepatchte Pakete einsetzt. Alternativ einfach das ./install.sh ausführen. Die Dateien /etc/zaptel.conf und /etc/asterisk/zapata.conf kommen im bristuff mit und müssen ausgetauscht werden, um mit der HFC zu funktionieren. Die Originale sind für größere Channelbanks und enthalten die bristuff Optionen nicht.
Besonderheiten mit dem ZapHFC Kernelmodul
Das ZapHFC Kernelmodul hat als Modulparameter "modes", der 1 für NT-Mode und 0 (oder nicht angegeben) für TE-Mode sein muss. Danach muss man mit ztcfg die Karte initialisieren. WICHTIG: Diese Initialisierung muss nur genau EINMAL erfolgen. Es klappt weder die Karte uninitialisiert im Asterisk zu nutzen, noch bei mehrfacher Initialisierung sie weiter zu benutzen. Bei mehrfacher Initialisierung kommen vor allem keine sprechenden Fehlermeldungen heraus. Dieser Fehler tritt bei mir mit RC5 noch auf, eventuell werden zukünftige Treiber das Problem nicht mehr haben.
Überflüssige Module in modules.conf
Bei mir konnte ich problemlos auf folgende Module verzichten (modules.conf)

noload => app_db.so
noload => app_forkcdr.so
noload => app_ices.so
noload => app_intercom.so
noload => app_nbscat.so
noload => app_parkandannounce.so
noload => cdr_csv.so
noload => cdr_sqlite.so
noload => cdr_manager.so
noload => cdr_odbc.so
noload => cdr_pgsql.so
noload => chan_agent.so
noload => chan_alsa.so
noload => chan_mgcp.so
noload => chan_modem.so
noload => chan_modem_aopen.so
noload => chan_modem_bestdata.so
noload => chan_modem_i4l.so
noload => chan_oss.so
noload => chan_phone.so
noload => chan_skinny.so
noload => codec_lpc10.so
noload => pbx_gtkconsole.so
noload => pbx_kdeconsole.so
noload => pbx_wilcalu.so
noload => res_config_odbc.so
noload => res_odbc.so
; these are for chan_capi
; (which you may or may not have)
noload => chan_capi.so
noload => app_capiCD.so
noload => app_capiHOLD.so
noload => app_capiECT.so
noload => app_capiRETRIEVE.so
noload => app_capiMCID.so
Beim Starten von "asterisk -U asterisk -vvvvvvvvc" sollte dann kein ERROR auftreten, sondern die CLI*> Konsole erscheinen.
Dialplan
Nach erfolgreicher Installation von zaphfc und Asterisk sollte mit dem "demo" context ein erster Test möglich sein. Das "s" Target ist dabei direkt als Freizeichen zu erreichen, man muss nicht einmal eine Zielnummer wählen. Bei der normalen Asterisk Installation bekommt man somit die Demoansage, die einen zur gelungenen Installation beglückwünscht. Mit der 500, 600 und 8500 kann man dann auch gleich etwas rumtesten.
Beispielhaft sieht der Dialplan dann wie folgt aus:

[local-isdn]
; leite den ankommenden ISDN-Anruf auf den internen Asterisk weiter...
exten => 948839,1,Macro(stdisdn,948839,IAX2/kk/948839,50)
exten => 7152948839,1,Goto(local-isdn,948839,1)

include => local-fax

[local]
; leite den ankommenden VoIP-Anruf auf den internen Asterisk weiter...
exten => 948839,1,Macro(stdexten,948839,IAX2/kk/948839,50)
exten => 7152948839,1,Goto(local,948839,1)
exten => kk,1,Goto(local,948839,1)
include => local-fax

exten => 7152903705,1,Goto(fax,903705,1)

[local-fax]
; inbound fax
exten => 903705,1,Goto(fax,903705,1)

; ENUM fuer Telefon
exten => _010990NXX.,1,Answer
exten => _010990NXX.,2,Playtones(ring)
exten => _010990NXX.,3,Dial(Zap/g1d/${EXTEN:5},30)
; ISDN fuer 01099 virtuelles call-by-call

exten => _0NXX.,1,Answer
exten => _0NXX.,2,Playtones(ring)
exten => _0NXX.,3,EnumLookup(49${EXTEN:1})
; Setzt ${ENUM}, springt zu 1 + 101 = 102 bei Fehler
exten => _0NXX.,4,Dial(${ENUM},30)
exten => _0NXX.,5,Goto(105)
; Keine Antwort auf ENUM, zurueck zu PSTN
exten => _0NXX.,54,Goto(105)
; tel:-URI, nimm lieber PSTN
; (koennte Service-Rufnummer sein)
exten => _0NXX.,104,SetCallerID(903707)
exten => _0NXX.,105,Dial(Zap/g1d/${EXTEN},30)
; PSTN-Dialer nimmt die fuehrende Ziffer weg.
; limit this with CheckGroup(1) like
; http://voip-info.org/wiki-Asterisk+cmd+SetGroup examples
Fax mit spandsp
Wer auf sein Fax nicht verzichten will, braucht dies auch bei VoIP nicht zu tun. Für Anrufe von ISDN ist das Problemlos, über das Internet muss zur Zeit noch G711 eingesetzt werden, was viel Bandbreite kostet, bis irgendwann T.38 verfügbar sein wird. Die benötigten rxfax und txfax Module gibt es unter ftp.opencall.org/pub/spandsp/ oder im Debian Paket asterisk-app-fax. Die Faxsconfig ist ebenfalls auf voip-info.org verfügbar und wurde nur minimal eingepasst. Dort gibt es auch ein Script mit detaillierterer Ausgabe, wer das möchte.
Beispiel für Fax mit spandsp

[fax]
exten => 903705,1,Macro(faxreceive)
exten => h,1,system(/var/lib/asterisk/bin/mailfax ${FAXFILE} ${EMAILADDR} ${CALLERIDNUM})

[macro-faxreceive]
exten => s,1,SetVar(FAXFILE=/var/spool/asterisk/fax/${UNIQUEID}.tif)
;exten => s,2,LDAPGet(EMAILADDR=cidmail/${NumberCalled})
exten => s,2,SetVar(EMAILADDR=hostmaster@mydomain.loc)
exten => s,3,rxfax(${FAXFILE})
; use this with the LDAPGet ..
;exten => s,103,SetVar(EMAILADDR=hostmaster@mydomain.loc)
;exten => s,104,rxfax(${FAXFILE})
mailfax Script

#!/bin/sh
# Aufruf mit:
# ############ /var/lib/asterisk/bin/mailfax ${FAXFILE} ${EMAILADDR} ${CALLERIDNUM} #####

if (hash tiff2ps ps2pdf mime-construct);then
# everything ok
/bin/true
else
echo Missing faxtools (run apt-get install libtiff-tools gs-common mime-construct).
exit 1
fi
FAXFILE=$1
RECIPIENT=$2
FAXSENDER=$3

/usr/bin/tiff2ps -2eaz -w8.3 -h11.7 $FAXFILE |
/usr/bin/ps2pdf - |
/usr/bin/mime-construct --to $RECIPIENT \
--subject "Fax from $FAXSENDER" \
--attachment "fax_$FAXSENDER""_`date +%Y%m%d%H%M%S`.pdf"\
--type application/pdf --file -

exit 0
Fazit
Abschliessend bleibt also zu sagen, dass Voice-over-IP mehr und mehr zur Endkundentauglichen Technik heranreift. Fehlende Unterstützungen wie T.38 für Fax werden nach und nach dazu kommen. Aktuell klappen Verbindungen mit SIP und IAX2 problemlos, wer H323 braucht, wird entweder auf OPAL-Unterstützung in aefirion warten oder mit asterisk-oh323 leben müssen. Chan_h323 von Asterisk kann nicht empfohlen werden, da dieses massiv instabil läuft und speziell auch beim Weiterverbinden Probleme hat. Sobald ich asterisk-oh323 oder aefirion mit OAPL eingehender getestet habe, werde ich hier noch ein paar Updates dazu einpflegen. Wer sonst noch Fragen oder Anregungen hat, darf mich gerne anmailen oder anrufen. Vorzugsweise natürlich über VoIP.
Zur Abwechslung mal was "Sinnvolles"
Ok, genug Theorie erstmal. Wird Zeit, mal zu den richtigen Herausforderungen zu kommen, oder nicht? Wie wär's mit MP3s im Streaming für alle Teilnehmer? Nichts leichter als das! Wir erstellen einen Konferenzraum (MeetMe) mit der Nummer 9876 und lassen alle Teilnehmer da hinein anrufen oder transferieren sie dort hinein. Danach rufen wir mit einem Callfile diesen Konferenzraum mit einem MP3 an.
Callfile und Dialpan für MP3 im Konferenz-Streaming

extensions.conf:
; playback des MP3
exten => 99914,1,Answer
exten => 99914,2,playback(hhg1)
exten => 99914,3,hangup

; Konferenzraum für alle Teilnehmer
exten => 99913,1,SetLanguage(de)
exten => 99913,2,Answer
exten => 99913,3,Wait(1)
exten => 99913,4,Meetme,9876
exten => 99913,5,Hangup

callfile um ein mp3 in einem MeetMe abzuspielen.
#
# Create the call on group 2 dial lines and set up
# some re-try timers
#
Channel: Local/99913@sservices
MaxRetries: 2
RetryTime: 60
WaitTime: 30
#
# Assuming that your local extensions are kept in the
# context called [extensions]
#
Context: sservices
Extension: 99914
Priority: 1