[Из песочницы] Asterisk, подмена Hangupcause

Решил написать коротенький мануал по вопросу подмены кодов отбоя (они же hangupcause Q.931 ISDN) в Asterisk.

Иногда нам необходимо отдать клиенту код отбоя вне зависимости от того, что нам пришло на другом конце линии. По умолчанию, при указанном экстене (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 я делать не буду, положим она уже сделана)

a4cae3968d1342319af2bca428b30276.gif

Теперь в исходящий контекст [outgoing] для пользователя 101 (sip-клиент) на asterisk в файле extensions.conf добавим наш диалплан:

диалплан
[outgoing]
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
B--->T
2016/12/07 14:31:47.864287 192.168.1.100:5060 → 192.168.1.59:5060
SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP 192.168.1.59:5060; branch=z9hG4bK5d05bcde; received=192.168.1.59
From: ; tag=as5eed27bb
To: ; 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

T--->A
2016/12/07 14:31:47.864536 172.16.1.1:5060 → 172.16.1.10:45416
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: ; tag=a946bd32
To: ; 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
B--->T
2016/12/07 15:01:06.232282 192.168.1.100:5060 → 192.168.1.59:5060
SIP/2.0 486 Busy here
Via: SIP/2.0/UDP 192.168.1.59:5060; branch=z9hG4bK49adb904; received=192.168.1.59
From: ; tag=as274a0aaa
To: ; 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

T--->A
2016/12/07 15:01:06.232644 172.16.1.1:5060 → 172.16.1.10:45416
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: ; tag=769e0625
To: ; 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
B--->T
2016/12/07 15:03:42.757761 192.168.1.100:5060 → 192.168.1.59:5060
SIP/2.0 484 Address incomplete
Via: SIP/2.0/UDP 192.168.1.59:5060; branch=z9hG4bK329498e8; received=192.168.1.59
From: ; tag=as7feed819
To: ; 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

T--->A
2016/12/07 15:03:42.758083 172.16.1.1:5060 → 172.16.1.10:45416
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: ; tag=2303fd45
To: ; 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
B--->T
2016/12/07 14:46:12.941218 192.168.1.100:5060 → 192.168.1.59:5060
SIP/2.0 502 Bad Gateway
Via: SIP/2.0/UDP 192.168.1.59:5060; branch=z9hG4bK39ae3e4a; received=192.168.1.59
From: ; tag=as0d0f21e7
To: ; 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

T-->A
2016/12/07 14:46:12.941529 172.16.1.1:5060 → 172.16.1.10:45416
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: ; tag=0aabc036
To: ; 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
B--->T
2016/12/07 15:05:17.966997 192.168.1.100:5060 → 192.168.1.59:5060
SIP/2.0 503 Service Unavailable
Via: SIP/2.0/UDP 192.168.1.59:5060; branch=z9hG4bK0c901ae6; received=192.168.1.59
From: ; tag=as049eed53
To: ; 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

T--->A
2016/12/07 15:05:17.967354 172.16.1.1:5060 → 172.16.1.10:45416
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: ; tag=886e8753
To: ; 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
B---T
2016/12/07 15:07:10.270648 192.168.1.100:5060 → 192.168.1.59:5060
SIP/2.0 404 Not Found
Via: SIP/2.0/UDP 192.168.1.59:5060; branch=z9hG4bK70bbffe3; received=192.168.1.59
From: ; tag=as42b18ba7
To: ; 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

T--->A
2016/12/07 15:07:10.271017 172.16.1.1:5060 → 172.16.1.10:45416
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: ; tag=e5ef327c
To: ; 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, чтобы в пакете с отбоем появилась информация такого вида:
Q.850
2016/12/07 15:26:35.746861 46.4.173.59:5060 → 213.231.39.180:45416
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: ; tag=e4923c2b
To: ; 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.

Спасибо за внимание.

Комментарии (0)

© Habrahabr.ru