How to check if a custom header exists on a message using a MSPL script

340 Views Asked by At

I'm using the following MSPL script to direct audio calls to a UCMA app.

<?xml version="1.0" encoding="utf-8"?>
<r:applicationManifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" r:appUri="http://www.example.com/recording" xmlns:r="http://schemas.microsoft.com/lcs/2006/05">
  <r:requestFilter methodNames="ALL" strictRoute="true" registrarGenerated="true" domainSupported="true" />
  <r:allowRegistrationBeforeUserServices action="true" />
  <r:responseFilter reasonCodes="NONE" />
  <r:proxyByDefault action="true" />
  <r:scriptOnly />
  <r:splScript><![CDATA[ 
            /* 
                This script has been generated by SimpleRoute. Changes to this file may cause unexpected behavior.
                -
                -
                -
                All audio calls from any origin
                are redirected to '[email protected]'!
            */

            function InviteHasBody()
            {
                foreach(header in GetHeaderValues(StandardHeader.ContentType))
                {
                    /* Found a content-type header, so we know it has a body. */
                    return true;
                }
                return false;
            }

            function IsAudioCall()
            {
                if((sipRequest.Method == "INVITE") && (!InviteHasBody() || ContainsString(sipRequest.Content,"\nm=audio ", false) || ContainsString(sipRequest.Content,"\rm=audio ", false)))
                {
                    return true;
                }
                return false;
            }

            function IgnoreCall()
            {
                foreach(header in GetHeaderValues("IgnoreCall"))
                {
                    /* Found ignore call. */
                    return true;
                }
                return false;
            }

            if (sipRequest)
            {
                if(IsAudioCall())
                {
                    if (!IgnoreCall())
                    {
                        targetUser = "sip:[email protected]";
                        userAtHost =  GetUserAtHost(targetUser);
                        targetRequestUri = "";
                        foreach(dbEndpoint in QueryEndpoints(userAtHost, true))
                        {
                            targetEpid = dbEndpoint.EPID;
                            targetRequestUri = dbEndpoint.ContactInfo;
                            if(targetRequestUri != "" && targetRequestUri != null)
                                break;
                        }

                        if(targetRequestUri == "")
                        {
                            RetargetRequest("sip:[email protected]");
                            return;
                        }
                        ProxyRequest(targetRequestUri);
                    }
                }
            }
]]></r:splScript>
</r:applicationManifest>

The problems is the UCMA app receives an incoming call, creates a conference with a trusted participant (so it can be recorded), and then calls the 2nd leg and joins the call to the conference. The problem part is making the call to the 2nd leg as this is picked up by the MSPL script and the call is directed to the UCMA app. This causes an error saying

Fork invalid for request with route headers

When the 2 leg call is made I add a custom header called IgnoreCall using the code below.

McuDialOutOptions mcuDialOutOptions = new McuDialOutOptions();
mcuDialOutOptions.ParticipantUri = destinationUri;
mcuDialOutOptions.Headers.Add(new SignalingHeader("IgnoreCall", "true"));
_incomingAudioVideoCall.Conversation.ConferenceSession.AudioVideoMcuSession.DialOutAsync(destinationUri, mcuDialOutOptions);

This is so the MSPL script can check to see if the call should be directed to the UCMA app. But the MSPL script isn't detecting that the message/call has the IgnoreCall header.

Can someone please tell me what is the best way to check if the message/call contains a header called IgnoreCall so I know when not to direct the message/call to the UCMA app?

1

There are 1 best solutions below

0
On

Your code looks ok to me, I would try to determine if the new INVITE from the conference server has the header or not.

You can: * Use Skype logging to check the INVITE has the excepted header. If it doesn't then it's something about the DialOutAsync that is incorrect. Not sure I can help with that. * You can use MSPL Log command to "log" debug info to see how your MSPL script is flowing.

Some small MSPL notes:

You don't need to call "ProxyRequest". It does it by default anyway if the request has not been retargeted or already proxyed.

I'm not sure what you are doing with the "QueryEndpoints" call, it seams like you are doing nothing so I would remove it.

I would restrict the methods supported to just "INVITE" as you don't want to retarget other request types. e.g.

I would only redirect invites and not re-invites. So you need to check if the To header has the "tag" parameter. e.g.

toTag = GetParameterValue(sipRequest.To, "tag");
if (toTag != null) {
    // This is a re-INVITE.
    return;
}

You should filter out any INVITE that is already heading for your retarget target anyway...

Another option is that you could filter out any call from/to the conference call. e.g. From conference server:

opaqueTag = GetParameterValue(sipRequest.From, "opaque");
if (opaqueTag != null && ContainsString(opaqueTag, "app:conf:")) {
    // This is a conference call.
    return;
}

You should be able to figure out the To conference server call.