
Итак, как оказывается, за нас уже все придумали, нам лишь нужно взять инструмент в руки и адаптировать его под себя. Нам понадобиться Asterisk версии старше 11 и умение немного программировать. Краткая справка от вики:
RTCP (англ. Real-Time Transport Control Protocol — протокол управления передачей в реальном времени) — протокол, используемый совместно с RTP. Протокол описан в RFC 3550,[1]. RTCP базируется на периодической передаче управляющих пакетов всем участникам сессии, используя тот же механизм рассылки, что и для пакетов данных.
Протокол RTCP используется для передачи информации о задержках и потерях медиа-пакетов, джиттер-буфере, уровне звукового сигнала. Также передаются метрика качества сигнала (Call Quality Metrics) и Echo Return Loss.
Начиная с 11 версии, астериск через AMI присылает событие RTCPReceived и RTCPSent. Наиболее интересно для нас RTCPReceived, поскольку оно несет важную для нас информацию.
Выглядит оно так:
Event: RTCPReceived
privilege: reporting,all
sequencenumber: 23177
file: manager.c
line: 1696
func: manager_default_msg_cb
channel: SIP/MainAsterisk-0000113f
channelstate: 6
channelstatedesc: Up
calleridnum: 79914099
calleridname: RC
connectedlinenum: unknown
connectedlinename: unknown
language: ru
context: TO_REGION
exten: 680000130
priority: 1
uniqueid: 1481711487.11714
linkedid: 1481711487.11714
to: Адрес астериска:12611
from: Адрес пира:14555
rtt: 0.0272
ssrc: 0x73f52b22
pt: 200(SR)
reportcount: 1
sentntp: 1481712636.17532474232832
sentrtp: 9159680
sentpackets: 57246
sentoctets: 9159360
report0sourcessrc: 0x3098e4b3
report0fractionlost: 0
report0cumulativelost: 0
report0highestsequence: 7177
report0sequencenumbercycles: 1
report0iajitter: 3
report0lsr: 2726085614
report0dlsr: 0.0590
Интересные для нас поля:
channel — имя ассоциированного канала
from — IP удаленного пира
rtt — «задержка», точнее круговая задержка
sentpackets — колличество отправленых пакетов
sentoctets — колличество байт отправленых
report0cumulativelost — количество потерянных пакетов, с начала сессии
Схема хождения пакетов RTCP:

R-Фактор lite
Конечно, интересно получить итоговое качество канала в виде %. Для этого есть два параметра:
R-фактор и MOS. Более подробно ознакомиться сними можно тут.
Вычислить их точно мы, конечно же не можем, но можем сделать свою lite-вресию.
Общий алгоритм вычисления может выглядеть так:
— Считаем максимальную задержку (RTT) на всех плечах и берем за аксиому, что проблемы со слышимостью начинаются при 1000 мс.
— Считаем процент потерь (максимальный) и берем за аксиому, что при 40 процентах качество связи не приемлемое.
Итого, вычисление R-фактора может выглядеть так:
R=100-(MaxRTT/10+2*MaxLostPackets)
Оценка:
80-100% — хорошее качество звука
60-79% — удовлетворительно
<60% — Качество звука ужасное
Где применить?
На данный момент «играемся» с этим. Была написана программа для визуальной оценки.
Кроме того есть в планах вычислять автоматически для каждого звонка и класть в CDR дополнительным полем, что позволит оценить не только качество определенного звонка, но и направлений в целом в разрезе временных периодов.
Ссылка на программу
Проверенно для Asterisk 13, будет ли работать в младших версиях — не знаю.
UPD:
Как положить вычисленное значение в CDR?
На самом деле тут все проще, чем кажется. Не нужно делать интеграцию в своем скрипте или программе с базой данных и делать UPDATE. Достаточно после каждого вычисления R-фактора через тот же AMI интерфейс установить канальную переменную:
Action: Setvar
Channel: Имя канала, для которого вычислили R-фактор
Variable: CDR(r-factor)
Value: Значение, которое вычислили
И если в таблице CDR, есть столбец r-factor, оно заполниться этим значением. Кончено же, в эту переменную лучше класть усредненное значение за весь звонок.

