diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index b342e0bae74b3fb106d26a0692c93925b71426a8..884ad4b00f552f3368e14e6cec620b1567fac6e2 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -4248,6 +4248,7 @@ static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disco
 	ast_copy_string(cause_code->chan_name, ast_channel_name(p->owner), AST_CHANNEL_NAME);
 	ast_copy_string(cause_code->code, cause_str, datalen + 1 - sizeof(*cause_code));
 	ast_queue_control_data(p->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, datalen);
+	ast_channel_hangupcause_hash_set(p->owner, cause_code, datalen);
 
 	/* when we have an owner we don't call dahdi_r2_disconnect_call here, that will
 	   be done in dahdi_hangup */
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 51e777cd0a8e014a71efff610dbd881f3af2d2fb..3774962887505b324c7dc1b53b4466a239e849f9 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -10237,7 +10237,12 @@ static int socket_process_helper(struct iax2_thread *thread)
 		cause_code->ast_cause = ies.causecode;
 		snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "IAX2 %s(%d)", subclass, ies.causecode);
 
-		iax2_queue_control_data(fr->callno, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+		iax2_lock_owner(fr->callno);
+		if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
+			ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+			ast_channel_hangupcause_hash_set(iaxs[fr->callno]->owner, cause_code, data_size);
+			ast_channel_unlock(iaxs[fr->callno]->owner);
+		}
 		if (!iaxs[fr->callno]) {
 			ast_variables_destroy(ies.vars);
 			ast_mutex_unlock(&iaxsl[fr->callno]);
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 252e87d3421ae6e299a8ac313318a686c990aeeb..03f7a447a15d9b424d68aa3f58fc41018d114f8e 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -27207,6 +27207,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct as
 				}
 
 				ast_queue_control_data(p->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+				ast_channel_hangupcause_hash_set(p->owner, cause_code, data_size);
 			}
 
 			handle_response(p, respid, e + len, req, seqno);
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index a7f7b2ff30d74fdc8d32187cf4184a5925e8e451..79e8e7cb24f4daad461bc9cfe7727f78e1fd1471 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -2819,6 +2819,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
 		cause_code->ast_cause = AST_CAUSE_NETWORK_OUT_OF_ORDER;
 	case ANALOG_EVENT_ONHOOK:
 		ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+		ast_channel_hangupcause_hash_set(ast, cause_code, data_size);
 		switch (p->sig) {
 		case ANALOG_SIG_FXOLS:
 		case ANALOG_SIG_FXOGS:
@@ -3498,6 +3499,7 @@ winkflashdone:
 					if (p->hanguponpolarityswitch) {
 						ast_debug(1, "HangingUp on polarity switch! channel %d\n", p->channel);
 						ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+						ast_channel_hangupcause_hash_set(ast, cause_code, data_size);
 						ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
 						p->polarity = POLARITY_IDLE;
 					} else {
diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index 2840c3b280235314df6e5e2064c95fafa60d29d5..da60e7edfa6e579679099dc2cb760738570d4db3 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -1300,6 +1300,7 @@ static void pri_queue_pvt_cause_data(struct sig_pri_span *pri, int chanpos, cons
 		ast_copy_string(cause_code->chan_name, ast_channel_name(chan), AST_CHANNEL_NAME);
 		ast_copy_string(cause_code->code, cause, datalen + 1 - sizeof(*cause_code));
 		ast_queue_control_data(chan, AST_CONTROL_PVT_CAUSE_CODE, cause_code, datalen);
+		ast_channel_hangupcause_hash_set(chan, cause_code, datalen);
 		ast_channel_unlock(chan);
 	}
 }
diff --git a/channels/sig_ss7.c b/channels/sig_ss7.c
index e6999238bb6087ba743865b5c8a9f748c3144aeb..0c9b8f51e7e49a136633df8cf1032b9ef4a54a5b 100644
--- a/channels/sig_ss7.c
+++ b/channels/sig_ss7.c
@@ -397,6 +397,7 @@ static void ss7_queue_pvt_cause_data(struct ast_channel *owner, const char *caus
 	ast_copy_string(cause_code->chan_name, ast_channel_name(owner), AST_CHANNEL_NAME);
 	ast_copy_string(cause_code->code, cause, datalen + 1 - sizeof(*cause_code));
 	ast_queue_control_data(owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, datalen);
+	ast_channel_hangupcause_hash_set(owner, cause_code, datalen);
 }