Not a secret, that rtpengine can collect MOS stats during a call. So, this small note is just filling some gaps in an official documentation:
kamailio.cfg
# rtpengine cumulative MOS
modparam("rtpengine", "mos_min_pv", "$avp(re_mos_min)")
modparam("rtpengine", "mos_min_at_pv", "$avp(re_mos_min_at)")
...
# rtpengine A-Leg MOS
modparam("rtpengine", "mos_A_label_pv", "$avp(re_mos_A_label)")
modparam("rtpengine", "mos_min_A_pv", "$avp(re_mos_min_A)")
modparam("rtpengine", "mos_min_packetloss_A_pv", "$avp(re_mos_min_packetloss_A)")
...
# rtpengine B-Leg MOS
modparam("rtpengine", "mos_B_label_pv", "$avp(re_mos_B_label)")
modparam("rtpengine", "mos_min_B_pv", "$avp(re_mos_min_B)")
modparam("rtpengine", "mos_min_packetloss_B_pv", "$avp(re_mos_min_packetloss_B)")
...
# route is called on both request and responce.
route[RTPENGINE_MANAGE]
# Here we're adding labels to A and B channels.
...
# Values would be used later in rtpengine_delete() call
if (is_request()) {
$var(rtpengine_params) = $var(rtpengine_params) + " label=leg_A";
} else {
$var(rtpengine_params) = $var(rtpengine_params) + " label=leg_B";
}
...
rtpengine_manage("$var(rtpengine_params)");
}
...
# This route is called on freeing resources on rtpengine
route[RTPENGINE_DELETE] {
# Here we're initializing variables that were mentioned in modparam.
$avp(re_mos_A_label) = "leg_A";
$avp(re_mos_B_label) = "leg_B";
rtpengine_delete();
# Print quality stats for the call
if (!is_method("BYE")) {
return;
}
if ($avp(re_mos_average) != $null) {
xlog("L_NOTICE", "[CALL_STATS][MIN] MOS:$avp(re_mos_min) T:$avp(re_mos_min_at) L:$avp(re_mos_min_packetloss) J:$avp(re_mos_min_jitter) RTT:$avp(re_mos_min_roundtrip) [MAX] MOS:$avp(re_mos_max) T:$avp(re_mos_max_at) L:$avp(re_mos_max_packetloss) J:$avp(re_mos_max_jitter) RTT:$avp(re_mos_max_roundtrip) [AVG] MOS:$avp(re_mos_average) L:$avp(re_mos_average_packetloss) J:$avp(re_mos_average_jitter) RTT:$avp(re_mos_average_roundtrip)\n");
}
if ($avp(re_mos_average_A) != $null) {
xlog("L_NOTICE", "[CALL_STATS][A][MIN] MOS:$avp(re_mos_min_A) T:$avp(re_mos_min_at_A) L:$avp(re_mos_min_packetloss_A) J:$avp(re_mos_min_jitter_A) RTT: $avp(re_mos_min_roundtrip_A) [MAX] MOS:$avp(re_mos_max_A) T:$avp(re_mos_max_at_A) L:$avp(re_mos_max_packetloss_A) J:$avp(re_mos_max_jitter_A) RTT:$avp(re_mos_max_roundtrip_A) [AVG] MOS:$avp(re_mos_average_A) L:$avp(re_mos_average_packetloss_A) J:$avp(re_mos_average_jitter_A) RTT:$avp(re_mos_average_roundtrip_A)\n");
}
if ($avp(re_mos_average_B) != $null) {
xlog("L_NOTICE", "[CALL_STATS][B][MIN] MOS:$avp(re_mos_min_B) T:$avp(re_mos_min_at_B) L:$avp(re_mos_min_packetloss_B) J:$avp(re_mos_min_jitter_B) RTT:$avp(re_mos_min_roundtrip_B) [MAX] MOS:$avp(re_mos_max_B) T:$avp(re_mos_max_at_B) L:$avp(re_mos_max_packetloss_B) J:$avp(re_mos_max_jitter_B) RTT:$avp(re_mos_max_roundtrip_B) [AVG] MOS:$avp(re_mos_average_B) L:$avp(re_mos_average_packetloss_B) J:$avp(re_mos_average_jitter_B) RTT:$avp(re_mos_average_roundtrip_B)\n");
}
}
Example is not far from the documentation, but just to point how initialize the corresponding variables correctly.