Как я разбираю эхо и сбои звука в Asterisk
Эхо в телефонной трубке чаще связано с акустикой, задержкой или обработкой сигнала, а не с одним параметром PJSIP. Я начинаю с контрольного звонка и логов, затем проверяю NAT, согласование кодеков и сам телефон. Ниже — порядок диагностики, который помогает не менять конфигурацию наугад.
Сначала отделяю эхо от обрыва звука
Я начинаю с простого вопроса: что именно слышит собеседник? Эхо — это повтор собственного голоса с задержкой; односторонний звук, треск, пропуски и обрыв разговора — другие симптомы. Их часто складывают в одну жалобу «плохо слышно», а потом лечат NAT-настройками всё подряд. Так не работает. Попросите двух сотрудников провести звонок и отдельно описать направление дефекта: кто слышит повтор, слышат ли его оба, возникает ли он постоянно или только при разговоре по громкой связи. Запишите время теста, внутренние номера и маршрут звонка. Это даст точку отсчёта для журналов, а не коллекцию догадок.
Затем меняю по одному условию: другой телефон, другая гарнитура, обычная трубка вместо громкой связи, внутренний вызов вместо внешнего. Если проблема возникает только на одном аппарате или в одной комнате, начинать с pjsip.conf рано. Проверьте положение микрофона, громкость динамика, акустическое отражение от стола и стен, а также режим эхоподавления в самом устройстве. Устойчивое акустическое эхо и сетевые потери звучат по-разному и требуют разных действий. Я не обещаю, что «правильный NAT» исправит отражение звука в переговорной: сервер не переставит микрофон подальше от динамика.
В ООО «Факел» я бы фиксировал наблюдения тем же способом: какой аппарат, какая сторона слышит повтор и воспроизводится ли он на другом маршруте. Если это условный кейс, в статье нельзя выдавать придуманные замеры или результат настройки за измеренную историю. Именно поэтому здесь нет заявления, будто один параметр уже избавил бухгалтерию от эха. Сначала соберите повторяемый тест, иначе сравнить результат до и после невозможно. Для работы с настройкой Asterisk пригодится такой же порядок: симптом, маршрут, время и только потом правка.
Полезно вести короткую таблицу наблюдений: «внутренний звонок — чисто», «внешний через транк — слышит абонент», «громкая связь — повтор усиливается». Она помогает отличить локальный дефект устройства от общего сбоя. Не называйте это доказательством причины: это пока границы, внутри которых надо искать. Если повтор появляется на всех аппаратах только при внешнем вызове, проверяйте тракт до оператора. Если он следует за одним телефоном, проверяйте телефон. Чем раньше мы отделим эти случаи, тем меньше шансов снести рабочую конфигурацию ради случайного улучшения.
Если сотрудники описывают один и тот же дефект по-разному, не сводите жалобы к общему «эхо». Попросите каждого повторить одинаковую короткую фразу в одном и том же сценарии, затем поменяйте только устройство или режим разговора. Слушайте запись только при наличии законных оснований и согласованного процесса; для первичной диагностики обычно хватает воспроизводимого звонка и точного описания слышимого эффекта. Так я отделяю впечатление от наблюдаемого симптома.
- Проверить, кто именно слышит повтор.
- Сравнить трубку, гарнитуру и громкую связь.
- Зафиксировать внутренний и внешний маршрут.
Собираю SIP-логи и проверяю endpoint
Когда проблема воспроизводится через Asterisk, я открываю CLI и включаю диагностический вывод: core set verbose 4, core set debug 4, pjsip set logger on. Эти команды есть в руководстве Asterisk по поиску проблем PJSIP. Затем повторяю звонок и сопоставляю SIP-обмен с конкретным временем теста. pjsip set logger on показывает SIP-сообщения; это не запись аудио и не анализатор качества RTP. Не следует обещать, что такая команда сама покажет каждый потерянный медиапакет. Для медиатракта нужны подходящие сетевые наблюдения и доступная телеметрия, а содержимое журналов зависит от версии, настроек и конкретного сбоя.
Для остановки SIP-трассировки использую pjsip set logger off, как только закончил сбор. В подробных логах могут оказаться адреса и служебные данные звонка, поэтому сохраняю их с ограниченным доступом и не оставляю отладку включённой без причины. Подробность вывода — не универсальная нагрузочная проблема и не «каждый пакет»; включайте её на время конкретного теста, следите за размером журналов и выключайте после проверки. Временный сбор данных полезен, а бесконечный лог — просто бесконечный лог.
Проверить загруженную конфигурацию можно командами pjsip show endpoints и pjsip show endpoint <имя>. Первая перечисляет конечные точки, вторая показывает сведения об указанной точке, включая связанные объекты конфигурации и транспорт. Вывод не является готовым отчётом о потерях RTP или акустическом эхе. Если endpoint отсутствует, изучаю сообщения о загрузке конфигурации и точное имя объекта; если он присутствует, сверяю его параметры с ожидаемыми. Это конкретная проверка, а не команда «покажи причину плохого звука».
Не публикуйте полные SIP-дампы с адресами и идентификаторами звонков. Для разбора достаточно оставить временную метку, направление вызова, типовой фрагмент обмена и замаскировать значения, по которым можно опознать абонента. Отдельно отмечайте, включали ли verbose/debug до воспроизведения: иначе можно сравнить разные условия и принять обычный отказ регистрации за причину эха. Я связываю журнал с тестовым звонком, а не с любым сообщением, попавшим в консоль за день.
Удобнее снимать журнал в момент тестового вызова, чем включить трассировку утром и пытаться найти звонок вечером. Сначала фиксирую точное время и идентификатор теста, затем включаю вывод, воспроизвожу дефект и выключаю его. Такой короткий фрагмент проще сопоставить с сообщениями SIP и безопаснее хранить. Если проблема не воспроизвелась, не делаю вывод, что она исчезла: отмечаю условия и повторяю сценарий при появлении симптома.
- Включить verbose и debug на время теста.
- Запустить `pjsip set logger on`.
- Проверить endpoint и затем выключить трассировку.
Проверяю NAT по роли каждого параметра
Если Asterisk находится за NAT, проверяю транспорт и то, какие адреса попадут в SIP и SDP. В официальной документации Asterisk external_signaling_address относится к SIP-сигнализации, а external_media_address — к RTP-медиа. Там же описан local_net: он задаёт локальные сети, для которых внешняя подмена адресов не применяется. Эти параметры относятся к объекту транспорта. Значения должны соответствовать реальной схеме адресации; адреса сигнализации и медиа обычно совпадают, но могут различаться, если для них выделены отдельные адреса или узлы. Не вставляйте публичный адрес по шаблону, не проверив, что именно видит удалённая сторона.
rtp_symmetric и force_rport — другие настройки: это параметры endpoint. Первая направляет RTP обратно на адрес и порт, откуда Asterisk его получил; вторая заставляет отправлять SIP-ответ на исходный адрес и порт запроса. Они решают определённые задачи прохождения NAT, но не являются «фиксами эха». В инструкции Asterisk для удалённых телефонов вместе с ними рассматриваются и другие параметры, включая rewrite_contact и direct_media; применимость зависит от топологии, телефона и транка. Поэтому не переношу эти строки в секцию transport и не включаю все флаги подряд по принципу «хуже не будет».
В каждой схеме проверяю, какие сети считаются внутренними, какой адрес записан в SDP, куда направляется RTP и остаётся ли Asterisk в медиатракте. direct_media влияет на возможность прямого обмена медиа между конечными точками, поэтому его значение тоже нельзя выбирать без понимания маршрута. Если сигнализация проходит, но собеседники не слышат друг друга, это полезное направление поиска. Если звук двусторонний и чистый, а повтор слышен лишь на громкой связи одного аппарата, NAT-параметры могут вообще не иметь отношения к жалобе.
Я также не утверждаю, что каждый дополнительный UDP/TLS-транспорт создаёт отдельный RTP-порт или дублирует медиа. В PJSIP может быть несколько транспортов — например, под разные способы SIP-соединения, — а RTP-порты и их диапазон задаются отдельно в настройках RTP. Нужен тот набор, который требует схема и поддерживаемые устройства. В рабочем конфиге лишние объекты стоит убирать после проверки зависимостей, но правило «оставить ровно один транспорт» документацией не подтверждается. Простота полезна, пока не превращается в догму.
Проверка не заканчивается просмотром SIP-заголовков. Сверьте настройки межсетевого экрана и маршрутизатора с реальным диапазоном RTP-портов, выбранным в установке Asterisk, и проверьте доступность этого диапазона с нужных направлений. Универсального номера порта для любой инсталляции здесь нет: он зависит от конфигурации. В конфигурации PJSIP важно не смешивать SIP-транспорт и медиатрафик. Подробности объектов и взаимосвязей собраны в руководстве по PJSIP.
- Сверить `local_net` и внешние адреса транспорта.
- Проверить NAT-флаги в endpoint.
- Сопоставить адрес в SDP с фактическим RTP-маршрутом.
Сверяю кодеки и эхоподавление на телефоне
Кодеки в PJSIP задаются для endpoint через allow и, при необходимости, disallow, а не в выдуманной секции codecs. В документации Asterisk приведён пример с запретом всех форматов и разрешением ulaw; конкретный перечень выбирают по возможностям телефонов и транка. Набор ulaw,alaw,g722 не является универсальным рецептом для «чистого звука». Проверьте, что общие форматы действительно согласуются на обоих участках вызова. При несовпадении возможны отказ согласования или транскодирование, но нельзя без измерений приписывать этому акустическое эхо. Сначала выясните, какой формат предложен и какой согласован на каждом плече.
Если после изменения списка вызов перестал устанавливаться или качество изменилось, верните прежнюю конфигурацию и проведите A/B-проверку на одном тестовом endpoint. Делайте резервную копию изменяемого файла, сохраняйте исходный набор форматов и меняйте только одну настройку за раз. При согласовании важно учитывать оба устройства и промежуточный транк; сервер не может заставить телефон поддерживать отсутствующий кодек. Не ставьте G.722, Opus или любой другой формат «в начало» просто потому, что он звучит современно: совместимость и транскодирование важнее модного названия.
Эхоподавление проверяю на конкретном телефоне по руководству его производителя. Название пункта меню и доступность обработки отличаются между моделями и прошивками, поэтому строка Echo Cancellation не универсальная команда для Yealink или любого другого телефона. Сравниваю один и тот же звонок с прежней настройкой и после контролируемого изменения, отдельно для трубки и громкой связи. Если меняется только громкая связь, ищу причину в акустике и обработке самого аппарата. Если дефект возникает у разных устройств только на одном внешнем маршруте, возвращаюсь к медиатракту и сети.
Не отключайте эхоподавление на всех телефонах, чтобы «доверить работу серверному DSP». Это утверждение требует конкретной схемы и конкретного оборудования; сервер может не выполнять нужную обработку вообще. Сначала выясните, где функция включена и какой эффект даёт именно на этой модели. Сравнительный тест делайте с одним аппаратом, фиксированной громкостью и неизменным маршрутом. Если результат не повторяется, это не основание массово менять профили телефонов. Списки кодеков и функции аппаратов стоит документировать вместе с версией конфигурации, чтобы потом можно было вернуть рабочее состояние.
Удобный способ проверить кодек — сопоставить конфигурацию endpoint с предложением и ответом в SIP/SDP конкретного тестового вызова. Смотрите на оба плеча: при транскодировании формат на стороне телефона может отличаться от формата транка. Сверяйте результат с возможностями конечного устройства, а не с тем, что вы хотели разрешить в конфиге. Если нужна отдельная схема обмена медиа за NAT, полезен материал о настройке PJSIP за NAT; применяйте параметры только после сверки топологии.
- Проверить `allow` и `disallow` у endpoint.
- Сверить общие кодеки на обоих плечах.
- Тестировать обработку звука на одном аппарате.
Проверяю результат и закрепляю рабочую конфигурацию
После каждой правки провожу несколько одинаковых тестовых звонков: один внутренний, один через нужный транк и, если жалоба связана с громкой связью, отдельный тест с ней. Продолжительность звонка сама по себе ничего не доказывает: исходная статья придумывала пять минут и три направления как универсальные критерии. Здесь важны повторяемые условия и сравнение до/после. Записываю, кто слышит дефект, какой endpoint участвовал, какие настройки менялись и что показали журналы. Если результат нестабилен, возвращаюсь к сбору наблюдений, а не объявляю исправление успешным по одному удачному звонку.
Команда pjsip show endpoint <имя> полезна для проверки загруженной конфигурации endpoint, но она не гарантирует отображение текущего RTP-потока, MOS или строки rtp timeout. Для состояния регистрации и перечня объектов применяю команды в соответствии с их назначением; данные о медиапотоке собираю отдельными средствами, если они доступны в конкретной установке. Zabbix можно использовать для мониторинга доступных показателей Asterisk, но обещание «проверять RTP каждые пять минут» требует отдельно настроенного источника метрик и триггера. Не называю проверку endpoint мониторингом RTP: это разные вещи.
Перед изменением на рабочей системе сохраняю копию конфигурации и план отката. После правки сверяю сообщения о загрузке объектов, затем повторяю звонок тем же маршрутом. Если нужно менять внешний адрес или политику медиа для нескольких устройств, сначала проверяю один endpoint и зависимые настройки транка. Ansible может помочь поддерживать шаблоны конфигурации в нескольких системах, но сам по себе не делает внесённые значения правильными. Переменная с неверным адресом, размноженная на десять серверов, — это уже автоматизированная ошибка; процессу тоже нужна проверка и контроль изменений.
В кратком отчёте оставляю симптом, подтверждённую причину, изменённые параметры, результат повторного теста и способ отката. Если причина оказалась в телефонной трубке или акустике помещения, так и пишу; не приписываю заслугу PJSIP. Если подтвердились проблемы NAT, документирую адресацию и настройки endpoint/transport. Такой итог полезнее обещания «звук всегда будет чистым»: сеть, устройства и акустическая среда меняются, поэтому проверяем не обещание, а конкретный тракт и наблюдаемый результат.
План отката должен быть понятен тому, кто дежурит после вас: какой файл восстановить, какие значения вернулись и как проверить звонок. Не сохраняйте несколько похожих копий с названиями «новая», «финал» и «точно финал» — через месяц они не объяснят, что работало. Зафиксируйте версию конфигурации и время изменения в принятом у вас журнале. Если мониторинг строится на собственных метриках, отдельно документируйте источник и условие тревоги; иначе срабатывание никто не сможет истолковать.
- Повторить звонок по тем же маршрутам.
- Сверить вывод CLI и доступные метрики.
- Зафиксировать правку и откат.
Частые вопросы
`rtp_symmetric` убирает эхо?
Нет. Он помогает направлять RTP на адрес и порт, откуда Asterisk его получил. Это настройка NAT-маршрута, а не акустическое эхоподавление.
Где задаются кодеки для PJSIP?
В настройках endpoint через `allow` и `disallow`. Проверяйте совместимые форматы на обоих участках вызова.
Что показывает `pjsip show endpoint`?
Сведения о выбранном endpoint и его конфигурационных связях. Команда не является отчётом о качестве RTP или MOS.
Нужно ли оставлять `pjsip set logger on` включённым?
Нет. Включайте SIP-трассировку на время воспроизводимого теста, затем отключайте командой `pjsip set logger off`.
Почему эхо слышно только на громкой связи?
Это повод проверить микрофон, динамик, расположение устройства и его обработку звука. Сравните результат с трубкой и гарнитурой.
Источники
- Asterisk PJSIP Troubleshooting Guide — Команды диагностики, SIP logger и проверка endpoint: https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Asterisk-PJSIP-Troubleshooting-Guide/
- Configuring res_pjsip to work through NAT — Назначение local_net, external_media_address, external_signaling_address, rtp_symmetric и force_rport: https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Configuring-res_pjsip-to-work-through-NAT/
- Asterisk Audio and Video Capabilities — Настройка разрешённых форматов PJSIP endpoint через allow/disallow: https://docs.asterisk.org/Operation/Asterisk-Audio-and-Video-Capabilities/
- PJSIP Configuration Sections and Relationships — Типы объектов и связи конфигурации PJSIP: https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/PJSIP-Configuration-Sections-and-Relationships/



