ISDN-Anruf-Monitoring unter Linux

Letztes UPDATE: 14.01.2009 - Version v.0.4.1 (Inverssuche funktioniert wieder, danke an Rene Hartmann für den Hinweis!)

Mit dem im isdn4linux-Paket enthaltenen isdnlog lassen sich abhängig von angerufener MSN Aktionen auf dem Linux-Rechner ausführen. isdnlog stellt dabei alle nötigen Informationen zum eingehenden Anruf bereit, so dass sich ein ausgefeiltes Call-Tracking realisieren lässt.

Hier wird grob der Aufbau eines Systems beschrieben, das
  1. die Inverssuche von dasoertliche.de mit der Nummer des Anrufers füttert
  2. ein- und ausgehende Anrufe in einer SQL-Datenbank speichert
  3. Windows- und Linux-Clients via Nachrichtendienst über den Anruf (und ggf. den Anrufer) informiert
  4. auf einem optionalen HD44780-kompatiblen LCD-Display Anrufernummer sowie Anrufernamen anzeigt

Copyright

Das Copyright an sämtlichem im Rahmen dieses Projektes bereit gestellten Material liegt beim Autor. Die Weitergabe ist unter den Bedingungen der GNU Public License zulässig.

Funktionsweise

Später legen wir fest, dass isdnlog bei eingehenden Anrufen das nachfolgend abgedruckte PHP-Script isdnMonitor.php auszuführen hat. Es sollte im Verzeichnis /etc/isdn/isdnmonitor abgelegt werden. Das Paket beinhaltet eine Beispiel-Konfiguration für isdnlog.

Das Script erhält als Aufruf-Parameter die Nummer des Anrufers und die gerufene MSN. Als dritter Parameter kann optional 'smbnotify' übergeben werden, was die Benachrichtigung von Windows-Clients via Nachrichtendienst (installiertes SAMBA erforderlich) ermöglicht.

In der MySQL-Datenbank wird die Zuordnung zwischen Rufnummern und Namen von Anrufern (Tabelle caller_name) sowie die vollständige Liste aller eingegangenen Anrufe (Tabelle incoming) gespeichert.

Liefert die Inverssuche des "Örtlichen" ein Ergebnis, so dient die lokale Datenbank als Cache, wodurch bei wiederholten Anrufen von dieser Nummer die Inverssuche nicht mehr erneut bemüht werden muss (spart Last und vor allem Zeit).

Der isdnMonitor.php nutzt meine speziell entwickelte PHP-Methode, die mit der Inverssuche des "Örtlichen" kommuniziert.

Ohne dem tar.gz-Paket vorzugreifen, möge man sich einen Einblick in das zentrale PHP-Script verschaffen:

<?

  /*************************************************************************
  *                                                                        *
  * Copyright (C) 2005-2007 Leonhard Fellermayr             *
  * All rights reserved by the author.                                     *
  *                                                                        *
  *************************************************************************/

  include 'config.inc.php';

  include 'funcs/functions.general.inc.php';
  include 'funcs/functions.inverseSearch.inc.php';
  include 'funcs/functions.ortsnetz.inc.php';
  include 'funcs/functions.postRequest.inc.php';

  /* *********************************************************************** */
  /* we get caller number and called MSN from command line */

  $caller = removePrefix ($argv[1]);
  $msn    = shortenMSN ($argv[2]);

  $want_smb_notify = (strtolower ($argv[3]) == 'smbnotify');

  /* *********************************************************************** */
  /* do logging of call */

  $query = "INSERT INTO incoming (date, caller, msn) VALUES ('" .
    time ()              . "','" .
    addslashes ($caller) . "','" .
    addslashes ($msn)    . "')";

  mysql_query ($query);

  /* exit now, if unknown caller (it's further uninteresting) */

  if ($caller == '?')
    exit (0);

  /* *********************************************************************** */
  /* perform inverse search, if number is NOT already in local database */

  if (!exists_in_db ($caller))
  {

    /* do inverse */
    $result = inverse_search ($caller);

    /* if search successful and not yet in database : do DB insert */
    if (!empty ($result))
    {

      $query = "INSERT INTO caller_name (number, name, adresse) VALUES ('" .
        addslashes ($caller)    . "','" .
        addslashes ($result[0]) . "','" .
        addslashes ($result[1]) . "'" . ")";

      mysql_query ($query);

    } // endif

  } // endif

  /* *********************************************************************** */
  /* get caller information, if there is any */

  $res = mysql_query ("SELECT * FROM caller_name WHERE number = '" . addslashes ($caller) . "'");

  if (mysql_num_rows ($res) > 0)
  {

    $data = mysql_fetch_array ($res);

    if ($want_smb_notify)

      for ($i = 4; $i < $argc; $i++)
      {

        /* *********************************************************************** */
        /* notification of Windoze clients */

        $fd = popen ("smbclient -M " . $argv[$i] . " -I " . $_SETTINGS['smb_clients'][$argv[$i]], "w");

        fputs ($fd, "Eingehender Anruf auf " . $msn . " von ...\n\n");
        fputs ($fd, "\t\t" . $caller . "\n\n");
        fputs ($fd, str_replace ($umlauts, $noumlauts, $data["name"]) . "\n");
        fputs ($fd, str_replace ($umlauts, $noumlauts, $data["adresse"]) . "\n");

        pclose ($fd);

      } // endfor

    mysql_free_result ($res);

  } // endif

  /* display call on LCD in basement if desired */

  if ($_SETTINGS['lcd_notify'])

    include 'lcdCall.inc.php';

  /* finally, close DB connection */

  mysql_close ($db);

?>

Inverssuche (Rückwärtssuche) von dasoertliche.de

Die nachfolgend abgedruckte PHP-Methode liefert zur übergebenen Nummer einen Array mit weiteren Informationen zurück, falls der entsprechende Teilnehmer einer Indizierung seiner Daten in der Inverssuche nicht widersprochen hat.

WICHTIG: Die Nutzung alternativer Seiten zur Inverssuche hat sich als nicht empfehlenswert erwiesen. Verhältnismäßig viele Nummern werden dort nicht gefunden, so dass man lieber beim "Örtlichen" bleiben sollte.

DISCLAIMER: Eine missbräuchliche (insbesondere im Sinne von "exzessive" Nutzung der Inverssuche und insbesondere der PHP-Methode ist ausdrücklich untersagt und wird von den Betreibern ggf. strafrechtlich verfolgt.

  /*************************************************************************
  *                                                                        *
  * Copyright (C) 2005-2009 Leonhard Fellermayr             *
  * All rights reserved by the author.                                     *
  *                                                                        *
  *************************************************************************/

  /* this is working as of 2009-01-14, LF */

  function inverse_search ($number)
  {

    return inverse_dasoertliche ($number);

  } // inverse_search ()

  /* ******************************************************************** */

  function inverse_dasoertliche ($number)
  {

    $phoneurl = 'http://www.dasoertliche.de/Controller?form_name=search_inv&la=de&ph=%s';

    $url = sprintf ($phoneurl, rawurlencode ($number));

    $result = implode ("\n", file ($url));

    $regexes = array (
                      '/title="Details zu diesem Eintrag anzeigen" class="entry">([^<]+)<\/a>/',
                      '/<\/div>\s+([^<]+)/'
                     );
    $ret = array ();

    foreach ($regexes as $regex)
      if (preg_match ($regex, $result, $matches))
        $ret[] = html_entity_decode ($matches[1]);

    return ($ret);

  } // inverse_dasoertliche ()

MySQL-Datenbank

Wie beschrieben werden verschiedene MySQL-Tabellen benötigt, die mindestens von der folgenden Form sein sollten:

mysql> explain incoming;
+----------+------------+------+-----+---------+----------------+
| Field    | Type       | Null | Key | Default | Extra          |
+----------+------------+------+-----+---------+----------------+
| id       | int(11)    |      | PRI | NULL    | auto_increment |
| date     | int(11)    | YES  |     | NULL    |                |
| caller   | char(50)   | YES  |     | NULL    |                |
| msn      | char(15)   | YES  |     | NULL    |                |
| duration | int(11)    | YES  |     | NULL    |                |
| connect  | tinyint(1) | YES  |     | 0       |                |
+----------+------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

mysql> explain caller_name;
+---------+-----------+------+-----+---------+-------+
| Field   | Type      | Null | Key | Default | Extra |
+---------+-----------+------+-----+---------+-------+
| number  | char(255) | YES  |     | NULL    |       |
| name    | char(255) | YES  |     | NULL    |       |
| adresse | char(255) |      |     |         |       |
+---------+-----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
Zusätzlich biete ich noch die Tabellen ausland und vorwahlen an, um bestimmte Vorwahlen bzw. Rufnummern ihrem Ursprungsort zuzuordnen. Entsprechende schlüsselfertige SQL-Dumps finden sich im herunterzuladenden Datei-Archiv (siehe unten).

callerid.conf

Um lokale Windows-Rechner über eingehende Anrufe zu informieren, schreibe man Folgendes in die /etc/callerid.conf:
[MSN]
NUMBER = 806465
ALIAS  = MJ
SI     = 1
ZONE   = 1
START  = {
  [FLAG]
  FLAGS = I|R
  PROGRAM = /usr/bin/php /etc/isdn/isdnmonitor/isdnMonitor.php \$2 \$3 smbnotify saturn neptun
  [FLAG]
  FLAGS = I|C
  PROGRAM = /usr/bin/php /etc/isdn/isdnmonitor/addPosterior.php \$2 \$3 connect
  [FLAG]
  FLAGS = I|H
  PROGRAM = /usr/bin/php /etc/isdn/isdnmonitor/addPosterior.php incoming \$2 \$3 duration \$5
}
Beim Ring (Flags: I|R) werden grundlegende Informationen (Anrufer, angerufene MSN) in der Datenbank abgelegt und ggf. SMB-Clients benachrichtigt.
Wird ein CONNECT registriert, so wird die Information ("Verbindung kam tatsächlich zustande"> in der Datenbank gespeichert (Flags: I|C). Bei Beendigung einer Verbindung wird deren Laufzeit ebenfalls nachgespeichert (Flags: I|H). Auf ähnliche Weise könnte man ein Wake-On-LAN bestimmter Rechner realisieren. Sehr praktisch, wenn man gerade auf einem anderen Stockwerk weilt.
Tipp: Abläufe, die für alle MSN's gelten sollen, lassen sich auch in /etc/isdn.conf ablegen.

Starten von isdnlog

isdnlog wird in einer der rc-Scripten gestartet, die beim Booten des Systems abgearbeitet werden (abhängig von der Distribution). Folgender Aufruf bietet sich im Allgemeinen dafür an:
# start ISDNlog
/sbin/isdnlog /dev/isdnctrl -S -D

WWW-Oberfläche

Eine beispielhafte WWW-Oberfläche mit Formularen zum Abruf der eingehenden Anrufe über das Internet liegt dem Paket bei.

Download

Alle benötigten Dateien können als tar-gz-Archiv heruntergeladen werden: Download.

Ich freue mich jederzeit über Ideen und Verbesserungsvorschläge, ob konkret oder weniger konkret. Die vorliegende Version ist sicher nur ein (guter) Anfang.

Links