Workaround for Ring Back Issues in Office Communications Server

Caveat: What follows could best be classified as a hack. I have posted this information because sometimes a hack is called for but also because it highlights the strength of OCS as a platform. Although implementing this workaround is via supported mechanisms, there is no support for the code included below. Please test in a non-production environment to ensure that this solves your problem with no other side effects.

On a particular voice deployment, we noticed an issue with PSTN callers to OCS not hearing any ring back tones (the ringing sound) in certain situations. We were able to fix the issue, though, with the creative use of the Microsoft SIP Processing Language (MSPL).

Our specific scenario was that the Communicator user had configured OCS to simultaneously ring (hereafter simply called “SimRing”) a PSTN phone number. While the user was signed into Communicator, the caller would hear ringing and SimRing would work. When the user was not signed into Communicator, the caller would not hear ringing and the call would disconnect within a few seconds before the called party could pick up the SimRing phone.

The problem occurred because of a missing “180 Ringing” SIP response message. When Communicator is signed in, it generates the ringing message and OCS routes this back to the caller appropriately. When Communicator is not signed in, it obviously does not generate this message. The endpoint that is being called through SimRing should generate it and OCS will route that back to the caller. In our case, that other endpoint was not generating it. So, to the caller, it did not look like any endpoints were ringing.

The most appropriate fix, in this case, would be to resolve why the ringing endpoint is not sending the alert appropriately. But, that would involve working with multiple vendors and resolving a complex call flow. We chose, instead, to simply generate the “180 Ringing” response for all calls inbound from the PSTN regardless of Communicator’s online status. This amounts to a little white lie. We will be telling the caller that an endpoint is ringing in some cases where none really are. (Because of the way it works, too, if Communicator is online, two ringing responses will be sent.)

The script that generates this response is pretty straightforward. It is written in MSPL and is added to the OCS front end server that is the mediation server’s next hop. Because it generates ringing responses for all inbound calls from the mediation server, it is likely to help in other situations where PSTN callers are not hearing ring back tones. To my knowledge, this script has been used without issue on both OCS 2007 and OCS 2007 R2.

The code is provided below for easy discovery and reading. To use the code, I have also provided it as an attachment to this post (RespondWithRinging.am). You can download that attachment and install it with the steps below. (Sometimes the attachment link is hard to find. Open the post and look for the attachments just before the comment section.)

To Install the Script

Select the “Front End Scripts” node that is under the OCS server that is the next hop for your mediation server. (You may need to repeat these steps for each server or pool that mediation servers use.) We will be adding this script to the list in the position just above UserServices. Right-click “Front End Scripts” and choose “Properties” to modify the list of scripts.

FrontEndScripts-before

Click the “Add…” button to add a new script.

FrontEndScripts-properties

Complete the “Add Front End Script” dialog with the appropriate information. The script path is wherever you have saved the RespondWithRinging.am file attached to this post. The script name is an arbitrary value you can supply. The URI must match the appUri value given in the application manifest.

FrontEndScripts-add

The script will be added to the bottom of the list. In this position, it will not be called for inbound calls because they will be handled by applications higher in the stack. You will need to use the “Up” button to move the script into the position above UserServices. There is no reason to mark this script as critical.

FrontEndScripts-order

After applying the new front end script properties, your list of front end scripts should look like this:

FrontEndScripts-after

With this script in place, you should be able to see the “180 Ringing” responses that are generated by it for inbound PSTN calls. Notice the “FALSE-180” header that the script inserts to let you know where this response comes from.

FrontEndScripts-snooper

For reference, here are the contents of RespondWithRinging.am. (If you view this post, you can see the attachments link just before the comment area at the bottom.)

 <?xml version="1.0"?>
<lc:applicationManifest
 lc:appUri="www.contoso.com/RespondWithRinging"
 xmlns:lc="schemas.microsoft.com/lcs/2006/05">
<lc:allowRegistrationBeforeUserServices action="true" />
<lc:requestFilter methodNames="INVITE" 
  strictRoute="false"
  registrarGenerated="true"
  domainSupported="true" />
<lc:responseFilter reasonCodes="NONE" />
<lc:proxyByDefault action="true" />
<lc:scriptOnly />
<lc:splScript><![CDATA[

    // This script will respond to incoming INVITEs from
    // the mediation server.

    // Build the user@host from the To: header.
    toUri = GetUri( sipRequest.To );
    toUserAtHost = Concatenate( GetUserName( toUri ), "@", GetHostName( toUri ) );

    Log( "Debug", false, "RespondWithRinging: we have a request: ", sipRequest.Method, " ", toUserAtHost );

    // Check if this is a re-INVITE and exit if so
    foreach ( sessionExpires in GetHeaderValues( "Session-Expires" ) ) {
        if ( ContainsString( sessionExpires, "refresher", true ) ) {
            Log( "Debug", false, "RespondWithRinging:         * skipped; This is a session refreshing invite" );
            return;
        }
    }
    
    // Check to make sure that the INVITE is from a mediation server
    foreach ( userAgent in GetHeaderValues( "USER-AGENT" ) ) {
        if ( ! ContainsString( userAgent, "mediation", true ) ) {
            Log( "Debug", false, "RespondWithRinging:         * skipped; not a mediation server request" );
            return;
        }
    }

    // If we're here, send a 180 response
    // Headers are being added in case it's important to detect this generated 180 response in a log
    Log( "Debug", 1, "RespondWithRinging:         * Ringing response being submitted" );
    AddHeader( "FALSE-180", "true" );
    Respond( 180, "Ringing", "FALSE-180=true" );
    return;
    
]]></lc:splScript>
</lc:applicationManifest>

As I have mentioned, there is no support for this solution. If it feels like a kludge to you, you are right to feel that way. That said, it may be the quickest way to workaround issues of missing ring back tones while you are working to resolve the real underlying issue. If you use this script in your environment, I would appreciate you contacting me and letting me know how it’s going.

--Doug

This post has been brought to you by VoIPNorm.

RespondWithRinging.am