Lync 2010 Mobility – Push Notifications

Through reverse engineering here is my take on how Lync Mobility push notifications function for Apple and Windows Phone devices. This article assumes that push notifications is configured and the user is granted the policy to permit push notification (default). Push notifications is only applicable when the application is running in the background (inactive). When the Lync Mobile application is active, HTTPS communications via the Reverse Proxy is used. As you’ll see below, the reverse proxy continues to be the transport for IM conversations, and the push notification is simply the notification service for the device.

How it works

The following diagram shows how the Lync Mobile client functions with Lync Push Notifications.

1 The device requests a push notification URI from the Push client service.
2, 3 The Push client service then negotiates with the Microsoft Push Notification Service (MPNS) or the Apple notification service and returns a notification URI to the Lync Mobile client application (2 and 3).
4 The Lync Mobile client application then sends the URI to the Lync front-end via the reverse proxy (HTTPS).
5 When the user then receives an instant message the internal Lync server, the Lync server knows the user is currently active for Push Notifications. The Lync server sends a SIP request via the Edge to the Microsoft Lync Push Notification Service (Push Notification Clearing House). This Lync Online clearing house forwards the request to the Microsoft Push Notification Service (MPNS)
6 The Microsoft Push Notification Service in turn routes the push notification to the Lync Mobile application running on a Windows Phone device (or an Apple device via the Apple notification service).

Sending an Instant Message to a Push User

Take a scenario of a new Instant Message to a Lync Mobile user who is active for Push notifications. The Instant Message is generated from the Lync Front-end and an interception by the MCX Component initiates the SIP request to the Lync Online Clearing House (as shown in Step 5). The Lync Online clearing house receives the interpreted message using SIP and translates that to a HTTP request to the Microsoft Push Notification Service. The payload of this message includes the URI of the device (push notification URI) along with instructions for the Lync Mobile client. This includes information such as:

  • The visual update to the Lync Mobile application tile (ie message count)
  • A toast notification for the device with a preview of the message.

The Microsoft Push Notification Service sends a response code to the Lync Online Clearing House which converts back to SIP for a notification back to the Lync front-end via the Lync Edge. The message is delivered to the mobile device at the next possible opportunity. However, the Microsoft Push Notification Service does not provide an end-to-end confirmation that your push notification was delivered to the device. Hence the message notification back to the sender, though it is likely it was actually delivered to the device.

Attempt 1: IM Not Acknowledged

Send an IM to a mobile user – Waiting for a response…

Response not acknowledged by the mobile user
Attempt 2: IM Acknowledged

Send an IM to a mobile user – Waiting for a response…

Response acknowledged by the mobile user (Lync client lauched/resumed)

Looking at the SIP Stack, you see that in all cases the Lync front-end sends a simple message request to the Lync Online Clearing House. You can surmise that the message body in this request includes XML information pertaining to the new invitation, including:

  • Importance
  • Conference or Not
  • Invitation Modality, eg Text, Call etc
  • Message Body, eg “Hi Brendan”
  • Timestamp

Peer: sipfed.online.lync.com:5061

Message-Type: request

Start-Line: MESSAGE sip:push@push.lync.com SIP/2.0

From: “Brendan Carius”<sip:McxUsere70bc1dd4f9f40fead43db9502b00564brendan.carius@kloud.com.au>;epid=3470B22863;tag=b6d38c5ec0

To: <sip:push@push.lync.com>

CSeq: 21319 MESSAGE

Call-ID: e16e70125be6482ea259f9a1e0bf06c9

Via: SIP/2.0/TLS 155.25.24.23:22360;branch=z9hG4bK3753723F.FE580C552FA25BA9;branched=FALSE;ms-internal-info=”djml34b0vzwRElFhOibGyaNltxs2YuxJMSXdKiHG2lPvxVDFj-w3gGawAA”

Max-Forwards: 68

Via: SIP/2.0/TLS 192.168.1.15:55243;branch=z9hG4bK6C6FDB33.5F9554A4FC3B7C7A;branched=FALSE;ms-received-port=55243;ms-received-cid=562400

Via: SIP/2.0/TLS 192.168.1.15:55241;branch=z9hG4bK2acd82a;ms-received-port=55241;ms-received-cid=13A0800

CONTACT: <sip: atl-edge-001.litwareinc.com;gruu;opaque=srvr:McxExternal:AbaS4im61lGvIsQfMHKgsQAA>;IsOutsideVoiceB2B;automata;actor=”attendant”;text;audio;video;image

CONTENT-LENGTH: 830

SUPPORTED: gruu-10

USER-AGENT: RTCC/4.0.0.0 McxService/4.0.0.0

CONTENT-TYPE: application/vnd.microsoft.lync.pushNotification+xml; charset=”Unicode (UTF-8)”

ms-asserted-verification-level: ms-source-verified-user=verified

Message-Body: —-****MESSAGE BODY DELETED****—-

$$end_record

And, the Response OK.

Peer: lyncse.kloud.net:55243

Message-Type: response

Start-Line: SIP/2.0 200 OK

From: “Brendan Carius”<sip:McxUsere70bc1dd4f9f40fead43db9502b00564brendan.carius@kloud.com.au>;tag=b6d38c5ec0;epid=3470B22863

To: “Push Notification Clearing House”<sip:push@push.lync.com>;tag=f1cbe21fcc

CSeq: 21319 MESSAGE

Call-ID: e16e70125be6482ea259f9a1e0bf06c9

Via: SIP/2.0/TLS 192.168.1.15:55243;branch=z9hG4bK6C6FDB33.5F9554A4FC3B7C7A;branched=FALSE;ms-received-port=55243;ms-received-cid=562400,SIP/2.0/TLS 192.168.1.15:55241;branch=z9hG4bK2acd82a;ms-received-port=55241;ms-received-cid=13A0800

CONTENT-LENGTH: 0

CONTENT-TYPE: application/vnd.microsoft.lync.pushNotification+xml; charset=”Unicode (UTF-8)”

SERVER: RTCC/4.0.0.0 PnchApplication

ms-diagnostics-public: 30000;Reason=”Success”

ms-edge-proxy-message-trust: ms-source-type=DirectPartner;ms-ep-fqdn=atl-edge-001.litwareinc.com;ms-source-verified-user=verified;ms-source-network=federation

Message-Body: –

$$end_record

So as per above, the notification service simply sends a response to Lync to notify that the MS Push Notification Service successfully received the message. This does not indicate whether the device actually received the invitation.

This was an out of band message generated by the MCX application on the Lync Front-end based on a new instant message conversation being generated for the Lync Mobile user. Therefore we have the original SIP dialog between Alice and Bob still occurring. As per any SIP dialog, the initial INVITE responses are TRYING (100) then RINGING (180), assuming all is good.

In ATTEMPT 1, the Lync Mobile user does not acknowledge the new invitation. That is, the person misses the notification and does not launch the Lync Mobile client on the device. This results in a REQUEST TIMEOUT (408) response to the original SIP INVITE. The sender receives the warning of “This message may not have been delivered to….”.

However, in ATTEMPT 2 above, the Lync Mobile user does acknowledge the invitation and does launch the Lync Mobile client when they receive the Push Notification. In this case the response is a 200 OK rather than the timeout. Therefore the “waiting for response…” text is removed from the Instant Message conversation window and the Instant Message conversation is conducted.

The Push Notification service simply operates as a means of notifying the Lync Mobile client of a new invitation (instant message). The Notification Service provides the 1st line of the IM conversation and updates the Lync Mobile tile with a missed conversation / call count. The instant message conversation between to a Lync Mobile client user is always performed over HTTPS through the Reverse Proxy to the MCX Service on the Lync Front-ends.

Push Notification Synthetic Transactions

An initial test of the push notification service is to run a Test-csMcxPushNotification. To the cmdlet, simply pass the Lync Edge internal FQDN.

Test-CsMcxPushNotification -AccessEdgeFqdn “atl-edge-001.litwareinc.com”

If configured correctly, the result will return:

PS C:\> Test-CsMcxPushNotification -AccessEdgeFqdn “atl-edge-001.litwareinc.com”
TargetFqdn :
Result : Success
Latency : 00:00:00
Error :
Diagnosis :

Looking at the SIPStack on the Edge you will see an outbound request to the Push Notification clearing house (push.lync.com):

Trace-Correlation-Id: 999570620

Instance-Id: 000E445E

Direction: outgoing;source=”internal edge”;destination=”external edge”

Peer: sipfed.online.lync.com:5061

Message-Type: request

Start-Line: MESSAGE sip:push@push.lync.com SIP/2.0

From: <sip:McxUser26df046c-84c7-4ea2-b506-a962bc731b92@kloud.com.au>;epid=40CA3D275B;tag=00c7e644

To: <sip:push@push.lync.com>

CSeq: 1 MESSAGE

Call-ID: 473648cd73334c94a11b8140d3bfaabd

Via: SIP/2.0/TLS 155.25.24.23:22321;branch=z9hG4bK9C46E3C8.30D9E486908D36CB;branched=FALSE;ms-internal-info=”bjLizr_XsA-roWQDzGqWJn-x8229wLtllPfCz1SYhZ2lCG5Nkww3gGawAA”

Max-Forwards: 69

Via: SIP/2.0/TLS 192.168.1.15:54018;branch=z9hG4bKbec5f4fe;ms-received-port=54018;ms-received-cid=55E500

CONTACT: <sip:atl-edge-001.litwareinc.com;transport=Tls>

CONTENT-LENGTH: 434

USER-AGENT: RTCC/4.0.0.0

CONTENT-TYPE: application/vnd.microsoft.lync.pushNotification+xml; charset=”Unicode (UTF-8)”

ms-asserted-verification-level: ms-source-verified-user=verified

Message-Body: —-****MESSAGE BODY DELETED****—-

$$end_record

In response, the Push Notification clearing house should respond with a successful processing of the synthetic transaction:

Trace-Correlation-Id: 999570620

Instance-Id: 000E445F

Direction: incoming;source=”external edge”;destination=”internal edge”

Peer: sipfed.online.lync.com:5061

Message-Type: response

Start-Line: SIP/2.0 200 OK

From: <sip:McxUser26df046c-84c7-4ea2-b506-a962bc731b92@kloud.com.au>;tag=00c7e644;epid=40CA3D275B

To: “Push Notification Clearing House”<sip:push@push.lync.com>;tag=8edaf7323d

CSeq: 1 MESSAGE

Call-ID: 473648cd73334c94a11b8140d3bfaabd

Via: SIP/2.0/TLS 155.25.24.23:22321;received=111.221.22.73;branch=z9hG4bK9C46E3C8.30D9E486908D36CB;branched=FALSE;ms-internal-info=”bjLizr_XsA-roWQDzGqWJn-x8229wLtllPfCz1SYhZ2lCG5Nkww3gGawAA”;ms-received-port=22321;ms-received-cid=15225400,SIP/2.0/TLS 192.168.1.15:54018;branch=z9hG4bKbec5f4fe;ms-received-port=54018;ms-received-cid=55E500

CONTENT-LENGTH: 0

CONTENT-TYPE: application/vnd.microsoft.lync.pushNotification+xml; charset=”Unicode (UTF-8)”

SERVER: RTCC/4.0.0.0 PnchApplication

ms-diagnostics-public: 30007;Reason=”Push Notification synthetic transaction succeeded

ms-asserted-verification-level: ms-source-verified-user=verified

Message-Body: –

$$end_record

I hope that helps in understanding the function of the Push Notification service for the Lync Mobile client and assists you in troubleshooting any issues with the notification service.

Lync 2010 Mobility – Do I need lyncdiscoverinternal?

Lync Server 2010 Mobility supports an internal and an external automatic discovery record. As described in this post, the mobile client signs-in by performing a DNS query for lyncdiscoverinternal.<your sip domain>. If this record is not present (does not resolve), the client attempts lyncdiscover.<your sip domain>. This design approach aligns to the Lync 2010 client software for Windows. First an attempt for the SRV record _sipinternaltls._tcp.<your sip domain>, followed by _sipinternal.tcp, followed by _sip._tls, then the A record fallbacks. This approach is great for Windows PCs, and allows Split-DNS configurations to bounce client systems to either the Internal Front-end Pool or the External Access Edge on the Internet. The Windows PCs are managed and Group Policy can add trusted root certificates to the computer certificate store.

But thinking about Mobile clients specifically, they do not have this Group Policy deployment luxury. I’m trying to determine the advantage of ever defining lyncdiscoverinternal.<your sip domain> in the internal DNS namespace. Typically, the Lync Web Services certificate assigned to the Front-end Pool is issued by an internal certificate authority. This Root Certificate Authority certificate is not present on Mobile devices, therefore will be untrusted. The Lync mobile client would not be able to sign-in, unless the internal root certificate was pre-installed on the device.

As you are unable to simply deploy the root certificates to your fleet of mobile devices, bouncing all the devices to lyncdiscover.<your sip domain> looks to be the most appropriate approach. This will typically require routing and access rules to allow internal traffic a connection to the Reverse Proxy server.

Lync 2010 Mobility Sign-in Internals

The best way to understand the internals of a product or service is to reverse engineer the process using logging and network captures. Capturing the process end-to-end helps paint a clear view as to what is going. Here is what happens when you sign-in on the Lync Mobile client for Windows Phone.

  1. Enter sign-in information and credentials into the Lync Mobile client. (hmmm, screen crack)

  2. Performs a standard DNS query for lyncdiscoverinternal.<sip domain namespace>.

    If the client is external, this DNS resolution will fail and the client will drop to the next discovery record

  3. Performs a standard DNS query for lyncdiscover.<sip domain namespace>.

    This DNS query will succeed and typically respond with a subsequent query for the value of the lyncdiscover.<sip domain namespace> CNAME entry. In my case, this is the Lync External Web Services URL.

  4. Perform a standard DNS query for external Lync Web services URL and return the IP to connect.
  5. Establish a HTTP and HTTPS connection to the resolved lyncdiscover.<sip domain namespace> location, which will be a TMG or other reverse proxy.
  6. As all good citizens should, our TMG listener switches HTTP inbound traffic to HTTPS.

    We’re now only talking to TMG using HTTPS. As a result a bunch of stuff happens on the wire that I cannot see, so look at TMG logs to get further information

  7. The TMG request is destined to lyncdiscover.<sip domain namespace>/?sipuri=<your sip address>
  8. The client is provided the Lync external web services URL, which will be used for all further communications.
  9. The first activity is to authenticate the client. A Web Ticket request is raised to obtain a client certificate for authentication.

     

    With authentication complete, Lync sign-in and in-band provisioning occurs. To capture this information, I’m looking at the MCXService and SIPStack traces at sign-in.

     

  10. The REGISTER request comes into the Lync Front-end as using the McxSipExternalListeningPort, 5087 (CONTACT: <sip:<<LYNC FRONT-END POOL>:5087)

     

  11. First and foremost, am I granted a mobility policy? sip:brendan.carius@kloud.com.au is enabled for mobility: True… Phew.

     

    To grant a mobility policy, assign the policy scope Global, to a Site, or to a User. For example: Get-CsUser -filter {samaccountname -eq “bcarius”} | Grant-CsMobilityPolicy -PolicyName All_Mobility. The “All_Mobility” policy grants Mobility and Outside Voice Control (get-csmobilitypolicy).

     

  12. The standing in-band provisioning occurs on the Lync front-end and I expect MCX is parsing this provisioning to provide the Lync Mobile client only what is requires. This includes:
    1. My Voicemail URI
    2. Whether I’m allows simRing, callForwarding, delegation, team call,
    3. The Address Book, Group Expansion, Location Information URLs
    4. Contact and photo display policies
    5. Mobility policies (outside voice, push notification etc)
    6. And my Dial Plan, ahhh wonderful, a consistent dialing experience to when I’m in the office, this is excellent!!!
  13. I now need to figure out if I am a push or pull sorta guy. If I am enabled for PUSH notification, I need to establish a subscription to the Microsoft Online Push Notification Service. If I’m a Pull sorta guy, then my TMG server with GET/POST requests will be apples.

     

  14. From here I’m subscribed and ready to use Lync Mobile, my buddy list and contact cards are retrieved.

Lync 2010 Mobility Configuration Overview

Lync mobility requires the installation of cumulative update 4 across your Lync server infrastructure. To install CU4, visit here. Once CU4 is deployed, you’re ready to configure the mobility service. You can download the Mobility deployment guide here. A high level summary is:

  1. DNS: Create an External DNS CNAME.

    Create CNAME Lyncdiscover.<your sip domain> that resolves to your external web services.

  2. Configure Ports: Configure Ports for the Mobility Service

    Set-CsWebServer –Identity <name of pool> –McxSipPrimaryListeningPort 5086

    Set-CsWebServer –Identity <name of pool> –McxSipExternalListeningPort 5087

    Enable-CsTopology –verbose

  3. Install Components: Install the Mobility and Lync Automatic discovery services

    On each front-end and director run McsStandalone.msi to install the Mobility Service and the Autodiscover Service. If you’re Windows Server 2008 (not Windows Server 2008 R2) you need to manually modify C:\Windows\System32\inetsrv\config\applicationHost.config. Refer to here.

  4. Update Certificates: Update certificates subject alternate names

    As the mobility service has added lyncdiscover.<your sip domain> a new subject alternate name is required on the Reverse Proxy certificate. There are multiple options in publishing the new service using the Reverse Proxy, but the easiest would be to:

    1. Request a new Reverse Proxy certificate that adds lyncdiscover.<your sip domain> to the subject alternate name list.
    2. Install the new certificate on the Reverse Proxy
  5. Update Reverse Proxy: Update the Reverse Proxy Listener and Web publishing rule.

    It is easier to update the using Lync external web services listener and publishing rule to support mobility.

    1. On the Listener – Select the new Certificate
    2. On the Web Publishing Rule – Add lyncdiscover.<your sip domain> to the list of Public Names.

    As long as the Path configuration is set to /*, it will be functional.

  6. Configure Push: Configure Push Notifications

    To support push notifications, execute the following:

    1. New-CsHostingProvider –Identity “LyncOnline” –Enabled $True –ProxyFqdn “sipfed.online.lync.com” –VerificationLevel UseSourceVerification
    2. New-CsAllowedDomain –Identity “push.lync.com”
    3. Set-CsPushNotificationConfiguration –EnableApplePushNotificationService $True –EnableMicrosoftPushNotificationService $True

Push and client mobility can be restricted using mobility policies if desired.