Invalid Hangup Cause Code?

Hi I have an Asterisk (FreePBX) installation in a call centre with 2 x Sangoma A101 cards. Calls are completing properly and everything seems normal EXCEPT if the far end disconnects then Asterisk sees a “Normal Clearing” event Cause Code 0 even if the number was unavailable , busy, whatever.

We can make and receive calls fine, the only issue is that we are not picking up the cause code after the far end disconnects. In PRI intense debug I can see that the last 7 bits of the PRI message are a valid cause code… I’m confused.

I have attached an excerpt from /var/log/asterisk/full with pri intense debug span 2 turned on. During testing we dialled invalid, busy and rejected numbers. The resulting PRI/ZAP/Wanrouter/Asterisk conversation seems to show a cause code from Eircom (main provider in Ireland) which is interpretted as an Uunknown" Cause… for example a rejected call to a local number (below) gives disconnect cause 149 which should be equivalent to 149-128=21 since cause code is 7 bits. Cause code 21 is Normal “Rejected” (ref … angupCause) but it is being interpreted as “Ext: 1 Cause: Unknown (0), class = Normal Event (0) ]”.

I think it is all going wrong at the line:

but that is sent from the DUMP routine in q931.c, I think I need to find the source of the error/confusion/mismatch further up the code… I’m stuck

Is there a configuration issue on the box? Where should I look next?

Thanks for your help
Paul Smith
Clarity Telecom

[Jul 3 21:24:06] VERBOSE[963] logger.c: < Message type: DISCONNECT (69) [Jul 3 21:24:06] VERBOSE[963] logger.c: < [08 03 00 80 95] [Jul 3 21:24:06] VERBOSE[963] logger.c: < Cause (len= 5) [ Ext: 0 Coding: CCITT (ITU) standard (0) Spare: 0 Location: User (0) [Jul 3 21:24:06] VERBOSE[963] logger.c: < Ext: 1 Cause: Unknown (0), class = Normal Event (0) ] [Jul 3 21:24:06] VERBOSE[963] logger.c: < Cause data 1: 95 (149)

Software compiled on the Server:

asterisk-sounds-1.2.1.tar.gz libpri-1.4.1.tar.gz
linux-headers-2.6.18-6-686 zabbix-agent.1.4.4.deb

I’d love to know if the Eircom disconnect message is valid [08 03 00 80 95]. I have hacked q931.c so that my PBX can parse it and retrieve a valid cause code!

Extract of the Engineering report to customer:

After many intense hours of reading q931 standards and asterisk/libpri
q931.c it transpires that the problem boils down to Eircom sending an
extra 2 octets of data in the PRI Disconnect message. This does not
happen on any other PRI line we use with our Asterisk servers. It is
not compatible with Asterisk, I do not think it is compliant with
EuroISDN standard.

I have implemented a rather crude hack in q931.c on the box and
compiled and installed it. I restarted amportal and wanrouter.

I can now see valid hangup cause codes on the CLI and the phones. Data is available in the ${HANGUPCAUSE} variable in
Extensions.conf and is used to retrieve the screen message in
macro-dial-result… all standard stuff, all working.

The patch is crude but I believe it is effective: When
retrieving a q931 disconnect message if the data is longer than expected
then put the last 2 octets (the causecode) into the second pair (where
Asterisk expects to find them later)…this over writes the other data
content but I do not believe that is a problem … still testing
thoroughly. Significant line in hack is “ie->data[1]=ie->data[len-3];”

Diff file for the hack is as follows:

[code]tsg2:/usr/src/libpri-1.4.1# diff q931.c q931.c.beforeCorkLashup
< /Clarity Fix for : PRI Hangup has extra 2 octets of data preceding valid cause info/
< /
int datasize = sizeof(ie->data) / sizeof(ie->data[0]); /
< pri_message(pri, " Dump: Clarity Cause length %d\n", ie->len);
< if (ie->len > 4){
< pri_message(pri, " Dump: Clarity Cause data length %d: %02x (%d)\n", len,ie->data[ie->len - 1], ie->data[ie->len] - 1);
< /
ie->data[0]=ie->data[datasize-2]; /
< /
ie->data[1]=ie->data[len-3]; /
< }
< /
< /Clarity Fix for
*****: PRI Hangup has extra 2 octets of data preceding valid cause info*/
< /* int datasize = sizeof(ie->data) / sizeof(ie->data[0]); /
< pri_message(pri, " Clarity Cause %d\n", len);
< if (len > 4){
< pri_message(pri, " Clarity Cause data length %d: %02x (%d)\n", len-2, ie->data[len-3], ie->data[len-3]);
< /
ie->data[0]=ie->data[datasize-2]; /
< ie->data[1]=ie->data[len-3];
< }
< /
END OF Clarity HACK*/
< if (call->cause > 0) {

  if (call->cause > 0) {



double post…sorry