Moving Custom OCS Dial-in Access Number Contacts to Lync

This was interesting case I thought I'd share - in OCS 2007 R2 when you created a dial-in access number you were presented with this screen:

If you accepted the default configuration and SIP URI (a random GUID), the SIP enabled contact representing this dial-in access number would be stored within Active Directory in the Configuration context. Specifically, it would be placed in CN=Application Contacts,CN=RTC Service,CN=Services,CN=Configuration,DC=ptown,DC=local.

Or, if you pressed the Advanced button you could specify an existing contact object to associate with the dial-in number. This allowed you to create contacts in advance which would represent these numbers. This process worked just fine in OCS and really had no negative impact.

However, when you go to move these custom contact objects to Lync as part of your migration process you’ll find Lync doesn’t really “see” these objects. If you run Get-CsApplicationEndpoint you should notice that Lync will only return objects within the Application Contacts container mentioned previously. Any SIP-enabled contact objects outside of this location are not returned.

As an added bonus you can actually find (and move!) these objects by specifying their entire DN when running Get-CsApplicationEndpoint. But after successfully moving these endpoints you’ll notice they still do not appear as a dial-in number in Lync. So even though the contact is now homed to the Lync pool, the server still only considers objects in the Application Contacts container a valid dial-in access contact and these numbers don't go out on meeting invites.

In order to get these numbers fully moved to Lync you’ll need to do the following:

  1. Leave the contact object homed to the OCS pool
  2. Disable the contact for OCS
  3. Recreate the dial-in access number within Lync

Also, be sure to pay attention to the migration docs and only perform these steps after all users are moved to the Lync pool. If you disable the OCS contact before that point any new meeting invitations created by a user on the OCS pool won’t have the deleted dial-in number available.

Lync Dial-In Conferencing Static Route Configuration

Something I haven't seen documented with Lync Server 2010 so far is the dial-in conferencing configuration required to enable outbound dialing. This allows non-Enteprise Voice Lync, Lync Web App, or Lync Attendee users to join the conference by having the conferencing service call outbound to them as opposed to them manually dialing in to the conference and entering conference ID and passcodes.

In OCS 2007 R2 this was accomplished by adding a static route from the Front-End pool to a Mediation server for phone URI requests. The concept in Lync is the same, but there is a slight difference in ports used because the Mediation service in Lync now listens on Port 5070 for server-to-server traffic as opposed to 5061 in OCS 2007 R2. The route configuration also varies a bit. In the example below I have a Mediation server role collocated with my Front-End pool, fepool.confusedamused.com.

As Mike Stacy has already pointed out, the GUI for configuring static routes is now gone and must be done through the Lync Management Shell. To get started, we need to create the route statement and store it in a temporary variable. Replace the destination with your Mediation server pool FQDN and the matching URI with your own SIP domain:

$route = New-CsStaticRoute -Destination "fepool.ptown.local" -Port 5070 -MatchUri "confusedamused.com" -MatchOnlyPhoneUri $true -TLSRoute -UseDefaultCertificate $true -ReplaceHostInRequestUri $true

Then, we can assign the route to the global configuration:

Set-CsStaticRoutingConfiguration Global -Route @{Add=$route}

You should see the Front-End pick up this change within 5 minutes (another nice change over OCS 2007 R2) with an event log entry:

The observant folks here who have configured this in OCS 2007 R2 might have noticed the Replace host in request URI option wasn't necessary back then. What I've found is that not selecting this option in Lync causes the calls to fail for non-Enterprise voice users. The SIP invite that gets sent to a Mediation server will typically look like this for an outbound call when the Replace host in request URI option is not selected:

INVITE sip:+12223334444@confusedamused.com;user=phone SIP/2.0
FROM: <sip:eddie@confusedamused.com;gruu;opaque=app:conf:audio-video:id:GJ5CPPSK>;epid=C68D6F45DA;tag=7ee8ecfbea
TO: <sip:+12223334444@confusedamused.com;user=phone>

This request will actually fail and you'll see a SIP 488 Not acceptable here error message, followed by a SIP 503 Service unavailable error on the Mediation server. If you look at the trace you'll find the following detailed error:

ms-diagnostics-public: 10025;reason="Gateway peer in outbound call is not found in topology document";component="MediationServer"

What this boils down to is the call won't route because the host the INVITE is addressed to (@confusedamused.com) isn't actually part of the topology. If the Replace host in request URI option is selected, the SIP INVITE sent to the Mediation server replaces the @confusedamused.com with the actual destination in our route, @fepool.ptown.local, as seen below. Notice the difference in the first line, where the Mediation pool name has now replaced the previous host of just confusedamused.com. This call will be successful:

INVITE sip:+12223334444@fepool.ptown.local;user=phone SIP/2.0
FROM: <sip:eddie@confusedamused.com;gruu;opaque=app:conf:audio-video:id:F0GS16HB>;epid=BFDBD3B7B8;tag=42bd8c5b8
TO: <sip:+12223334444@confusedamused.com;user=phone>

I'll throw out a disclaimer that the officially documented process may be different and that I may have to update this later, but I wanted to at least share what I've got working so far.