mirror of
https://github.com/asterisk/asterisk.git
synced 2026-07-01 04:29:38 -07:00
Ensure that pvt cause information does not break native bridging
Channel drivers that allow native bridging need to handle AST_CONTROL_PVT_CAUSE_CODE frames and previously did not handle them properly, usually breaking out of the native bridge. This change corrects that behavior and exposes the available cause code information to the dialplan while native bridges are in place. This required exposing the HANGUPCAUSE hash setter outside of channel.c, so additional documentation has been added. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369086 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -7586,6 +7586,10 @@ static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_ch
|
||||
f = ast_read(who);
|
||||
switch (f ? f->frametype : AST_FRAME_CONTROL) {
|
||||
case AST_FRAME_CONTROL:
|
||||
if (f && f->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_channel_hangupcause_hash_set((who == c0) ? c1 : c0, f->data.ptr);
|
||||
break;
|
||||
}
|
||||
*fo = f;
|
||||
*rc = who;
|
||||
res = AST_BRIDGE_COMPLETE;
|
||||
|
||||
+12
-7
@@ -5593,19 +5593,24 @@ static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_cha
|
||||
res = AST_BRIDGE_COMPLETE;
|
||||
break;
|
||||
}
|
||||
if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
|
||||
*fo = f;
|
||||
*rc = who;
|
||||
res = AST_BRIDGE_COMPLETE;
|
||||
break;
|
||||
}
|
||||
other = (who == c0) ? c1 : c0; /* the 'other' channel */
|
||||
if ((f->frametype == AST_FRAME_CONTROL)) {
|
||||
if (f->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_channel_hangupcause_hash_set(other, f->data.ptr);
|
||||
} else if (!(flags & AST_BRIDGE_IGNORE_SIGS)
|
||||
&& (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
|
||||
*fo = f;
|
||||
*rc = who;
|
||||
res = AST_BRIDGE_COMPLETE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((f->frametype == AST_FRAME_VOICE) ||
|
||||
(f->frametype == AST_FRAME_TEXT) ||
|
||||
(f->frametype == AST_FRAME_VIDEO) ||
|
||||
(f->frametype == AST_FRAME_IMAGE) ||
|
||||
(f->frametype == AST_FRAME_DTMF) ||
|
||||
(f->frametype == AST_FRAME_CONTROL)) {
|
||||
(f->frametype == AST_FRAME_CONTROL && f->subclass.integer != AST_CONTROL_PVT_CAUSE_CODE)) {
|
||||
/* monitored dtmf take out of the bridge.
|
||||
* check if we monitor the specific source.
|
||||
*/
|
||||
|
||||
@@ -7583,7 +7583,7 @@ static enum ast_bridge_result misdn_bridge(struct ast_channel *c0,
|
||||
}
|
||||
f = ast_read(who);
|
||||
|
||||
if (!f || f->frametype == AST_FRAME_CONTROL) {
|
||||
if (!f || (f->frametype == AST_FRAME_CONTROL && f->subtype.integer != AST_CONTROL_PVT_CAUSE_CODE)) {
|
||||
/* got hangup .. */
|
||||
|
||||
if (!f) {
|
||||
@@ -7613,7 +7613,11 @@ static enum ast_bridge_result misdn_bridge(struct ast_channel *c0,
|
||||
}
|
||||
#endif
|
||||
|
||||
ast_write((who == c0) ? c1 : c0, f);
|
||||
if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_channel_hangupcause_hash_set((who == c0) ? c1 : c0, f->data.ptr);
|
||||
} else {
|
||||
ast_write((who == c0) ? c1 : c0, f);
|
||||
}
|
||||
}
|
||||
|
||||
chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1);
|
||||
|
||||
@@ -3565,6 +3565,15 @@ int ast_channel_get_cc_agent_type(struct ast_channel *chan, char *agent_type, si
|
||||
*/
|
||||
void ast_channel_unlink(struct ast_channel *chan);
|
||||
|
||||
/*!
|
||||
* \brief Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash
|
||||
* on the given channel
|
||||
*
|
||||
* \param chan channel on which to set the cause information
|
||||
* \param cause_code ast_control_pvt_cause_code structure containing cause information
|
||||
*/
|
||||
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code);
|
||||
|
||||
/* ACCESSOR FUNTIONS */
|
||||
/*! \brief Set the channel name */
|
||||
void ast_channel_name_set(struct ast_channel *chan, const char *name);
|
||||
|
||||
+3
-6
@@ -4208,12 +4208,9 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \brief Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash
|
||||
* on the given channel */
|
||||
static void set_hangupcause_hash(struct ast_channel *chan, const void *data)
|
||||
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code)
|
||||
{
|
||||
char causevar[256];
|
||||
const struct ast_control_pvt_cause_code *cause_code = data;
|
||||
|
||||
snprintf(causevar, sizeof(causevar), "HASH(HANGUPCAUSE,%s)", cause_code->chan_name);
|
||||
ast_func_write(chan, causevar, cause_code->code);
|
||||
@@ -4368,7 +4365,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
|
||||
ts = ast_get_indication_tone(ast_channel_zone(chan), "congestion");
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
set_hangupcause_hash(chan, data);
|
||||
ast_channel_hangupcause_hash_set(chan, data);
|
||||
res = 0;
|
||||
break;
|
||||
case AST_CONTROL_PROGRESS:
|
||||
@@ -5515,7 +5512,7 @@ struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_c
|
||||
break;
|
||||
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
set_hangupcause_hash(chan, f->data.ptr);
|
||||
ast_channel_hangupcause_hash_set(chan, f->data.ptr);
|
||||
break;
|
||||
|
||||
/* Ignore these */
|
||||
|
||||
+2
-2
@@ -933,7 +933,7 @@ static enum ast_bridge_result local_bridge_loop(struct ast_channel *c0, struct a
|
||||
}
|
||||
ast_frfree(fr);
|
||||
} else if (fr->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
|
||||
ast_channel_hangupcause_hash_set(other, fr->data.ptr);
|
||||
ast_frfree(fr);
|
||||
} else {
|
||||
*fo = fr;
|
||||
@@ -1227,7 +1227,7 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0,
|
||||
}
|
||||
ast_frfree(fr);
|
||||
} else if (fr->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
|
||||
ast_channel_hangupcause_hash_set(other, fr->data.ptr);
|
||||
ast_frfree(fr);
|
||||
} else {
|
||||
*fo = fr;
|
||||
|
||||
Reference in New Issue
Block a user