Страница 2644 из 2772

Cообщение от   Telegram-канал Andrew

Добавлено: 04 апр 2026, 00:30
notify_ded_bot
И соответственно, в базе данных в поле dst получаю просто s.

AGI?
Там про сип, но https://community.asterisk.org/t/unable-to-find-cdr-for-sip-channel-asterisk-18/103109

Cообщение от   Telegram-канал Alexandr_halyk

Добавлено: 04 апр 2026, 06:12
notify_ded_bot

Ниже — подробный разбор каждой строки приведённого лога Asterisk. Лог относится к моменту обработки входящего или исходящего вызова через канал PJSIP (современный драйвер SIP в Asterisk).

---

1. Настройка TOS и CoS для RTP-аудио

== Using SIP RTP Audio TOS bits 184
== Using SIP RTP Audio TOS bits 184 in TCLASS field.
== Using SIP RTP Audio CoS mark 5
Эти строки не являются ошибками, а информируют о применении QoS-меток к RTP-пакетам (аудиотрафику) вызова.

Параметр Значение Что означает
TOS bits 184 (десятичная) В IPv4 заголовке поле TOS (Type of Service) устанавливается в 184. В шестнадцатеричном виде это 0xB8. В терминах DSCP (Differentiated Services Code Point) это значение соответствует классу EF (Expedited Forwarding, 46) – высший приоритет для реального времени.
TCLASS field те же 184 Для IPv6 вместо TOS используется поле Traffic Class. Значение переиспользуется.
CoS mark 5 Класс обслуживания на уровне Ethernet (802.1p). Значение 5 (обычно «voice») означает, что кадры с аудио будут помещаться в высокоприоритетную очередь коммутаторов.

Откуда берутся эти значения?
Обычно из конфигурации канала или профиля RTP, например в rtp.conf:
tos=ef или tos=184, cos=5. Также могут наследоваться от настроек peer/endpoint в PJSIP.

Зачем нужно?
Чтобы голосовые пакеты не задерживались в очередях маршрутизаторов/коммутаторов в условиях перегрузки сети.

---

2. Ошибки CDR

[2026-04-03 23:21:32] ERROR[734261]: cdr.c:3481 ast_cdr_getvar: Unable to find CDR for channel PJSIP/1019-00001a96
[2026-04-03 23:21:32] ERROR[734261]: cdr.c:3481 ast_cdr_getvar: Unable to find CDR for channel PJSIP/1019-00001a96
[2026-04-03 23:21:32] ERROR[734261]: cdr.c:3481 ast_cdr_getvar: Unable to find CDR for channel PJSIP/1019-00001a96
CDR (Call Detail Record) – запись деталей вызова: кто звонил, кому, время начала/окончания, статус и т.д.
Функция ast_cdr_getvar пытается прочитать переменную, связанную с CDR канала. Если CDR для канала не существует или уже уничтожена, возникает эта ошибка.

Возможные причины:

· Вызов ещё не полностью установлен – CDR создаётся при начале вызова (обычно на этапе ANSWER или даже раньше). Если скрипт диалплана (или приложение) пытается обратиться к переменным CDR до того, как канал привязан к CDR, получим такую ошибку.
· Использование устаревших или несуществующих переменных – например, попытка прочитать ${CDR(uniqueid)} или другую переменную, но модуль cdr не настроен, либо CDR отключена для этого канала (настройка cdr=no в endpoint).
· Параллельные или нестандартные сценарии – при transfer, bridge, masquerade канал может временно остаться без собственной CDR.
· Три повторения ошибки – скорее всего, скрипт диалплана трижды пытается получить разные переменные CDR (например, ${CDR(src)}, ${CDR(dst)}, ${CDR(duration)}) или один и тот же вызов повторяется из-за цикла.

Как исправить:

· Проверить диалплан: перед обращением к CDR убедиться, что вызов отвечен или хотя бы начат. Иногда помогает принудительно вызвать NoCDR() в начале диалплана (отключает CDR) или, наоборот, ForkCDR() для инициализации.
· Убедиться, что в cdr.conf и в конфигурации PJSIP endpoint не запрещена запись CDR.
· Если ошибка не влияет на прохождение вызова – можно проигнорировать. Если критична – стоит обновить логику диалплана.

---

3. Выполнение действия Set в диалплане

-- Executing [1920@from-internal:1] Set("PJSIP/1019-00001a96", "__RINGTIMER=15") in new stack
Это информационное сообщение (уровень VERBOSE) о том, что Asterisk выполняет команду Set в контексте from-internal, расширение 1920, приоритет 1.

Что происходит:

· Канал: PJSIP/1019-00001a96 – внутренний номер 1019, подключённый через PJSIP, уникальный идентификатор канала.
· Устанавливается переменная __RINGTIMER = 15.
· Двойное подчёркивание (__) означает наследование: переменная будет скопирована в любой другой канал, который будет соединён с текущим (например, при Dial, Bridge). Обычно используется для передачи таймаутов между каналами.

Cообщение от   Telegram-канал Alexandr_halyk

Добавлено: 04 апр 2026, 06:12
notify_ded_bot

· RINGTIMER – не встроенная переменная Asterisk, а пользовательская. По смыслу – таймер ринга (сколько секунд ждать ответа вызываемого абонента). Далее в диалплане эта переменная, вероятно, используется в Dial(): Dial(PJSIP/1920,${RINGTIMER}).

Итог: Вызов с номера 1019 пытается дозвониться на расширение 1920, но перед набором задаётся таймер ожидания ответа 15 секунд.

---

Связь всех событий в одном вызове

1. При установке RTP-сессии (ещё до ответа) Asterisk применяет QoS-метки.
2. Одновременно скрипт диалплана (вероятно, в начале обработки вызова) пытается прочитать переменные CDR, но CDR ещё нет – отсюда три ошибки.
3. Затем диалплан продолжает работу, устанавливает переменную __RINGTIMER=15 и, скорее всего, переходит к команде Dial.

Рекомендация: Перенесите чтение переменных CDR на более поздний этап (например, после Answer() или в контекст h). Или подавите ошибки, проверив существование CDR через функцию CDR_exists().

Если же ошибки CDR не мешают работе – их можно игнорировать. QoS-метки и установка таймера работают штатно.

Cообщение от   Telegram-канал Stamnik

Добавлено: 04 апр 2026, 12:43
notify_ded_bot
· RINGTIMER – не встроенная переменная Asterisk, а пользовательская. По смыслу – таймер ринга (сколько секунд ждать ответа вызываемого абонента). Далее в диалплане эта переменная, вероятно, используется в Dial(): Dial(PJSIP/1920,${RINGTIMER}).

Итог: Вызов с номера 1019 пытается дозвониться на расширение 1920, но перед набором задаётся таймер ожидания ответа 15 секунд.

---

Связь всех событий в одном вызове

1. При установке RTP-сессии (ещё до ответа) Asterisk применяет QoS-метки.
2. Одновременно скрипт диалплана (вероятно, в начале обработки вызова) пытается прочитать переменные CDR, но CDR ещё нет – отсюда три ошибки.
3. Затем диалплан продолжает работу, устанавливает переменную __RINGTIMER=15 и, скорее всего, переходит к команде Dial.

Рекомендация: Перенесите чтение переменных CDR на более поздний этап (например, после Answer() или в контекст h). Или подавите ошибки, проверив существование CDR через функцию CDR_exists().

Если же ошибки CDR не мешают работе – их можно игнорировать. QoS-метки и установка таймера работают штатно.

Спасибо большое. В принципе, мне это не особо мешает. Просто изначально у меня проблема что все звонки в CDR в базе денных в поле cdr.dst пишет s. Нет там номера куда звонили. Думал может это как-то влияет. Причём в macro-hangupcall всё красиво, проверил ${CDR(dst)} = 1920.

Cообщение от   Telegram-канал anonymous

Добавлено: 04 апр 2026, 13:37
notify_ded_bot

Приветствую, можно получить часовой пояс номера телефона в сервисе num.voxlink.ru?
Или делал кто-то маппинг по "region" (какой часовой пояс у региона)? Нужен только для номеров РФ

Cообщение от   Telegram-канал md_chewbacca

Добавлено: 04 апр 2026, 13:47
notify_ded_bot
Приветствую, можно получить часовой пояс номера телефона в сервисе num.voxlink.ru?
Или делал кто-то маппинг по "region" (какой часовой пояс у региона)? Нужен только для номеров РФ

Привет!
Я делал подобное вручную - брал список регионов, смотрел часовой пояс, сделал mysql табличку, заполнил, пока работает.

Cообщение от   Telegram-канал anonymous

Добавлено: 04 апр 2026, 13:52
notify_ded_bot
Привет!
Я делал подобное вручную - брал список регионов, смотрел часовой пояс, сделал mysql табличку, заполнил, пока работает.

а можешь мне скинуть?) Я просто не знаю, в каком формате регион (строка) будет приходить

Cообщение от   Telegram-канал md_chewbacca

Добавлено: 04 апр 2026, 14:00
notify_ded_bot


; Определение часового пояса вызываемого абонента
same => n,Set(tz-region=${SHELL(/var/lib/asterisk/scripts/clean_text.sh "${PSTN_REGION}")})
same => n,Set(ARRAY(tz_region,tz_iana,tz_utc)=${ODBC_GET-TZ-BY-REGION(${tz-region})})
same => n,Return()```

Cообщение от   Telegram-канал md_chewbacca

Добавлено: 04 апр 2026, 14:00
notify_ded_bot

[GET-TZ-BY-REGION]
escapecommas=yes
dsn=asterisk
readsql=SELECT * FROM data.region_timezone WHERE region LIKE '%${SQL_ESC(${ARG1})}%' ORDER BY region ASC LIMIT 1

Cообщение от   Telegram-канал md_chewbacca

Добавлено: 04 апр 2026, 14:02
notify_ded_bot

/var/lib/asterisk/scripts/clean_text.sh
#!/bin/bash

# Входной текст как аргумент
input="$1"

# Настройка локали (чтобы [:alpha:] поддерживал кириллицу)
#export LC_ALL=ru_RU.UTF-8

# Удаляем всё до и включая "и" с пробелами вокруг
input=$(echo "$input" | sed -E 's/.*[[:space:]]и[[:space:]]//')

# Шаг 1: удалить "г." (в начале слов)
input=$(echo "$input" | sed -E 's/\bг\. ?//g')

# Шаг 2: удалить слово "город" (в любом регистре)
input=$(echo "$input" | sed -E 's/\b[Гг]ород\b//g')

# Шаг 3: удалить слова "край", "республика", "округ"
input=$(echo "$input" | sed -E 's/\b[Кк]рай\b//g')
input=$(echo "$input" | sed -E 's/\b[Рр]еспублика\b//g')
input=$(echo "$input" | sed -E 's/\b[Оо]круг\b//g')
input=$(echo "$input" | sed -E 's/\b[Оо]бласть\b//g')
input=$(echo "$input" | sed -E 's/\b[Оо]бл\b//g')

# Шаг 4: удалить всё в круглых скобках
input=$(echo "$input" | sed -E 's/\([^)]*\)//g')

# Шаг 5: удалить всё после тире, если оно окружено пробелами
# (поддерживаются: -, – и —)
input=$(echo "$input" | sed -E 's/ [\-–—] .*//g')
input=$(echo "$input" | sed -E 's/ [\-] .*//g')

# Шаг 6: удалить все символы, кроме букв, пробелов и дефисов (внутри слов)
cleaned=$(echo "$input" | sed 's/[^[:alpha:] -]//g')

# Шаг 7: удалить лишние пробелы
cleaned=$(echo "$cleaned" | sed -E 's/ +/ /g' | sed -E 's/^ | $//g')

echo -n "$cleaned"