Lync Server API - MSPL

Die wohl interessanteste aber auch heikelste Schnittstelle an einem Lync-Server ist die direkte Injektion einer Programme in die SIP-Verarbeitung. Im Gegensatz zu UCMA oder der Lync Client API wird hier direkt auf dem Server gearbeitet. Wird die eigene Erweiterung sogar als "critical" eingestuft und läuft nicht, dann ist der komplette SIP-Stack des Frontend-Servers nicht funktionsfähig. Wer schon mit Exchange gearbeitet hat, wird sich hier an die "OnArrival"-Events erinnert fühlen.

Warnung:
Diese Seite dient zur Information über die Schnittstelle und deren Möglichkeiten als solche aber darf nicht als "How-To" verstanden werden. Ein falsches Zeichen kann sehr einfach den kompletten Lync-Server außer Funktion setzen. Wer damit Erfahrungen sammeln will, sollte dazu eine komplett abgeschirmte TestUmgebung nutzen.

Wer aber das Risiko eingeht, wird mit der umfangreichsten Möglichkeit belohnt, die SIP-Meldungen auszuwerten oder sogar zu verändern. Allerdings muss er wissen, wo und über welchen Server die SIP-Meldungen laufen und das Skript bzw. Programm natürlich auf allen Servern ausführen lassen, auf denen solche Meldungen durchlaufen können. Das Skript bekommt die Meldungen noch ehe Sie durch die Lync Routing oder Normalisierung gelaufen sind. Da aber auch diese Lync-Programme selbst als MSPL-Skript geschrieben sind, können Sie über Priorität ein Reihenfolge hier alles durcheinander würfeln.

Die aktuell installierten Module pro Server können Sie recht einfach ermitteln.

Get-CsServerApplication `
   -Filter "service:*poolname* `
| ft Priority,Name,Enabled,Critical,Scriptname

Sie sehen also hier genau, in welcher Reihenfolge die entsprechenden Skripte abgearbeitet werden. Sie sehen aber auch, dass das Feld "Skriptname" leer ist. Sie können das auszuführende MSPL-Skript nämlich hier fix hinterlegen oder über Managed-Code im Betrieb einbinden. Die Priorität ist natürlich auch wichtig um die richtigen Daten zu erhalten. Wer eine normierte E164-Nummer erwartet, darf sich nicht zu früh einhängen. Wer sich aber zu spät einhängt, wird das ein oder andere Paket vielleicht gar nicht mehr sehen.

Einsatzbereiche

Sie wissen nun, dass solch ein Skript die SIP-Meldung lesen, verändern oder sogar mit einer andere Meldung beantworten kann. Damit haben Sie alle drei Optionen zur Wahl:

  • Betrachten
    Sie können die Meldungen einfach nur "ReadOnly" betrachten und ihre Schlüsse draus ziehen, z.B. Statistiken erstellen, Fehlermeldungen protokollieren oder auch die Inhalte abspeichern. Wer mag kann also sich schon seinen "Archivserver für Arm" oder "Monitoring Server für Anfänger" erstellen. Wer z.B. nur alle Verbindungen als "Einzelverbindungsnachweis" als CSV-Datei braucht, könnte mit wenig Aufwand dies realisieren.
  • Verändern
    Interessant ist natürlich auch die Veränderung von eingehenden Paketen. Sie könnten an jede Meldung einen Disclaimer addieren oder zu einem eingehenden Ruf zu Rufnummer aus einer anderen Datenquelle (ERP, CRM) den Namen holen. Theoretisch könnte auch die Zieladresse abhängig vom Anrufer verändert werden. Globale "Blocklisten" für unerwünschte Anrufer wären so denkbar. Ebenso zentrale "Weiterleitungen" oder das Einfügen eine "AppID", damit auf dem Client der Lync Client die passende Erweiterung "nachholt"
  • Verwerfen
    Ein SIP-Paket sollte man nie einfach "löschen". Aber sie können es natürlich mit einer eigenen Antwort quittieren und das ursprüngliche Ziel gar nicht informieren. Das wär z.B. der "Busy-Fall", d.h. ein Skript blockiert einen Zweitanruf.

Beachten Sie dabei aber immer, dass SIP keine SMTP ist. SIP ist "Echtzeit" und wenn eine Aktion ein paar Sekunden dauert, dann wird dieser Timeout schnell zu anderen Problemen führen. Die Zeit bis ein Server auf eine Meldung mit einer Antwort reagiert, sollte keinesfalls 10 Sekunden überschreiten, da dann sendende Systeme vielleicht einen Alternativweg suchen.

Ideen und Beispiele zu MSPL-Lösungen

Vielleicht wird der Einsatzbereich von MSPL etwas deutlicher, wenn ich ein paar Beispiele aufführe, was eine Serverapplikation mit einem SIP-Paket und einer Entscheidungslogik alles machen kann. Die ein oder andere Idee wird vielleicht zukünftig von einer Lösung umgesetzt. Daher ist das eine Tabelle.

Idee Status

Error-Logger
Nicht immer wird ein SIP-Dialog mit einem "200 OK" abgeschlossen. Wenn Sie denn mal einen Fehler bekommen, dann sind die Meldungen des Lync-Clients alles andere als hilfreich. für die meisten Probleme wie falsche oder unvollständige Rufnummer liefert Lync schon den passenden Error-Code und der Client zeigt diesen auch an. Aber es gibt auch Fehlercodes, die der Client auch nur "numerisch" anzeigt, wie z.B. einen 481. Einige Fehler (z.B. 504) werden gar nicht angezeigt.

Dabei steht im entsprechenden SIP-Paket natürlich neben dem Fehler oft auch die detaillierte Meldung. Nur sieht sie keiner und gespeichert wird sie auch nicht. Ein einfaches MSPL-Skript, welches einfach die SIP-Pakete in eine CSV-Datei schreibt und Datum/Zeit, Sender, Empfänger und eben den Fehler protokolliert, könnte schon schnell die Ursache ermitteln lassen. Vor allem, wen es sporadische Fehler sind. Man muss dazu ja nicht gleich den Snopper alle Pakete mit schneiden lassen

 

Poor mans QoE Collector
"Natürlich" sollte man bei der Einführung von Lync für Enterprise Voice auf jeden Fall auch immer einen Monitoring-Server bereit halten. Fakt ist aber, dass gerade in Deutschland der "kleine Mittelstand" gerne diesen SQL-Server und auf das drum herum verzichtet. Also hat man gar keine Information über die Qualität der Audioverbindungen, besonders, wenn Lync oder OCS eigentlich nur für Präsenz und Instant Messaging vorgesehen wurde und die Audio/Video/Konferenz-Funktion erst nach und nach dazu gekommen ist. So sieht der SERVICE-Request aus, der am Ende einer Verbindung vom Client an den Server geht.

Jeder Client sendet am Ende der Verbindung als "SERVICE"-Paket auf die Leitung, welcher dann einen "VQREPORT" enthält. Das ist auch nur eine XML-Datei, die man aber im ersten Schritt erst mal "sichern" könnte und später dann auswertet. Sonst landen die Daten einfach im digitalen Mülleimer.
(Noch zu verifizieren, ob das auch ohne Monitoringrolle der Fall ist)

 

CallDataRecord
Neben den statistischen Daten ist der Monitoring-Server natürlich auch die Quelle für Gebührenerfassung und Einzelverbindungsnachweisen. Ohne Monitoring-Server können Sie natürlich auch dem Gateway zum PSTN vielleicht ein paar Daten entlocken. Audiocodes kann diese z.B. per SYSLOG senden.
Wenn eine Webserver für jeden Abruf einer Seite die einzelnen Abrufe der HTML, GIF, CSS und anderer Dateien protokolliert und ein Exchange Server für jede Mail das Message-Tracking beschreibt, dann kann es ja nicht zu viel verlangt sein, zumindest die INVITE und BYE zu protokollieren.

 

Callback on Fail
Wer jemand schon eine Lösung hat, einen Zweitanruf zu unterdrücken oder der angerufene Teilnehmer nicht annimmt, dann wäre es doch schön, wenn ein MSPL-Script dies erkennen könnte und bei einer erneuten Verfügbarkeit (oder StatusÄnderung oder Ende eines Rufs) des gewünschten Teilnehmers den ersten Anrufer darüber mit einer IM samt TELURI informiert, die er dann nur noch anklicken muss

 

Absender verbergen
Lync kann die ausgehende Rufnummer eigentlich nicht richtig verbergen. Auf der Route kann nur eine globale Ersetzung hinterlegt werden. Niemand wird nun für jeden Anwender eine individuelle Route einrichten. Ein MSPL-Skript könnte hier die Absendernummer einfach ersetzen.
Idealerweise natürlich nur für ausgehende Calls oder nach bestimmten Regeln.

 

Busy on Busy
Mittlerweile gibt es Lösungen von Colima, unify²,die diese oft nachgefragte Funktion integrierte haben, so dass ich da sicher nicht mehr selbst aktiv werde.
http://www.unifysquare.com/busyonbusy.aspx
http://blog.colima.de/2012/04/busyonbusy-bei-lync-was-ist-das/

 

OfflineIM
Stört es Sie nicht auch, dass Sie manchmal eine IM an einen Kollegen senden, dieser aber mittlerweile "offline" ist und die IM dann noch nicht ankommt. Was machen Sie ? Sie senden das ganze noch mal als Mail. (Leider hat der Lync Client hier keinen direkt erreichbaren Button. So eine Skript könnte aber die IM sehen, Buffern und auf den Status warten. Kommt dann eine Fehler, dann könnte es die IM speichern, bis der Zielempfänger mal wieder "online" ist

 

SIP-Address
In Exchange ist es schon "üblich", dass ein Postfach eine primäre aber durchaus viele sekundäre SMTP-Adressen hat. OCS/Lync kennt nur eine SIP-Adresse. Interessant wäre hier ein MSPL-Script, welches eine ungültige primäre Adresse oder Rufnummer gegen die Proxy-Adressen zu prüfen. Gerne auch mit SIP oder TEL-Prefix und dann das Ziel umzuschreiben. Genau genommen könnte man so auch eine "Wildcard"-Behandlung machen, d.h. Ungültige SIP-Adressen landen bei einem zentralen SIP-Account.

 

Testbot
Wie kann man am einfachsten Federation testen ? durch aktive Calls. Dazu muss es eine Gegenstelle geben. Bei AOL gibt es z.B. sipcheck@aol.com um PIC mit AOL zu testen. Ich würde mir schon wünschen, wenn es einfach möglich wäre einen entsprechenden Agenten zu haben. Der Audio Test Service unterstützt leider nur Audio-Anrufe aber keine IMs. Denkbar wäre diese Aufgabenstellung aber auch mit einem UCMA-Agenten.

 

RewriteCaller und AnonymCall
Viele Firmen fragen nach der Funktion die ausgehende Nummer "umzuschreiben". Sicher hat Lync hier mehrere Möglichkeiten (z.B.: als RGS zu rufen, über einen Trunk die CallingID umzusetzen oder auf dem Gateway die Nummern zu verschieben) aber schön ist das alles nicht. Auch wenn es dazu keine "100%" Lösung gibt, könnte ein Programm durchaus effektivere Wege aufzeigen.
Analog könnte man z.B.: auch einen Blocklist von Rufnummern pflegen, die extern nie sichtbar werden sollen, z.B. spezielle Durchwahlen.

 

Corporate Adressbuch Resolution
Wer mit Lync auch telefoniert, wird auch Anrufe von extern nach intern bekommen. Lync löst rufende Nummern natürlich lokal gegen das Adressbuch und die Kontakte auf. Aber wer hat schon alle Kunden oder andere Stammdaten in den eigenen Kontakten ? Ein MSPL-Skript könnte die rufende Nummer in einer Datenbank nachschlagen und dann den Anzeigename entsprechend setzen.

 

Unterschiedliche Ringtöne
Wenn das SIP-Endgerät (z.B. SNOM Telefone) unterschiedliche Klingeltöne beim INVITE unterstützt, kann ein MSPL-Script z.B. abhängig vom Useragent (z.B. Externe Anrufe kommen über Mediation Server oder Gateway) andere Töne starten:

 

Secondary SIPAddress
Ein Lync Benutzer hat immer genau eine SIP-Adresse bzw Telefonnummer und optional eine PrivateLine. Bei Exchange kann ein Postfach neben einer primären Adresse noch weitere Empfangsadressen haben. Ein MSPL Skript müsste jedes SIP-Paket analyiseren und ungültige SIP-Adressen z.B. Umschreiben. Es könnte ja die gleichen Informationen aus ProxyAddresses nutzen, wie Exchange

 

Das sind nur ein paar Beispiele.

Auch SIP-Meldungen an ungültige Adressen (User@server.irgndwas.com) kommen im Lync erst mal an. Wenn ihr Skript als "früh" genug einsortiert ist, können Sie solche Meldungen auch verarbeiten, ehe das interne Lync Routing diese verwirft.

SIP-Routing/Rewriting passiert immer auf dem Registrar, d.h. die SIP-Meldungen werden auf dem werden Registrar gleich "richtig" normalisiert und an den Ziel-Registrar zur Zustellung geleitet. Das muss man beachten, wenn ein Client die Meldung an seinem Homeserver oder einer SBA einstellt und man beim Mediation Server dann auf die Normalisierung hofft.pro

Skript oder Managed Code oder Server Application Module

Wer eine Lösung basierend auf MSPL schreiben will, muss sich überlegen, wie er als "TrustedApplication" sich im Lync Server integrieren will. Ich kenne drei Zugänge:

  • MSPL-Skript
    Ein einfaches Skript ist für erste Gehversuche nutzbar, da es passende Beispielcodes bei Microsoft in der MSDN gibt und man nichts anderes braucht als Notepad. Allerdings ist die Funktion natürlich beschränkt auf die wenigen von MSPL bereitgestellten Methoden. Auch ist ein Debugging nicht einfach.
  • MSPL-Skript mit ManagedAPI
    Besser und Leistungsfähiger ist die Nutzung der ManagedAPI. Über ManagedCode können Sie auf alle Funktionen von Windows zugreifen. Das Skript ist im wesentlichen nur ein Rumpf, mit dem die gewünschten SIP-Meldungen abgefangen und an eine DLL übergeben werden.
  • Server Application Module
    Bei der Analyse des Lync Dialog Listeners habe ich das erste mal eine Applikation gesehen, die ohne Skript auskommt und dennoch an die die Lync Dialoge kommt. Eine Beschreibung der API habe ich nicht gefunden aber auch diese Applikation muss vorab als CsTrustedApplication registriert werden.

Hier ein paar weiterführende Links.

Skript Only

Eine als Skript erstellte Logik ist eine Textdatei mit der Endung ".am", die bei der Registrierung der CsTrustedApplication mit angegeben wird.

Allerdings sind Sie bei einer "Script only" Lösung auch auf die Funktionen beschränkt, die die Script-Umgebung bereit stellt. Und die ist bei MSPL alles andere als umfangreich. Sie können nach extern gerade mal eine Textdatei einlesen und ins Eventlog schreiben schreiben. Eine Skriptversion ist also auf die Veränderung von SIP-Anfragen anhand einiger in der Anfrage selbst vorhandenen Kriterien beschränkt.

Managed Code

Interessanter ist da schon die Arbeit mit "Managed Code". Das Skript ist dann nur noch für die Einbindung da und enthält im wesentlichen die Funktion "Dispatch"

In C# oder einer anderen Programmiersprache können Sie dann mit der SIP-Meldung sehr viel umfangreichere Aktionen ausüben und natürlich auch mit einem Debugger eleganter die Verarbeitung analysieren.

Machen Sie dies BITTE nicht mit dem produktiven System, denn der Debugger stoppt die Verarbeitung nachfolgender Meldungen.

Server Application Module

Hier habe ich

Skript einrichten

Ehe der Lync Server ein solches MSPL-Skript ausführt, muss dieses natürlich dort installiert werden. Wer mehrere FE-Server hat, muss das Skript natürlich auf allen Servern einrichten, die den Code auch ausführen sollen. Das ist nicht viel anders als ein Exchange Transportagent. Dabei hilft die PowerShell:

New-CsServerApplication

Wenn Sie eine "ScriptOnly" variante gewählt haben, dann müssen Sie hier natürlich noch den Pfad zum Skript hinterlegen und das Skript auch an den richtigen Platz legen.

Ich empfehle ihnen das Skript, wie alle anderen Skript in das Serververzeichnis zu lesen. Dann ist sichergestellt, dass der Server auch die Leserechte hat.

Hinweis2: Setzen Sie ein Skript nur dann auf "Kritisch", wenn Sie verhindern müssen, dass der Frontend-Dienst ohne Skript läuft. Das ist für die Lync-eigenen Komponenten und einen Virenscanner vielleicht sinnvoll, aber weniger für eine Auswerteapplikation. Da ist vielleicht die "Funktion" von Lync wichtiger.

Wenn Sie die "ManagedCode"-Variante nutzen, dann sollten Sie kein Skript angeben. Denn was hilft das Skript mit dem Dispatch, wenn das Programm nicht gestartet ist? Hier ist es am Programm beim Start das Skript in den Server einzubinden. Nach der Einrichtung des Skripts ist in der Regel ein Neustart des Frontend-Diensts erforderlich, um die Änderungen zu übernehmen.

Debugging und Monitoring

Skripte im "Herzen" eines Systems sind nicht immer einfach zu debuggen. Während der Entwicklungsphase sollte so etwas also "NIE" am Live-System erfolgen. Ich trennen das mal in drei Phasen auf:

  • Einrichtung
    Ob die Einrichtung erfolgreich war, sehen Sie schon beim Konfigurieren per PowerShell und wenn der Frontend wieder startet. Lync überprüft das Skript hier schon auf "Syntax" und lädt es gar nicht erst, wenn es einen Fehler erkennt. Das finden Sie recht einfach im Eventlog wieder
  • Überwachung
    Wenn das Skript dann erfolgreich geladen wurde, dann möchte man natürlich auch sehen, dass es etwas tut. für den Anfang reichen da die Eventlog-Einträge und Debug-Ausgaben schon mal aus. Ich hoffe ihr Skript meldet nun nicht alle SIP-Meldungen sondern hat einen Filter in Form einer IF-Abfrage davor. Es reicht ja, wenn Sie nur ihre eigenen Meldungen filtern.
  • Fehlersuche
    Wenn ihr Skript dann in die Wirkphase kommt und etwas verändert, dann wird es schon kniffliger. Mehr als ein paar "Debug-Ausgaben" gibt es bei einem Skript nicht, die man zudem noch selbst hineinschreiben muss. Und in interaktiver Debugger in Visual Studio verbietet sich auf dem produktiven System.

Ein guter Entwickler wird aber auch hier eine Wege finden und wird auf jeden Fall eine Fehlerbehandlung dergestalt einbauen, dass ein Code-Fehler im schlimmsten Fall das Paket unbearbeitet ziehen lässt.

SimpleRoute für MSPL von Colima

Wer nicht gleich selbst mit Notepad oder Visual Studio loslegen will, kann vielleicht auch mit dem MSPL-Codegenerator von Colima erste erfolge verbuchen. Es gibt diesen als kostenfreie "Free" und als "Pro Version. Die Software orientiert sich schon am zukünftigen Metro-Design und erlaubt in der hier gezeigten "Free-Version" die Konfiguration einer Aktion abhängig von der Absenderadresse und dem Inhalt der Message.

Wenn Sie ihre "Regel" erstellt haben, dann speichern Sie diese einfach als AM-Datei ab. Diese müssen Sie dann natürlich auf den Lync Server bringen und dort registrieren. Aber auch hierbei werden Sie durch eine Beschreibung unterstützt.:

Insofern ist dies ganz einfach umzusetzen, wenn Sie mit den Lösungen zurecht kommen, die durch den Skript abgedeckt werden.

Link zu MSPL-Code

Es gibt nicht allzu viele Codesamples und Projekte um MSPL. Vielleicht liegt es auch daran, dass die Entwicklung nicht ganz einfach und natürlich auch nicht ungefährlich ist. Eine falsches Komma und das Skript kann die komplette Lync Funktion stören. Daher sollten Sie auch die hier verlinkten Skripte erst einmal in einer TestUmgebung analysieren und mit Bedacht einsetzen. Viele "kleine Skripte" skalieren vielleicht nicht in größeren Umgebungen oder decken alle Fälle mit Director, Pool und Proxy ab.

Weitere Links

Lync Server 2010 SDK Content Notification Sample Walkthrough
http://gotuc.net/gotuc-blog/lync-server-2010-sdk-content-notification-sample-walkthrough

VIDEO: Installing and configuring an MSPL script
http://blog.greenl.ee/2012/02/09/video-installing-configuring-mspl-script/