Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 211038) +++ channels/chan_sip.c (working copy) @@ -18450,8 +18450,13 @@ sipmethod = find_sip_method(msg); owner = p->owner; - if (owner) + if (owner) { + char causevar[256], causeval[256]; owner->hangupcause = hangup_sip2cause(resp); + snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name); + snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2)); + pbx_builtin_setvar_helper(owner, causevar, causeval); + } /* Acknowledge whatever it is destined for */ if ((resp >= 100) && (resp <= 199)) { Index: funcs/func_channel.c =================================================================== --- funcs/func_channel.c (revision 211038) +++ funcs/func_channel.c (working copy) @@ -55,6 +55,15 @@ will be space-delimited. + + + Gets or sets variables on the master channel + + + Allows access to the channel which created the current channel, if any. If the channel is already + a master channel, then accesses local channel variables. + + Gets/sets various pieces of information about the channel. @@ -496,23 +505,55 @@ .read = func_channels_read, }; +static int func_mchan_read(struct ast_channel *chan, const char *function, + char *data, struct ast_str **buf, ssize_t len) +{ + struct ast_channel *mchan = ast_channel_get_by_name(chan->linkedid); + char *template = alloca(4 + strlen(data)); + sprintf(template, "${%s}", data); /* SAFE */ + ast_str_substitute_variables(buf, len, mchan ? mchan : chan, template); + if (mchan) { + ast_channel_unref(mchan); + } + return 0; +} + +static int func_mchan_write(struct ast_channel *chan, const char *function, + char *data, const char *value) +{ + struct ast_channel *mchan = ast_channel_get_by_name(chan->linkedid); + pbx_builtin_setvar_helper(mchan ? mchan : chan, data, value); + if (mchan) { + ast_channel_unref(mchan); + } + return 0; +} + +static struct ast_custom_function mchan_function = { + .name = "MASTER_CHANNEL", + .read2 = func_mchan_read, + .write = func_mchan_write, +}; + static int unload_module(void) { int res = 0; - + res |= ast_custom_function_unregister(&channel_function); res |= ast_custom_function_unregister(&channels_function); - + res |= ast_custom_function_unregister(&mchan_function); + return res; } static int load_module(void) { int res = 0; - + res |= ast_custom_function_register(&channel_function); res |= ast_custom_function_register(&channels_function); - + res |= ast_custom_function_register(&mchan_function); + return res; }