diff --git a/cdr/cdr_csv.c b/cdr/cdr_csv.c
index d8249e5f57f054154b68d849579d7c741eeb3550..ee3785fed806dfa31d43bd2ea2e89e0b1f499369 100644
--- a/cdr/cdr_csv.c
+++ b/cdr/cdr_csv.c
@@ -336,6 +336,12 @@ static int csv_log(struct ast_cdr *cdr)
 {
 	/* Make sure we have a big enough buf */
 	char buf[1024];
+
+	/* Don't create records for CDRs where dcontext = "hangup" */
+	if (!strcasecmp(cdr->dcontext, "hangup")) {
+		return 0;
+	}
+
 	if (build_csv_record(buf, sizeof(buf), cdr)) {
 		ast_log(LOG_WARNING, "Unable to create CSV record in %d bytes.  CDR not recorded!\n", (int)sizeof(buf));
 		return 0;
diff --git a/channels/chan_brcm.c b/channels/chan_brcm.c
index bf4629e8dd8cd1d4fd19c012372fbc743e9d781b..9eb146a7f473ec4a3d10899e06ad8cc049022385 100644
--- a/channels/chan_brcm.c
+++ b/channels/chan_brcm.c
@@ -85,6 +85,7 @@ static int brcm_stop_conference(struct brcm_subchannel *p);
 static int brcm_finish_transfer(struct ast_channel *owner, struct brcm_subchannel *p, int result);
 static int brcm_call(struct ast_channel *ast, const char *dest, int timeout);
 static int brcm_hangup(struct ast_channel *ast);
+static int brcm_getRtpStats(struct ast_channel *ast);
 static int brcm_answer(struct ast_channel *ast);
 static struct ast_frame *brcm_read(struct ast_channel *ast);
 static int brcm_write(struct ast_channel *ast, struct ast_frame *frame);
@@ -136,7 +137,7 @@ static int num_fxo_endpoints = -1;
 static int num_dect_endpoints = -1;
 static int num_endpoints = -1;
 static int clip = 1; // Caller ID presentation
-static rtp_statistics rtp_stats = {0};
+
 /* driver scheduler */
 static struct ast_sched_context *sched = NULL;
 
@@ -327,6 +328,7 @@ static struct ast_channel_tech brcm_tech = {
 	.read = brcm_read,				//Channel is locked
 	.write = brcm_write,				//Channel is locked
 	.send_digit_begin = brcm_senddigit_begin,	//Channel is NOT locked
+	.getRtpStats = brcm_getRtpStats,	//Channel is NOT locked
 	.send_digit_end = brcm_senddigit_end,		//Channel is NOT locked
 	.indicate = brcm_indicate,			//Channel is locked
 	.transfer = brcm_transfer			// Channel is locked
@@ -618,6 +620,28 @@ static int brcm_indicate(struct ast_channel *ast, int condition, const void *dat
 	return res;
 }
 
+static int brcm_getRtpStats(struct ast_channel *ast)
+{
+	struct brcm_subchannel *sub;
+
+	sub = ast_channel_tech_pvt(ast);
+	if (!sub) {
+		ast_log(LOG_ERROR, "Failed to get peer subchannel\n");
+		return -1;
+	}
+
+	pvt_lock(sub->parent, "brcm_getRtpStats");
+	if (sub->parent) {
+		if (endpt_get_rtp_stats(sub->parent->line_id)) {
+			ast_log(LOG_WARNING, "Unable to get RTP statistics\n");
+		}
+		ast_channel_rtpStats_set(ast, &sub->rtp_stats);
+	}
+	pvt_unlock(sub->parent);
+
+	return 0;
+}
+
 static int brcm_transfer(struct ast_channel *ast, const char *newdest)
 {
 	struct brcm_pvt *pvt;
@@ -894,11 +918,6 @@ static int brcm_hangup(struct ast_channel *ast)
         sub->conf_timer_id = -1;
         }
 
-	if (endpt_get_rtp_stats(p->line_id)) {
-		ast_log(LOG_WARNING, "Unable to get RTP statistics\n");
-	}
-	ast_channel_rtpStats_set(ast, &rtp_stats);
-
 	if (sub->channel_state == CALLWAITING) {
 		brcm_stop_callwaiting(p);
 	} else if (sub_peer->channel_state == ONHOLD &&
@@ -2488,6 +2507,9 @@ static void *brcm_process_event(struct endpt_event *ev) {
 			if (sub->channel_state == OFFHOOK || sub->channel_state == AWAITONHOOK) {
 				/* Received EVENT_ONHOOK in state OFFHOOK/AWAITONHOOK, stop dial/congestion tone */
 				brcm_stop_dialtone(p);
+			} else if (sub->channel_state == RINGBACK) {
+				/* Outgoing unanswered call - rtp stats need to be collected */
+				brcm_getRtpStats(owner);
 			}
 
 			sub->channel_state = ONHOOK;
@@ -3429,6 +3451,7 @@ static const struct blobmsg_policy endpt_count_policy[__MAX_ENDPOINTS] = {
 };
 
 enum {
+	RTP_STATS_LINE_ID,
 	RTP_STATS_LOCAL_BURST_DENSITY,
 	RTP_STATS_REMOTE_BURST_DENSITY,
 	RTP_STATS_LOCAL_BURST_DURATION,
@@ -3457,6 +3480,7 @@ enum {
 };
 
 static const struct blobmsg_policy endpt_rtp_stats_policy[__MAX_RTP_STATS] = {
+	[RTP_STATS_LINE_ID] = { .name = "lineId", .type = BLOBMSG_TYPE_INT16 },
 	[RTP_STATS_LOCAL_BURST_DENSITY] = { .name = "localBurstDensity", .type = BLOBMSG_TYPE_INT16 },
 	[RTP_STATS_REMOTE_BURST_DENSITY] = { .name = "remoteBurstDensity", .type = BLOBMSG_TYPE_INT16 },
 	[RTP_STATS_LOCAL_BURST_DURATION] = { .name = "localBurstDuration", .type = BLOBMSG_TYPE_INT16 },
@@ -3549,58 +3573,76 @@ static int endpt_get_count(void) {
 
 static void ubus_call_answer_rtp_stats(struct ubus_request *req, int type, struct blob_attr *msg) {
 	struct blob_attr *tb[__MAX_RTP_STATS];
+	uint16_t lineId = 0;
+	struct brcm_pvt *p = NULL;
+	struct brcm_subchannel *sub = NULL;
 
 	ast_log(LOG_DEBUG, "thread %d: got answer from endptmngr on rtp_stats ubus call.\n", ast_get_tid());
 	blobmsg_parse(endpt_rtp_stats_policy, __MAX_RTP_STATS, tb, blob_data(msg), blob_len(msg));
 
+	if (tb[RTP_STATS_LINE_ID])
+		lineId = blobmsg_get_u16(tb[RTP_STATS_LINE_ID]);
+
+	p = brcm_get_pvt_from_lineid(iflist, lineId);
+	if (!p) {
+		ast_log(LOG_ERROR, "No pvt with the line_id %d found!\n", lineId);
+		return;
+	}
+
+	sub = brcm_get_active_subchannel(p);
+	if (!sub) {
+		ast_log(LOG_ERROR, "No active subchannel to write rtp stats!\n");
+		return;
+	}
+
 	if (tb[RTP_STATS_LOCAL_BURST_DENSITY])
-		rtp_stats.localBurstDensity = blobmsg_get_u16(tb[RTP_STATS_LOCAL_BURST_DENSITY]);
+		sub->rtp_stats.localBurstDensity = blobmsg_get_u16(tb[RTP_STATS_LOCAL_BURST_DENSITY]);
 	if (tb[RTP_STATS_REMOTE_BURST_DENSITY])
-		rtp_stats.remoteBurstDensity = blobmsg_get_u16(tb[RTP_STATS_REMOTE_BURST_DENSITY]);
+		sub->rtp_stats.remoteBurstDensity = blobmsg_get_u16(tb[RTP_STATS_REMOTE_BURST_DENSITY]);
 	if (tb[RTP_STATS_LOCAL_BURST_DURATION])
-		rtp_stats.localBurstDuration = blobmsg_get_u16(tb[RTP_STATS_LOCAL_BURST_DURATION]);
+		sub->rtp_stats.localBurstDuration = blobmsg_get_u16(tb[RTP_STATS_LOCAL_BURST_DURATION]);
 	if (tb[RTP_STATS_REMOTE_BURST_DURATION])
-		rtp_stats.remoteBurstDuration = blobmsg_get_u16(tb[RTP_STATS_REMOTE_BURST_DURATION]);
+		sub->rtp_stats.remoteBurstDuration = blobmsg_get_u16(tb[RTP_STATS_REMOTE_BURST_DURATION]);
 	if (tb[RTP_STATS_LOCAL_GAP_DENSITY])
-		rtp_stats.localGapDensity = blobmsg_get_u16(tb[RTP_STATS_LOCAL_GAP_DENSITY]);
+		sub->rtp_stats.localGapDensity = blobmsg_get_u16(tb[RTP_STATS_LOCAL_GAP_DENSITY]);
 	if (tb[RTP_STATS_REMOTE_GAP_DENSITY])
-		rtp_stats.remoteGapDensity = blobmsg_get_u16(tb[RTP_STATS_REMOTE_GAP_DENSITY]);
+		sub->rtp_stats.remoteGapDensity = blobmsg_get_u16(tb[RTP_STATS_REMOTE_GAP_DENSITY]);
 	if (tb[RTP_STATS_LOCAL_GAP_DURATION])
-		rtp_stats.localGapDuration = blobmsg_get_u16(tb[RTP_STATS_LOCAL_GAP_DURATION]);
+		sub->rtp_stats.localGapDuration = blobmsg_get_u16(tb[RTP_STATS_LOCAL_GAP_DURATION]);
 	if (tb[RTP_STATS_REMOTE_GAP_DURATION])
-		rtp_stats.remoteGapDuration = blobmsg_get_u16(tb[RTP_STATS_REMOTE_GAP_DURATION]);
+		sub->rtp_stats.remoteGapDuration = blobmsg_get_u16(tb[RTP_STATS_REMOTE_GAP_DURATION]);
 	if (tb[RTP_STATS_LOCAL_JB_RATE])
-		rtp_stats.localJbRate = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_RATE]);
+		sub->rtp_stats.localJbRate = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_RATE]);
 	if (tb[RTP_STATS_REMOTE_JB_RATE])
-		rtp_stats.remoteJbRate = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_RATE]);
+		sub->rtp_stats.remoteJbRate = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_RATE]);
 	if (tb[RTP_STATS_LOCAL_JB_MAX])
-		rtp_stats.localJbMax = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_MAX]);
+		sub->rtp_stats.localJbMax = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_MAX]);
 	if (tb[RTP_STATS_REMOTE_JB_MAX])
-		rtp_stats.remoteJbMax = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_MAX]);
+		sub->rtp_stats.remoteJbMax = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_MAX]);
 	if (tb[RTP_STATS_LOCAL_JB_NOMINAL])
-		rtp_stats.localJbNominal = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_NOMINAL]);
+		sub->rtp_stats.localJbNominal = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_NOMINAL]);
 	if (tb[RTP_STATS_REMOTE_JB_NOMINAL])
-		rtp_stats.remoteJbNominal = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_NOMINAL]);
+		sub->rtp_stats.remoteJbNominal = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_NOMINAL]);
 	if (tb[RTP_STATS_LOCAL_JB_ABS_MAX])
-		rtp_stats.localJbAbsMax = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_ABS_MAX]);
+		sub->rtp_stats.localJbAbsMax = blobmsg_get_u16(tb[RTP_STATS_LOCAL_JB_ABS_MAX]);
 	if (tb[RTP_STATS_REMOTE_JB_ABS_MAX])
-		rtp_stats.remoteJbAbsMax = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_ABS_MAX]);
+		sub->rtp_stats.remoteJbAbsMax = blobmsg_get_u16(tb[RTP_STATS_REMOTE_JB_ABS_MAX]);
 	if (tb[RTP_STATS_DISCARDED])
-		rtp_stats.discarded = blobmsg_get_u32(tb[RTP_STATS_DISCARDED]);
+		sub->rtp_stats.discarded = blobmsg_get_u32(tb[RTP_STATS_DISCARDED]);
 	if (tb[RTP_STATS_LOST])
-		rtp_stats.lost = blobmsg_get_u32(tb[RTP_STATS_LOST]);
+		sub->rtp_stats.lost = blobmsg_get_u32(tb[RTP_STATS_LOST]);
 	if (tb[RTP_STATS_RX_PKTS])
-		rtp_stats.rxpkts = blobmsg_get_u32(tb[RTP_STATS_RX_PKTS]);
+		sub->rtp_stats.rxpkts = blobmsg_get_u32(tb[RTP_STATS_RX_PKTS]);
 	if (tb[RTP_STATS_TX_PKTS])
-		rtp_stats.txpkts = blobmsg_get_u32(tb[RTP_STATS_TX_PKTS]);
+		sub->rtp_stats.txpkts = blobmsg_get_u32(tb[RTP_STATS_TX_PKTS]);
 	if (tb[RTP_STATS_JB_AVG])
-		rtp_stats.jbAvg = blobmsg_get_u16(tb[RTP_STATS_JB_AVG]);
+		sub->rtp_stats.jbAvg = blobmsg_get_u16(tb[RTP_STATS_JB_AVG]);
 	if (tb[RTP_STATS_JITTER])
-		rtp_stats.jitter = blobmsg_get_u32(tb[RTP_STATS_JITTER]);
+		sub->rtp_stats.jitter = blobmsg_get_u32(tb[RTP_STATS_JITTER]);
 	if (tb[RTP_STATS_LOSS_RATE])
-		rtp_stats.uLossRate = blobmsg_get_u16(tb[RTP_STATS_LOSS_RATE]);
+		sub->rtp_stats.uLossRate = blobmsg_get_u16(tb[RTP_STATS_LOSS_RATE]);
 	if (tb[RTP_STATS_MAX_JITTER])
-		rtp_stats.maxJitter = blobmsg_get_u32(tb[RTP_STATS_MAX_JITTER]);
+		sub->rtp_stats.maxJitter = blobmsg_get_u32(tb[RTP_STATS_MAX_JITTER]);
 
 	ast_log(LOG_DEBUG, "RTP stats received:\nlocalBurstDensity: %d\nremoteBurstDensity: %d\n"
 			"localBurstDuration: %d\nremoteBurstDuration: %d\nlocalGapDensity: %d\n"
@@ -3609,13 +3651,13 @@ static void ubus_call_answer_rtp_stats(struct ubus_request *req, int type, struc
 			"localJbNominal: %d\nremoteJbNominal: %d\nlocalJbAbsMax: %d\n"
 			"remoteJbAbsMax: %d\ndiscarded: %d\nlost: %d\nrxpkts: %d\ntxpkts: %d\n"
 			"jbAvg: %d\njitter: %d\nuLossRate: %d\nmaxJitter: %d\n",
-			rtp_stats.localBurstDensity, rtp_stats.remoteBurstDensity, rtp_stats.localBurstDuration,
-			rtp_stats.remoteBurstDuration, rtp_stats.localGapDensity, rtp_stats.remoteGapDensity,
-			rtp_stats.localGapDuration, rtp_stats.remoteGapDuration, rtp_stats.localJbRate,
-			rtp_stats.remoteJbRate, rtp_stats.localJbMax, rtp_stats.remoteJbMax, rtp_stats.localJbNominal,
-			rtp_stats.remoteJbNominal, rtp_stats.localJbAbsMax, rtp_stats.remoteJbAbsMax, rtp_stats.discarded,
-			rtp_stats.lost, rtp_stats.rxpkts, rtp_stats.txpkts, rtp_stats.jbAvg, rtp_stats.jitter,
-			rtp_stats.uLossRate, rtp_stats.maxJitter);
+			sub->rtp_stats.localBurstDensity, sub->rtp_stats.remoteBurstDensity, sub->rtp_stats.localBurstDuration,
+			sub->rtp_stats.remoteBurstDuration, sub->rtp_stats.localGapDensity, sub->rtp_stats.remoteGapDensity,
+			sub->rtp_stats.localGapDuration, sub->rtp_stats.remoteGapDuration, sub->rtp_stats.localJbRate,
+			sub->rtp_stats.remoteJbRate, sub->rtp_stats.localJbMax, sub->rtp_stats.remoteJbMax, sub->rtp_stats.localJbNominal,
+			sub->rtp_stats.remoteJbNominal, sub->rtp_stats.localJbAbsMax, sub->rtp_stats.remoteJbAbsMax, sub->rtp_stats.discarded,
+			sub->rtp_stats.lost, sub->rtp_stats.rxpkts, sub->rtp_stats.txpkts, sub->rtp_stats.jbAvg, sub->rtp_stats.jitter,
+			sub->rtp_stats.uLossRate, sub->rtp_stats.maxJitter);
 }
 
 static int endpt_get_rtp_stats(int line) {
@@ -3623,13 +3665,26 @@ static int endpt_get_rtp_stats(int line) {
 	struct blob_buf bb;
 	struct ubus_request *req;
 	int ret;
+	struct brcm_pvt *p = NULL;
+	struct brcm_subchannel *sub = NULL;
 
 	/*
 	 * Reset rtp_stats first because ubus_call_answer_rtp_stats() will not be called if "ubus call endpt rtp_stats" fails,
 	 * e.g. an unanswered incoming call on which the connection is not created. In this case, all RTP statistics counters
 	 * shall be zeros.
 	 */
-	memset(&rtp_stats, 0, sizeof(rtp_stats));
+	p = brcm_get_pvt_from_lineid(iflist, line);
+	if (!p) {
+		ast_log(LOG_ERROR, "No pvt with the line %d found!\n", line);
+		return -1;
+	}
+
+	sub = brcm_get_active_subchannel(p);
+	if (!sub) {
+		ast_log(LOG_ERROR, "No active subchannel to get rtp stats!\n");
+		return -1;
+	}
+	memset(&sub->rtp_stats, 0, sizeof(sub->rtp_stats));
 
 	if (!endpt_id) {
 		return -1;
diff --git a/channels/chan_brcm.h b/channels/chan_brcm.h
index 5e1eca20d0733d234b886497c4aaaf48d4b84cc6..33a7da3fa1bc6fe355efea4ac6150bfee564cc50 100644
--- a/channels/chan_brcm.h
+++ b/channels/chan_brcm.h
@@ -111,7 +111,8 @@ struct brcm_subchannel {
 	int onhold_hangup_timer_id;	/* Current onhold hangup timer id, -1 if no active timer */
 	int conference_initiator;       /* True if this subchannel is the original leg in a 3-way conference */
 	char *conference_id;            /* uuid of the conference initiated by this subchannel */
-        int conf_timer_id;              /* Current conference call timer id, -1 if no active timer */
+	int conf_timer_id;              /* Current conference call timer id, -1 if no active timer */
+	rtp_statistics rtp_stats;	/* RTP statistics for currently hanging up channel */
 };
 
 
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index b091bad6281c9e50b193a4378a2c8d0eaea1bf07..ba8d74e1f9a90dd75edcccc4e1409dd01b3227cd 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -91,6 +91,7 @@ static struct ast_channel *chan_pjsip_request_with_stream_topology(const char *t
 static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg);
 static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text);
 static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit);
+static int chan_pjsip_getRtpStats(struct ast_channel *ast);
 static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int chan_pjsip_call(struct ast_channel *ast, const char *dest, int timeout);
 static int chan_pjsip_hangup(struct ast_channel *ast);
@@ -114,6 +115,7 @@ struct ast_channel_tech chan_pjsip_tech = {
 	.send_text = chan_pjsip_sendtext,
 	.send_text_data = chan_pjsip_sendtext_data,
 	.send_digit_begin = chan_pjsip_digit_begin,
+	.getRtpStats = chan_pjsip_getRtpStats,
 	.send_digit_end = chan_pjsip_digit_end,
 	.call = chan_pjsip_call,
 	.hangup = chan_pjsip_hangup,
@@ -2220,6 +2222,12 @@ static int chan_pjsip_transfer(struct ast_channel *chan, const char *target)
 	return 0;
 }
 
+/*! \brief Dummy function for getting RTP stats for PJSIP tech channel */
+static int chan_pjsip_getRtpStats(struct ast_channel *chan)
+{
+	return 0;
+}
+
 /*! \brief Function called by core to start a DTMF digit */
 static int chan_pjsip_digit_begin(struct ast_channel *chan, char digit)
 {
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 3bf020e1a4492b43532494a19992158411ef853f..1b7510606f96c62ed04538e100daffc92a0dadd6 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -711,6 +711,13 @@ struct ast_channel_tech {
 	 */
 	int (* const send_digit_begin)(struct ast_channel *chan, char digit);
 
+	/*!
+	 * \brief Get RTP stats for currently hanging up channel
+	 *
+	 * \note The channel is not locked when this function gets called.
+	 */
+	int (* const getRtpStats)(struct ast_channel *chan);
+
 	/*!
 	 * \brief Stop sending a literal DTMF digit
 	 *
diff --git a/main/bridge_channel.c b/main/bridge_channel.c
index 9d3934fae5d77d9a4b873c7802ff20788bbb69a6..d39e3e16ee0cbd648f08f03f0ef404d02f573f84 100644
--- a/main/bridge_channel.c
+++ b/main/bridge_channel.c
@@ -315,6 +315,7 @@ void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel,
 {
 	ast_bridge_channel_lock(bridge_channel);
 	ast_bridge_channel_leave_bridge_nolock(bridge_channel, new_state, cause);
+	ast_channel_tech(bridge_channel->chan)->getRtpStats(bridge_channel->chan);
 	ast_bridge_channel_unlock(bridge_channel);
 }
 
diff --git a/main/cdr.c b/main/cdr.c
index e549db6e92bd0db0847cd50e5966010b3e9014a6..5490291d91cd528185ae5dddc6b28ae7a709652f 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -2345,7 +2345,11 @@ static void handle_channel_snapshot_update_message(void *data, struct stasis_sub
 		cdr = ao2_find(active_cdrs_master, update->new_snapshot->base->uniqueid, OBJ_SEARCH_KEY);
 	}
 	if (update->new_snapshot->rtp_stats){
-		cdr->party_a.snapshot->rtp_stats = update->new_snapshot->rtp_stats;
+		if (cdr->party_a.snapshot)
+			cdr->party_a.snapshot->rtp_stats = update->new_snapshot->rtp_stats;
+		if (cdr->party_b.snapshot)
+			cdr->party_b.snapshot->rtp_stats = update->new_snapshot->rtp_stats;
+
 	}
 	/* Handle Party A */
 	if (!cdr) {