[Из песочницы] Asterisk, подмена Hangupcause
Иногда нам необходимо отдать клиенту код отбоя вне зависимости от того, что нам пришло на другом конце линии. По умолчанию, при указанном экстене (exten => s, n, HangUp) астериск шлет 34 код отбоя (в спецификации sip — это код ошибки 503). Задача сводится к следующему — поймать пришедший с плеча Б код, и передать плечу А уже то, что нам надо, согласно нашим условиям. Все это можно уместить в 2 контекста:
[outgoing]
exten => _X.,1,Dial(/${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 в 503SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP 192.168.1.59:5060; branch=z9hG4bK5d05bcde; received=192.168.1.59
From:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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:
To:
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.
Спасибо за внимание.