Asterisk 無法透過 Cisco 2430 路由器的 T1 PRI 介面撥打或接聽呼叫

Asterisk 無法透過 Cisco 2430 路由器的 T1 PRI 介面撥打或接聽呼叫

我有一個帶有 Digium T1 卡的 Asterisk 1.8 電話交換機。它透過我們現有的電話提供者使用 5ESS PRI 運行,沒有任何問題。然而,我們正在考慮切換到時代華納的光纖服務(不是 TWTelecom),然後由於 ISDN 協定錯誤而失敗。

他們的服務本質上是 VOIP,他們不會讓你直接接觸,儘管它與 Asterisk 配合得很好,我知道 - 我試過了。相反,他們使用 Cisco 2430 路由器公開它,唯一支援的選項是為您提供某種類型的 T1 介面。那麼 PRI 是最明智的選擇。一旦我們將插頭從現有電話提供者的 T1 分界點轉移到 Cisco 路由器,就不會再有任何呼叫通過——無論是呼出還是呼入。

啟用密集 pri 偵錯後,很明顯,libpri 發出的第一個資料包就會出現問題 - 無論是傳入的傳出呼叫。這是傳入呼叫的範例 - 前三個資料包。 Cisco 路由器對 libpri 發送的內容感到厭煩。問題是:什麼以及如何解決它。

思科路由器運行韌體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,它只處理 100 種情況中的兩種情況Q.850!值得慶幸的是,這不僅僅是一些隨機的專有診斷數據。

參考Q.850 原因和地點的使用...,表 1,我們需要檢查原因 100 存在哪些診斷資訊元素內容無效。你瞧,這是資訊元素標識符!因此,libpri 發出的 Call Proceeding 訊息的 IE 0x18 (24) 是有問題的。碰巧,IE 0x18 是通道 ID 元素。所以至少我們知道問題出在那個特定的元素。作為參考,以下是我們從 Cisco 收到的 Cause IE:

< [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,參考Q.931, 4.5.13 頻道識別 [IE],我們注意到,如果用戶設備只是想使用網路明確請求的唯一頻道(就像這裡的情況一樣),則在響應呼叫建立時整個元素是可選的(此處:思科路由器)。

唉,libpri 的內部 API 用於發送呼叫進行訊息,q931_call_proceedingq931.c,並不能讓不發送完整的頻道 ID IE 變得容易。事實上,libpristruct q931_call不保留明確的最近接收的通道 id,因此無法確定發送通道 id IE 是否合適。哎呀,這是一個錯誤,其中call_proceeding_ies[]包含Q931_CHANNEL_IDENT-- 呼叫進行訊息並不總是需要此 IE。

因此,解決方法之一就是不發送通道 ID。

但是什麼內部的問題?

唉,我們可以嘗試更深入地挖掘並檢查 IE 通道 ID 中的內容確實擾亂了 Cisco 的韌體。

讓我們比較一下從 Cisco 收到的通道 ID IE 和回覆中發回的通道 ID IE:

< [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 發揮作用所需的 hack 是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 進行一些更廣泛的調整才能正確修復。

相關內容