MWI mit mISDN und Asterisk

Message Waiting Indication (MWI) scheint von Asterisk aktuell nur für SIP- und Zapata-Channels unterstützt zu werden, wer mISDN (chan_misdn) nutzt, hat ein Problem: Es geht einfach nicht. :(

Da ich aber auch gerne darüber informiert würde, dass eine neue Nachricht auf meiner Voicemail-Box auf mich wartet, ohne dass ich in meine Mails gucken muss, habe ich mir eine andere Lösung einfallen lassen.

Asterisk kann SMS an entsprechende Telefone verschicken! Basierend auf diesen Skripten habe ich also ein neues AGI-Skript geschrieben, das man nach einem Anruf, der auf der Voicemail-Box gelandet ist, aufruft. Dieses Skript zählt die vorhandenen Nachrichten (ich habe keinen internen Zähler gefunden, den ich abfragen könnte... wenn es einen gibt: Bitte einfach in 'nem Kommentar darauf hinweisen, dann kann ich das Skript anpassen.) und schreibt dann eine entsprechende SMS an unser Telefon.

Dafür brauchen wir also zuerst einen neuen Context in der /etc/asterisk/extensions.conf:

[smsdial]
exten => _X.,1,SMS(${CALLERID(NUM)},s,${EXTEN},${CALLERID(NAME)})
exten => _X.,2,SMS(${CALLERID(NUM)},s)
exten => _X.,3,Hangup

Dieser kümmert sich darum, die SMS an unser Telefon zu schicken.

Als nächstes kommt dann auch schon das AGI-Skript, das ich als checkVM.agi unter /var/lib/asterisk/agi-bin gespeichert habe:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/perl -w

use strict;
use File::Copy;

my $location      = "/var/spool/asterisk/outgoing/";
my $templocation  = "/tmp/";
my $basePath      = '/var/spool/asterisk/voicemail';
my $MessageCentre = "01930100";
my $chanPrefix    = "mISDN/g:intern/";

my $error = 0;

my ($vmContext, $vmNum, $targetPhone) = ($ARGV[0], $ARGV[1], $ARGV[2]);

if (not $vmContext or not $vmNum or not $targetPhone){
    ($vmContext, $vmNum, $targetPhone) = split(/ /, $ARGV[0]);
    if (not $vmContext or not $vmNum or not $targetPhone){
        print "All 3 parameters are needed!\n";
        exit(1);
    }
}

srand;

my $vmPath = "$basePath/$vmContext/$vmNum/INBOX/";

opendir(DIR, $vmPath);
# count only wav-files:
my @files = grep(/\.wav$/i,readdir(DIR));
closedir(DIR);

my $msgCount = scalar @files;

if ($msgCount > 0){
    my $msg;
    if ($msgCount == 1){
        $msg = "Es ist $msgCount neue Nachricht in Ihrer Mailbox $vmNum!";
    } else {
        $msg = "Es sind $msgCount neue Nachrichten in Ihrer Mailbox $vmNum!";
    }

    my $random = int(rand 10000);
    my $datestamp = date_stamp();
    my $unique = "$datestamp$random$targetPhone";

    open(F, ">$templocation$unique.call") or $error = 1;
    print F "Channel: $chanPrefix$targetPhone\n";
    print F "CallerID: $msg <$MessageCentre>\n";
    print F "MaxRetries: 2\n";
    print F "RetryTime: 60\n";
    print F "WaitTime: 30\n";
    print F "Context: smsdial\n";
    print F "Extension: $vmNum\n";
    print F "Priority: 1\n";
    close(F);

    move("$templocation$unique.call","$location") or $error = 1;
}

exit $error;

sub date_stamp{
    (my $sec,my $min,my $hour,my $mday,my $mon,my $year,my $wday,my $yday,my $isdst) = localtime(time);
    my $t = sprintf "%4d%02d%02d%02d%02d%02d", 1900+$year,$mon+1,$mday,$hour,$min,$sec;
    return $t;
}

Das Skript erwartet 3 Parameter: Den Voicemail-Kontext, die Nummer der Voicemail-Box und die Zielrufnummer des Telefons, an das die SMS gehen soll. Die Fallunterscheidung bei der Parameterauswertung ist nötig, damit man das Skript sowohl von der Konsole als auch aus Asterisk heraus aufrufen kann: Wie es aussieht übergibt Asterisk alle Parameter in Anführungszeichen, so dass nur ein großer Parameter im Skript ankommt - auf der Kommandozeile ist das anders.

Danach werden die .wav-Files im angegebenen Verzeichnis gezählt (falls man die Anrufe nicht im wav-Format aufnimmt, muss diese Stelle angepasst werden) und - falls Nachrichten vorhanden sind - eine SMS generiert und in das Outgoing-Verzeichnis von Asterisk verschoben. Bei der Erzeugung der SMS fällt auf, dass ich hier die Nummer des Telekom SMS-Centers nutze. Dies war nötig, um mein Telefon davon zu überzeugen, die SMS ohne Klingeln anzunehmen und zu empfangen. Wer also ein anderes SMS-Zentrum in seinem Telefon eingerichtet hat, muss eventuell auch diese Nummer anpassen.

Als letztes fehlt jetzt nur noch der Aufruf des Skriptes nach der Mailbox:

exten => _X., n, VoiceMail(123@vmContext)
exten => _X., n+1, AGI,checkVM.agi|vmContext 123 ${EXTEN}

Beim Einfügen in die eigene extensions.conf ist natürlich darauf zu achten, die "Variablen" richtig zu ersetzen: n ist die Priorität, 123 die Nummer der Mailbox, vmContext der Context der Voicemail-Box.

Jetzt nur noch Asterisk neustarten oder den Dialplan neu einlesen und schon: Fertig!