Asterisk не может совершать и принимать звонки через интерфейс T1 PRI на маршрутизатор Cisco 2430

Asterisk не может совершать и принимать звонки через интерфейс T1 PRI на маршрутизатор Cisco 2430

У меня есть телефонный коммутатор Asterisk 1.8 с картой Digium T1. Он работает с использованием 5ESS PRI через нашего текущего телефонного провайдера без проблем. Однако мы подумываем о переходе на оптоволоконный сервис Time Warner (не TWTelecom), и тогда он выходит из строя с ошибками протокола ISDN.

Их сервис по сути является VOIP, к которому они не позволят вам прикоснуться напрямую, несмотря на то, что он отлично работает с Asterisk, я знаю - я пробовал. Вместо этого они выставляют его с помощью маршрутизатора Cisco 2430, и единственная поддерживаемая опция - предоставить вам интерфейс T1 какого-либо рода. PRI - самый разумный вариант, тогда. Как только мы переносим штекер с точки разграничения T1 нашего существующего телефонного провайдера на маршрутизатор Cisco, никакие звонки не проходят - ни исходящие, ни входящие.

При включении интенсивной отладки pri становится очевидным, что все ломается на первом пакете, который отправляет libpri — будь то входящий или исходящий вызов. Вот пример для входящего вызова — первые три пакета. Маршрутизатор Cisco ругается на то, что отправляет libpri. Вопрос в том: что именно и как это исправить.

Маршрутизатор Cisco работает под управлением прошивки c2430-ik9o3s-mz.124-15.T9.bin— судя по всему, это корпоративный стандарт TWC, и они не могут его изменить.

< TEI: 0 State 7(Multi-frame established)
< V(A)=2, V(S)=2, V(R)=2
< K=7, RC=0, l3_initiated=0, reject_except=0, ack_pend=0
< T200_id=0, N200=3, T203_id=8192
< [ 02 01 04 04 08 02 00 91 05 .... ]
< 59 bytes of data
< Protocol Discriminator: Q.931 (8)  len=59
< TEI=0 Call Ref: len= 2 (reference 145/0x91) (Sent from originator)
< Message Type: SETUP (5)
< [04 03 80 90 a2]
< Bearer Capability (len= 5) [ Ext: 1  Coding-Std: 0  Info transfer capability: Speech (0)
<                              Ext: 1  Trans mode/rate: 64kbps, circuit-mode (16)
<                                User information layer 1: u-Law (34)
< [18 03 a9 83 81]
< Channel ID (len= 5) [ Ext: 1  IntID: Implicit  Other(PRI)  Spare: 0  Exclusive  Dchan: 0
<                       ChanSel: As indicated in following octets
<                       Ext: 1  Coding: 0  Number Specified  Channel Type: 3
<                       Ext: 1  Channel: 1 Type: CPE]
< [28 0f ...]
< Display (len=15) [ ... ]
< [6c 0c 21 80 ...]
< Calling Party Number (len=14) [ Ext: 0  TON: National Number (2)  NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1)
<             Presentation: Presentation allowed, User-provided, not screened (0)  '...' ]
< [70 0b a1 ...]
< Called Party Number (len=13) [ Ext: 1  TON: National Number (2)  NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1)  '...' ]


> DL-DATA request
> Protocol Discriminator: Q.931 (8)  len=11
> TEI=0 Call Ref: len= 2 (reference 145/0x91) (Sent to originator)
> Message Type: CALL PROCEEDING (2)
TEI=0 Transmitting N(S)=2, window is open V(A)=2 K=7

> TEI: 0 State 7(Multi-frame established)
> V(A)=2, V(S)=2, V(R)=3
> K=7, RC=0, l3_initiated=0, reject_except=0, ack_pend=0
> T200_id=0, N200=3, T203_id=8192
> [ 00 01 04 06 08 02 80 91 02 18 04 e9 81 83 81 ]
> Informational frame:
> SAPI: 00  C/R: 0 EA: 0
>  TEI: 000        EA: 1
> N(S): 002   0: 0
> N(R): 003   P: 0
> 11 bytes of data
> Protocol Discriminator: Q.931 (8)  len=11
> TEI=0 Call Ref: len= 2 (reference 145/0x91) (Sent to originator)
> Message Type: CALL PROCEEDING (2)
> [18 04 e9 81 83 81]
> Channel ID (len= 6) [ Ext: 1  IntID: Explicit  Other(PRI)  Spare: 0  Exclusive  Dchan: 0
>                       ChanSel: As indicated in following octets
>                       Ext: 1  DS1 Identifier: 1  
>                       Ext: 1  Coding: 0  Number Specified  Channel Type: 3
>                       Ext: 1  Channel: 1 Type: CPE]

< TEI: 0 State 7(Multi-frame established)
< V(A)=3, V(S)=4, V(R)=3
< K=7, RC=0, l3_initiated=0, reject_except=0, ack_pend=0
< T200_id=8192, N200=3, T203_id=0
< [ 02 01 06 06 08 02 00 91 7d 08 03 80 e4 18 14 01 01 ]
< Informational frame:
< SAPI: 00  C/R: 1 EA: 0
<  TEI: 000        EA: 1
< N(S): 003   0: 0
< N(R): 003   P: 0
< 13 bytes of data
< Protocol Discriminator: Q.931 (8)  len=13
< TEI=0 Call Ref: len= 2 (reference 145/0x91) (Sent from originator)
< Message Type: STATUS (125)
< [08 03 80 e4 18]
< Cause (len= 5) [ Ext: 1  Coding: CCITT (ITU) standard (0)  Spare: 0  Location: User (0)
<                  Ext: 1  Cause: Invalid information element contents (100), class = Protocol Error (e.g. unknown message) (6) ]
<              Cause data 1: 18 (24)
< [14 01 01]
< Call State (len= 3) [ Ext: 0  Coding: CCITT (ITU) standard (0)  Call state: Call Initiated (1)

решение1

Данные причины? Данные причины!

libpri не очень умно указывает, что означают данные о причине в информационном элементе Причина (IE) - фактически, по состоянию на 1.4.13, он обрабатывает только два случая из ста, указанных вВ.850! К счастью, это не просто какие-то случайные запатентованные диагностические данные.

Ссылаясь наВ.850 Использование причины и места ..., Таблица 1, нам нужно проверить, какие диагностики присутствуют для Причины 100Неверное содержимое информационного элемента. И вот, этоидентификатор(ы) элемента информации! Итак, IE 0x18 (24) сообщения Call Proceeding, отправленного libpri, было проблемным. Как оказалось, IE 0x18 — это элемент Channel ID. Так что, по крайней мере, мы знаем, что проблема в этом конкретном элементе. Для справки, вот Cause IE, который мы получили от Cisco:

< [08 03 80 e4 18]
< Cause (len= 5) [ Ext: 1  Coding: CCITT (ITU) standard (0)  Spare: 0  Location: User (0)
<                  Ext: 1  Cause: Invalid information element contents (100), class = Protocol Error (e.g. unknown message) (6) ]
<              Cause data 1: 18 (24)

Идентификация канала IE — идентифицировать или нет

Теперь, когда мы сузили круг поиска до IE, ссылаясь наВ.931, 4.5.13 Идентификация канала [IE], отметим, что весь элемент является необязательным при ответе на установку вызова, если, как в данном случае, пользовательское оборудование просто хочет использовать единственный канал, который был явно запрошен сетью (здесь: маршрутизатор Cisco).

Увы, внутренний API libpri для отправки сообщения о ходе вызова, q931_call_proceedingвq931.c, на самом деле не упрощает задачу не отправлять полный идентификатор канала IE. Фактически, libpri struct q931_callне сохраняет явный последний полученный идентификатор канала, поэтому нет способа решить, является ли отправка идентификатора канала IE уместной или нет. Черт, это ошибка, которая call_proceeding_ies[]содержит Q931_CHANNEL_IDENT-- сообщение о продолжении вызова не всегда требует этого IE.

Поэтому одним из решений было бы просто не отправлять идентификатор канала.

Но чтоявляетсяПроблема внутри?

Увы, мы можем попытаться копнуть глубже и проверить, что именно в идентификаторе канала IE нарушило работу прошивки Cisco.

Давайте сравним идентификатор канала IE, полученный от Cisco, и отправленный в ответе:

< [18 03 a9 83 81]
< Channel ID (len= 5) [ Ext: 1  IntID: Implicit  Other(PRI)  Spare: 0  Exclusive  Dchan: 0
<                       ChanSel: As indicated in following octets
<                       Ext: 1  Coding: 0  Number Specified  Channel Type: 3
<                       Ext: 1  Channel: 1 Type: CPE]

> [18 04 e9 81 83 81]
> Channel ID (len= 6) [ Ext: 1  IntID: Explicit  Other(PRI)  Spare: 0  Exclusive  Dchan: 0
>                       ChanSel: As indicated in following octets
>                       Ext: 1  DS1 Identifier: 1  
>                       Ext: 1  Coding: 0  Number Specified  Channel Type: 3
>                       Ext: 1  Channel: 1 Type: CPE]

Разница довольно очевидна: libpri отвечает совершенно беспричинным октетом идентификатора DS1. Идентификатор DS1 — это идентификатор определенного диапазона PRI, который будет использоваться в системах, использующих несколько каналов. Здесь это вообще не нужно, поскольку между libpri и маршрутизатором Cisco есть только один диапазон T1.

Похоже, это ошибка в прошивке Cisco -- нет причин, по которым она не должна принимать идентификатор DS1 -- это необязательно, но допускается стандартом. Если, конечно, идентификатор DS1 не является каким-то неправильным -- я не исследовал это.

Хак, необходимый для того, чтобы libpri заработал, — это однострочный код в transmit_channel_id. Все, что нам нужно сделать, это подавить передачу октета 3.1, идентификатора DS1. Этот патч делает это:

--- libpri-1.4.14/q931.c.org    2013-04-16 15:22:24.910001979 -0400
+++ libpri-1.4.14/q931.c        2013-04-16 15:22:49.454001959 -0400
@@ -1441,7 +1441,7 @@
                return 0;
        }

-       if (!ctrl->bri && (((ctrl->switchtype != PRI_SWITCH_QSIG) && (call->ds1no > 0)) || call->ds1explicit)) {
+       if (0 && !ctrl->bri && (((ctrl->switchtype != PRI_SWITCH_QSIG) && (call->ds1no > 0)) || call->ds1explicit)) {
                /* We are specifying the interface.  Octet 3.1 */
                ie->data[pos++] |= 0x40;
                ie->data[pos++] = 0x80 | call->ds1no;

Следует добавить, что это ни в коем случае не постоянное исправление, предназначенное для включения в libpri, а всего лишь временный хак, для надлежащего исправления которого потребуются более масштабные изменения в libpri.

Связанный контент