PRI issue in China

We have recently encountered quite difficult issues with our PRI in China. We have found a solution: we’d like to share it with other people it could help and we’re curious to know if this solution may have some bad side-effect.

  1. We used to have a China Telecom PRI line as most people using Asterisk in China. We didn’t have any problem. We moved to another building (in Beijing) that is connected to CNC and we had to switch to a CNC PRI line.

  2. We encountered then a very annoying issue: when people called us from a cell phone (which 9 times out of 10 is using China Mobile), the call didn’t get through randomly: sometimes it gets through 5 times in a row, sometimes it didn’t get through 5 times in a row. Or whatever sequence.

  3. With my cell phone, I clearly got 2 debug output (using pri debug intense)
    i) when the call got through:
    Handling message for SAPI/TEI=0/0
    – ACKing all packets from 76 to (but not including) 77
    – Since there was nothing left, stopping T200 counter
    – Stopping T203 counter since we got an ACK
    – Nothing left, starting T203 counter
    < Protocol Discriminator: Q.931 (8) len=48
    < Call Ref: len= 2 (reference 1242/0x4DA) (Originator)
    < Message type: SETUP (5)
    < [a1]CLI>
    < Sending Complete (len= 1)
    < [04 03 80 90 a3]
    < Bearer Capability (len= 5) [ Ext: 1 Q.931 Std: 0 Info transfer capability: Speech (0)
    < Ext: 1 Trans mode/rate: 64kbps, circuit-mode (16)
    < User information layer 1: A-Law (35)
    < [18 03 a1 83 82]
    < Channel ID (len= 5) [ Ext: 1 IntID: Implicit PRI Spare: 0 Preferred Dchan: 0
    < ChanSel: As indicated in following octets
    < Ext: 1 Coding: 0 Number Specified Channel Type: 3
    < Ext: 1 Channel: 2 ]
    < [6c 0d 21 81 31 35 39 31 31 30 39 36 38 37 32]
    < Calling Number (len=15) [ Ext: 0 TON: National Number (2) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1)
    < Presentation: Presentation permitted, user number passed network screening (1) ‘15911096872’ ]
    < [70 0b a1 31 30 38 35 36 35 38 30 30 30]
    < Called Number (len=13) [ Ext: 1 TON: National Number (2) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1) ‘1085658000’ ]
    < [7d 02 91 81]
    < IE: High-layer Compatibility (len = 4)
    – Making new call for cr 1242
    – Processing Q.931 Call Setup
    – Processing IE 161 (cs0, Sending Complete)
    – Processing IE 4 (cs0, Bearer Capability)
    – Processing IE 24 (cs0, Channel Identification)
    – Processing IE 108 (cs0, Calling Party Number)
    – Processing IE 112 (cs0, Called Party Number)
    – Processing IE 125 (cs0, High-layer Compatibility)
    q931.c:3509 q931_receive: call 1242 on channel 2 enters state 6 (Call Present)
    Sending Receiver Ready (69)
    duobao
    CLI>

[ 02 01 01 8a ]

Supervisory frame:
SAPI: 00 C/R: 1 EA: 0
TEI: 000 EA: 1
Zero: 0 S: 0 01: 1 [ RR (receive ready) ]
N®: 069 P/F: 0
0 bytes of data
– Restarting T203 counter
– Restarting T203 counter
q931.c:2774 q931_call_proceeding: call 1242 on channel 2 enters state 9 (Incoming Call Proceeding)
duobao*CLI>
[ 00 01 9a 8a 08 02 84 da 02 18 03 a9 83 82 ]

Informational frame:
SAPI: 00 C/R: 0 EA: 0
TEI: 000 EA: 1
N(S): 077 0: 0
N®: 069 P: 0
10 bytes of data
– Restarting T203 counter
Stopping T_203 timer
Starting T_200 timer
Protocol Discriminator: Q.931 (8) len=10
Call Ref: len= 2 (reference 1242/0x4DA) (Terminator)
Message type: CALL PROCEEDING (2)
[18 03 a9 83 82]
Channel ID (len= 5) [ Ext: 1 IntID: Implicit PRI Spare: 0 Exclusive Dchan: 0
ChanSel: As indicated in following octets
Ext: 1 Coding: 0 Number Specified Channel Type: 3
Ext: 1 Channel: 2 ]
– Executing [1085658000@incoming:1] NoOp(“DAHDI/2-1”, ““from _10X “” <15911096872>””) in new stack
– Executing [1085658000@incoming:2] Goto(“DAHDI/2-1”, “incoming|85658000|1”) in new stack
– Goto (incoming,85658000,1)
– Executing [85658000@incoming:1] Answer(“DAHDI/2-1”, “”) in new stack
q931.c:2909 q931_connect: call 1242 on channel 2 enters state 8 (Connect Request)

[ 00 01 9c 8a 08 02 84 da 07 18 03 a9 83 82 1e 02 81 82 ]
duobaoCLI>
Informational frame:
SAPI: 00 C/R: 0 EA: 0
TEI: 000 EA: 1
N(S): 078 0: 0
N®: 069 P: 0
14 bytes of data
T_200 timer already going (2)
Protocol Discriminator: Q.931 (8) len=14
Call Ref: len= 2 (reference 1242/0x4DA) (Terminator)
Message type: CONNECT (7)
[18 03 a9 83 82]
Channel ID (len= 5) [ Ext: 1 IntID: Implicit PRI Spare: 0 Exclusive Dchan: 0
ChanSel: As indicated in following octets
Ext: 1 Coding: 0 Number Specified Channel Type: 3
Ext: 1 Channel: 2 ]
[1e 02 81 82]
Progress Indicator (len= 4) [ Ext: 1 Coding: CCITT (ITU) standard (0) 0: 0 Location: Private network serving the local user (1)
Ext: 1 Progress Description: Called equipment is non-ISDN. (2) ]
– Accepting call from ‘15911096872’ to ‘1085658000’ on channel 0/2, span 1
– Executing [85658000@incoming:2] Set(“DAHDI/2-1”, “CHANNEL(language)=en”) in new stack
– Executing [85658000@incoming:3] Set(“DAHDI/2-1”, “QUEUE=qutravel”) in new stack
– Executing [85658000@incoming:4] Set(“DAHDI/2-1”, “__GLOBAL_UNIQUEID=1247384474.3985”) in new stack
– Executing [85658000@incoming:5] Set(“DAHDI/2-1”, “CALLERID(name)=85658000^^1247384474.3985.gsm”) in new stack
– Executing [85658000@incoming:6] GotoIfTime(“DAHDI/2-1”, "09:00-19:59|
|28-31|may?open") in new stack
– Executing [85658000@incoming:7] GotoIfTime(“DAHDI/2-1”, “09:00-18:59|mon-fri||?open”) in new stack
– Executing [85658000@incoming:8] GotoIfTime(“DAHDI/2-1”, “09:00-18:59|sat-sun||?weekend”) in new stack
– Goto (incoming,85658000,13)
– Executing [85658000@incoming:13] Queue(“DAHDI/2-1”, “qutravel_weekend||||”) in new stack
– Started music on hold, class ‘qutravel_weekend’, on DAHDI/2-1
– Executing [1066@call-center-agent:1] Dial(“Local/1066@call-center-agent-6d37,2”, “SIP/qutravel-sipphone|12|TtM(call-agent^emilie^1066)”) in new stack
– Called qutravel-sipphone

ii) when the call didn’t get through:
Handling message for SAPI/TEI=0/0
– ACKing all packets from 63 to (but not including) 64
– Since there was nothing left, stopping T200 counter
– Stopping T203 counter since we got an ACK
– Nothing left, starting T203 counter
< Protocol Discriminator: Q.931 (8) len=54
< Call Ref: len= 2 (reference 1185/0x4A1) (Originator)
< Message type: SETUP (5)
< [a1]
< Sending Complete (len= 1)
< [04 03 80 90 a3]
< Bearer Capability (len= 5) [ Ext: 1 Q.931 Std: 0 Info transfer capability: Speech (0)
< Ext: 1 Trans mode/rate: 64kbps, circuit-mode (16)
< User information layer 1: A-Law (35)
< [04 04 80 98 90 a3]
< Bearer Capability (len= 6) [ Ext: 1 Q.931 Std: 0 Info transfer capability: Speech (0)
< Ext: 1 Trans mode/rate: (Nx64kbps) (24)
< Ext: 1 Transfer rate multiplier: 16 x 64
< User information layer 1: A-Law (35)
< [18 03 a1 83 98]
< Channel ID (len= 5) [ Ext: 1 IntID: Implicit PRI Spare: 0 Preferred Dchan: 0
< ChanSel: As indicated in following octets
< Ext: 1 Coding: 0 Number Specified Channel Type: 3
< Ext: 1 Channel: 24 ]
< [6c 0d 21 81 31 35 39 31 31 30 39 36 38 37 32]
< Calling Number (len=15) [ Ext: 0 TON: National Number (2) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1)
< Presentation: Presentation permitted, user number passed network screening (1) ‘15911096872’ ]
< [70 0b a1 31 30 38 35 36 35 38 30 30 30]
< Called Number (len=13) [ Ext: 1 TON: National Number (2) NPI: ISDN/Telephony Numbering Plan (E.164/E.163) (1) ‘1085658000’ ]
< [7d 02 91 81]
< IE: High-layer Compatibility (len = 4)
– Making new call for cr 1185
– Processing Q.931 Call Setup
– Processing IE 161 (cs0, Sending Complete)
– Processing IE 4 (cs0, Bearer Capability)
– Processing IE 4 (cs0, Bearer Capability)
– Processing IE 24 (cs0, Channel Identification)
– Processing IE 108 (cs0, Calling Party Number)
– Processing IE 112 (cs0, Called Party Number)
– Processing IE 125 (cs0, High-layer Compatibility)
q931.c:3509 q931_receive: call 1185 on channel 24 enters state 6 (Call Present)
q931.c:3104 q931_release_complete: call 1185 on channel 24 enters state 0 (Null)
duobao*CLI>

[ 00 01 80 6c 08 02 84 a1 5a 08 02 81 c1 ]

Informational frame:
SAPI: 00 C/R: 0 EA: 0
TEI: 000 EA: 1
N(S): 064 0: 0
N®: 054 P: 0
9 bytes of data
– Restarting T203 counter
Stopping T_203 timer
Starting T_200 timer
Protocol Discriminator: Q.931 (8) len=9
Call Ref: len= 2 (reference 1185/0x4A1) (Terminator)
Message type: RELEASE COMPLETE (90)
[08 02 81 c1]
Cause (len= 4) [ Ext: 1 Coding: CCITT (ITU) standard (0) Spare: 0 Location: Private network serving the local user (1)
Ext: 1 Cause: Bearer capability not implemented (65), class = Service or Option not Implemented (4) ]
NEW_HANGUP DEBUG: Calling q931_hangup, ourstate Null, peerstate Null
NEW_HANGUP DEBUG: Destroying the call, ourstate Null, peerstate Null
duobao*CLI>

These 2 cases happen randomly from the same cell number.

  1. I’m far from being a PRI expert, all my comments are quite empirical:
  • we can see some clear differences: the lenght after the Protocol Discriminator is different when the call gets through and when it doesn’t (but for each situation there are always the same, from my cell)
  • in the bad case, there is an additional Bearer Capability statement, as if there were another command
  1. Someone got a similar issue in China and they recommand modifying libpri, which we did: we commented out these lines:
    q931.c:
    if (c->transmoderate != TRANS_MODE_64_CIRCUIT) {
    q931_release_complete(pri, c, PRI_CAUSE_BEARERCAPABILITY_NOTIMPL);
    break;
    and, a bit magically, it worked.
    Now we still have the 2 Beared Capability statement randomly but there is no release_complete command that hangs the incoming call

  2. Has anyone else observed this? Does someone know why we still have this random PRI input from the same cell number (bad network interconnection?)? Does someone know if this change in libpri is safe?

Is there any chance of getting the person who created the patch to submit it formally to issues.asterisk.org?

Digium won’t accept patches, however small, unless they come from their original creator, and the creator grants them a licence to use the patch for any purpose.

It looks to me that the second bearer capability, on the second example, is bogus, as A-law speech can only ever consume 1*64kpbs. However I don’t know a lot about E1 ISDN protocols.

The change isn’t really safe, as it would cause the call to be accepted if it only had an incompatible bearer capability. However, its not going to cause problems if they always actually provide 64kbps A-law. I.E. it would probably accept 64kbps data connections and try and interpret them as speech.

In fact, it isn’t testing the speech part of the capability, so it is only the fact that that it is claiming to use other than 64kbps which is causing the problem (I think it is claiming 1024kbps).

yes, it is not a good way to handle that. sometime because of different calleris from different providers, it will causes noise during the conversation.
james.zhu

James (you helped us on that one, thanks again): if it’s not the good way to handle it, what do you propose?
And does someone has a clue while the same calling number generates randomly different PRI handling?

With the caveat that I don’t have direct experience of primary rate ISDN, I don’t see how it will cause noise.

The problem is that Asterisk has no means of coping with a 1024kb/s speech channel over ISDN, so, if it is genuinely offered one and doesn 't reject it (the code change is basically to stop it rejecting rates other than 64 kb/s) it will be in undefined territory.

I don’t know enough about the protocol, but to me it seems like the second network has broken software on their switches. I could just possibly imagine that negotiation is allowed at this stage in the protocol, and it is possible to accept the 64 kb/s option, and ignore the 1024 kb/s one, but even then A-law is a strictly 8 bits per sample 64 kb/s format, so the combination of A-law and 1024 bp/s seems broken.

Consequently, I suspect you are in a position of having to work round broken software on the network side.