Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 156755) +++ channels/chan_sip.c (working copy) @@ -16720,8 +16720,12 @@ sipmethod = find_sip_method(msg); owner = p->owner; - if (owner) + if (owner) { + char textcause[10]; owner->hangupcause = hangup_sip2cause(resp); + snprintf(textcause, sizeof(textcause), "SIP %s", req->rlPart2); + pbx_builtin_setvar_helper(owner, "^^HANGUPCAUSETEXT", textcause); + } /* Acknowledge whatever it is destined for */ if ((resp >= 100) && (resp <= 199)) Index: apps/app_dial.c =================================================================== --- apps/app_dial.c (revision 156755) +++ apps/app_dial.c (working copy) @@ -875,6 +875,7 @@ f = ast_read(winner); if (!f) { in->hangupcause = c->hangupcause; + ast_channel_rinherit_variables(in, c); #ifdef HAVE_EPOLL ast_poll_channel_del(in, c); #endif @@ -915,6 +916,7 @@ case AST_CONTROL_BUSY: ast_verb(3, "%s is busy\n", c->name); in->hangupcause = c->hangupcause; + ast_channel_rinherit_variables(in, c); ast_hangup(c); c = o->chan = NULL; ast_clear_flag64(o, DIAL_STILLGOING); @@ -923,6 +925,7 @@ case AST_CONTROL_CONGESTION: ast_verb(3, "%s is circuit-busy\n", c->name); in->hangupcause = c->hangupcause; + ast_channel_rinherit_variables(in, c); ast_hangup(c); c = o->chan = NULL; ast_clear_flag64(o, DIAL_STILLGOING); @@ -2232,8 +2235,10 @@ ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]); ast_pbx_start(peer); } else { - if (!ast_check_hangup(chan)) + if (!ast_check_hangup(chan)) { chan->hangupcause = peer->hangupcause; + ast_channel_rinherit_variables(chan, peer); + } ast_hangup(peer); } } Index: include/asterisk/channel.h =================================================================== --- include/asterisk/channel.h (revision 156755) +++ include/asterisk/channel.h (working copy) @@ -1462,6 +1462,7 @@ channel with their names unchanged. */ void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child); +void ast_channel_rinherit_variables(struct ast_channel *parent, const struct ast_channel *child); /*! \brief adds a list of channel variables to a channel Index: main/channel.c =================================================================== --- main/channel.c (revision 156755) +++ main/channel.c (working copy) @@ -3736,21 +3736,21 @@ ast_string_field_set(chan, name, newname); } -void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child) +static void channel_inherit_variables(const struct ast_channel *source, struct ast_channel *destination, const char c) { struct ast_var_t *current, *newvar; const char *varname; - AST_LIST_TRAVERSE(&parent->varshead, current, entries) { + AST_LIST_TRAVERSE(&source->varshead, current, entries) { int vartype = 0; varname = ast_var_full_name(current); if (!varname) continue; - if (varname[0] == '_') { + if (varname[0] == c) { vartype = 1; - if (varname[1] == '_') + if (varname[1] == c) vartype = 2; } @@ -3758,14 +3758,14 @@ case 1: newvar = ast_var_assign(&varname[1], ast_var_value(current)); if (newvar) { - AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); + AST_LIST_INSERT_TAIL(&destination->varshead, newvar, entries); ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); } break; case 2: newvar = ast_var_assign(varname, ast_var_value(current)); if (newvar) { - AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); + AST_LIST_INSERT_TAIL(&destination->varshead, newvar, entries); ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); } break; @@ -3776,6 +3776,16 @@ } } +void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child) +{ + channel_inherit_variables(parent, child, '_'); +} + +void ast_channel_rinherit_variables(struct ast_channel *parent, const struct ast_channel *child) +{ + channel_inherit_variables(child, parent, '^'); +} + /*! \brief Clone channel variables from 'clone' channel into 'original' channel Index: main/chanvars.c =================================================================== --- main/chanvars.c (revision 156755) +++ main/chanvars.c (working copy) @@ -71,8 +71,14 @@ /* Return the name without the initial underscores */ if (name[0] == '_') { name++; - if (name[0] == '_') + if (name[0] == '_') { name++; + } + } else if (name[0] == '^') { + name++; + if (name[0] == '^') { + name++; + } } return name; }