Asterisk und Misdn unter Debian

aus PUG, der Penguin User Group
Wechseln zu: Navigation, Suche

Einleitung

Mein neustes Projekt besteht darin, unsere grausame Firmentelefonanlage, durch Asterisk zu ersetzen. Leider ist unsere VO-IP Anlage nicht kompatibel zu Asterisk, da sie ein proprietäres Protokoll nutzt. Ob wir sie dennoch irgendwie integrieren können, steht in den Sternen. Wir möchten die Möglichkeit haben, sowohl ISDN Geräte zu verwenden, als auch SIP Geräte (Soft/Hard).


Hardware

In unserem Testrechner steckt ein Celeron 433Mhz mit 256MB Ram. Als Verbindung zur Außenwelt, stehen zwei HFC, eine AVM-B1(ISA) und eine Netzwerkkarte zur Verfügung. Die B1 wird noch eine weile brach liegen, bis ich sie sinnvoll nutzen kann.

Da unsere Telefone keine eigene Stromversorgung mitbringen und die günstigen HFC Karte keine Stromversorgung mitbringen, ist es nötig den NTBA mit einzubringen. Dieser dient nur als Stromquelle und wird über ein gekreuztes ISDN Kabel angeschlossen. Wie genau das gemacht wird, ist dieser Anleitung zu entnehmen. Eine HFC Karte wird in den NT-Modus gebracht und dient unseren ISDN Telefonen, die andere Karte verbleibt im TE-Modus und wird an den Anschluß NTBA des Telefon Providers (Telekom, Arcor etc.) angeschlossen.

lspci

# 0000:00:0a.0 Network controller: Cologne Chip Designs GmbH ISDN network controller [HFC-PCI] (rev 02)
# 0000:00:0b.0 Network controller: Cologne Chip Designs GmbH ISDN network controller [HFC-PCI] (rev 02)


Die ISDN Telefone selber, werden mit dem NTBA (unserer Stromquelle) verbunden, über das herkömmliche vier adrige ISDN Kabel.


Software

Als Grundlage habe ich mich gegen das äußerst beliebte Asterisk@home entschieden. Zum einen wollte ich wissen, was unter der Haube passiert, zum anderen möchte ich Asterisk in ein vorhandenes System integrieren.

Asterisk selber liegt in der Version 1.2 vor und als Treiber setze ich die aktuellen MISDN Treiber ein, und zwar ausschließlich. Bristuff oder Zaptel Treiber, sind nicht nötig.

Als Betriebssystem kommt Debian Sarge zum Einsatz und mit einem Vanilla Kernel 2.6.14. Der Kernel selber ist bis auf das nötigste abgespeckt, bis auf die benötigten Module. Unter anderem habe ich auch Alsa mit eingebunden, für spätere Spielereien mit Wartemusik etc.


Ziel

Das Basisziel soll es sein, internes und externes Telefonieren via SIP und/oder ISDN zu ermöglichen. Später kommen erweiterte Funktionen zum Einsatz, wie Voicebox (Anrufbeantworter), Weiterleitungen (fest, verzögert, besetzt) und Rückruf bei besetzt.

Jetzt befassen wir uns ersteinmal mit den Basis Funktionen. Dem Telefonieren:


Installation

Die Installation von Debian Sarge oder dem Kernel, werde ich hier nicht aufführen, da es davon mehr als genügend im Internet gibt.

Um die Sache ein wenig zu vereinfachen, habe ich meine Kernel Konfiguration hochgeladen. Es müssen lediglich der Prozessor, Netzwerk, Dateisystem und Alsa (Sound) angepasst werden. Auf SCSI und USB habe ich vollständig verzichtet. Raid (1/5), LVM und CAPI (AVM-B1 Isa) Unterstützung sind dagegen vorhanden.

Wurde der Kernel erstellt und installiert kann es mit Asterisk weitergehen.

Asterisk installieren

Als erstes sollte natürlich die aktuellste Variante vorliegen. Diese lässt sich hier herunterladen. Da ich es gerne aufgeräumt habe, packe ich alles in ein Verzeichnis:

# mkdir /usr/src/asterisk-pbx
# cd /usr/src/asterisk-pbx
# wget http://ftp.digium.com/pub/asterisk/asterisk-1.2.0.tar.gz


Außerdem den chan_misdn Treiber.

# cd /usr/src/asterisk-pbx
# wget http://www.beronet.com/downloads/install-misdn.tar.gz

Dieses Paket ist ein Installationsscript, welches alles nötige herunterlädt und installiert. Damit auch die Installation klappt, ist es wichtig, das die Links zu den Kernel Quellen stimmen:

# ln -s /usr/src/linux-2.6.14 /usr/linux
# ln -s /usr/src/linux-2.6.14 /usr/linux-2.6

Da auf einem normalen Debian keine Devel Pakete installiert werden, müssen wir in jedem Fall noch ein paar, per apt-get install, installieren:

# apt-get install libncurses5-dev libssl-dev zlib1g-dev 

Wer erfolgreich den Kernel kompiliert haben sollte, benötigt nur noch libssl-dev und zlib1g-dev. Wer später auch noch Wartemusik per mpg123 abspielen möchte, kann dann auch gleich noch libasound2-dev installieren, für die alsa Unterstützung.

Ist das erledigt, wirden die Pakete entpackt und übersetzt:

# cd /usr/src/asterisk-pbx
# tar xvzf asterisk-1.2.0.tar.gz
# cd asterisk-1.2.0
# make

Sollten beim make Fehler auftreten, liegt es häufig an fehlenden Devel Paketen. Einfach an den Anfang gehen und nach einem "No such file or directory" ausschau halten.

Wurde alles übersetzt, kann man installieren und die Beispiel Configurationen erzeugen:

# make install
# make samples

Die Beispiele werden automatisch nach /etc/asterisk kopiert.

Misdn installieren

Ist das erledigt, geht es an chan_misdn. Das Script erwartet die Asterisk Quellen in /usr/src/asterisk, also sorgen wir dafür, das es diese findet. Alternativ lässt sich auch das MAKEFILE anpassen:

# ln -s /usr/src/asterisk-pbx/asterisk-1.2 /usr/src/asterisk
# cd /usr/src/asterisk-pbx
# tar xvzf install-misdn.tar.gz
# cd misdn-install
# make && make install

Auch hier wieder bei Fehlern darauf achten, ob alle benötigten Devel Pakete installiert sind.

Misdn Einrichten

Misdn bring ein ein Startscript mit, welches die Vorarbeit leistet. Es kann nach den verfügbaren Karten suchen und auch eine Basis Konfiguration erstellen:

# /etc/init.d/misdn-init scan
[OK] found the following devices:
card=1,hfcpci
card=2,hfcpci
[ii] run "/etc/init.d/misdn-init config" to store this information to /etc/misdn-init.conf

Gesagt, getan:

# /etc/init.d/misdn-init config
[OK] /etc/misdn-init.conf created. It's now safe to run "/etc/init.d/misdn-init start"
[ii] make your ports (1-2) available in asterisk by editing "/etc/asterisk/misdn.conf"

Bevor wir Misdn starten, sollten wir noch mal in die /etc/misdn-init.conf schauen und anpassen (ohne Kommentare):

card=1,hfcpci
card=2,hfcpci
te_ptmp=1
nt_ptmp=2
poll=64
#pcm=1
debug=0

Die ersten beiden Einträge, stellen die Karten da, und welcher Treiber (modul) verwendet wird. In diesem Fall hfcpci. Die beiden nächsten Einträge bestimmen, in welchem Modus die Karte eins und zwei laufen soll. In diesem Fall ist Karte eins im TE Modus, welche dann am NTBA des Telefonproviders. od. TK-Anlage angeschlossen wird. Karte zwei läuft im NT-Modus und stellt uns damit einen internen S0 Bus zur Verfügung, der nötig ist, um unsere Telefone daran beteiben zu können.

Wichtig: Die Reihenfolge, welche Karte eins oder zwei ist, muss nicht der physikalische Reihenfolge entsprechen. In meinem Fall ist card=1 die zweite physikalische (PCI Slot 3) und card=2 die erste physikalische Karte (PCI Slot4). Dies ist unbedingt zu beachten bei der Zuordnung der Funktion (TE- od. NT- Modus), sprich welches Kabel hineinkommt.

Ist das erledigt, kann misdn gestartet werden:

# /etc/init.d/misdn-init start
-----------------------------------------
Loading module(s) for your misdn-cards:
-----------------------------------------
modprobe hfcpci protocol=0x2,0x12 layermask=0xf,0x3

An der Art, wie die Karten geladen werden, kann man erkennen, welcher Modus verwendet wird. Dies ist in der /etc/misdn-init.conf nachzulesen.

Per dmesg lässt sich dann folgendes lesen:

mISDN: devices open on remove
MISDN free_device: entitylist not empty
mISDNd: daemon exit now
mISDNcore unloaded
Modular ISDN Stack core $Revision: 1.23 $
mISDNd: kernel daemon started
ISDN L1 driver version 1.11
mISDNd: test event done
ISDN L2 driver version 1.19
mISDN: DSS1 Rev. 1.26
mISDN_dsp: Audio DSP  Rev. 1.10 (debug=0xf)
HFC card cf177000 dch cf177088 bch1 cf177208 bch2 cf177394
mISDN: HFC-PCI driver Rev. 1.38
PCI: Enabling device 0000:00:0a.0 (0000 -> 0003)
ACPI: PCI Interrupt 0000:00:0a.0[A] -> Link [LNKC] -> GSI 5 (level, low) -> IRQ 5
mISDN: HFC-PCI card manufacturer: CCD/Billion/Asuscom card name: 2BD0
HFC-PCI: defined at mem 0xd0894000 fifo 0xcf768000(0xf768000) IRQ 5 HZ 250
spin_lock_adr=cf177064 now(d08cbc2c)
busy_lock_adr=cf177068 now(d08cbc2c)
reset_hfcpci: entered
HFC_PCI: resetting HFC ChipId(30)
HFC-PCI status(4) before reset
HFC-PCI status(2) after reset
HFC-PCI status(4) after 5us
init_card: entered
inithfcpci: entered
HFC PCI: IRQ 5 count 34
HFC card cf330000 dch cf330088 bch1 cf330208 bch2 cf330394
mISDN: HFC-PCI driver Rev. 1.38
PCI: Enabling device 0000:00:0b.0 (0000 -> 0003)
ACPI: PCI Interrupt 0000:00:0b.0[A] -> Link [LNKB] -> GSI 9 (level, low) -> IRQ 9
mISDN: HFC-PCI card manufacturer: CCD/Billion/Asuscom card name: 2BD0
HFC-PCI: defined at mem 0xd08b6000 fifo 0xcf778000(0xf778000) IRQ 9 HZ 250
spin_lock_adr=cf330064 now(d08cbc2c)
busy_lock_adr=cf330068 now(d08cbc2c)
reset_hfcpci: entered
HFC_PCI: resetting HFC ChipId(30)
HFC-PCI status(4) before reset
HFC-PCI status(2) after reset
HFC-PCI status(4) after 5us
init_card: entered
inithfcpci: entered
HFC PCI: IRQ 9 count 34
HFC card cf17a000 dch cf17a088 bch1 cf17a208 bch2 cf17a394
mISDN: HFC-PCI driver Rev. 1.38
HFC-PCI: No more PCI cards found
HFC 2 cards installed

Es sollten dann folgende Module geladen worden sein:

 # lsmod
Module                  Size  Used by
hfcpci                 28460  0
mISDN_dsp             200928  0
l3udss1                38664  0
mISDN_l2               42368  0
mISDN_l1               10632  0
mISDN_core             69216  5 hfcpci,mISDN_dsp,l3udss1,mISDN_l2,mISDN_l1

Ist das auch geschafft, kann es endlich daran gehen, Asterisk zu konfigurieren.

Asterisk konfigurieren

Als erstes werden wir die Basisfunktionalität bereitstellen und es ermöglichen, intern als auch extern, über SIP und ISDN zu telefonieren. Für dieses Unterfangen, werden wir drei Konfigurationsdateien bearbeiten.

  • /etc/asterisk/misdn.conf - Sie ist für die verwaltung der Misdn Geräte zuständig.
  • /etc/asterisk/sip.conf - Diese Datei wird benötigt, um Benutzer und SIP-Provider anzulegen.
  • /etc/asterisk/extensions.conf - Hier wird letztendlich alles zusammen geführt. Diese Datei ist der Wählplan von Asterisk.


Misdn für Asterisk einrichten

Die /etc/asterisk/misdn.conf teilt Asterisk mit, wie die einzelnen HFC Karten genutzt werden. Eine typische Konfiguration sieht so aus (ohne Kommentare):

[general]
debug=0
method=standard
append_digits2exten=yes
bridging=yes

[default]
context=default
language=en
nationalprefix=0
internationalprefix=00
rxgain=0
txgain=0
dialplan=0

[NTports]
context=default
ports=2
msns=*

[TEports]
context=outgoing
ports=1
msns=12345,123457,123458

Hinweis: bridging=yes führt u.U. zu einem Kernel-Panic. In diesem Fall bridging=no setzen. In /etc/asterisk/misdn.conf muss dann unter [general] bridging=no gesetzt werden. Siehe auch Diskussion.

Die Contexte (in etwa zu Beschreiben als Regelkette) general und default sind standard Einstellungen und können in der Regel so übernommen werden. Wichtiger sind die beiden Contexte NTports und TEports. Eins vorweg, die Namen der Contexte können beliebig gewählt werden.

NTports

  • Der Context NTports ist unser eigener S0 Bus. An diesem werden unsere Telefone angeschlossen. Der Eintrag context=default beschreibt, das er den vorhandenen Context default mit einbeziehen soll.
  • ports=2 Beschreibt die Karte (der physikalische Anschluss), welche verwendet wird. Hier gilt es zu testen, ob dieser Port tatsächlich der NT-Port ist, welcher in der /etc/misdn-init.conf eingerichtet wurde. Das wird spätestens beim testen von Asterisk herauskommen ;-) .
  • msns=* sagt aus, das darüber jede (interne) MSN angenommen und über Asterisk verwaltet werden kann.

TEports

Diese Karte wird mit dem Telefon Anschluß (in der Regel dem NTBA) des Telefonproviders, oder einer TK-Anlage verbunden.

  • context=outgoing sagt Asterisk, "Verwende die Regeln, die in dem Context outgoing verwendet werden. Später mehr dazu.
  • ports=1 Hier wird unsere erste Karte angesprochen. Wieder daran denken, es muss nicht zwangsläufig der erste Karte im ersten PCI Slot sein.
  • msns=12345,123457,123458 ist die uns zugeteilte MSN. Diese benötigen wir, um Asterisk sagen zu können, was geschehen soll, wenn ein Anruf auf einer der MSNs eingeht.

SIP konfigurieren

SIP einzurichten, gehört mit zu den einfachsten Aufgaben, eines Asterisks- Neuling. Neue SIP-Benutzer und Zugänge von SIP-Providern, werden in der /etc/asterisk/sip.conf eingetragen. Eine typisches Beispiel, einer solchen Datei, stellt sich so da:

[general]
useragent= Asterisk-PBX
port=5060
context=default
tos=lowdelay
disallow=all
allow=alaw
allow=ulaw
allow=gsm
allow=ilbc
bindaddr = 0.0.0.0
localnet = 192.168.1.0/255.255.255.0
externip        =      meinhost.dyndns.org
qualify =       yes

register => 11223344:geheim@sipgate.de/11223344

[sipgate]
type=friend
username=11223344
secret=geheim
host=sipgate.de
fromuser=11223344
fromdomain=sipgate.de
nat=yes
qualify=yes
insecure=very
context=calls
canreinvite=no
dtmfmode=info

[200]
type=friend
username=200
secret=test
callerid="Denny" <200>
host=dynamic
dtmfmode=info

Diese Konfiguration ist für einen Asterisk, der hinter einem NAT-Router steht. Damit Asterisk das auch weiß, werden in dem Context general ensprechende Einträge erstellt:

  • bindaddr = 0.0.0.0 ; Soll sich an alle Netzwerkkarten binden
  • localnet = 192.168.1.0/255.255.255.0 ; Das lokale Netzwerk, welches verwendet wird
  • externip = meinhost.dyndns.org ; Die externe IP-Adresse ermittelt Asterisk mit Hilfe des meinhost.dyndns.org
  • qualify = yes ; Dieser Eintrag hat zur Folge, das Asterisk alle 2 Sekunden prüft, ob auch alle SIP Dienste erreichbar sind. Es wird speziell benötigt, für konfigurationen hinter NAT-Routern. Mehr dazu lässt sich hier nachlesen (englisch).
  • register => 11223344:geheim@sipgate.de/11223344 ; Dieser Eintrag teilt Asterisk mit, wo er sich als SIP-Client anmelden muss. Der erste Teil (11223344) stellt den Benutzernamen (SIP-Nummer) dar, gefolgt von einem Doppelpunkt mit dem dazugehörigen Kennwort. Als nächstes folgt das @ Symbol mit dem Servernamen des Sip-Providers, in diesem Fall Sipgate.de, einem Schrägstrick (Slash) und erneut dem Benutzernamen.

Da Asterisk aber noch nicht weiß, wie er mit dem SIP-Provider umgehen soll (wichtig für eingehende und ausgehende Gesprächer über SIP), teilen wir ihm das über den Context sipgate mit. Dieser ist eigentlich selbsterklärend, doch auf zwei Dinge möchte ich kurz eingehen:

  • type=friend ; Teilt Asterisk mit, das sipgate.de sowohl eine Vermittlungsstelle ist, als auch ein normaler SIP-Client. Hier für genauere Infos (englisch)
  • insecure=very ; dieser Eintrag ist nötig, da sonst die Authentifizierung zu sipgate nicht funktioniert.
  • context=calls ; Welche Regelkette für Sipgate.de zuständig ist. Diese werden wir in der extensions.conf wiedersehen.

Der letzte Context 200 stellt unseren ersten Benutzer da, mit dem wir uns per SIP an Asterisk anmelden können. Auch diese Datei ist selbsterklärend und bedarf hier keiner weiteren Erläuterung.

extensions.conf - Der Wählplan

Die extension.conf ist der Dreh und Angelpunkt einer jeden Asterisk Installation. Gleichzeitig ist sie auch die (aus meiner Sicht) komplizierteste Konfigurationsdatei. Dort wird festgelegt, wie Eingehen- und Ausgehende- Gespäche behandelt werden soll. Ob sie über/an SIP/Analog/ISDN geleitet werden. Oder was im Falle von nicht Erreichbarkeit (besetzt,Timeout etc) geschehen soll. Auch das Einbinden eines Anrufbeantworters oder einer Menüsteuerung, wie sie bei größeren Fimen gang und gäbe ist, lässt sich dort einstellen.

In unserem Fall, begnügen wir uns damit, einfach nur intern und extern Telefonieren zu können. Dabei spielt es keine Rolle, ob dies über SIP oder ISDN geschieht. Augrund der länge dieser Datei, werde ich sie in der Beispiel Darstellung kommentieren. Da dies auch noch Neuland für mich ist, stellt meine extensions.conf nicht das Optimum dar. Vieles ließe ganz sicher verbessern oder korrigieren :-) :

[general]

static=yes
writeprotect=no

[globals]
IAXINFO=guest

[default]
include => calls ; Den Context ''calls'' einbinden
include => outgoing ; Den Context ''outgoing'' einbinden

exten => 200,1,Dial(SIP/200,30,Ttr) ; Sip Client mit der Nr. 200 und einem Klingel Timeout von 30 Sekunden
exten => 200,2,Hangup ; Wenn keiner drangeht, auflegen

; Eintrag der immer enthalten sein sollte, denn er ist praktisch zum testen

exten => 663,1,Playback(demo-echotest)
exten => 663,2,Echo
exten => 663,3,Playback(demo-echodone)

; Unser context ''calls'' der über den Include=> calls im context ''default'' eingebunden wird.

[calls]

;
; Wichtig hier!! Besonder aus den Port achten.
; misdn/2/400,10,Ttr misdn ist die Schnittstelle, 2 beschreibt den Port (HFC Karte) und die 400 ist die MSN des Telefons.
;
; Der Eintrag wurde auskommentiert, da Anrufe von Sipgate.de an ein Sip Telefon weitergeleitet werden sollen, siehe drei Zeilen weiter.
; 
; exten => 11223344,1,Dial(misdn/2/400,10,Ttr) ; Wenn über SIPgate.de ein Anruf eingeht, an ein ISDN Telefon mit der MSN 400 weiterleiten
; exten => 11223344,2,Hangup ; wenn keiner drangeht, auflegen.

; Statt an ein ISDN Telefon, kann ein anruf über sipgate.de auch an ein Siptelefon/Client weitergeleitet werden.

exten => 11223344,1 ,1,Dial(SIP/200,10,Ttr) ; Anruf weiterleiten an den SIP Client mit der Kennung 200 
exten => 11223344,2,Hangup ; Wenn keiner drangeht, auflegen

exten => _3.,1,Dial(SIP/${EXTEN:1}@sipgate,10,Ttr) ; Ausgehende Gespräche gehen über sipgate. 
                                                                                   ; Die Infos werden aus dem Context ''sipgate'' in der sip.conf bezogen. 
exten => _3.,2,Congestion
exten => _3.,3,Busy
exten => _3.,4,Hang

exten => 400,1,Dial(misdn/2/400,10,Ttr) ; Ersten ISDN Telefon, mit der MSN 400 an Port 2
exten => 400,2,Hangup ; Auflegen, wenn keiner drangeht.

exten => 401,1,Dial(misdn/2/401,10,Ttr) ; Zweites ISDN Telefon, mit der MSN an Port 2
exten => 401,2,Hangup  ; Auflegen, wenn keiner drangeht.

; Unsere Extension, für ausgehende und eingehende Gespräche, über ISDN nach ISDN

[outgoing]

exten => _0.,1,Dial(mISDN/1/${EXTEN:1}) ; Für ausgehende Gespräche muß die 0 vorgewählt werden und es wird Port 1 verwendet.

; Zum testen auskommentiert. Eingehende Anrufe auf die MSN 123456 weiterleiten auf das interne Telefon mit der MSN 401

; exten => 123456,1,Dial(misdn/2/401,10,Ttr)
; exten => 123456,2,Hangup ; Auflegen, wenn keiner drangeht.

exten => 123457,1,Dial(SIP/200,10,Ttr) ; Eingehende Anrufe auf die MSN 123457 weiterleiten, an den SIP Client mit der Kennung 200
exten => 123457,2,Hangup  ; Auflegen, wenn keiner drangeht.


Verkabelung

Wie oben schon erwähnt, wir der NTBA des Telefonproviders in die Karte mit dem Port 1 gesteckt. Der NTBA mit dem Crosslinkkabel wird in die Karte mit dem Port 2 gesteckt. Die Telefone kommen dann in den NTBA, der in Port 2 steckt.

Wie jetz seine zwei ISDN Telefone auf die MSN 400 und 401 konfiguriert hat, kann nun munter testen und versuchen, das andere Telefon oder SIP Client anzurufen. Dazu muß asterisk noch gestartet werden:

# asterisk
# asterisk -r

Das erste Kommando startet asterisk, der zweite Eintrag verbindet uns zu der CLI Shell, in der wir verfolgen können, was passiert. Es ließe sich auch direkt mit der Shell starten:

# asterisk -c

Doch passen dann meine Terminalfarben nicht mehr :-)

Sollten es nicht klappen, können wir Asterisk sagen, er möge uns doch bitte mitteilen, was ihn schmerzt:

# asterisk -vvv

Das startet die Debugausgabe. Der Parameter -v lässt sich beliebig erweitern.

Ende

Hat alles bis hierher geklappt, sollte es möglich sein, sowohl intern, als auch extern zu telefonieren (ISDN<->ISDN/ISDN<->SIP). :-)

Hinweise zur Firewall

Damit auch die SIP Kommunikation nach außen klappt, müssen (UDP) Ports an den Asterisk Server, weitergeleitet werden. Das ist zum einen Port 5060 (Steuerungskanal) als auch ein Bereich, der in der /etc/asterisk/rtp.conf festgelegt wurde. Per Default ist das von (UDP) 5000 bis 31000, also eine ganze Menge.

ToDo

  • Extensions.conf aufräumen
  • Anrufbeantworter hinzufügen
  • Weiterleitung bei besetzt/Timeout
  • Gruppen
  • Gespräche weiterreichen

--Denny 15:16, 5. Dez 2005 (CET)