diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 6c5b00ef048d4702665dae349f8141a8fac33346..d90662bc9b41f7da136615c7d9545e122d6f3e67 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -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;
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 8f42bf3854e4b04e932f97193b1238daf62175b0..a723d2cf403559cb56f23e64be8f80f1ead196a2 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -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.
 			 */
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index ffae020f8a18c8042679384bd52917af37526fa4..b81d7ca5a5b4ea9e91116731e7c76b89f4c5720d 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -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);
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 170755b79b4e6a4c288f9466b494392044820399..06be07b2ad823b2eca0336af5a6d36b053ec1cf8 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -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);
diff --git a/main/channel.c b/main/channel.c
index 9955dea6868945693d7775313ca854fd02e77986..59d40dc6c531f2d8a92923c56625855d4cd3a5cc 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -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 */
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 81c2a0a5616e39cde9de6e97bf4f9f07f15736df..297bf3b77f28b611be84f090e6d51d433a1c8994 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -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;