Иногда нам необходимо отдать клиенту код отбоя вне зависимости от того, что нам пришло на другом конце линии. По умолчанию, при указанном экстене ( exten => s,n,HangUp ) астериск шлет 34 код отбоя (в спецификации sip — это код ошибки 503). Задача сводится к следующему — поймать пришедший с плеча Б код, и передать плечу А уже то, что нам надо, согласно нашим условиям. Все это можно уместить в 2 контекста:
[outgoing]
exten => _X.,1,Dial(<SIP|IAX2>/${EXTEN}@trunk,60,g)
same => n,GoTo(hangup,s,${HANGUPCAUSE})
[hangup]
exten => s,<1...127>,HangUp(<нужный нам код Q.931>)
Логика контекстов проста — после окончания вызова Dial переменная HANGUPCAUSE ловит прилетевшее со стороны Б значение, и посредством функции GoTo переходит в контекст hangup на приоритет со значением от 1 до 127. Непосредственно в нем мы указываем — нужна ли нам замена, либо же мы оставляем значение, которое нам пришло. Список соответствий кодов Q931 --> SIP можно посмотреть. К примеру, здесь
Пример
Давайте рассмотрим работающий пример с подробными логами. Имеется 2 сервера Asterisk, один из которых будет «наш», второй — отдающий произвольные коды отбоя, которые нам необходимо корректировать.
Для начала рассмотрим соответствия SIP кодов Asterisk и Q.931, которые мы будем подставлять в наш контекст:
— 403(21 как AST_CAUSE_CALL_REJECTED)
— 404(1 как AST_CAUSE_UNALLOCATED)
— 410(22 как AST_CAUSE_NUMBER_CHANGED)
— 484(28 как AST_CAUSE_INVALID_NUMBER_FORMAT)
— 486(17 как AST_CAUSE_USER_BUSY)
— 502(27 как AST_CAUSE_DESTINATION_OUT_OF_ORDER)
— 503(34 как AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, есть еще варианты его использования, но мы возьмем для примера этот)
А корректировать мы будем следующие коды:
- 403 в 503 (21--->34)
- 486 в 410 (17--->22)
- 484 в 404 (28--->1)
- 502 в 503(27--->34)
- 503 отдаем как есть(34--->34)
- 404 отдаем как есть(1--->1)
Схема подключения:
(предварительную настройку sip peers я делать не буду, положим она уже сделана)
Теперь в исходящий контекст [outgoing] для пользователя 101 (sip-клиент) на asterisk в файле extensions.conf добавим наш диалплан:
exten => _X.,1,Dial(SIP/${EXTEN}@192.168.1.100,60,g)
same => n,GoTo(hangup,s,${HANGUPCAUSE}) ;; значение HANGUPCAUSE является приоритетом в контексте hangup
[hangup]
exten => s,1,HangUp(1)
same => 17,HangUp(22)
same => 21,HangUp(34)
same => 27,HangUp(34)
same => 28,HangUp(1)
same => 34,HangUp(34)
Самое время проверить данный диалплан на практике. Будем инициировать отдачу sip-провайдером нужных нам кодов, чтобы проверить как asterisk их подменяет, согласно указанным правилам. Номер вызываемого абонента не имеет значения (указан шаблон _X.), поэтому звонить будем на 102. Обозначим sip-клиента A, sip-провайдер B, а наш астериск — Т.
Итак, начнем:
403 в 503
SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP 192.168.1.59:5060;branch=z9hG4bK5d05bcde;received=192.168.1.59
From: <sip:101@192.168.1.59>;tag=as5eed27bb
To: <sip:102@192.168.1.100>;tag=as64678c0b
Call-ID: 228c0daa2ce496dd10d46e9478757bdc@192.168.1.59:5060
CSeq: 102 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Session-Expires: 1800;refresher=uas
Content-Length: 0
SIP/2.0 503 Service Unavailable
Via: SIP/2.0/UDP 172.16.1.10:45416;branch=z9hG4bK-524287-1---3b6420a969f2c3a5;received=172.16.1.10;rport=45416
From: <sip:101@172.16.1.1;transport=UDP>;tag=a946bd32
To: <sip:102@172.16.1.1;transport=UDP>;tag=as558ab11d
Call-ID: t_H-Dcu8ceIhISoGT7dI9w…
CSeq: 2 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
X-Asterisk-HangupCause: Call Rejected
X-Asterisk-HangupCauseCode: 21
Content-Length: 0
486 в 410
SIP/2.0 486 Busy here
Via: SIP/2.0/UDP 192.168.1.59:5060;branch=z9hG4bK49adb904;received=192.168.1.59
From: <sip:101@192.168.1.59>;tag=as274a0aaa
To: <sip:102@192.168.1.100>;tag=as0865c714
Call-ID: 133710b7018b6f003e461b7366dc071d@192.168.1.59:5060
CSeq: 102 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Session-Expires: 1800;refresher=uas
Content-Length: 0
SIP/2.0 410 Gone
Via: SIP/2.0/UDP 172.16.1.10:45416;branch=z9hG4bK-524287-1---ffcd5e1a73cb2616;received=172.16.1.10;rport=45416
From: <sip:101@172.16.1.1;transport=UDP>;tag=769e0625
To: <sip:102@172.16.1.1;transport=UDP>;tag=as4a312af7
Call-ID: TJ49AuSsPy15GbKbIn3KTw…
CSeq: 2 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Content-Length: 0
484 в 404
SIP/2.0 484 Address incomplete
Via: SIP/2.0/UDP 192.168.1.59:5060;branch=z9hG4bK329498e8;received=192.168.1.59
From: <sip:101@192.168.1.59>;tag=as7feed819
To: <sip:102@192.168.1.100>;tag=as31afa634
Call-ID: 4c129a6b7680fc2f6940c77525a58e48@192.168.1.59:5060
CSeq: 102 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Session-Expires: 1800;refresher=uas
Content-Length: 0
SIP/2.0 404 Not Found
Via: SIP/2.0/UDP 172.16.1.10:45416;branch=z9hG4bK-524287-1---60687a681de37faa;received=172.16.1.10;rport=45416
From: <sip:101@172.16.1.1;transport=UDP>;tag=2303fd45
To: <sip:102@172.16.1.1;transport=UDP>;tag=as6f3c2e31
Call-ID: VPDPD8Wtelh7GfRX5OSnig…
CSeq: 2 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Content-Length: 0
502 в 503
SIP/2.0 502 Bad Gateway
Via: SIP/2.0/UDP 192.168.1.59:5060;branch=z9hG4bK39ae3e4a;received=192.168.1.59
From: <sip:101@192.168.1.59>;tag=as0d0f21e7
To: <sip:102@192.168.1.100>;tag=as501e30d3
Call-ID: 50cc1fca1b0c8d4807c110ab2621de88@192.168.1.59:5060
CSeq: 102 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Session-Expires: 1800;refresher=uas
Content-Length: 0
SIP/2.0 503 Service Unavailable
Via: SIP/2.0/UDP 172.16.1.10:45416;branch=z9hG4bK-524287-1---34f25329bb23215d;received=172.16.1.10;rport=45416
From: <sip:101@172.16.1.1;transport=UDP>;tag=0aabc036
To: <sip:102@172.16.1.1;transport=UDP>;tag=as61430d18
Call-ID: pH7WSH9iuRXDNJ0lyRnlGQ…
CSeq: 2 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
X-Asterisk-HangupCause: Destination out of order
X-Asterisk-HangupCauseCode: 27
Content-Length: 0
503
SIP/2.0 503 Service Unavailable
Via: SIP/2.0/UDP 192.168.1.59:5060;branch=z9hG4bK0c901ae6;received=192.168.1.59
From: <sip:101@192.168.1.59>;tag=as049eed53
To: <sip:102@192.168.1.100>;tag=as5b5775fa
Call-ID: 115e76677306210f6841df276dba9084@192.168.1.59:5060
CSeq: 102 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Session-Expires: 1800;refresher=uas
Content-Length: 0
SIP/2.0 503 Service Unavailable
Via: SIP/2.0/UDP 172.16.1.10:45416;branch=z9hG4bK-524287-1---a5d67aaf0d62c772;received=172.16.1.10;rport=45416
From: <sip:101@172.16.1.1;transport=UDP>;tag=886e8753
To: <sip:102@172.16.1.1;transport=UDP>;tag=as515af7fd
Call-ID: rd_vI3FHvTGECqLBPqu_mQ…
CSeq: 2 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Content-Length: 0
404
SIP/2.0 404 Not Found
Via: SIP/2.0/UDP 192.168.1.59:5060;branch=z9hG4bK70bbffe3;received=192.168.1.59
From: <sip:101@192.168.1.59>;tag=as42b18ba7
To: <sip:102@192.168.1.100>;tag=as4bbccb03
Call-ID: 681fa91b5d0b43d56125561a0a128540@192.168.1.59:5060
CSeq: 102 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Session-Expires: 1800;refresher=uas
Content-Length: 0
SIP/2.0 404 Not Found
Via: SIP/2.0/UDP 172.16.1.10:45416;branch=z9hG4bK-524287-1---4ccc9dc26a7e83a5;received=172.16.1.10;rport=45416
From: <sip:101@172.16.1.1;transport=UDP>;tag=e5ef327c
To: <sip:102@172.16.1.1;transport=UDP>;tag=as4d3749c4
Call-ID: O5xqrboDIZBqx44TJNEmPA…
CSeq: 2 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Content-Length: 0
Можно в настройках sip.conf в разделе [global] также прописать use_q850_reason=yes, чтобы в пакете с отбоем появилась информация такого вида:
SIP/2.0 503 Service Unavailable
Via: SIP/2.0/UDP 213.231.39.180:45416;branch=z9hG4bK-524287-1---a8e0763fbaad1b3f;received=213.231.39.180;rport=45416
From: <sip:101@46.4.173.59;transport=UDP>;tag=e4923c2b
To: <sip:102@46.4.173.59;transport=UDP>;tag=as6328694d
Call-ID: YhLSgjZP-vgF2rrqlKstcA…
CSeq: 2 INVITE
Server: Asterisk PBX 11.25.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Reason: Q.850;cause=34
Content-Length: 0
Таким образом Вы можете контролировать, что именно отдаете своим клиентам, и также настраивать логику согласно специфике работы Вашей АТС на базе Asterisk.
Спасибо за внимание.
Комментарии (7)
xomiakba
08.12.2016 12:24А еще можно запихнуть соответствия подмены в AstDB, и делать так:
same => n, Hangup(${DB(Hag/${HANGUPCAUSE})})
Не будет необходимости лезть в диалплан.
А в чем практический смыл этого? Есть пример, где понадобилось?
spacewalk
08.12.2016 13:57Пример, когда у Вас несколько транков на провайдеров, и один отдает некорректный отбой — вместо 503/480 отдает 486 (занято), то на следующий транк такой звонок не перейдет. В данной ситуации подмена поможет
xomiakba
08.12.2016 16:40Да? Хм, а мы тут и не в курсе…
Балансировка по транкам работает и 486 отбоем.
Asterisk >1.8
Так что вопрос актуален.spacewalk
08.12.2016 21:35Я писал про наш пример, когда сам абонент отдает 486 — нет необходимости к нему ломиться с другой линии, поэтому звонок не переходит на другой транк. И иной случай, когда провайдер вместо 503 отдает 486 — тогда необходимо в существующей логике просто подменить код.
В Вашем случае у Вас настроено иначе, и наш пример не работаетxomiakba
09.12.2016 13:00Выше как раз Ваш пример, звонок идет на АТС в регионе, которая в виду ошибки отдает 486.
Если обратите внимание, далее звонок идет на тот же регион и на тот же телефон, но через резервную АТС, и в этом случае уже достигает нужного абонента.
В вашем случае:
Если провайдер отдает вам 486 ошибочно, и отдает 486 не ошибочно (истиная занятость), то тем более нужно делать перебор безусловный провайдеров — хуже от этого не будет, но количество звонков, отбитых из-за неполадок на линии сведете к 0.Столько раз наступали на эти грабли.spacewalk
09.12.2016 13:58В нашем случае провайдер отдавал 486 ошибочно постоянно, после того как начал проводить ремонтные работы. Это было выявлено на 100%, и уточнено у него. Поэтому и возникла такая необходимость.
В остальных случаях согласен, Ваше решение подходит лучше
xtelekom
Для слива обычно нужно