Call on Hold

Diese Seite beschreibt den Sonderfall "Anruf mit Halten", der oft mal bei unterstützten Verbindungsaufbauten auftreten kann. Es gibt mehrere Wege so einen Anruf zu tätigen, von denen Skype for Business nur eine Variante zulässt.

Anwendungsfall

Um das Beispiel konkreter zu machen, müssen Sie sich folgende Dreiecksbeziehung vorstellen:

  • A = Agent
    Ein Agent ist in Mitarbeiter im Callcenter ihrer Firma, der sehr häufig Kunden anruft oder Anrufe annimmt.
  • B = Bot
    Dieser Teilnehmer ist die "Call Center Software", die für die Anwahl und das Vermitteln zuständig ist, den Status der Agenten kennt, Warteschlangen betreibt, Rufe aufzeichnet und Statistiken führt etc.
  • C = Customer
    Der Kunde ist der Anrufer oder das angerufene Ziel.

Nun könnten wir uns die Arbeit einfach machen und den Agenten (A) einfach direkt den Kunden (C) anrufen lassen. Diverse Callcenter-Lösungen funktionieren genau so, indem eine zusätzliche Software auf dem Client den Skype for Business Client steuert. In dem Fall kommt in der Regel kein "Call on Hold" zum Einsatz.

Dieser Fall hat auch nichts mit "Predictive Dialing" zu tun, bei dem zuerst ein oder mehrere Kunden angerufen werden und der erste, der den Ruf annimmt zum Agenten durchgestellt wird während die anderen Anrufe abgebrochen werden.

Das nachfolgend beschriebene Szenario passiert dann, wenn der BOT die Verbindung zu beiden Parteien aufbaut und dann vermittelt.

  1. Die Callcenter-Lösung startet einen Anruf direkt an den verfügbaren Agenten
    Der Agent nimmt den Ruf an, aber wird aus seiner Sicht noch "gehalten"
  2. Das Callcenter startet einen ausgehenden Anruf zum Kunden
    Das ist aber kein zweiter INVITE sondern ein REFER an den SBC, welcher dann nach extern einen INVITE startet
  3. Vermitteln nach Rufannahme
    Sobald die Verbindung nach Extern steht, wird diese vom SBC zum Agenten vermittelt.

Weiter unten habe ich einen ausführlicheren SIP-Trace für diese Konstellation beschrieben.

Varianten von Call On Hold

Damit der Initiator des Anrufs den angerufenen Teilnehmer direkt auf den "Anruf halten"-Status bringt und sich damit den RTP/ICE-Handshake erspart, gibt es drei Varianten

  1. INVITE mit SDP 0.0.0.0
    Der Anrufer kann einen INVITE zum Ziel senden aber übermittelt im SDP für "m=audio" einfach eine 0.0.0.0 als IP-Adresse. Der angerufene Teilnehmer kann also gar nicht wissen, wohin er seine Audio-Daten senden soll und interpretiert den Anruf dann als "Hold". Der angerufene Teilnehmer erwartet einfach später mit einem reINVITE die entsprechende Daten. Dieses Verfahren ist in der RFC 4317 unter 5.2 auch beschrieben. Allerdings versteht Skype for Business dieses Verfahren nicht
  2. INVITE mit SDP "a=inactive"
    Die zweite Option besteht darin im SDP die Option "a=inactive" zu nutzen. Damit wird zwar Audio ausgehandelt aber eben "inaktiv" gelassen. Der angerufene Teilnehmer steht damit auf "wird gehalten". Auch dieses Verfahren ist beschrieben aber wird vom Skype for Business Client nicht verstanden
  3. INVITE mit SDP "a=sendonly"
    Skype for Business versteht aber die dritte Option, bei der ein Anrufer die Option "a=sendonly" im SDP verwendet. In dem Fall kann der angerufene Teilnehmer annehmen, aber wird sofort "gehalten"

Sie sehen an diesem Beispiel gut, dass SIP zwar ein Standard ist, aber nicht alle Besonderheiten in jeder Variante implementiert sein müssen. Skype for Business sagt in der Regel aber im SIP-Paket als auch im Eventlog deutlich, wenn er diesbezüglich etwas nicht mag.

Skype for Business und 0.0.0.0

Ich bin auf das Problem eigentlich erst aufmerksam geworden, als ein SIP-Client über den Session Border Controller einen INVITE mit 0.0.0.0 als Media IP-Adresse an einen Skype for Business Mediation Server gesendet hat, und die Verbindung gar nicht erst zustande gekommen ist. Der gerufene Teilnehmer hat also nicht mal einen eingehenden Ruf signalisiert bekommen. Über den SIP-Trace auf dem SBC konnten ich folgendes sehen:

Der Mediation Server meldet einen "488 Invalid incoming Gateway SDP.  Das komplette 488-Paket ist:

SIP/2.0 488 Invalid incoming Gateway SDP: Call hold not allowed for initial INVITE offer
FROM: <sip:+4952579388@192.168.178.82>;tag=1c1258104475
TO: <sip:+495251304613@sbc1.msxfaq.net>;transport=tls;epid=20375E7CF3;tag=3135ca0a6
CSEQ: 1 INVITE
CALL-ID: 12345678@192.168.178.201
VIA: SIP/2.0/TLS 192.168.178.201:5061;branch=z9hG4bKac592199727;alias
CONTENT-LENGTH: 0
SERVER: RTCC/6.0.0.0 MediationServer

Passend dazu gibt es auch im Eventlog des Mediation Servers einen Eintrag:

Log Name:      Lync Server
Source:        LS Mediation Server
Event ID:      25039
Task Category: (1030)
Level:         Error
Keywords:      Classic User:          N/A
Description:
SDP negotiation failed with the Trunk.
 
Trunk FQDN sbc.msxfaq.net;trunk=sbc.msxfaq.net, Reason Call hold not allowed for initial INVITE offer
Cause: The Trunk is either not configured correctly, incompatible with Mediation Server, or not certified.
Resolution: Check that the Mediation server and Trunk are configured correctly.

Deutlicher kann man es ja wohl nicht sagen, dass Skype for Business mit einem 0.0.0.0 als IP-Adresse nicht arbeiten will. Aber warum hat Microsoft dieses Verfahren nicht implementiert? Eine Quelle hierzu habe ich nicht aber wenn ich mir die Funktion von Skype for Business anschaue, dann ist es technologisch ungünstig, einen Ruf zu signalisieren und durch den Client annehmen zu lassen, wenn gar nicht klar ist, ob die Audio-Verbindung zustande kommen könnte. Alle Tricks wie MediaBypass, EarlyMedia greifen nicht, wenn die Gegenstelle nicht bekannt ist. Ich habe etwas recherchiert und andere Produkte raten wohl auch davon ab,

"CUCM  no longer uses the 0.0.0.0 to put the call on Hold. It uses the SDP  with a=inactive/sendonly/recvonly to establish break of audio or  transmission of audio only in one direction today This is the recommended way of putting SIP calls on hold.”
Quelle: Cisco Support Forum https://supportforums.cisco.com/t5/collaboration-voice-and-video/the-significance-of-c-in-ip4-0-0-0-0-and-media-m-line-ports-in-a/ta-p/3152037

8.4 Putting a Unicast Media Stream on Hold   RFC 2543 [10] specified that placing a User on hold was accomplished
by setting the connection address to 0.0.0.0. Its usage for putting a call on hold is no longer recommended, since it doesn't allow for RTCP to be used with held streams, doesn't work with IPv6, and breaks with connection oriented media. However, it can be useful in an initial offer when the offerer knows it wants to use a particular set of media streams and formats, but doesn't know the addresses and ports at the time of the offer. Of course, when used, the port number MUST NOT be zero, which would specify that the stream has been disabled. An agent MUST be capable of receiving SDP with a connection address of 0.0.0.0, in which case it means that neither RTP nor RTCP should be sent to the peer.
Quelle: RFC3264 An Offer/Answer Model with the Session Description Protocol (SDP) https://www.ietf.org/rfc/rfc3264.txt

Es ist also wohl doch was dran, dieses Verfahren zumindest nicht mehr anzuwenden. Warum diese Callcenter-Software aber noch so arbeitet, konnte ich bislang nicht klären. Interessanterweise ist dies nur der Fall, wenn der Agent mit einem Teilnehmer direkt verbunden wird. Wenn das Callcenter aber Funktionen wie Recording, Zufriedenheitsinterview am Ende oder Assistenzfnuktionen (Slient Whisper) unterstützt, dann baut das Callcenter eine Audio-Verbindung auf und agiert auch als Mediarelay.

Aber da auch der einfache Fall eines durch das Callcenter ausgelösten Anrufs funktionieren muss, habe ich weiter suchen dürfen:

SBC Übersetzung mit "Remote Hold Format"

Wenn daher zwei Systeme zu koppeln sind, die zwar beide "SIP sprechen" aber sich an solchen Besonderheiten unterscheiden, dann kommt dem Session Border Controller eine große Bedeutung zu. Er kann solche Unterschiede ausgleichen, indem er entweder die SDP-Parameter entsprechend umsetzt oder direkt als B2BUA sich auch in den Medienstrom einschaltet. Bei einem Audiocodes Mediant ist das z.B. der Parameter "Remote Hold Format” im IP-Profil.

Hier sehen Sie, dass es mit Kombinationen sogar noch mehr Möglichkeiten gibt, wie ein Client ein "Call on Hold" signalisiert bekommt. ich durfte vor einiger Zeit eine Anbindung mit einem Callcenter unterstützen, bei dem genau dieses Verhalten erforderlich war. Der SBC war zwar als “Media Relay” ohne Bypass konfiguriert, aber die SDP-Parameter beim INVITE-Befehle wurden als Teil der Signalisierung erst einmal transparent durchgereicht. Das Call Center hat aber darauf bestanden, einen INVITE mit 0.0.0.0 zu senden, worauf der angerufene Agent natürlich den Ruf abgelehnt hat:

Ich habe daher mit drei verschiedenen Einstellungen des Parameters "Remote Hold Format" experimentiert und sowohl den eingehenden INVITE als auch den ausgehenden INVITE mitgeschnitten und das Ergebnis bewertet

CallCenter INVITE SDP

Audiocodes
Setting

Invite zu Skype for Business

Status

v=0
o=CallCenter 1507188203 1 IN IP4 0.0.0.0
s=3pcc Make Call
c=IN IP4 0.0.0.0
m=audio 10000 RTP/AVP 101 0 8 4 18 3
a=rtpmap:101 telephone-event/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:4 G723/8000
a=rtpmap:18 G729/8000
a=rtpmap:3 GSM/8000		

Transparent

v=0
o=CallCenter 574051086 958258021 IN IP4 192.168.178.201
s=3pcc Make Call
c=IN IP4 0.0.0.0
t=0 0
m=audio 9980 RTP/AVP 0 8 4 18 3 101
a=rtpmap:101 telephone-event/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:4 G723/8000
a=rtpmap:3 GSM/8000
a=sendonly
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=yes	

Fail

Inactive

v=0
o=CallCenter 574051086 958258021 IN IP4 192.168.178.201
s=3pcc Make Call
c=IN IP4 192.168.178.201
t=0 0
m=audio 9980 RTP/AVP 0 8 4 18 3 101
a=rtpmap:101 telephone-event/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:4 G723/8000
a=rtpmap:3 GSM/8000
a=inactive
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=yes

Fail

SendOnly

v=0
o=CallCenter 574051086 958258021 IN IP4 192.168.178.201
s=3pcc Make Call
c=IN IP4 192.168.178.201
t=0 0
m=audio 9980 RTP/AVP 0 8 4 18 3 101
a=rtpmap:101 telephone-event/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:4 G723/8000
a=rtpmap:3 GSM/8000
a=sendonly
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=yes

OK

Mit Skype for Business funktioniert also ein "Call on Hold" nur in Verbindung mit einem "a=sendonly".

SIP Flussdiagramm

Nachdem dann die Konfiguration "gepasst" hat, dann konnte folgender funktionierender SIP-Dialog analysiert werden. Das Callcenter ist per SIP mit dem SBC verbunden, der seinerseits per SIP mit Skype for Business und der TK-Anlage als Übergang zum Amt verbunden ist.

Aktion SIP-Flussdiagramm

Zuerst beginnt das CallCenter einen INVITE zum Agenten mit "Call on Hold". Sieh sehen hier, dass der Session Border Controller die Verbindung zum SfB Mediation Server weiter gibt und die Verbindung aufgebaut wird. Leider kann man in diesem Diagramm nicht sehen, dass aus dem IP = 0.0.0.0 ein "a=sendonly" wird.

Nachdem die Verbindung zum Agenten steht, macht das CallCenter einen "REFER" zum eigentlich Ziel. Das CallCenter ruft also nicht selbst den Kunden mit einer zweiten INVITE-Session an, sondern macht einen "Blind Transfer" des bestehenden gehaltenen Gesprächs.
Der SBC mach daraus dann einen INVITE zur TK-Anlage, die später dann ein "RINGING" und letztlich ein 200OK meldet.

Dann sendet der SBC ohne weitere Mithilfe des Callcenters einen INVITE zum Skype for Business, um die Verbindung nun aktiv zu nehmen. Sie bis eben immer noch "On Hold".
Das bedeutet aber auch, dass der Agent in der ganzen Zeit leider keine Information über den Wahlfortgang hat. Er hört also keine "Klickergeräusche" und nicht einmal das Freizeichen, wenn es beim Kunden klingelt. Die Verbindung ist irgendwann einfach da.

Das SBC informiert das Callcenter über die erfolgreiche Vermittlung. Das Callcenter baut dann seine Session mit einem BYE ab.

Irgendwann später legt in diesem Beispiel der angerufene Kunde auf. Der SBC meldet das eingehende BYE weiter an Skype for Business, welcher das Ende bestätigt.
Das Callcenter bekommt davon direkt nichts mehr mit. Es bliebt also nun an der Clientsoftware, den beendeten Anruf auch im Callcenter zu erfassen, wenn der Anwender das nicht selbst schon macht.
Ein Callcenter kann natürlich den "Status" des Agenten überwachen und wenn der Skype for Business Status von "Am Telefon" auf "Idle" wechselt, ist das ein guter Indikator für eine Gesprächsende.

Weitere Links