
我有一個帶有 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_proceeding
在q931.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 進行一些更廣泛的調整才能正確修復。