Mean Opinion Score (MOS) Calculation of Asterisk VoIP calls
If you running asterisk box as PBX or call center server, you might want to know the quality of the calls. In the VoIP world, We often use Mean Opinion Score or MOS as a call quality metric for VoIP calls. So in this tutorial we will try to calculate the MOS of Asterisk Calls.
What is MOS ( Mean Opinion Score ) :
MOS score is the Call quality score which is calculated by considering Network related things like Latency, Packet Loss and Jitter. MOS score is a value between the 1 and 5.
MOS value of 1 ( one ) is unacceptable call, and MOS value of three 3 means Okay and MOS value of 5 means Excellent call quality.
MOS Value | Quality |
---|---|
5 | Excellent |
4 | Good |
3 | Fair |
2 | Poor |
1 | Bad |
There are many algorithms used to calculate the MOS values but I came across one Algorithm from PingPlotter. I tested with few calls and found it is working good.
Calculating the MOS for Asterisk Calls :
Asterisk provides few RTCP statistics in the Dialplan. We can get those RTCP statistics by calling channel dialplan function. Usually, I calculate the call quality at the hang-up extension i.e at 'h' extension of Asterisk Dialplan.
So go ahead and add the following extension in the desired context.
1 2 3 |
exten => h,1,Set(RTCP_data=${CHANNEL(rtpqos,audio,all)}) exten => h,n,NoOp(RTCP Values : ${RTCP_data}) exten => h,n,AGI(/root/agi.py,${RTCP_data}) |
Here is the sample output:
1 2 |
- Executing [h@test:1] Set("SIP/ast-0000000d", "RTCP_data=ssrc=2000676536;themssrc=1925648282;lp=0;rxjitter=0.000000;rxcount=1398;txjitter=0.000181;txcount=1514;rlp=0;rtt=0.000534") in new stack -- Executing [h@test:2] NoOp("SIP/ast-0000000d", "RTCP Values : ssrc=2000676536;themssrc=1925648282;lp=0;rxjitter=0.000000;rxcount=1398;txjitter=0.000181;txcount=1514;rlp=0;rtt=0.000534") in new stack |
RTCP Values :
1 |
ssrc=2000676536;themssrc=1925648282;lp=0;rxjitter=0.000000;rxcount=1398;txjitter=0.000181;txcount=1514;rlp=0;rtt=0.000534 |
Here we have two legs for our call, One is between the Caller to Asterisk and then Asterisk to Callee.
Note: In above example call, I generated call using Asterisk Call file. So Receiving end, don’t have many values.
Receiver End :
ssrc means our ( Receiver) ssrc
rxcount means the number of packets received.
lp means lost packets/Lost packets
rxjitter means our calculated jitter(rx)/Jitter
Sender End:
themssrc means their ssrc
txcount means transmitted packets/Sent packet
rlp means remote lost packets/Lost packets
txjitter means reported jitter of the other end/Jitter
Round Trip Time :
rtt – round trip time/RTT
Now we can pass these values to any AGI Script to calculate the MOS using following formula.
The formula to calculate the MOS ( Mean Opinion Score ) for VoIP and Asterisk Calls :
Here is the PingPlotter formula to calculate the MoS score.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
' Take the average latency, add jitter, but double the impact to latency ' then add 10 for protocol latencies EffectiveLatency = ( AverageLatency + Jitter * 2 + 10 ) ' Implement a basic curve - deduct 4 for the R value at 160ms of latency ' (round trip). Anything over that gets a much more agressive deduction if EffectiveLatency < 160 then R = 93.2 - (EffectiveLatency / 40) else R = 93.2 - (EffectiveLatency - 120) / 10 ' Now, let's deduct 2.5 R values per percentage of packet loss R = R - (PacketLoss * 2.5) ' Convert the R into an MOS value.(this is a known formula) MOS = 1 + (0.035) * R + (.000007) * R * (R-60) * (100-R) |
You could try following one.
#!/bin/bash
IFS=’;’
A=”ssrc=1635470750;themssrc=1908891085;lp=0;rxjitter=0.000000;rxcount=93;txjitter=0.000134;txcount=93;rlp=0;rtt=0.000000″
SRC=${1:-$A} # get from first parameter or, for tests, from A variable.
for VAL in $SRC; do
declare -x $VAL
done
AverageLatency=$rtt
EffectiveLatency=$(echo “$AverageLatency+txjitter*2+10” |bc)
if [[ EffectiveLatency > /var/log/mos.log
Is this working example?
Yes, it works in my environment.
Dear,
Sir, thanks for this helpful article, but its not clear to me! the calculation of PingPlotter
‘ Take the average latency, add jitter, but double the impact to latency
‘ then add 10 for protocol latencies
EffectiveLatency = ( AverageLatency + Jitter * 2 + 10 ) >> From where we will get AverageLatency & Jitter
‘ Implement a basic curve – deduct 4 for the R value at 160ms of latency
‘ (round trip). Anything over that gets a much more aggressive deduction
if EffectiveLatency > (how did you make round value of RTT because asterisk not provide rtt with that way asterisk give like thsi rtt=0.000534 )
R = 93.2 – (EffectiveLatency / 40)
else
R = 93.2 – (EffectiveLatency – 120) / 10
‘ Now, let’s deduct 2.5 R values per percentage of packet loss
R = R – (PacketLoss * 2.5) >> which packetloss you are talking about Local Server Packet Loss or Remote Server
‘ Convert the R into an MOS value.(this is a known formula)
MOS = 1 + (0.035) * R + (.000007) * R * (R-60) * (100-R)
& you didn’t share AGI scripts if you was then it was more clear to us / everyone. waiting for your replay & if you can share AGI scritsp it would be great for us. Thanks for your kind attention.