Microsoft Lync has a rich set of .NET APIs which make it easy to extend the platform and integrate it with other applications. This blog helps explain how to use them.

Skype connectivity and Lync applications

Posted: April 29th, 2013 | Author: | Filed under: Lync Development | Tags: | No Comments »

Earlier this year, at the Lync Conference, Microsoft announced (and demonstrated) the new connectivity between Lync and Skype, to be fully operational in June of this year. Skype and Lync users will be able to see one another’s presence, and IM and call one another. Video calling between Lync and Skype users will follow sometime later. There’s been a lot of interest in Skype connectivity, along with some questions about what the applications will be. In my mind, a big part of the value of Skype connectivity to Lync lies in the potential for opening up Lync applications – IVR systems, auto-attendants, contact centers, and the like – to the public via the Skype network. This has three high-level advantages:

  • Convenience for consumers who prefer Skype over PSTN calls, or who are initiating the call through your website
  • Cost savings, because the calls aren’t going over the PSTN at all
  • Ability to offer more sophisticated customer service experiences, using IM, presence, web resources, or the known Skype identity of the user

I’ve done a few presentations recently on this topic, and some people have asked for more technical details on how to handle communication between Skype users and, say, a UCMA application, so I thought I would write up a post to share what I know so far about Skype connectivity and Lync development, and what you can test out today.

To reiterate, this functionality is not officially available until June 2013, so while some pieces seem to be working now, there is no guarantee that they will work every time you try, and so I strongly recommend that you not use them in any production system until they are officially enabled.

Prerequisites

Button to sign in to Skype with a Microsoft account

Before you can do anything with Skype connectivity, you need to meet a few conditions. First of all, you need an Edge Server in the environment you are testing in, and the public IM connectivity (a.k.a. PIC) feature must be enabled for the Lync users you are testing with. At the moment, Skype connectivity on the Lync side works more or less exactly as MSN/Live Messenger connectivity did previously, so everything you need in order for Live Messenger connectivity to work is also required for Skype connectivity.

On the Skype end, you can only communicate with Lync users if you are signed in with a Microsoft account (rather than an ordinary Skype Name and password). In other words, when you open the Skype client, you should be clicking on the “Microsoft account” button (screen shot to the right) on the sign-in screen, and signing in with Microsoft account credentials.

Adding contacts and making calls with Skype URIs

The first issue you will face when trying to test a Skype to Lync call in your own environment is that there is currently no way to add a Lync contact to your Skype contact list. Today, if you try to type in the SIP URI of a Lync user when adding a contact to Skype, it will try to search for a matching Skype user rather than giving you the option of adding a Lync contact. So it’s necessary to use a workaround to add a Lync contact.

The workaround is actually pretty simple. Skype allows you to use specially formatted URIs (Skype URIs) to perform operations like placing a call or adding a contact. Even though there’s no UI yet for adding or calling Lync contacts, the Skype client is capable of handling those operations, and you can kick them off using Skype URIs.

For example, let’s say you want to add a Lync user to my contact list with the SIP URI sip:jdoe@example.com.

Once the Skype client is running and signed in, open your web browser and enter the following in the address bar:

skype:2:jdoe@example.com?add

You’ll get a couple of security prompts, which you can turn off if you like, and then the Skype client will add the Lync user to your Skype contact list. Now you can right-click on the Lync contact and choose Call to place an audio call via Skype-Lync connectivity, or Send an IM to send instant messages.

If you don’t want to add someone to your contact list, but just want to place a call, you can drop off the ?add at the end of the Skype URI:

skype:2:jdoe@example.com

This will tell Skype to place a call but won’t cause the contact to be added to the contact list. Besides using this approach to test Skype connectivity, you can use a Skype URI like this if you want to put a link on your website to allow people to place a call to you via Skype.

Calling a UCMA application from Lync

Placing calls from Skype to Lync and Lync to Skype can be fun, and makes for a good demo, but what if you want to open up your support hotline, powered by a UCMA application, to Skype users? How do you configure a UCMA application so that Skype users can reach it?

I have great news for you: assuming Skype connectivity works in your environment for ordinary Lync users, there’s nothing else you need to do to enable it for UCMA applications. Just make sure that the trusted application endpoint that you want to expose to Skype users has an external access policy that permits PIC communication.

Assigning an external access policy to a trusted application endpoint can be a bit confusing, so I’ll review how to do it here. First of all, if you want to check which external access policy is currently assigned to a trusted application endpoint, you can’t see this in the normal output from Get-CsTrustedApplicationEndpoint; you need to use the following command in Lync Management Shell:

Get-CsTrustedApplicationEndpoint -Identity sip:endpoint@example.com | Select-Object *

This will output every property of the trusted application endpoint, including the external access policy.

To assign a new external access policy, you can use the same command you would use for a Lync user:

Grant-CsExternalAccessPolicy -Identity sip:endpoint@example.com -PolicyName MyPolicyName

Obviously, make sure the policy you are assigning has PIC enabled. I won’t go into how to modify the policy itself here, since there’s plenty of documentation on how to do that.

Once you have the appropriate external access policy assigned, you should be able to call UCMA applications using the same Skype URI technique described above.

Identifying calls from Skype users

Now that your UCMA application can receive calls from Skype users, how do you distinguish them from calls coming from, for instance, internal Lync users, or federated users?

I mentioned before that Skype connectivity uses a lot of the infrastructure from Live Messenger connectivity. If you look at the From URI on a call coming from a Skype user, you’ll see something like this:

sip:user(example.com)@msn.com

The domain in parentheses is the actual domain from the user’s email address, so in this example the email address on the user’s Microsoft account is user@example.com. So, to identify Skype (and Live Messenger) calls, you can check for the domain msn.com on the SIP URI; if it’s there, you have either a Live Messenger call or a Skype call.

Keep in mind that there’s no guarantee this won’t change later, but as far as I’ve been able to tell, it reliably identifies calls from Skype users for the time being.

Dissecting a SIP INVITE from a Skype user

I promised technical details, so let’s look now at an example INVITE message from a call placed from a Skype user to a Lync user. Here’s the entire message:

INVITE sip:user@example.com SIP/2.0
Start-Line: INVITE sip:user@example.com SIP/2.0
From: <sip:user(example.com)@msn.com>;epid=2539071F25;tag=7166e331a
To: <sip:user@example.com>
Call-ID: f82fcb08-2095-46af-888b-0869f3f32fd3
CSeq: 20415 INVITE
Contact: <sip:sn20s00med03.infra.lync.com@online.lync.com;gruu;opaque=srvr:MediationServer:aXTdrLsH5l-BH67UyIuQpwAA;grid=a6680a354e78424cae0b3241de377835>
Via: SIP/2.0/TLS 192.168.100.0:61241;branch=z9hG4bK28328D48.3099D438C1294CF5;branched=FALSE
Via: SIP/2.0/TLS 157.0.0.0:60517;branch=z9hG4bKEC925B93.9F787FF972469CF9;branched=FALSE;ms-internal-info="ckmnl32XuJMJH3virth0ihz93rnI8KnEgW7OM9MQelrVD5f3ifc8U1YQAA";ms-received-port=60517;ms-received-cid=5128500
Via: SIP/2.0/TLS 157.0.0.0:62983;branch=z9hG4bK66EA4B88.0543C53859478CF9;branched=FALSE;ms-received-port=62983;ms-received-cid=488C7F00
Via: SIP/2.0/TLS 157.0.0.0:57460;branch=z9hG4bK41799a16;ms-received-port=57460;ms-received-cid=571200
Record-Route: <sip:edge.example.com:5061;transport=tls;lr>;tag=FADBA4EDD0E3674D3FDED518A20E47A9
Record-Route: <sip:federation.messenger.msn.com:5061;transport=tls;epid=2539071F25;lr;ms-key-info=AAEAAXqing1AxSJ6hELOARzXMPrLNgxR-H8e9Ffw7BRLbWIbjlYjifJsKUt0d02_0ZT_7zr45lLHDiwfEXg75-a__b-79UZ6X_j2PGfjyncCccgrVdrq50t2aUobq9mSpIz-hIvLKkw-V96KMRGSGSBCoUDUDdo0eMqmK5zxlUFaX3xeVjltQepg8E2ygfyKD3YF4wwCLZSlk0N_ndfgN0USxDAbrlDr_w0Qh6Im-RlGb7ycco8St00Hy_YorVqaIjMEdrPnk9j9ehoOYq-_GvnQNgH3bqzF2v7f-qgW6o9QOt_uaDM6Ds0eKF53HtISazKyJiPERsegt6nyuYi52dkm1tCEP5cIlE6lkx6N3PgNl0G6TgbiLh6govEfZ5VGTylMeptYqlSNC2OwlQ4xHQFVJsvFddQB-3aVVHSPkaBEjQW4DDqHZxiCzHeZ-tJAi-sFMX3lKaMydVat89zu1mHH6nNgwvcwEQlX3y7RMzMtGr00M6FXyRKWKEwpLo2OA1oupm1F0hyRKDTeZEy_LHb_rZ56EM227bYnWlcjSLe_179-pl6ML3w4uJOak1YfOp08UQjNqtXCWMSb9EwHNEfcYkl8x3hnmeN64gmiFJ-qztyFFs_nao91BtL_ZpakmGr8-7z8N_NNTnEmKKO86TjhcBoAYMw3VXd_SvU9RX7HmwQ8nKhiU79YBs8jmvBN;ms-route-sig=dk5YuW8DWu503daWy66OWqKyIZ-5Kc-iKIrlMKEavvoyL5f3ifL7rfswAA>;ms-rrsig=dkwbTdd2t_AWMtau92380YH-WqJWTAqCodzaOUasbPK_f5f3ifL7rfswAA;tag=2A3EDAB22F1C6A1202525757E2C62192
Record-Route: <sip:sippoolsn20s01.infra.lync.com:5061;transport=tls;ms-fe=SN20S00MED06.infra.lync.com;lr>;tag=512CE64317FC969E2185663B72B8C2AA
Max-Forwards: 67
Content-Length: 4364
Content-Type: multipart/alternative; boundary=KKWiSO6FAnlHya1650XtrmcyOwkz7ktn
Message-Body: 
--KKWiSO6FAnlHya1650XtrmcyOwkz7ktn
Content-Type: application/sdp
Content-ID: <9e5331f5-18cc-4720-af22-de76188280bd>
Content-Disposition: Session;handling=optional;ms-proxy-2007fallback
v=0
o=- 1665 0 IN IP4 157.0.0.0
s=session
c=IN IP4 157.0.0.0
b=CT:1000000
t=0 0
m=audio 50018 RTP/AVP 9 0 8 115 13 118 97 101
c=IN IP4 157.0.0.0
a=rtcp:50019
a=candidate:uHfxpC5Yu329AWHdJ9IyB2p43Sk3+HQy5alRqrpBF7w 1 PF57frcH6o61FPTS51wG3g UDP 0.830 10.0.0.0 54846
a=candidate:uHfxpC5Yu329AWHdJ9IyB2p43Sk3+HQy5alRqrpBF7w 2 PF57frcH6o61FPTS51wG3g UDP 0.830 10.0.0.0 54847
a=candidate:7xqovqccusLiPHK7WkORFM1g2W3uYGCsXRWtmLhyfpg 1 aBBeuUg8ePSM0gdUScH//A UDP 0.840 157.0.0.0 55364
a=candidate:7xqovqccusLiPHK7WkORFM1g2W3uYGCsXRWtmLhyfpg 2 aBBeuUg8ePSM0gdUScH//A UDP 0.840 157.0.0.0 55365
a=candidate:cIDDhFrYWqd9hq0MWkrpP3j5yLhDwMSPCacvhBYeVu4 1 etVlTFPSTUGeS7w3ZtheTw UDP 0.850 157.0.0.0 50018
a=candidate:cIDDhFrYWqd9hq0MWkrpP3j5yLhDwMSPCacvhBYeVu4 2 etVlTFPSTUGeS7w3ZtheTw UDP 0.850 157.0.0.0 50019
a=candidate:SaY89eLdEZaQ/WaxZM/diXe6sTOxUXHmEvrM5C237LQ 1 auF1qI358uo3tHkjKBXzLQ TCP 0.150 157.0.0.0 56418
a=candidate:SaY89eLdEZaQ/WaxZM/diXe6sTOxUXHmEvrM5C237LQ 2 auF1qI358uo3tHkjKBXzLQ TCP 0.150 157.0.0.0 56418
a=candidate:4pdPYJn+vnYhhLbKH0YyxddtNPfZM1nGYQ/sxPUpie8 1 qijjfq+Q7Z2VC1awjgd8kA UDP 0.450 157.0.0.0 52862
a=candidate:4pdPYJn+vnYhhLbKH0YyxddtNPfZM1nGYQ/sxPUpie8 2 qijjfq+Q7Z2VC1awjgd8kA UDP 0.450 157.0.0.0 54878
a=candidate:YAf8pCbg5YOmA5b04f6NgTTtoVCE9cjElbP1x7H9Txg 1 JHsEOfjrCHxN2XfIGpW9Yw TCP 0.250 157.0.0.0 52803
a=candidate:YAf8pCbg5YOmA5b04f6NgTTtoVCE9cjElbP1x7H9Txg 2 JHsEOfjrCHxN2XfIGpW9Yw TCP 0.250 157.0.0.0 52803
a=label:main-audio
a=cryptoscale:1 client AES_CM_128_HMAC_SHA1_80 inline:XzKXZWV4TAZbM6e1v+NAIkdEEWQTSzU9SfZ6snJc|2^31|1:1
a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:ZGxzaJmwYPXAShdAXk5LYN7inCyHPCrwppGMJL8e|2^31|1:1
a=crypto:3 AES_CM_128_HMAC_SHA1_80 inline:2ffhbQFPGI2bdThhrSluK3RBHF0Mcv/k+PNQYJlW|2^31
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:115 x-msrta/8000
a=fmtp:115 bitrate=11800
a=rtpmap:13 CN/8000
a=rtpmap:118 CN/16000
a=rtpmap:97 RED/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16,36
--KKWiSO6FAnlHya1650XtrmcyOwkz7ktn
Content-Type: application/sdp
Content-ID: <38b61b4b-7c2b-45de-9c71-c8014a0532f1>
v=0
o=- 1666 0 IN IP4 157.0.0.0
s=session
c=IN IP4 157.0.0.0
b=CT:1000000
t=0 0
m=audio 49160 RTP/AVP 9 0 8 115 13 118 97 101
c=IN IP4 157.0.0.0
a=rtcp:49161
a=ice-ufrag:AQd3
a=ice-pwd:QrDSkppCN8vz13Ut8fEuyh6+
a=candidate:1 1 UDP 2130706431 157.0.0.0 49160 typ host
a=candidate:1 2 UDP 2130705918 157.0.0.0 49161 typ host
a=candidate:2 1 UDP 2130705919 157.0.0.0 51986 typ host
a=candidate:2 2 UDP 2130705406 157.0.0.0 51987 typ host
a=candidate:3 1 UDP 2130705407 10.0.0.0 55310 typ host
a=candidate:3 2 UDP 2130704894 10.0.0.0 55311 typ host
a=candidate:4 1 tcp-pass 174455295 157.0.0.0 52424 typ relay raddr 157.0.0.0 rport 49710
a=candidate:4 2 tcp-pass 174454782 157.0.0.0 52424 typ relay raddr 157.0.0.0 rport 49710
a=candidate:5 1 UDP 184547327 157.0.0.0 50472 typ relay raddr 157.0.0.0 rport 50802
a=candidate:5 2 UDP 184546814 157.0.0.0 55933 typ relay raddr 157.0.0.0 rport 50803
a=candidate:6 1 tcp-act 174847487 157.0.0.0 52424 typ relay raddr 157.0.0.0 rport 49710
a=candidate:6 2 tcp-act 174846974 157.0.0.0 52424 typ relay raddr 157.0.0.0 rport 49710
a=candidate:7 1 tcp-act 1684796415 157.0.0.0 49710 typ srflx raddr 157.0.0.0 rport 49710
a=candidate:7 2 tcp-act 1684795902 157.0.0.0 49710 typ srflx raddr 157.0.0.0 rport 49710
a=label:main-audio
a=cryptoscale:1 client AES_CM_128_HMAC_SHA1_80 inline:XzKXZWV4TAZbM6e1v+NAIkdEEWQTSzU9SfZ6snJc|2^31|1:1
a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:ZGxzaJmwYPXAShdAXk5LYN7inCyHPCrwppGMJL8e|2^31|1:1
a=crypto:3 AES_CM_128_HMAC_SHA1_80 inline:2ffhbQFPGI2bdThhrSluK3RBHF0Mcv/k+PNQYJlW|2^31
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:115 x-msrta/8000
a=fmtp:115 bitrate=11800
a=rtpmap:13 CN/8000
a=rtpmap:118 CN/16000
a=rtpmap:97 RED/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16,36
--KKWiSO6FAnlHya1650XtrmcyOwkz7ktn--

Mostly it looks like a normal Lync SIP INVITE; after all, the messages are going through the Edge Server. But I want to point out a few things that are interesting. I already mentioned the formatting of SIP URIs for Skype users, which you can see in the From header:

From: <sip:user(example.com)@msn.com>;epid=2539071F25;tag=7166e331a

Another point of interest can be found in the SDP. The “RTP/AVP” here indicates that the media is unencrypted RTP, not SRTP. As far as I can tell, there’s no way so far to get Skype calls to use SRTP, so keep this in mind when deciding what to use Skype connectivity for.

m=audio 49160 RTP/AVP 9 0 8 115 13 118 97 101

Also in the SDP is a line indicating support for the “cryptoscale” method of encryption, a.k.a. Scale-SRTP:

a=cryptoscale:1 client AES_CM_128_HMAC_SHA1_80 inline:XzKXZWV4TAZbM6e1v+NAIkdEEWQTSzU9SfZ6snJc|2^31|1:1

This tells us that, from a media perspective, Skype users should be able to communicate with an audio/video MCU in the same way as an ordinary Lync user. Now, at the moment there’s no way for the Skype client to join a Lync conference; the necessary UI elements aren’t there, for one thing. But where media is concerned, there’s no barrier to having media flowing between a Lync conference and a Skype user, which leaves the door open to some workarounds.

Finally, we can see the codecs supported for Skype to Lync connectivity:

a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:115 x-msrta/8000

G722 is, unsurprisingly, G.722. PCMU and PCMA are G.711 (u-Law and A-Law, respectively), and x-msrta is RTAudio.

Conclusion

With the official availability of Skype connectivity coming in June, there will probably be much more to find out about the inner workings over the next few months. It will also be interesting to see how Skype connectivity gets used and what creative applications people devise for it. If you have any questions about what I’ve described here, or any crazy ideas for using UCMA applications with Skype users, feel free to comment.



Leave a Reply

  • Note: Comment moderation is in use because of excessive spam. Your comment may not appear immediately.

  •