Microsoft Lync and Skype for Business have 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 those APIs.

Media troubleshooting and quality data in UCMA 3.0

Posted: October 12th, 2011 | Author: | Filed under: UCMA 3.0 | Tags: , , | 2 Comments »

There is a little-known feature in UCMA, introduced in version 3.0 of the API, that allows applications to receive a detailed report on the call quality metrics of each audio/video call when it concludes. The data reported to the application are essentially the same that are included in Lync Server’s call detail recording (CDR) records, and by receiving the information in a UCMA application in real time as calls conclude, you can correlate quality data with other information you collect or record about calls, or even adjust your application’s behaviour on the basis of call quality metrics.

Subscribing to the call quality reports is as simple as hooking up an event handler to the MediaTroubleshootingDataReported event on AudioVideoCall, as you can see in the following incoming call handler:

void OnCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)
{
    e.Call.MediaTroubleshootingDataReported +=
        new EventHandler<MediaTroubleshootingDataReportedEventArgs>(
            Call_MediaTroubleshootingDataReported);

    // Accept the call, do other important stuff, etc.
}

There are two components to the data that are reported. The first is a collection of MediaChannelEstablishmentData objects, which tell you whether media establishment succeeded or failed, and, if it failed, why. Mostly these are useful in identifying A/V Edge Server issues that are interfering with audio/video call establishment.

The second is an XML document that contains all of the juicy details about the audio quality, also known as the “quality of experience” (or QoE) data. Because this information is sent to the UCMA application in the body of a SIP message, it is provided by UCMA as a ContentDescription object, and the message body must be converted from a byte array into a string.

Here is a very rudimentary example of an event handler for MediaTroubleshootingDataReported that writes both the contents of the MediaChannelEstablishmentData objects and the QoE data to the console:

void OnMediaTroubleshootingDataReported(object sender,
    MediaTroubleshootingDataReportedEventArgs e)
{
    foreach (MediaChannelEstablishmentData data in
        e.MediaChannelEstablishmentDataCollection)
    {
        if (data.EstablishmentStatus == MediaChannelEstablishmentStatus.Succeeded)
        {
            Console.WriteLine("Media establishment succeeded.");
        }
        else
        {
            Console.WriteLine("Media establishment failed: {0}",
                data.GetDiagnosticsReason());
        }
    }

    string qualityOfExperienceXml =
        System.Text.Encoding.UTF8.GetString(e.QualityOfExperienceContent.GetBody());
    Console.WriteLine(qualityOfExperienceXml);
}

The output from the first part is fairly straightforward and will normally just tell you that media establishment succeeded. The output from the second part is generally much more involved, and looks something like this:

<?xml version="1.0"?>
<VQReportEvent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema" Version="1.1" d1p1:SchemaVersion="2.0" xmlns:d
1p1="ms-rtcp-metrics.v2" xmlns="ms-rtcp-metrics">
  <VQSessionReport SessionId="ZjA1Y2UzYTAwZjk0YjBiY2E0YWE0MjYzZjkyODI4ZTI.;from-
tag=bd18df45;to-tag=59b3f8d7f">
    <Endpoint Name="LAPTOP" d1p1:OS="Windows 6.1.7600 SP: 0.0 Type: 1(W
orkstation) Suite: 00000100 Arch: x64 WOW64: True" d1p1:CPUName="CPU Brand Genui
neIntel Family 0x6 Model 0x25 EM64T MaxFunc 0xb MaxFuncExt 0x80000008" d1p1:CPUN
umberOfCores="2" d1p1:CPUProcessorSpeed="2660" d1p1:VirtualizationFlag="0" />
    <DialogInfo Start="2011-10-12T19:57:14.9568959-06:00" End="2011-10-12T19:57:
25.0089439-06:00" CallId="ZjA1Y2UzYTAwZjk0YjBiY2E0YWE0MjYzZjkyODI4ZTI." FromTag=
"59b3f8d7f" ToTag="bd18df45">
      <FromURI>sip:this@192.168.0.12:5060</FromURI>
      <ToURI>sip:t@192.168.0.1</ToURI>
      <Caller>false</Caller>
      <LocalContactURI>sip:LAPTOP.domain.local:5060;transport=Tcp</
LocalContactURI>
      <RemoteContactURI>sip:t@192.168.0.12:22860;transport=TCP</RemoteContactU
RI>
      <LocalUserAgent>RTCC/4.0.0.0 standalone</LocalUserAgent>
      <RemoteUserAgent>X-Lite 4 release 4.1 stamp 63214</RemoteUserAgent>
      <LocalPAI>sip:default@LAPTOP.domain.local</LocalPAI>
      <d1p1:Separator />
      <d1p1:RegisteredInside>true</d1p1:RegisteredInside>
    </DialogInfo>
    <MediaLine Label="main-audio">
      <Description>
        <Connectivity>
          <Ice>DIRECT</Ice>
        </Connectivity>
        <Security>None</Security>
        <Transport>UDP</Transport>
        <NetworkConnectivityInfo>
          <NetworkConnection>wifi</NetworkConnection>
          <VPN>false</VPN>
          <LinkSpeed>2.02E+08</LinkSpeed>
          <d1p1:BSSID>C4-10-8A-31-EE-79</d1p1:BSSID>
        </NetworkConnectivityInfo>
        <LocalAddr>
          <IPAddr>192.168.0.1</IPAddr>
          <Port>1066</Port>
          <SubnetMask>255.255.0.0</SubnetMask>
          <d1p1:MACAddr>C0-00-11-00-00-00</d1p1:MACAddr>
        </LocalAddr>
        <RemoteAddr>
          <IPAddr>192.168.0.12</IPAddr>
          <Port>52294</Port>
        </RemoteAddr>
      </Description>
      <InboundStream Id="3794822267">
        <Network>
          <Jitter>
            <InterArrival>2</InterArrival>
            <InterArrivalMax>4</InterArrivalMax>
          </Jitter>
          <PacketLoss>
            <LossRate>0</LossRate>
            <LossRateMax>0</LossRateMax>
          </PacketLoss>
          <BurstGapLoss>
            <BurstDensity>0</BurstDensity>
            <BurstDuration>0</BurstDuration>
            <GapDensity>0</GapDensity>
            <GapDuration>5920</GapDuration>
          </BurstGapLoss>
          <Utilization>
            <Packets>362</Packets>
          </Utilization>
          <d1p1:RatioConcealedSamplesAvg>0</d1p1:RatioConcealedSamplesAvg>
          <d1p1:RatioStretchedSamplesAvg>0</d1p1:RatioStretchedSamplesAvg>
          <d1p1:RatioCompressedSamplesAvg>0</d1p1:RatioCompressedSamplesAvg>
        </Network>
        <Payload>
          <Audio>
            <PayloadType>0</PayloadType>
            <PayloadDescription>PCMU</PayloadDescription>
            <SampleRate>8000</SampleRate>
            <Signal>
              <d1p1:InitialSignalLevelRMS>50.47846</d1p1:InitialSignalLevelRMS>
            </Signal>
          </Audio>
        </Payload>
        <QualityEstimates>
          <Audio>
            <NetworkMOS>
              <OverallAvg>3.71</OverallAvg>
              <OverallMin>3.71</OverallMin>
              <DegradationAvg>0</DegradationAvg>
              <DegradationMax>0</DegradationMax>
              <DegradationJitterAvg>0</DegradationJitterAvg>
              <DegradationPacketLossAvg>0</DegradationPacketLossAvg>
            </NetworkMOS>
          </Audio>
        </QualityEstimates>
      </InboundStream>
      <OutboundStream Id="558378251">
        <Network>
          <Jitter>
            <InterArrival>1</InterArrival>
            <InterArrivalMax>1</InterArrivalMax>
          </Jitter>
          <PacketLoss>
            <LossRate>0</LossRate>
            <LossRateMax>0</LossRateMax>
          </PacketLoss>
          <Delay>
            <RoundTrip>0</RoundTrip>
            <RoundTripMax>0</RoundTripMax>
          </Delay>
          <Utilization>
            <Packets>312</Packets>
          </Utilization>
        </Network>
        <Payload>
          <Audio>
            <PayloadType>0</PayloadType>
            <PayloadDescription>PCMU</PayloadDescription>
            <SampleRate>8000</SampleRate>
            <d1p1:AudioFECUsed>false</d1p1:AudioFECUsed>
          </Audio>
        </Payload>
      </OutboundStream>
      <d1p1:AppliedBandwidthLimit>150800</d1p1:AppliedBandwidthLimit>
      <d1p1:AppliedBandwidthSource>StaticMax</d1p1:AppliedBandwidthSource>
    </MediaLine>
  </VQSessionReport>
</VQReportEvent>

As you can see, there is a wealth of information here. You can see details about the remote endpoint, the transport and security type used for media, whether ICE was used, and even the type and speed of the network connection. Further down, there are details about things that can affect call quality, like jitter and packet loss. One particularly useful bit of information for getting a quick assessment of call quality is the information in the <NetworkMOS> element. This shows calculated MOS scores for the call. MOS stands for “Mean Opinion Score,” and the idea is that the MOS score represents an average of people’s subjective ratings of audio quality on a scale of 1 to 5. In this case, rather than actually asking users to rate calls, Lync looks at the network conditions and calculates a score that is meant to approximate the ratings people would probably provide.

In order to do anything with the data, you’ll need to dig it out of the XML document, but there’s quite a bit of useful information here that you can use to assess audio quality from within your UCMA applications.


2 Comments on “Media troubleshooting and quality data in UCMA 3.0”

  1. 1 mike castillo said at 7:44 pm on August 17th, 2012:

    This is great information Michael! Thanks for posting. Is there some documentation on what all these fields mean and how they are derived. Like the AppliedBandwidthLimit; that one scares me a little because I wasn’t aware of any limits in bandwith or in calls being handled by a ucma app (at least not without setting up some throttling).
    Thanks again for posting this.
    Mike

  2. 2 Michael said at 6:14 pm on August 21st, 2012:

    Hi Mike,

    There’s a protocol specification at http://msdn.microsoft.com/en-us/library/cc431512(v=office.12) which might help a bit, although it doesn’t have much explanation of the fields. I also found Curtis Johnstone’s blog post at http://blog.insidelync.com/2012/06/a-primer-on-lync-audio-quality-metrics/ helpful, although it doesn’t cover the specific format in which UCMA receives the reporting.

    As far as bandwidth limitations, there are no limits on UCMA applications in general (as long as they’re trusted and not being throttled). I would guess that the bandwidth limit fields have to do with call admission control and the bandwidth policies you can define in there.

    Hope this helps.

    Michael


Leave a Reply

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

  •