Montag, 27. November 2006

HOWTO_ Asterisk 1.2 spricht deutsch

Im Zuge der Voicemail-Einrichtung wollte ich auch vom Asterisk deutsch hören - auch der lieben Anrufer willen!

Netterweise gibt es von der Stadt Pforzheim unter der GPL veröffentlichte deutsche Soundfiles für Asterisk.

Diese lädt man sich herunter, entpackt sie und schiebt sie zu den Asterisk-Soundfiles.
#> cd ~
#> wget http://www.stadt-pforzheim.de/asterisk/dateien/ast_prompts_de_v2_0.tar.gz
#> tar -xzf ast_prompts_de_v2_0.tar.gz
#> cp -r ast_prompts_de_v2_0/var/lib/asterisk/sounds/* /var/lib/asterisk/sounds/

Die Sprache lässt sich generell umstellen oder für jeden SIP-Client extra, die Option heisst language und wird in der sip.conf auf de gestellt.

Mein Problem war nun, dass die deutschen Sounds normalisiert sind, d.h. mit maximal möglicher Lautstärke abgespielt werden. Dadurch sind sie zwar alle auf dem gleichen Pegel, diese liegt jedoch deutlich über dem der englischen Sounds und auch deutlich über dem eines normalen Telefonats - haut einem also das Trommelfell glattweg durch das Hirn.

Ich habe die Dateien also leiser gemacht. Dafür brauchte ich erst mal das Tool sox.
#> apt-get install sox
Ich entpackte die Soundfiles, und reduzierte vor dem Kopieren erst einmal die Lautstärke.
#> cd ast_prompts_de_v2_0/var/lib/asterisk/sounds/de
#> for i in *.gsm; do \
> cp $i /tmp/$i \
> sox /tmp/$i -v 0.502 $i \
> done \
> rm /tmp/*.gsm
#> cd ../digits/de
...
Insgesamt führte ich das Kommando also vier Mal aus, anschließend kopierte ich die Dateien wie oben ins Asterisk-Verzeichnis. Die Lautstärke wurde um den Faktor 0.502 reduziert und war damit auf vergleichbarem Niveau wie die Originaldateien, die Asterisk mitliefert.
Alternativ biete ich auch die leiseren Dateien an: ast_prompts_de_v2_1-tar-gz (gz, 1,406 KB)

HOWTO_ Asterisk 1.2 mit deutscher Mailbox

Wenn ich nun schon Asterisk laufen habe, dann möchte ich natürlich auch eine Mailbox dazu haben. Hier also eine kurze Anleitung zur Einrichtung.

Einrichtung der Mailbox

In der voicemail.conf erstellt man einen einfachen Eintrag in der Form
[mbox]
50000 => ,Herr cypressor,mail@provider.com
Im Kontext mbox gibt es nun unter der Nummer 50000 eine Mailbox ohne Passwort (das erste Komma!). Empfangene Nachrichten werden per E-Mail an mail@provider.com gesendet, als Begrüßung steht dort Herr cypressor drin.

Kleines Tweak: Im Kontext general die Option minmessage auskommentieren und auf 5 setzen - Nachrichten mit weniger als 5 Sekunden Länge sind ganz sicher keine sinnvollen Nachrichten und werden ignoriert.

Aktivieren

Um die Mailbox zu aktivieren, muss sie in den Dialplan eingebaut werden. Zwei unterschiedliche Einträge in der extensions.conf machen sie erreichbar.
exten => _X.,1,VoiceMail(su50000@mbox)
Das generelle Format einer Extension sollte bekannt sein, wichtig ist das Command VoiceMail, das den Anrufer auf die Mailbox 50000 im Voicemailkontext mbox weiterleitet. Die beiden Flags su vor der Nummer schalten die (nervige) Anleitung für den Anrufer (s) ab und spielen die unavailable-Nachricht ab.

Um selber Einstellungen vornehmen zu können und neue Nachrichten abzuhören, erstellt man eine Extension auf das Kommando VoiceMailMain.
exten => 50000,1,VoiceMailMain(50000@mbox)
exten => 50000,2,Hangup

Samstag, 18. November 2006

TECH_ Firefox verwendet Media Player 6.4 Plugin statt aktueller Version

Seit ich auf Firefox 2.0 upgegradet habe, konnte ich auf diversen Fun-Seiten keine eingebetteten MediaPlayer-Videos mehr angucken - der Ton lief aber.

Mit bissel Sucherei habe ich herausgefunden, dass dies ein alter Bug ist, der sich durch einen kleinen Registryeingriff beheben lässt:
Es muss einfach der in der Registry der neue (leere) Schlüssel
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MediaPlayer\ShimInclusionList\FIREFOX.EXE
angelegt werden.

Montag, 2. Oktober 2006

TECH_ Start von xterm bei X11 verhinden

Unter Mac OS X startet automatisch ein xterm-Fenster beim Start von X11. Dies stört mich jedoch sehr, weil ich das Terminal nie brauche, und es beim Beenden von X11 immer eine Fehlermeldung wegen noch laufenden Applikationen aufpoppen lässt.

Doch wie bekommt man es weg? Existiert ~/.xinitrc nicht, kopiert man sich die default-Datei von /etc/X11/xinit/xinitrc. Nun kommentiert man in der ~/.xinitrc die Zeile
#start some nice programs

xterm &
aus.

Sonntag, 1. Oktober 2006

TECH_ Ein Launch-Application für Darwinports GIMP

Darwin Ports installiert Gimp 2 unter /opt/local/bin/. Leider lässt es sich nicht direkt aus der grafischen Oberfläche starten.

Eine Möglichkeit besteht darin, unter Utilities X11 zu starten und im Applications-Menü Gimp als Applikation mit den Kommando /opt/local/bin/gimp einzutragen.

Wer es lieber bequem hat, und Gimp auch direkt aus dem Dock starten möchte, hat noch eine andere Wahl. Mit dem ScriptEditor erstellt man ein Script mit dem Inhalt
do shell script "open-x11 /opt/local/bin/gimp &"
Dieses speichert man als Application Bundle mit der Option "Run only" ab. Um noch ein nettes Icon zu verwenden, zeigt man die Dateiinformationen mit Apfel+i an, klickt ein Mal auf das Icon und pastet mit Apfel+V ein zuvor mit Apfel+C kopiertes Icon. So einfach geht das :)

Mittwoch, 13. September 2006

TECH_ iBook G4 schläft nicht mehr ein

Nachdem ich (jaja, ganz toll, ich weiss) im laufenden Betrieb die Tastatur meines iBooks abgehoben habe, um die MAC-Adresse des Airport Extreme herauszubekommen (und nein, mein Mac OS hat keinen System Profiler *hust*), stürzte es ab, d.h. es fror einfach komplett ein. Ein Neustart per Tastatur führte zwar zum Reboot, aber nicht zum Starten von OS X. Also Aus- und wieder Einschalten.

Nun aber ging der Sleep-Modus nicht mehr - in dem Sinne, dass das iBook einschlief, die LED ein Mal aufleuchtete, das iBook aufwachte und der Bildschirm anging - und es wieder einschlief und alles von vorne losging.

Nunja, meine Befürchtungen, die Tastatur hätte einen Kabelbruch erlitten und würde irgendwelche "Aufwach"-Signale schicken, bewahrheiteten sich nicht. Letztendlich löste nämlich ein simpler Reset der PMU (Power Management Unit) das Problem.

Der geht, wie Apple beschreibt: Herunterfahren, die Tasten Shift+Control+Command+Power ein Mal kurz zusammen drücken (es kommt KEINE Rückmeldung, das iBook darf auch nicht starten), und nach ca. 5 Sekunden dann regulär die Powertaste zum Einschalten drücken. Unter anderem werden dabei die Uhrzeit und das NVRAM zurückgesetzt, aber auf jeden Fall haben die Schlafprobleme ein Ende. Vielleicht sogar der Akku-Leersaug-Effekt, wo der Ladestand von 5 auf 0% umspringt und mich wiederholt in Panik versetzt... sonst konnte ich noch cool ca. 15 Minuten weiterarbeiten, bis der Stand auf 1% war.

Dienstag, 29. August 2006

HOWTO_ Slipstream und Multiboot-CD Windows 2000

Der Vorteil einer Multiboot-CD liegt nicht darin, dass man mit Hilfe von nur einer CD mehrere Betriebssysteme installieren kann. Nunja, er liegt natürlich schon auch darin, aber sicherlich ist dies nicht gerade ein alltäglicher Vorgang eines normalen Windows-Benutzers. Der Hauptvorteil liegt eben darin, dass man selber alle angefallenen Updates in die Installationsdaten einspielt und nach der Installation ein Betriebssystem installiert hat, das wirklich up-to-date ist und mit dem man mehr oder weniger gefahrlos online gehen kann.

Hier geht es nun darum, wie man ein Windows 2000 mit allen aktuellen Updates versorgt (slipstreamed) und dann auf eine bootbare CD packt.


1. Vorbereitungen

Ich verwende HFSlip, um alle Updates und Zusatzsoftware zu slipstreamen. Das Tool gibt es hier zum Download. Herunterladen, in das Arbeitsverzeichnis entpacken, und ein Mal die Datei HFSLIP_XXXXX.CMD ausführen. Dabei wird die benötigte Verzeichnisstruktur angelegt.
Neben den Windows Original-CDs werden natürlich auch noch alle Updates benötigt. Auf der Seite http://users.telenet.be/tc76/winup/_win2k.html finden sich alle seit dem ServicePack 4 angefallenen Updates. Darüber hinaus bietet es noch mehr, zB den Internet Explorer 6 SP1 und DirectX 9.0c. Im oberen Teil der Seite setzt man bei allen Komponenten, die man installieren möchte, ein Häkchen. Im unteren Teil gibt es dann die lange Liste mit direkten Downloadlinks. Vorsicht: Nur die englischen Versionen sind verlinkt, anderssprachige muss man sich selber zusammensuchen. Die Liste ist bereits nach den Ordnern, die am Anfang von HFSlip angelegt wurden, sortiert.
Da ich noch DirectX 9.0c und den Internet Explorer 6.0 SP1 mitinstalliere, tauchen die benötigten CAB-Dateien für den Ordner HFCABS auf. Für DirectX lädt man das jeweils aktuellste Redistributable herunter und entpackt es mit einem Packer wie WinZip. Beim IE ist die Installationsdatei nur ein paar hundert KByte groß, da die benötigten Daten während der Installation heruntergeladen werden. Um nur an die Dateien zu kommen, ruft man die Datei auf der Kommandozeile mit folgenden Parametern auf:
D:\ie6setup.exe /c:"ie6wzd.exe /d /s:""#E"""
Achtung: Die Anführungszeichen sind so korrekt! Anschließend lässt sich ein Pfad angeben, wohinein die Dateien kopiert werden. Eine Installation findet nicht statt.

In den Ordner HFTOOLS kommt noch Bart's Image Extractor - sonst funktioniert HFSlip nicht. Download und die bbie.exe in HFTOOLS.

Jetzt fehlen nur noch die Windows-Dateien: Den Ordner I386 sowie CDROM_IP.5 (für Professional, bzw. CDROM_IS.5 für 2000 Server oder CDROM_IA.5 für den Advanced Server), CDROM_NT.5 und, wenn vorhanden, cdromsp4.tst (wenn das ServicePack 4 bereits integriert ist).


2. Slipstream!

So, nun sind alle Dateien vorbereitet, nun wird (mit Administratorrechten) HFSlip gestartet und durch die ganzen Hinweisscreens gezappt. Irgendwann muss man dann die Kompressionsmethode für die Treiber wählen (A ist in Ordnung) und danach den Pfad auf der Installations-CD für Multiboot. Der ist prinzipell frei wählbar, ich habe W2K\PRO\EN\ (bzw W2K\SRV\EN\ oder W2K\ASV\EN\) verwendet.
So, nun sollte das Slipstreaming beginnen, es dauerte bei mir ca. 15-20 Minuten. Beim allerersten Mal wird noch nach der Original-CD gefragt, wegen dem Bootimage. Dabei werden alle eingebauten CD-Laufwerke der Reihe nach abgeklappert, bis die CD gefunden wurde. Alles kein Problem.
Die Ausgabe liegt nun im Ordner SOURCESS, diesen verschiebt man aus dem HFSlip-Ordner und benennt ihn so um, dass klar ist, welche Windows-Version da drin "residiert".


3. CD zusammenstellen

Da ich alle drei Varianten von Windows 2000 - Professional, Server und Advanced Server - auf eine CD packe, musste ich natürlich den letzten Absatz von 1. sowie 2. für jede Version ein mal durchmachen.
Ich erstellte mir nun folgende Struktur für meine CD:
+ASRV
-W2K
 -ASV
  -EN
 -PRO
  -EN
 -SRV
  -EN
+WPRO
+WSRV
In die drei EN-Ordner kopierte ich die jeweils passende Original-CD (ohne I386), und anschließend den Inhalt des im 2. Schritt entstandenen SOURCESS-Ordner. Bei Professional sind nun die folgenden Dateien vorhanden:
+BOOTDISC
+DISCOVER
+I386
+SETUPTXT
+SUPPORT
+VALUEADD
AUTORUN.INF
CDROM_IP.5
CDROM_NT.5
cdromsp4.tst
HFSLIP.LOG
READ1ST.TXT
README.DOC
SETUP.EXE
spnotes.htm



4. Bootdisketten

In jedem I386-Ordner liegen unter BOOTDISK vier Diskettenimages. Diese werden mit einem entsprechenden Programm, zB WinImage, in den passenden Ordner im Rootverzeichnis, also WPRO für Professional, WSRV für Server und ASRV für den Advanced Server, extrahiert.

Aus I386 wird nun zusätzlich die BOOTFIX.BIN, SETUPLDR.BIN und TXTSETUP.SIF nach WPRO respektive WSRV oder ASRV kopiert.
Mit einem Hex-Editor sucht und ersetzt man in den drei kopierten SETUPLDR.BIN den String i386 durch WPRO respektive WSRV oder ASRV.
Mit Notepad o.ä. ersetzt man in den kopierten TXTSETUP.SIF
SetupSourcePath=\
durch
SetupSourcePath=\W2K\PRO\EN\
respektive \W2K\SRV\EN\ oder \W2K\ASV\EN\.


5. Bootmanager

In das Rootverzeichnis der zusammengestellten CD kommen jetzt noch die Dateien
CDROM_IA.5
CDROM_IP.5
CDROM_IS.5
cdromsp4.tst
READ1ST.TXT
README.DOC
spnotes.htm
Aus der ZIP-Datei des Bootmanagers diskemu kommen noch die Dateien
DISKEMU.CMD, DISKEM1X.BIN, BOOTCAT.BIN und LOADER.BIN dazu.
Die beim Slipstreaming extrahierte BOOT.BIN (im HFSlip-Ordner HFTOOLS kopiert man drei Mal in das Rootverzeichnis, und benennt die Kopien ASRVSECT.DAT, WPROSECT.DAT und WSRVSECT.DAT. Mit einem Hexeditor sucht man am Ende den String SETUPLDR.BINBOOTFIX.BINI386 und ändert I386 um auf den Pfad, in dem die entsprechenden Bootdisketten liegen, also ASRV, WPRO bzw WSRV.

Die Datei DISKEMU.CMD konfiguriert das Bootmenü, meines sieht folgendermaßen aus:
:start
cls
print
print ================================================================================
print                                  MultiBoot Menu
print                         All Windows 2000 Installation CD
print ================================================================================
print Make your Choice:
print
print 1. Microsoft Windows 2000 Professional with ServicePack 4*
print 2. Microsoft Windows 2000 Server with ServicePack 4*
print 3. Microsoft Windows 2000 Advanced Server with ServicePack 4*
print
print Esc) Boot from hard disk
print
print ================================================================================
print * All versions come with post-SP4 hotfixes up to 08/25/2006. The following
print   Software is also included:
print   - Microsoft DirectX 9.0c (August 2006)
print   - Microsoft Internet Explorer 6 SP1
print   - Microsoft Windows Media 9/10 Codecs
print   - Microsoft Windows Update v4 and Windows Update Agent 2.0
print
print
print Timeout is 9 seconds, Default is Esc.
print
print Enter your choice:

:mainkey
; timeout is 9 seconds, default key is escape
getkey 9 esc
onkey 1 goto pro
onkey 2 goto srv
onkey 3 goto advsrv
onkey 4 goto xppro
onkey f1 goto help
onkey esc boot 80
; When no key found...
goto mainkey
;

:pro
run WPROSECT.DAT
; when run has failed
print
print Failed to run "WPROSECT.DAT", hit any key.
getkey
goto start
;

:srv
run WSRVSECT.DAT
; when run has failed
print
print Failed to run "WSRVSECT.DAT", hit any key.
getkey
goto start
;

:advsrv
run ASRVSECT.DAT
; when run has failed
print
print Failed to run "ASRVSECT.DAT", hit any key.
getkey
goto start
;
Das Rootmenü sollte nun so aussehen:
+ASRV			# Bootdiskette Advanced Server
-W2K
 -ASV
  +EN			# Installationsdateien Advanced Server
 -PRO
  +EN			# Installationsdateien Professional
 -SRV
  +EN			# Installationsdateien Server
+WPRO			# Bootdiskette Professional
+WSRV			# Bootdiskette Server
ASRVSECT.DAT
BOOTCAT.BIN
CDROM_IA.5
CDROM_IP.5
CDROM_IS.5
CDROM_NT.5
cdromsp4.tst
diskem1x.bin
diskemu.cmd
loader.bin
READ1ST.TXT
README.DOC
spnotes.htm
WPROSECT.DAT
WSRVSECT.DAT



6. CD erstellen

Mit Hilfe von CDimage erstellt man sich nun die ein Image. Das Kommando sieht so aus
cdimage.exe -l"W2KSP5" -t12/06/1999,23:00:00 -g -h -n -b"D:\CDROOT\loader.bin" -o -oi -m "D:\CDROOT" "D:\w2ksp5_multiboot.iso"
Ich empfehle CDImageGUI, dort sind alle Kommandozeilenparameter auch erklärt.

Am Ende entsteht nun ein Image, in dem alle mehrfach vorhandenen Dateien nur ein Mal drin stecken (wie Hardlinks unter Linux-Dateisystemen). Mein Image ist ca. 606 MByte groß.


7. Credits

All das habe ich natürlich nicht selber herausgefundenen, sondern mir aus diesen Howtos zusammengesucht:
Tech-Hints.com Windows 2000 Multiboot
Slipstreaming Windows 2000 with latest Patches
Basis HFSlip Howto
Current Windows 2000 updates

Samstag, 26. August 2006

HOWTO_ Asterisk 1.2 als SIP-Proxy für Sipgate, QSC IPfonie und dus.net

Neulich erinnerte ich mich daran, dass ich Monat für Monat ungenutzte Freiminuten bei QSC IPfonie privat, dem kostenlosen VoIP-Anschluss, welcher bei meinem Q-DSL Internetanschluss inklusive ist, verfallen lasse.

Bei VoIP bin ich recht früh eingestiegen, d.h. zu dem Zeitpunkt, als in Deutschland die erste Hardware dafür nicht mehr preislich weit im dreistelligen Bereich lag. Daher nenne ich ein Grandstream Budge-Tone 101 mein Eigen.
Dieses unterstützt aber nur einen Account, und komplett von Sipgate zu QSC möchte ich auch nicht wechseln, dagegen sprechen einfach zu viele Gründe: Rufnummer, Anrufhistorie, Adressbuch, und und und.

Dann erinnerte ich mich an die Software-Telefonanlage Asterisk und einen Einführungsartikel in der c't. Und so fing ich langsam an, mich zu erkundigen, was Asterisk im SIP-Bereich leistet und ob es für meine Zwecke dienlich sein kann.

Offensichtlich ist dies der Fall, was sollte sonst dieser Artikel. Also, folgende Eckdaten beschreiben meine Installation:
  • Läuft auf einem Debian GNU/Linux Server
  • Verwendet ausschließlich SIP
  • Ist bei den drei Providern Sipgate, QSC sowie dus.net registriert
  • Annahme von Anrufen von allen Providern
  • ausgehende Anrufe über alle Provider
  • einfaches LCR (Least Cost Routing), welches ausgehende Anrufe
    • ins Festnetz in der Nebenzeit über QSC,
    • ins Festnetz in der Hauptzeit über dus.net und
    • alle anderen Anrufe über sipgate leitet.
  • Direkte Wahl eines Anbieters über eine führende Ziffer
    • 3 für dus.net
    • 4 für QSC IPfonie
    • 7 für Sipgate
Alles lässt sich über 2 Konfigurationsdateien regeln, welche ich im Folgenden kurz erkläre.

sip.conf:
;
; SIP Configuration for Asterisk
;
; Syntax for specifying a SIP device in extensions.conf is
; SIP/devicename where devicename is defined in a section below.
;
; You may also use
; SIP/username@domain to call any SIP user on the Internet
; (Don't forget to enable DNS SRV records if you want to use this)
;
; If you define a SIP proxy as a peer below, you may call
; SIP/proxyhostname/user or SIP/user@proxyhostname
; where the proxyhostname is defined in a section below
;
; Useful CLI commands to check peers/users:
;   sip show peers              Show all SIP peers (including friends)
;   sip show users              Show all SIP users (including friends)
;   sip show registry           Show status of hosts we register with
;
;   sip debug                   Show all SIP messages
;
;   reload chan_sip.so          Reload configuration file
;                               Active SIP peers will not be reconfigured
;

[general]
context=from-sip                ; Default context for incoming calls

;recordhistory=yes              ; Record SIP history by default (see sip history / sip no history)
;realm=qsc.de                   ; Realm for digest authentication
                                ; defaults to "asterisk"
                                ; Realms MUST be globally unique according to RFC 3261
                                ; Set this to your host name or domain name
port=5060                       ; UDP Port to bind to (SIP standard port is 5060)
bindaddr=0.0.0.0                ; IP address to bind to (0.0.0.0 binds to all)
srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
                                ; Note: Asterisk only uses the first host
                                ; in SRV records
                                ; Disabling DNS SRV lookups disables the
                                ; ability to place SIP calls based on domain
                                ; names to some other SIP users on the Internet
;pedantic=yes                   ; Enable slow, pedantic checking for Pingtel
                                ; and multiline formatted headers for strict
                                ; SIP compatibility (defaults to "no")
;tos=184                        ; Set IP QoS to either a keyword or numeric val
;tos=lowdelay                   ; lowdelay,throughput,reliability,mincost,none
;maxexpirey=3600                ; Max length of incoming registration we allow
;defaultexpirey=120             ; Default length of incoming/outoing registration
;notifymimetype=text/plain      ; Allow overriding of mime type in MWI NOTIFY
;videosupport=yes               ; Turn on support for SIP video

disallow=all                    ; First disallow all codecs
; use "show translation" for installed codecs
;allow=gsm
;allow=g726
;allow=adpcm
;allow=slin
;allow=lpc10
allow=alaw
allow=ulaw                      ; Allow codecs in order of preference
;allow=ilbc                     ; Note: codec order is respected only in [general]
;musicclass=default             ; Sets the default music on hold class for all SIP calls
                                ; This may also be set for individual users/peers
;language=en                    ; Default language setting for all users/peers
                                ; This may also be set for individual users/peers
;relaxdtmf=yes                  ; Relax dtmf handling
;rtptimeout=60                  ; Terminate call if 60 seconds of no RTP activity
                                ; when we're not on hold
;rtpholdtimeout=300             ; Terminate call if 300 seconds of no RTP activity
                                ; when we're on hold (must be > rtptimeout)
;trustrpid = no                 ; If Remote-Party-ID should be trusted
;progressinband=no              ; If we should generate in-band ringing always
useragent=Asterisk 1.2          ; Allows you to change the user agent string
nat=yes                         ; NAT settings
                                ; yes = Always ignore info and assume NAT
                                ; no = Use NAT mode only according to RFC3581
                                ; never = Never attempt NAT mode or RFC3581 support
                                ; route = Assume NAT, don't send rport (work around more UNIDEN bugs)
;promiscredir = no      ; If yes, allows 302 or REDIR to non-local SIP address
;                       ; Note that promiscredir when redirects are made to the
;                       ; local system will cause loops since SIP is incapable
;                       ; of performing a "hairpin" call.
;
; Examples:
;externip = 83.236.156.2        ; Address that we're going to put in outbound SIP messages
                                ; if we're behind a NAT

                                ; The externip and localnet is used
                                ; when registering and communicating with other proxies
                                ; that we're registered with
                                ; You may add multiple local networks.  A reasonable set of defaults
                                ; are:
;localnet=10.0.0.10
;localnet=192.168.0.0/255.255.0.0; All RFC 1918 addresses are local networks
;localnet=10.0.0.0/255.255.255.0        ; Also RFC1918
;localnet=172.16.0.0/12         ; Another RFC1918 with CIDR notation


register => 030123456789:MYPASSWD@sip.qsc.de/030123456789       ; Register 030123456789 @ QSC
register => SIP-ID:SIP-PWD@sipgate.de/SIP-ID                 ; Register SIP-ID @ sipgate
register => Auth-ID:Kennwort@voip.dus.net/Auth-ID     ; Register AuthID @ dus.net


; ##### SIP PROVIDERS #####
[qsc]
type=peer
context=qsc-incoming
insecure=very
username=030123456789
secret=MYPASSWD
fromuser=030123456789
host=sip.qsc.de
dtmfmode=rfc2833
canredirect=no


[sipgate]
type=peer
context=sip-incoming
insecure=very
username=SIP-ID
secret=SIP-PWD
fromuser=SIP-ID
fromdomain=sipgate.de
host=sipgate.de
qualify=no
dtmfmode=info
canredirect=no


[dus]
type=peer
context=dus-incoming
insecure=very
username=Auth-ID
secret=Kennwort
fromuser=Auth-ID
host=proxy.dus.net
dtmfmode=rfc2833
canredirect=no
language=de


; ##### SIP CLIENTS #####
[client01]
; ~~~ Grandstream Budge-Tone 101 ~~~
type=friend
context=intern-client01
username=client01
secret=password01
host=dynamic
dtmfmode=info


[client02]
type=friend
context=intern-client02
username=client02
secret=password02
host=dynamic
dtmfmode=info
Ja, was bedeutet das jetzt alles? [name] bezeichnet einen sogenannten Kontext, für den die folgenden Zuweisungen der Art Variable=Wert gelten.

Die Kontexte [qsc], [sipgate] und [dus] sind meine drei VoIP-Anbieter. Die Daten sind eigentlich selbsterklärend. Zusätzlich benötigt jeder Anbieter noch eine Registrierung, bei der sich Asterisk als SIP-Client anmeldet. Dies wird durch die Befehle register => AUTH[:PWD]@HOST[:PORT]/AUTH vorgenommen. Für QSC müssen 030123456789 durch die eigene QSC-Rufnummer und MYPASSWD durch das vergebene Passwort, für sipgate SIP-ID durch die Sipgate-ID und SIP-PWD durch das SIP-Passwort, für dus.net Auth-ID und Kennwort durch die entsprechenden Daten ersetzt werden.

[client01] und [client02] konfigurieren zwei locale SIP-Clients, in meinem Falle das Grandstream Budge-Tone 101 sowie ein weiterer, welchen ich mit X-Lite zum Testen verwende.

Wichtig sind hier (eigentlich) nur noch die vergebenen Kontexte context=. Diese werde in der Datei extensions.conf ausgeführt, und bei einem von einem hier festgelegten Kontexte ausgeführten Anruf angesprungen. Kommt also ein Anruf auf die Sipgate-Rufnummer, so wird der Kontext sip-incoming angesprungen.


extensions.conf:
;
; The "General" category is for certain variables.  All other categories
; are interpreted as extension contexts
;
[general]

static=yes
writeprotect=no
autofallthrough=yes
;clearglobalvars=no
;priorityjumping=no

;
[globals]

USERNAME=cypressor                  ; display name for  caller ID in outgoing calls

QSCUSERID=030123456789                          ; caller ID number for QSC calls
QSCPREFIX=4                                     ; 4-GHI (Ipfonie)
DUSUSERID=Auth-ID                               ; caller ID number for dus.net calls
DUSPREFIX=3                                     ; 3-DEF (Dus.net)
SIPUSERID=SIP-ID                                ; caller ID number for sipgate calls
SIPPREFIX=7                                     ; 7-PQRS (Sipgate)

DEFAULTCONTEXT=sipgate-out                      ; default outgoing context for all calls
                                                ; that could not be routed

PHONE1=SIP/client01                             ; identification of phone no. 1
PHONE1NAME=(local) Grandstream BT101            ; display name, will be set if phone does not provide a name itself
PHONE1NUMBER=101                                ; extension number of phone no. 1

PHONE2=SIP/client02
PHONE2NAME=(local) Phone 2
PHONE2NUMBER=102



; #############################################
; #####  CALLS MADE FROM INTERNAL PHONES  #####
[intern-client01]
exten => _X.,1,NoOp(${CALLERID})
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE1NUMBER}>)
exten => _X.,4,Goto(6)
exten => _X.,5,SetCallerID("${PHONE1NAME}" <${PHONE1NUMBER}>)
exten => _X.,6,Goto(intern,${EXTEN},1)
include => intern

[intern-client02]
exten => _X.,1,NoOp(${CALLERID})
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE2NUMBER}>)
exten => _X.,4,Goto(6)
exten => _X.,5,SetCallerID("${PHONE2NAME}" <${PHONE2NUMBER}>)
exten => _X.,6,Goto(intern,${EXTEN},1)
include => intern

[intern]
; check with exceptions
include => out-exceptions
; try to route calls with available providers
include => out-route
; unrouteable extension, try default
include => default-out
; no outgoing extension available, try local
include => local
; nothing found yet? playback error
exten => i,1,Playback(invalid)
exten => i,2,Hangup



; #############################################
; ##### CALLS GOING OUT TO SIP-PROVIDERS  #####
[out-exceptions]
; exceptional extensions for outgoing calls
; especially numbers not beginning with 0 to prevent them
; from being routed to another (not-default) provider
include => out-mailbox
exten => 110,1,GoSub(sipgate-out,${EXTEN},1)

[out-mailbox]
; external mailboxes
; sipgate
exten => 50000,1,GoSub(sipgate-out,${EXTEN},1)

[out-route]
; route outgoing (external) calls to provider
; use the first number 2-9 to choose provider
; try numbers beginning with 1 in local context
exten => _1.,1,GoSub(local,${EXTEN},1)
exten => _${DUSPREFIX}.,1,GoSub(dus-out,${EXTEN:1},1)
exten => _${QSCPREFIX}.,1,GoSub(qsc-out,${EXTEN:1},1)
exten => _${SIPPREFIX}.,1,GoSub(sipgate-out,${EXTEN:1},1)
; weekend, always Off-Peak
exten => _0[2-9]X.,1,GoSubIf($["${IFTIME(*|sat-sun|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
 ; mo-fr, Off-Peak is 18-9h
exten => _0[2-9]X.,2,GoSubIf($["${IFTIME(18:00-8:50|mon-fri|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
; On-Peak, use dus.net
exten => _0[2-9]X.,3,GoSub(dus-out,${EXTEN},1)
; 01802/01804 not supported by sipgate
exten => _0180[2,4].,1,GoSub(dus-out,${EXTEN},1)

[default-out]
; include default for outgoing calls
include => ${DEFAULTCONTEXT}

[qsc-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${QSCUSERID}>|a)
exten => _X.,2,Dial(SIP/${EXTEN}@qsc,90,tr)
exten => _X.,3,Hangup
; Return
exten => i,1,Return

[dus-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${DUSUSERID}>)
exten => _X.,2,Dial(SIP/${EXTEN}@dus,60)
exten => _X.,3,Hangup
; Return
exten => i,1,Return

[sipgate-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${SIPUSERID}>)
exten => _X.,2,Dial(SIP/${EXTEN}@sipgate,30,trg)
exten => _X.,3,Hangup
; Return
exten => i,1,Return


; #############################################
; ##### LOCAL CALLS TO OTHER PHONES #####
[local]
; Phone 1
exten => ${PHONE1NUMBER},1,Dial(${PHONE1},60)
exten => ${PHONE1NUMBER},2,Hangup
; Phone 2
exten => ${PHONE2NUMBER},1,Dial(${PHONE2},60)
exten => ${PHONE2NUMBER},2,Hangup
; Return
exten => i,1,Return

; #############################################
; ##### INCOMING CALLS ON ASTERISK #####
[from-sip]
exten => s,1,NoOp(Incoming asterisk call\, no extension)
exten => s,2,NoOp(Setting pseudo extension 00 to call)
exten => s,3,NoOp(${STRFTIME(,,%H)})
exten => s,4,GoTo(00,1)
include => ring-all


; #############################################
; ##### INCOMING CALLS FROM SIP-PROVIDERS #####
[qsc-incoming]
include => ring-all

[sip-incoming]
include => ring-all

[dus-incoming]
include => ring-all


; #############################################
; ##### CALLS TO ALL PHONES #####
[ring-all]
exten => _X.,1,NoOp(Call on line ${EXTEN} from ${CALLERID}.)
exten => _X.,2,DIAL(${PHONE1}&${PHONE2}, 90)
exten => _X.,3,Hangup
Diese Datei ist etwas komplexer. Eine Extension bezeichnet eigentlich nur eine Nummer, welche angerufen wird. Ausgehend von dem Kontext, von dem aus eine Rufnummer gewählt wird, wird nun nach passenden Extensions gesucht und die entsprechenden Kommandos ausgeführt.
exten => <EXTEN>,<PRIO>,<COMMAND>
<EXTEN> war wie gesagt eine Nummer. <PRIO> ist die Priorität. Dabei wird mit 1 angefangen und mit jedem Kommando um eins hochgezählt. <COMMAND> ist ein Kommando, welches mit diversen Parametern versehen irgendeine Aktion ausführt. Zu kompliziert? Ein Beispiel:
[intern-client01]
exten => 100,1,NoOp
exten => 100,2,Answer
exten => 100,3,Wait(5)
exten => 100,4,Playback(invalid)
exten => 100,5,Hangup
Wählt der erste Client ([client01] in sip.conf) die Rufnummer 100, wird die erste definierte Extension mit der Priorität 1 angesprungen und das Kommando NoOp (No Operation) ausgeführt. Das macht - nichts. Anschließend wird die Priorität um eins erhöht, ist also 2. Dazu passt die zweite Extension. So weit dürfte die Sache mit der Priorität also klar sein. Kann ich also kurz die meist verwendeten Kommandos erklären.
NoOp		macht nichts
Hangup		legt auf, beendet also die Verbindung bzw weist einen Anruf ab
Dial		wählt einen anderen Anschluss an
Goto		springt zu einem Ziel
GoSub		geht in eine Unterroutine
Return		kehrt aus einer Unterroutine zurück
GotoIf		springt zu einem Ziel, wenn die Bedingung erfüllt ist
GoSubIf		geht in die Unterroutine, wenn die Bedingung erfüllt ist
SetCallerID	setzt Displayname und Nummer des Anrufers
In Klammern stehen dabei jeweils die benötigten Parameter - oder eben auch keine.

So, was ist nun ${EXTEN} und ähnliches? Ganz offensichtlich Variablen, die von Asterisk automatisch gesetzt werden. Einen Überblick gibt es unter http://www.voip-info.org/wiki/view/Asterisk+variables. Diese werden beim Auswerten der Extensions automatisch ersetzt durch ihren Wert. ${EXTEN} liefert übrigens die aktuelle Extension, ${EXTEN:1} schneidet das erste Zeichen ab, ${EXTEN:0:3} liefert nur die ersten drei Zeichen.

Ah, und warum ist eigentlich bei mir (fast) keine Extension eine richtige Nummer? Nun ja, irgendwie muss man ja doch mit Wildcards arbeiten. Einfache Ausdrücke leitet man dabei mit _ ein. Neben normalen Zahlen gibt es die folgenden Wildcards
  • X Eine Zahl zwischen 0 und 9
  • N Eine Zahl zwischen 2 und 9
  • Z Eine Zahl zwischen 1 und 9
  • . beliebig viele Zeichen und Zahlen
  • [125-8] Eine Zahl aus 1,2,5,6,7,8
So, jetzt versuche ich mal einen Weg durch den ganzen Dschungel zu erklären. Gehen wir also davon aus, dass mein Telefon als [client01] bei Asterisk angemeldet ist. Es sei Mittwoch, 13 Uhr und ich rufe die Festnetznummer 030-18 44 00 1 an.
In sip.conf ist nun als Kontext intern-client01 definiert. Diesen springen wir nun in der extensions.conf an und suchen nach der ersten zur Rufnummer passenden Extension - die Priorität ist eins.
[intern-client01]
exten => _X.,1,NoOp(${CALLERID})
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE1NUMBER}>)
exten => _X.,4,Goto(6)
exten => _X.,5,SetCallerID("${PHONE1NAME}" <${PHONE1NUMBER}>)
exten => _X.,6,Goto(intern,${EXTEN},1)
include => intern
Ah, _X. passt zu uns, denn die angerufene Nummer ist fängt mit einer Zahl zwischen 0 und 9 an. NoOp macht nichts,
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
setzt die Priorität auf 3, wenn ${CALLERIDNAME}, also der vom Telefon gelieferte Display Name, nicht leer ist, ansonsten auf 5. Gehen wir mal davon aus, dass mein Telefon einen Namen liefert, wir springen also zu
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE1NUMBER}>)
und setzen die Anrufer-ID. Die folgende Zeile springt zum Goto, welches uns wiederum in den Kontext intern katapultiert und die Priorität wieder auf eins zurücksetzt.
[intern]
; check with exceptions
include => out-exceptions
; try to route calls with available providers
include => out-route
; unrouteable extension, try default
include => default-out
; no outgoing extension available, try local
include => local
; nothing found yet? playback error
exten => i,1,Playback(invalid)
exten => i,2,Hangup
Oh, aber was macht include? Naja, es inkludiert den benannten Kontext in den aktuellen, tut also so, also ob der Inhalt des inkludierten Kontextes im aktuellen stehen würde.
Ich nehme einfach mal vorne weg, dass die out-exceptions bei unserer Rufnummer nicht zutreffen und wandere in den Routingteil.
[out-route]
; route outgoing (external) calls to provider
; use the first number 2-9 to choose provider
; try numbers beginning with 1 in local context
exten => _1.,1,GoSub(local,${EXTEN},1)
exten => _${DUSPREFIX}.,1,GoSub(dus-out,${EXTEN:1},1)
exten => _${QSCPREFIX}.,1,GoSub(qsc-out,${EXTEN:1},1)
exten => _${SIPPREFIX}.,1,GoSub(sipgate-out,${EXTEN:1},1)
; weekend, always Off-Peak
exten => _0[2-9]X.,1,GoSubIf($["${IFTIME(*|sat-sun|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
 ; mo-fr, Off-Peak is 18-9h
exten => _0[2-9]X.,2,GoSubIf($["${IFTIME(18:00-8:50|mon-fri|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
; On-Peak, use dus.net
exten => _0[2-9]X.,3,GoSub(dus-out,${EXTEN},1)
; 01802/01804 not supported by sipgate
exten => _0180[2,4].,1,GoSub(dus-out,${EXTEN},1)
Da wird's schon besser. Die drei Prefixe checken auf die Verwendung einer Durchwahlnummer, um direkt über den gewählten Anbieter zu telefonieren. Da unsere Nummer aber mit 0 anfängt, treffen diese schon mal nicht zu, und wir wenden uns
; weekend, always Off-Peak
exten => _0[2-9]X.,1,GoSubIf($["${IFTIME(*|sat-sun|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
zu. Die Extension _0[2-9]X. trifft auf alle Festnetzrufnummern zu. GoSubIf überprüft die Bedingung und springt bei Erfüllung in die Subroutine - den Kontext [qsc-out]. Die Bedingung ist ein Ausdruck, diese werden in der Art
$[expr1 operator expr2]
formuliert; siehe auch http://www.voip-info.org/wiki/view/Asterisk+Expressions. Im Ausdruck wird die Funktion IfTime aufgerufen, welche bei Zutreffen der Zeitangabe *|sat-sun|*|* den String true zurückliefert, andernfalls einen Leerstring. Die Zeitangabe trifft für alle Tage zwischen Samstag und Sonntag, jeweils inklusive, zu; also fürs Wochenende. Heute sei jedoch Mittwoch, damit müssen wir also weitermachen. Mehr zur Zeitangabe gibt es unter http://www.voip-info.org/wiki/view/Asterisk+cmd+GotoIfTime.
So viel sei gesagt, auch die nächste Extension trifft nicht zu, erst wieder
; On-Peak, use dus.net
exten => _0[2-9]X.,3,GoSub(dus-out,${EXTEN},1)
und diese geht sofort in den Kontext
[dus-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${DUSUSERID}>)
exten => _X.,2,Dial(SIP/${EXTEN}@dus,60)
exten => _X.,3,Hangup
; Return
exten => i,1,Return
Ich setze die von dus.net erwartete Caller-ID
SetCallerID("${USERNAME}" <${DUSUSERID}>)
und rufe über den Kontext dus in sip.conf die Nummer ${EXTEN}, welche ja die zu Beginn gewählte 030 - 18 44 00 1 ist:
Dial(SIP/${EXTEN}@dus,60)
Dial lässt es hier 60 Sekunden lang klingeln, dann wird automatisch aufgelegt.

Konnte keine passende Extension im aktuellen Kontext gefunden werden, so wird automatisch die Extension auf i für Invalid gesetzt, und mittels Return landen wir wieder im aufrufenden Kontext, in diesem Falle wäre das out-route. Da jedoch kein Fehler auftrat, hatten wir hier unser Telefonat und sind fertig.

Damit sollte jetzt sowohl die Konfiguration im Groben als auch die Vorgehensweise bei einem Anruf verstanden sein. Hoffe ich :)

Freitag, 25. August 2006

TECH_ Namen im Display vom Grandstream BT-101

Das Grandstream Budge-Tone 100 (auch BT101, BT102) kann bis zu 12 Zeichen und Ziffern auf seinem Display darstellen. Im Zusammenspiel mit Asterisk lassen sich damit sogar Wörter als Anrufernummer im Display anzeigen.

Die folgenden Zeichen werden vom Budge-Tone unterstützt und mehr oder minder leserlich dargestellt.
AbCcdEFGgHhIiJLNnOoPqrStUuy0123456789_*#
Wie man sieht, fehlen nur K,M,V,W,X und Z. Manche Sonderzeichen werden der Darstellung unterschlagen, andere "evaluieren" zu einem Leerzeichen. Bei bestimmten Sonderzeichen wird nur ein Fehlercode auf dem Display dargestellt.

So, wo in Asterisk verwendet man nun diese Ziffern? Na klar, bei einem Anruf auf einem Budge-Tone setzt man als Caller-Nummer diese Buchstaben ein.
exten => _X.,1,SetCallerID("Haha Hacked!" <HAHA!HACCED>)

HOWTO_ Asterisk 1.2 unter Debian "Sarge" 3.1 installieren

Diese Anleitung beschäftigt sich mit der Installation des aktuellen PBX Asterisk 1.2.11 auf Debian GNU/Linux "Sarge" 3.1 (stable).
Um nicht auf meinem Produktivserver herumspielen zu müssen, installierte ich kurzerhand das aktuelle Debian 3.1r3 in einer virtuellen Maschine in VirtualPC 2004 SP1. Da im stable-Zweig des Debian-Package-Repositories leider nur eine veraltete Version von Asterisk vorhanden ist, welche nicht mit QSC IPfonie privat zusammenarbeitet, kompilierte ich das ganze kurzerhand selbst. Dies war in wenigen Minuten abgehandelt.
Doch nun kam der Schock, als ich das ganze ebenso auf meinem Produktivsystem machen wollte - denn die zur Kompilierung benötigen Packages ließen sich nicht installieren. Ich hatte nämlich bereits Software aus dem testing-Zweig installiert und mir damit Packages eingehandelt, welche sich nicht mehr mit den äußerst empfindlichen libc-Packages vereinbaren ließen.
Genauso wenig konnte ich auch den halbwegs aktuellen Asterisk 1.2.10 aus testing verwenden, denn die diversen Inkompatibilitäten hätten gleich noch den MySQL 4.1 Server mit deinstalliert.
Nach vielem Herumprobieren fand ich nun doch einen Weg, wie der Asterisk ohne große Klimmzüge auf meinen Server findet.

Teil 1: Pinnen

In /etc/apt/sources.list muss mindestens ein testing Zweig hinzugefügt werden. Am einfachsten kopiert man sich dazu einen der vorhandenen stable-Server und schreibt diesen auf testing um:
# Stable server
deb http://ftp.uni-koeln.de/debian/ stable main

# testing server
deb http://ftp.uni-koeln.de/debian/ testing main

# unstable server
deb http://ftp.uni-koeln.de/debian/ unstable main

Nun müssen, damit das System nicht vollkommen durcheinander gerät, noch die Prioritäten der einzelnen Zweige eingestellt werden. Sofern nicht vorhanden, legt man mit touch /etc/apt/prefences die entsprechende Datei an und schreibt folgende Zeilen hinein.
Package: *
Pin: release a=stable
Pin-Priority: 700

Package: *
Pin: release a=testing
Pin-Priority: 650

Package: *
Pin: release a=unstable
Pin-Priority: 600
Man beachte die absteigenden Prioritäten.

Teil 2: Software installieren

Um Asterisk kompilieren zu können, muss erst einmal eine Menge Software installiert werden. Auf einem "frischen" System wird das mit dem folgenden Kommando erledigt.
# apt-get -t testing install termcap-compat libnewt-dev \
libncurses5-dev openssl libssl-dev zlib1g-dev gcc make

Jetzt noch Asterisk herunterladen und dann kann es losgehen.
# cd ~
# wget http://ftp.digium.com/pub/asterisk/asterisk-1.2-current.tar.gz
# tar -xzf asterisk-1.2-current.tar.gz


Teil 3: Asterisk compilieren

# cd ~/asterisk-1.2.11
# make clean; make install; make samples
Mehr gibt es nicht dazu :).

Teil 4: Startupscript anlegen

In /etc/init.d erzeugt man noch mit touch /etc/init.d/asterisk ein Startupscript, in welches der folgende Inhalt eingetragen wird.
#!/bin/sh -e
#
# asterisk              This init.d script is used to start asterisk.
#                       It basically just calls asterisk.

ENV="env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin"


set -e
if [ -x /usr/sbin/asterisk ] ; then
        HAVE_ASTERISK=1
else
        exit 0
fi

ASTERISK="$ENV /usr/sbin/asterisk"
PIDFILE="/var/run/asterisk.pid"

asterisk_start() {
        if [ -e "$PIDFILE" ]
        then
                echo " ... Already running"
                exit 1
        fi

        $ASTERISK
}

asterisk_stop() {
        if [ -e "$PIDFILE" ]
        then
                PID=`cat $PIDFILE 2>/dev/nul`

                $ASTERISK -rx "stop now"

                CNT=0
                while [ 1 ]
                do
                        CNT=$(expr $CNT + 1)

                        [ ! -d /proc/$PID ] && break

                        if [ $CNT -gt 60 ]
                        then
                                echo " ... failed!"
                                echo "Asterisk failed to honor the stop command, please investigate the situation by hand."
                                exit 1
                        fi

                        sleep 1
                done
        else
                echo -n " ... no pidfile found! not running?"
        fi
}

case $1 in
        start)
                echo -n "Starting PBX: Asterisk"
                asterisk_start
                echo "."
        ;;
        stop)
                echo -n "Stopping PBX: Asterisk"
                asterisk_stop
                echo "."
        ;;
        reload)
                echo -n "Reloading PBX config..."
                $ASTERISK -rx "restart gracefully"
                echo "done."
        ;;
        restart | force-reload)
                echo -n "Forcing reload of PBX: Asterisk"
                asterisk_stop
                asterisk_start
                echo "."
        ;;
        *)
                echo "Usage: /etc/init.d/asterisk start|stop|restart|reload|force-reload"
        ;;
esac
Jetzt muss nur noch dieses Script beim Hoch- und Herunterfahren des System ausgeführt werden:
# update-rc.d asterisk defaults 99 00


Teil 5: Starten und verbinden

Mit /etc/init.d/asterisk start wird der Service gestartet, verbinden kann man über asterisk -r.
Die Konfigurationsdateien liegen unter /etc/asterisk.

Reflog

Informationstechnische Howtos, Hinweise und Merkwürdiges

Batchlib v1.0 2008-03-29

Aktuelle Beiträge

HOWTO_ O2 DSL Surf &...
Der O2 DSL Surf & Phone-Router ist für die alleinige...
cypressor - 12. Feb, 19:57
Uptweak Windows XP Home...
There are a lot of annoying limitations in Windows...
cypressor - 9. Okt, 19:30
BATCHLIB_ Batchlib package...
Download Batchlib package v1.0 (5 KB zip file) What...
cypressor - 29. Mär, 19:10
BATCHLIB_ Batchlib library...
The batchlib library string.cmd is part of the batchlib...
cypressor - 29. Mär, 18:10

Homepage Ticker

Links

Status

Online seit 6600 Tagen
Zuletzt aktualisiert: 28. Jun, 11:32
RSS XML 1.0 Button-Get-Firefox

batch
batchlib
howto
tech
video
Profil
Abmelden
Weblog abonnieren