Updated: CUCM SIP URI Dialing to Lync 2013–New SIP URI Normalization rules on CUCM

I created the original post for this configuration back in July of last year and its seen quite a bit of traffic and had some great comments. I just thought with the release of Lync 2013 and some new interesting developments it would be worth adding new info and refreshing some of the content to better speak to Lync 2013.

I have recently added community fixes to issues that have arisen so this post is certainly worth a revisit when I make updates. Please continue to comment and make suggestions. I know quite a few companies are now using this configuration based on this blog post so keep the info and questions coming and I will keep updating.

What's this post all about?

I have seen quite a bit of using Cisco’s mobility feature to dual ring a Cisco phone and Lync. There is an interesting feature in CUCM that could make your life easier. Its called SIP URI dialing. This isn't a new feature as its been around since 7.x days or possibly earlier. It sparked my interest back in 2008 but I never really investigated it further until 2012.

SIP URI dialing is really a pretty basic concept. Instead of using a normal DID route pattern to designate a destination you use a SIP URI such as lyncuser1@contoso.com. By specifying @contoso.com as your SIP route you assign a SIP trunk that points to Lync. Its actually pretty simple and works with Cisco’s mobility feature used in Remote Destination Profiles.

There are some caveats with this feature though and its not terribly flexible. It does require some special configuration but could possibly make dial plans and  interoperability a little easier. Also you can remove the issue of requiring unique DID’s on both systems because now that your ringing between systems with a unique SIP URI using the same DID on both systems is much less problematic. So users don’t have to change numbers or use a new number for Lync, it can be the same as their Cisco IP phone.

To make things a little easier to understand, in this post I am referencing the To field in a SIP message when I am talking about Tel URI or SIP URI. I am using Tel or SIP to define trunk routing behavior even though both are configured as SIP trunks when configured in CUCM. Its just the routing behavior based on the address format I am trying to better define. Hope that’s not to confusing.

Why use it?

While working in the field I get a lot of questions from engineers around how do I make my Cisco phone and Lync ring at the same time. As I have covered here on my blog there are a couple of ways to do this from either CUCM, Lync or even potentially from a gateway. But there is a level complexity in regards to how to configure DID’s and how to make DID’s unique enough so that you can route between the two platforms. Well using SIP URI dialing instead of DID’s this simplifies this portion of the configuration and leaves Lync’s Sim Ring feature open for users to configure it for their cell phones. Using Sim Ring as the tool to ring a Cisco desk phone in my opinion is a waste of an easy to configure end user setting. I strongly believe this feature is better used to ring a cell phone or other devices self administered by the user.

The interface for configuring Cisco Remote Destination Profiles is potentially very intimidating for normal users. There are settings and timers that if set incorrectly can cause issues. That’s why in my opinion RDP’s should be configured by an administrator and Sim Ring on Lync is a better choice for self service by the average user. There is only one timer and phone number fields can be prepopulated making the users phone number selection easy. Also Sim Ring has the ability to use the business hours set in Outlook where as Cisco’s RDP requires this to be recreated under the RDP profile. If your using RDP’s for more than just ringing Lync this might be handy.

image

From a self service point of view Lync allows the user to set Sim Ring and Business hours which are inherent in Outlook straight from within Lync. Timers for voicemail forwarding are available but other timers are system controlled and not exposed to users removing the potential to create issues. Sim Ring can also be changed by the user from all the mobile apps.

image

image

RDP’s although not overly end user friendly can be used in different ways to help integrate Lync into your preexisting environment. It can ring up to 5 endpoints. RDP could also be used as way to keep voicemail in a different voicemail messaging platform other than Exchange UM for Lync users but still allow a user to have Lync as a softphone. This might be important for companies that do want voicemail in email for compliance reasons etc. So RDP has some great uses for working around common issues.

Caveats for SIP URI dialing?

The single biggest caveat for SIP URI dialing is that when you create a SIP Route pattern in CUCM it does not allow assigning a route group to it. You have to directly assign a trunk to the route pattern. The main issue is that once assigned to the SIP route pattern you can no longer assign the same trunk to a route group which limits your options. The best way to deal with this is to have a SIP trunk just for SIP URI routing. In CUCM 8.6 you can have multiple endpoints (in our case mediation servers) assigned within a SIP trunk which means that this isn't a redundancy problem. Its more a configuration issue on the CUCM side but since this configuration is for a specific purpose I don’t consider this a show stopper.

With Lync 2013 this trunk can now have its own port within the Lync trunk configuration. This means we can create a trunk with its own rules on either system. It really doesn’t mean that its simpler but certainly more configurable from a call control point of view.

How to set it up?

The easiest way to do the setup is to follow this guide with a few alteration which I will call out below. This is the Microsoft produced guide. In the Microsoft guide they make use of Calling Search Spaces (CSS) which gives a more complete picture of the settings required. In the Cisco guide there is no call authorization setup so unless you know which CSS to configure you could easily miss a setting as there are multiple places to set CSS on various pages. The one that caught me out was the rerouting CSS on the Remote Destination Profile.

image

What's needed for Lync?

The SIP URI trunk is for inbound use only. This means that setup on the Lync is pretty simple if you already have a SIP trunk setup for your CUCM deployment. As long as your CUCM servers are already added to the topology as gateways you are already done. Just make sure that the inbound SIP URI trunk to Lync is using already established ports.

In Lync Server 2013 we can take the configuration a little further than 2010. We can define individual trunks for each dialing type. Like I said earlier this doesn’t make it simpler to configure but it can make the configuration clearer to understand. Now we have two well define trunks to the same gateway and we can name it accordingly so we have a clear understanding of the configuration.

image

If creating two trunks in Lync 2013 the individual trunks are identified by the inbound port on the gateway side of the configuration (in our case CUCM).

image

The trunk configuration is then completed in the Lync Control Panel or PowerShell. Below are a couple of screen shots for the configuration I completed in my lab but for more complete details on setting up a SIP trunk to CUCM refer to this document http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=26800. Although this document refers to Lync 2010 a lot of the same rules apply to 2013. Also keep in mind there are variances in the exact setup according to the version of CUCM you are using. In my example lab REFER is support by CUCM 8.6 so I left it as enabled but other versions this will differ. Use this link to match your CUCM version setting requirements http://technet.microsoft.com/en-us/lync/gg131938.aspx.

image

Trunk settings for encryption, enable media bypass and REFER for CUCM 8.6.

image

The last time I posted this info Alex Lewis asked the question about “You say the DID can be the same in Cisco and in Lync but if I'm in Lync and dial another user then only their Lync endpoint will ring.” Well thanks to an Anonymous tipster I believe that we have somewhat of a solution to this. There is an attribute that can be added to the users Tel URI that will stop Lync from doing the usual RNL behavior. This means that any call to the users extension can be routed to CUCM regardless of whether its configured in Lync as the user line URI while allowing the RDP in CUCM to ring the Lync client. Now this is by no means a perfect solution. There is potential hair pinning of calls through Lync to CUCM and back to Lync. While this has the potential to consume some extra resources its not going to be life threatening in most cases. Its just a matter of planning for it and understanding call flows in your environment.

What you potentially end up with is a Line URI that looks like this:

tel:+12345678;ext=5479;ms-skip-rnl

The ms-skip-rnl is what will cause Lync to pass the call directly out to CUCM rather than follow normal reverse number look up behavior for calls to be routed to users. This attribute is actually used else where in the product for certain functions such as CAC and RCC so its not a total mystery of its existence but this is not its normal use.

Lastly I just want to mention, use this configuration at your own risk. This is not the usual configuration that one would follow in setting up Lync. When calling in a support ticket this attribute may be required to be removed if you are having issues. As my friend and college Doug wrote to me in an email exchange “The mechanism that it leverages will probably remain in the product forever but, if they called support, the engineer would probably go, “huh?”. I think you get the idea now.

image

How do I configure CUCM?

In my testing I was using CUCM 8.6 so your settings may vary depending on the version you have.

SIP Trunk

The thing with this configuration is that you are creating a SIP trunk for one purpose and that is to ship messages with headers that have the “to” field with a SIP URI format to Lync. So LyncUser1@contoso.com as an example.

Your Tel URI and SIP URI SIP trunks can share the same SIP Security Profile and outbound ports to Lync but you will need to use different DNS/SRV names or IP address DNS name combinations. So as an example:

SIP URI Trunk – FQDN – 2013-lync-fe.contoso.com

Tel URI SIP Trunk – IP Address 192.168.0.170

Below is my trunk configuration for my SIP URI routing with a FQDN for my Lync 2013 Mediation Server.

image

SIP Profile for calling out a specific listening port:

image

In my case I used a IP address on one trunk for Tel URI calling and the FQDN on the SIP URI trunk. Now if you are not that fixed on configuring route groups and route lists for the SIP trunk connecting to Lync you can configure the trunk directly on both DID and SIP URI route patterns and just have one trunk. I tried both in my lab and it worked either way.

In this 2013 update I changed around my configuration somewhat to route to separate trunks that have separate port numbers as well. Like I said earlier this give the ability to create more control at either end of the trunk on either Lync or CUCM.

Update: SIP Normalization Rules

I received quite a few emails and comments from people that ran across an issue. If your Lync deployment was larger than a single pool the port specified in the SIP invite from CUCM would cause calls to fail. If you user wasn’t part of the pool associated with the mediation server receiving the invite from CUCM redirecting the invite to the correct pool would fail. The error message generated indicated a port issue.

LogType: diagnostic
Severity: warning
Text: Message was discarded by the application
Result-Code: 0xc3ee7964 ES_E_REQUESTURI_VALIDATION_FAILED
SIP-Start-Line: INVITE sip:firstname.lastname@contoso.com:5060 SIP/2.0
SIP-Call-ID: a5c03a60-e790-4490-9e02-75baf13b8250
SIP-CSeq: 51567 INVITE
Data: application="http://www.microsoft.com/LCS/UserServices"
$$end_record

Seems Lync didn’t like the header with port 5060 being part of it when passed to another pool. The exact reason why it doesn’t like it I am not sure why but this was the issue identified.

This really stumped me. I wasn’t quite sure how to work around it but luckily a reader supplied the answer. CUCM has the ability to create normalization scripts to fix header issues like this. This is somewhat similar to MSPL scripts in Lync which many of you are probably familiar with but uses an open source scripting language called Lua http://www.lua.org/docs.html. Here is a similar example I also found that replaces IP address with a domain name.

Creating the Script: Device>Devices Settings>SIP Normalization Script

image

Add new-

image

Paste in the follow contents, name the script and save::

M = {}
function M.outbound_INVITE(msg)
local method, ruri, ver = msg:getRequestLine()
local uri = string.gsub(ruri, "5060", "5061")
msg:setRequestUri(uri)
end
return M

image

Finally apply the script to your CUCM SIP trunk for SIP URI dialing.

image

SIP Route

Probably the new piece of configuration to most people will be the SIP route itself. Its pretty easy to configure. See below. I created a domain route to contoso.com to route my SIP URI traffic that I setup for my users on their Remote Destinations.

image

User Setup

As far as the user setup goes the only variation between the standard setup mentioned in the guide I referenced earlier is to configure the user with a SIP address to route calls in the Destination Number under Remote Destination configuration. In my case I used garthf@contoso.com as my destination number rather than a DID or other number.

image

This configuration is probably one of the most important interoperability pieces I have written in a while. I can see this alleviating quite a few issue I have come across in the field and hopefully this article will get good circulation so more people know about it. If I look over all the possible ways to do interoperability between Lync and CUCM (RCC, Plugins etc, etc) this really does give the best of both worlds without sacrificing one for the other unlike other methods like plugins which ruin the Lync UI experience. There are some complexities for the initial setup but at the end of the day your using the features available of both products without the use of third parties or additional servers. Call it the biggest bang for your buck if you will.

If folks need more explanation please feel free to post your questions.

VoIPNorm

24 comments:

  1. Hi Chris

    I am very happy to see such article, as this is exactly what I am trying to setup. Thank you and well done writing up these great articles! I have overcome some challanges already (multiple trunks to centralized CUCM with media bypass in branch sites, and splitting the SIP-uri for same domain to multiple trunks) but one issue is still oustanding. I am curious if you have come accross this. If you use sip-uri dialing the mediation server trace indicates this:

    -MEDIATIONSERVER
    MediationCall: 4d6a991bf1724f7ca99d08d2ebdf0a23
    CallId: 3c5afe00-1281bdd5-76c5b-11e6fc17@x.x.x.x
    From: sip:+44444444@x.x.x.x
    To: sip:firstname.lastname@contoso.com:5060
    Direction: Inbound
    Start-Line: Invalid phone number for inbound call, pass it along.
    $$END-MEDIATIONSERVER


    The call is still passed to the front-end pool and succeeds.

    However, if the user is in another pool, the call is still delivered to the local pool and not the users's pool. The local pool FE seems to log this and drop the call:

    LogType: diagnostic
    Severity: warning
    Text: Message was discarded by the application
    Result-Code: 0xc3ee7964 ES_E_REQUESTURI_VALIDATION_FAILED
    SIP-Start-Line: INVITE sip:firstname.lastname@contoso.com:5060 SIP/2.0
    SIP-Call-ID: a5c03a60-e790-4490-9e02-75baf13b8250
    SIP-CSeq: 51567 INVITE
    Data: application="http://www.microsoft.com/LCS/UserServices"
    $$end_record

    BTW it's Lync 2010.
    Do you know if any special format of the request Uri is required? Like adding ;user=phone, or ;phone-context=enterpise, or something like this?


    Michael

    ReplyDelete
    Replies
    1. Hi Michael,

      How does Lync reject the call back to CUCM? Does it return a SIP message back to CUCM to say it dropped the call?

      Also is this a collocated mediation server on the FE? and do you have a mediation server setup on the other pool?

      BTW I have not heard or seen this before, but its good info to know because multiple pool scenarios is something I had not tested and may require a little different design.

      Delete
    2. Hi Chris

      In the case when user is in another pool, The front-end server rejects the call to Mediation server via response containing:
      Start-Line: FailureResponseException: ResponseCode=504 ResponseText=Server time-out
      DiagnosticInformation=ErrorCode=2,Source=FE-servername,Reason=See response code and reason phrase

      The "Server time out" is also logged as the reason for the failed call in monitoring reports.

      I have separated mediation server pool, no co-location. I also have mediation server pool as part of the other FE pool, but it is not integrated to this same CUCM that I talk about.

      This brings me to idea that potentially - if you needed to host users in the other pool, (and Lync turns out not able to handle this rerouting natively), you can add use different "virtual" SIP domain in the RDP profile for the user to route these calls to the different trunk - and remap the domain back to normal Lync SIP domain via Lua script just before sending to Lync. Would work but not very clean.
      Well ideal would be if this routing happens natively in Lync.

      Michael

      Delete
    3. UPDATE:
      I raised a case with Premier support and the engineer has lead me to add UserServices in the SIP Trace. This helped us find this error:
      “Exit: Port already present; and it is not 5061; reject request”

      After changing the SIP Request Uri to port 5061 on Cisco side, the issue was resolved and calls now succeed in all cases - does not matter in what pool the user is.

      I conclude that this configutation works perfectly and provides exactly the capability that we needed. You get the best of both Lync and Cisco.

      Delete
    4. Thanks for the update. Its a great way to configure the environments when you have an existing legacy Cisco install and layering on UC with Lync.

      Delete
    5. Hi Michael,

      I am investigating your issue a little further. Wondering if you could email me how you exactly addressed this issue. chris.norman@hotmail.com

      Let me know how you setup port 5061 on the mediation server side. I am assuming that because you has a separate mediation server that you could set the listening port to 5061 but I want to make sure. If you can send me some screenshots of your setup that would be great.

      Delete
    6. Hi Chris ,

      We've been planning to configure setup between Lync 2013 and CUCM. please send me some screenshots related setup. maxcoder1 at gmail dot com

      Delete
  2. Talking about SIP-URI dialing feature, can I dial any desired SIP-URI on world with it without preconfiguring each domain in dial plan?

    ReplyDelete
  3. Hello again Chris,
    Thanks for your help (previous writeup on the SIP-URI dialing). Lab setup was working great, however a Cisco person told us there is a limited number of RDP available... this lead us to try RCC (since they are installing CUPS). it worked nice, other than losing the ability to use the Lync soft phone when dialing out. Then I saw this update with the addition of the ms-skip-rnl in the lineURI. When i tried to add this entry to an existing user, it returned an error.
    I don't have DID numbers assigned, I also don't have extensions assigned. Will this command work without extensions?

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Chris, Anonymous, We were facing the same issue with the Invite coming in as user@domain.com:5060 from CUCM. When you stated this was fixed by setting the port to 5061 I presumed you had a mediation pool so could use 5061. We don't have mediation pools with each our pools so we looked on the Cisco side and came up with the following normalization script to associate with the trunk to change default 5060 to 5061.

    M = {}
    function M.outbound_INVITE(msg)
    local method, ruri, ver = msg:getRequestLine()
    local uri = string.gsub(ruri, "5060", "5061")
    msg:setRequestUri(uri)

    end
    return M

    ReplyDelete
    Replies
    1. Thanks Simon. Looks like a great addition to the solution. I will post it up as an update when I get a chance to collect some more info on how to implement.

      Delete
  6. Hello Dave,

    I have tried to send u n email. But address seem to be wrong. Can you please take contact with me on evyn.valayten@eis.mu. I really need your expert advise with lync 2013.

    Cheers,
    Evyn

    ReplyDelete
  7. Hi,
    Great blogs! They have been very helpful to me as Ii am in the middle of a Lync 2013 - Cicso integration project (about 1000 users with a pilot of 250 lync plus cals).
    Currently our Cisco partner is only pushing the interop capabilities of RCC with our cisco environment, which to me totally defeats the purpose of the advantages that lync brings over jabber/webex.
    I think I will trial the 3 integration methods that I have found – cucilync, rcc and dual call controls (with sip uri dialling!  )
    What sort of click to call control is possible between lync and the cisco handsets with a dual call control configuration?
    On a side note, your fantastic blog has inspired me to write one about a win I just had with publishing lync via citrix xenapp. I have gotten the vdi plug in to work while delivering a rich ICA experience from our xenapp servers (despite a distinct lack of good blog articles about it).

    Cheers
    Matt

    ReplyDelete
  8. Hello Chris,

    Thank you very much for the great step-by-step documents. I am now working on integrating LYNC2013 and CUCM 8.6.2. The outgoing calls from LYNC are working perfectly well, but the incoming i cannot make to ring simultaneously on the Cisco phone and LYNC. I configured the second trunk exactly as you've proposed but it does not work. It rather rings ONLY on the Cisco phone with enabled remote destination, but if the Cisco phone is off, the call fails. I tried to trace the call to SIPUri trunk but could not even find the trunk name in the tracelogs on call mananger. Can you, please, advice me where to look for the further investigations as i love the idea of SIP URI remote destination. DO not want to deal with a separate extensions pool for dual-forking.

    Thank you very much in advance,

    Best regards,

    Dmitry. (klimed@gmail.com)

    ReplyDelete
  9. We need a consultant who can help us to make this configuration work. Please, send a mail to dklimenkov@temenos.com.

    Best regards,

    Dmitry Klimenkov

    ReplyDelete
  10. Thanks for such a great integration article - I have this working (mostly) with Lync 2013 and CUCM 9.1.2. There is a delay for some users when calling their Cisco extension and having RDP ring their Lync phone. We are seeing a few "SIP/2.0 403 Forbidden" with a reason of "Application accepts invitations via static registration only." using ocslogger / snooper. I can't find anything useful through Google, wondering if you have ever see this error / delay or have any suggestions?

    Thanks!

    ReplyDelete
    Replies
    1. Great article!

      Hey Tony did you sort this out i also have the same problem with 9.1.2.

      Delete
  11. Can you please help to transform Request URI from:

    INVITE sip:6101;phone-context=cdp.udp@umc.ua:5060;maddr=172.20.245.196;transport=udp;user=phone;x-nt-redirect=redirect-server SIP/2.0

    to that Request Uri:

    INVITE sip:6101@172.20.245.196:5060 SIP/2.0

    ReplyDelete
  12. It is really not easy to do this kind of configurations but mostly companies have experts who do only this kind of work, I think they done best what they can. As I am a user of IP phone Grandstream DP715 when ever I have an issue the company who is providing me services they come to me and resolve issue. Hope they will come back to you.

    ReplyDelete
  13. Hello Chris,

    I agree with everyone here that your blogs are fantastic. Thank you for sharing your knowledge. We went ahead and followed this guide and setup SIP URI dialing. It is working beautifully. I noticed something about the call flow and was wondering if this is expected or not. So, the scenario is that we have two Lync users in the data center, User1 and User2. User1 dials User2's extension in his Lync client and this in turn rings User2's Cisco phone and User2's Lync client. If User2 answers the Lync client, the the snooper trace shows that the ICE negotiation is happening with the Mediation Server's IP address. I was assuming the ICE candidate IP address would be that of User1. So, the media flow is happening through the Mediation Server in this scenario. Is that expected behavior when using SIP URI dialing method and RDP ? Thanks in advance.

    ReplyDelete
  14. Hello, in a semi-related question, has anybody gotten Twilio SIP to work for inbound directly to CUCM without CUBE? I got it working outbound perfectly (for use by lync 2013) thanks

    ReplyDelete
  15. Hi Chris,

    A quick question. If the user hits ignore in Lync when a call comes from CUCM via his RDP Lync sends back a SIP DECLINE message and CUCM drops the call for good. Normally the expected behavior is if a remote destination rejects the call it should still ring the main Cisco phone until NOAN timer expires. Any comments on this and how can we fix it?

    Thanks a lot!

    ReplyDelete

Note: Only a member of this blog may post a comment.