How to determine direction of RELEASE/HANGUP

Is there a variable I can use to record the direction of hangup?

Calling ----> Called. Called party hangs up. Info I want --> ** Release from Called party **

Example 2:
Calling ----> Called. Caller hangs up. Info I want --> ** Release from Calling party **

I have tried using these 2 variables ${HANGUPCAUSE} & ${DIALSTATUS} but they’re not what I’m looking for, HANGUPCAUSE gives the cause code & DIALSTATUS gives the status, but neither indicate which direction hung the call up.

exten => h,1,Set(CDR(causecode)=${HANGUPCAUSE})
exten => h,n,Set(CDR(dialstatus)=${DIALSTATUS})

I’m sure there must be an easy way to do this, but I’ve searched and not found anything yet.


If you are running the h extension, either party A hungup, or you failed to provide any dialplan after the call of Dial. Simply set a variable, after Dial, to indicate that the B side cleared. You will need the Dial option that stops hanging up A on a succesful call completion.

This should have been on the Asterisk Support forum.

This did not work.
I added this after the Dial() and the dial plan never reaches the NoOp() regardless of who hangs up.

; LD
exten => _91XXXXXXXXXX!,1,Dial(${PRI}/${EXTEN:1})
exten => _91XXXXXXXXXX!,n,NoOp(Far-end hung up) <---- Added

Any other suggestions?

Thanks David. I needed the ‘g’ option in Dial and now this works.

exten => _91XXXXXXXXXX!,n,Dial(${PRI}/${EXTEN:1},g)

Although… now it seems the ‘g’ option breaks functionality in the custom CDR variables I’m saving using the h extension. The ultimate goal is to have a record of which direction hung the call up saved in the CDR’s.

Here is some detail on how the ‘g’ option breaks custom CDR variables. Currently the LD part of the dialplan looks like this (before I add the ‘g’), without adding any code to determine release direction:

; LD
exten => _91XXXXXXXXXX!,1,Dial(${PRI}/${EXTEN:1})
exten => _91XXXXXXXXXX!,n,Hangup()

; on hangup, record the cause code
exten => h,1,Set(CDR(causecode)=${HANGUPCAUSE})
exten => h,n,Set(CDR(dialstatus)=${DIALSTATUS})

Our CDR’s then store the HANGUPCAUSE and DIALSTATUS variables in addition to the rest of the CDR data that is always saved.

Asterisk output on call hangup before adding ‘g’

    -- Executing [h@supervisor:1] Set("SIP/RCA1091-0000000f", "CDR(causecode)=16") in new stack
    -- Executing [h@supervisor:2] Set("SIP/RCA1091-0000000f", "CDR(dialstatus)=ANSWER") in new stack

CDR output before adding 'g’
End = 2012-08-30 06:21:41
Result = ANSWER
Cause Code = 16

Duration = 12
Billable = 9

If I add the ‘g’ option so that I can determine the release direction, then the CDR’s no longer record the values I set in the ‘h’ extension. I show them being set in the console output, but they are not added to the CDR.

Asterisk console output after adding ‘g’:

    -- Executing [h@supervisor:1] Set("SIP/RCA1091-0000000d", "CDR(causecode)=16") in new stack
    -- Executing [h@supervisor:2] Set("SIP/RCA1091-0000000d", "CDR(dialstatus)=ANSWER") in new stack

CDR result after adding 'g’
End = 2012-08-30 06:33:27
Result =
Cause Code = 0

Duration = 6
Billable = 2

There is some switching of CDRs that goes on during the h extension. I’m afraid you will have to do you own investigation, but I seem to remember that we forced out CDRs in the h extension, to ensure that the right values were used.

I opened a ticket with Digium support on this. Using CDR’s we’re not able to accomplish recording the cause codes in ‘h’ extension as well as the release direction.

We had to use CEL to accomplish recording hangup direction, and disconnect cause codes.

This works but it is not as clean & simple as CDR’s are, since you can create custom CDR variables for each item:
releasedir=orig, causecode=16, dialstatus=answer

vs. with CEL I’m forced to use ONE variable “userfield” to store all of these items.

It does work using CEL but seems like CDR’s should be fixed to allow this.

Thank you for the help on this. In case anyone is trying to do this in the future, here is a relevant part of the extensions.conf:

exten => _91XXXXXXXXXX!,1,Set(releasedir=orig) ; set releasedir variable to orig before call is set up
exten => _91XXXXXXXXXX!,n,Dial(${PRI}/${EXTEN:1},,g)
exten => _91XXXXXXXXXX!,n,Set(releasedir=term) ; far end hung up if we make it here
exten => _91XXXXXXXXXX!,n,Hangup()

; on hangup, record the cause code and release direction in CEL

My understanding is that no feature requests are being accepted for CDRs and bugs will only get fixed if there is a very low risk of breaking some other use of CDRs. You are expected to use CELs for anything non-trivial.

The gist is that every time CDRs are changed, it breaks the world for someone. David’s right, we don’t change it unless it’s armageddon. Inconvenient when you need a change, yes, but much safer for anyone depending on its behavior.