A Sample Message Filter Script
The following annotated MSPL script filters incoming SIP responses and attempts to select the best endpoint for each message based on the endpoint ID (EPID).
<?xml version="1.0">
<lc:applicationManifest
lc:appUri="https://www.contoso.com/DefaultRoutingScript"
xmlns:lc="https://schemas.microsoft.com/lcs/2006/05">
<lc:requestFilter methodNames="INVITE,MESSAGE,INFO,REFER,ACK,BYE,OTHER"
strictRoute="false"
registrarGenerated="true"
domainSupported="true"/ >
<lc:responseFilter reasonCodes="NONE" />
<lc:proxyByDefault action="true" />
<lc:scriptOnly />
<lc:splScript><![CDATA[
//
// This script handles default routing of requests to Lync Server. It
// looks up all the registered endpoints for the To: user@host and tries
// to pick the best endpoint to route to based on:
// EPID
//
// Endpoints with no presence or an availability less than 100, or
// no routing information (for example, set presence without
// register) are not considered.
//
Log( "Debugr", 1, "we have a request - ", sipRequest.Method );
//
// Build the user@host from the To: header.
//
toUri = GetUri( sipRequest.To );
toUserAtHost = Concatenate( GetUserName( toUri ), "@", GetHostName( toUri ) );
//
// Determine whether this request is already asking for a specific EPID
// via a parameter in the To: header.
//
requestEPID = GetParameterValue( sipRequest.To, "EPID" );
//
// Now loop over all the endpoints for the To: user@host.
//
bestEPID = "";
bestAgeOfPresence = 0x7FFFFFFF;
bestAvailability = 0;
bestActivity = 0;
bestContactInfo = "";
Log( "Debugr", 1, "EPID - ", requestEPID );
Log( "Debugr", 1, "toUserAtHost - ", toUserAtHost );
foreach (dbEndpoint in QueryEndpoints( toUserAtHost, true )) {
Log( "Debugr", 1, " endpoint.EPID - ", dbEndpoint.EPID );
Log( "Debugr", 1, " endpoint.ContactInfo - ", dbEndpoint.ContactInfo );
//
// First, determine whether this endpoint supports the method in the request.
//
if (!SupportsMethod( sipRequest.Method, dbEndpoint.StandardMethods, dbEndpoint.ExtraMethods )) {
//
// Skip this endpoint because it cannot handle the method on this request.
//
Log( "Debugr", 1, " * skipped because of method" );
continue;
}
if (requestEPID != "") {
if (requestEPID == dbEndpoint.EPID) {
//
// The request is already targeted at a specific EPID that can handle the method,
// so use this endpoint.
//
Log( "Debugr", 1, " * matched EPID" );
bestContactInfo = dbEndpoint.ContactInfo;
break;
}
else {
//
// The request is targeted at a specific EPID, but does not match this endpoint.
// Skip this endpoint.
//
Log( "Debugr", 1, " * skipped because of EPID" );
continue;
}
}
bestEPID = dbEndpoint.EPID;
bestContactInfo = dbEndpoint.ContactInfo;
Log( "Debugr", 1, " *** new best contact" );
}
//
// See if an endpoint to proxy to was found.
//
if (bestContactInfo == "") {
/* Uncomment this block of code and the two assignments to sawAtLeastOneEndpoint
above if you want to run a UAC application before this one and have this code
route your messages to the correct home server.
if (!sawAtLeastOneEndpoint) {
homeServer = QueryHomeServer( toUserAtHost );
if (!EqualString( homeServer, FQDN, true )) {
Log( "Debugr", 1, toUserAtHost, " is homed on ", homeServer );
newRequestUri = Concatenate( sipRequest.RequestUri, ";maddr=", homeServer );
Log( "Debugr", 1, "Request is being routed to ", newRequestUri );
AddHeader( "MS-LBVIA", FQDN );
ProxyRequest( newRequestUri );
return;
}
}
*/
Log( "Debugr", 1, "Responding 480 - temporarily unavailable as no suitable endpoint found" );
Respond( 480, "Temporarily Unavailable" );
}
else {
if (requestEPID == "") {
Log( "Debugr", 1, "Adding missing EPID '", bestEPID, "' to To header" );
SetParameterValue( "To", "epid", bestEPID );
}
Log( "Debugr", 1, "Proxying request to - ", bestContactInfo );
ProxyRequest( bestContactInfo );
}
return;
]]></lc:splScript>
</lc:applicationManifest>
Note
The use of the following patterns:
request.RequestUri = ...
ProxyRequest(sipRequestUri)
If you change RequestUri, the request is marked as routed without providing a request target. Applications that do not have routing information for a request should not modify the request-uri. We recommend that non-routing applications never change the request-uri.