From 237b2001e3ce5728f5521d3ee5350d7706e769d0 Mon Sep 17 00:00:00 2001
From: Grzegorz Sluja <grzegorz.sluja@sigma.se>
Date: Fri, 13 Oct 2023 12:19:11 +0200
Subject: [PATCH] Use the same header for RTP/RTCP packets in DSP and Asterisk

- SSRC of RTCP and RTP should are synchronized
- source1->identifier is the SSRC of the peer stream
---
 src/channels/chan_voicemngr.c | 26 +++++++++-----------------
 src/channels/chan_voicemngr.h |  2 --
 2 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/src/channels/chan_voicemngr.c b/src/channels/chan_voicemngr.c
index f161446..4934f45 100644
--- a/src/channels/chan_voicemngr.c
+++ b/src/channels/chan_voicemngr.c
@@ -79,7 +79,7 @@ static int chan_voicemngr_in_conference(const struct chan_voicemngr_pvt *p);
 static int cwtimeout_cb(const void *data);
 static int call_waiting_cb(const void *data);
 static int r4hanguptimeout_cb(const void *data);
-static void chan_voicemngr_generate_rtp_packet(struct chan_voicemngr_subchannel *p, uint8_t *packet_buf, int type, int seqno, unsigned int rtp_timestamp);
+static void chan_voicemngr_generate_rtp_packet(struct chan_voicemngr_subchannel *p, uint8_t *packet_buf, int type, int seqno, unsigned int rtp_timestamp, unsigned int ssrc);
 static void chan_voicemngr_process_incoming_rtcp_packet(struct chan_voicemngr_subchannel *p, uint8_t *rtcp_frame, uint32_t rtcp_size);
 static void chan_voicemngr_process_outgoing_rtcp_packet(struct chan_voicemngr_subchannel *p, uint8_t *rtcp_frame, uint32_t rtcp_size);
 static int chan_voicemngr_mute_connection(struct chan_voicemngr_subchannel *p);
@@ -1747,7 +1747,7 @@ static int chan_voicemngr_write(struct ast_channel *ast, struct ast_frame *frame
 		pvt_lock(sub->parent, "TELCHAN write frame");
 
 		/* generate the rtp header */
-		chan_voicemngr_generate_rtp_packet(sub, ap->rtp, RTP_PT_CN, frame->seqno, rtp_timestamp);
+		chan_voicemngr_generate_rtp_packet(sub, ap->rtp, RTP_PT_CN, frame->seqno, rtp_timestamp, frame->ssrc);
 
 		sip_client_id = chan_voicemngr_get_sip_client_id(sub);
 		if (sip_client_id >= 0 && sip_client_id < MAX_SIP_CLIENTS) {
@@ -1783,7 +1783,7 @@ static int chan_voicemngr_write(struct ast_channel *ast, struct ast_frame *frame
 		pvt_lock(sub->parent, "TELCHAN write frame");
 
 		/* generate the rtp header */
-		chan_voicemngr_generate_rtp_packet(sub, ap->rtp, map_ast_codec_id_to_rtp(frame->subclass.format), frame->seqno, rtp_timestamp);
+		chan_voicemngr_generate_rtp_packet(sub, ap->rtp, map_ast_codec_id_to_rtp(frame->subclass.format), frame->seqno, rtp_timestamp, frame->ssrc);
 
 		sip_client_id = chan_voicemngr_get_sip_client_id(sub);
 		if (sip_client_id >= 0 && sip_client_id < MAX_SIP_CLIENTS) {
@@ -3199,7 +3199,10 @@ static void audio_packet_handler(pe_packet_t *p) {
 		} else {
 			ast_debug(9, "Wrong sip client id: %d\n", sip_client_id);
 		}
-		sub->dsp_ssrc = packet_buf32[2]; // save the DSP's SSRC
+		// write header values into frame so asterisk uses the same RTP header as DSP
+		frame.seqno = (ntohl(packet_buf32[0]) & 0xffff);
+		frame.ts =  ntohl(packet_buf32[1]);
+		frame.ssrc = ntohl(packet_buf32[2]);
 	} else if (packet_type == CHAN_VOICEMNGR_RTCP_SR || packet_type == CHAN_VOICEMNGR_RTCP_RR) {
 		frame.frametype = AST_FRAME_RTCP;
 		frame.data.ptr = ap->rtp;
@@ -3739,8 +3742,6 @@ static struct chan_voicemngr_pvt *chan_voicemngr_allocate_pvt(void)
 				sub->channel_state = ONHOOK;
 				sub->time_stamp = 0;
 				sub->sequence_number = 0;
-				sub->far_end_ssrc = 0;
-				sub->dsp_ssrc = 0;
 				sub->codec = -1;
 				sub->parent = tmp;
 				sub->cw_timer_id = -1;
@@ -4011,8 +4012,6 @@ static void chan_voicemngr_show_subchannels(struct ast_cli_args *a, struct chan_
 		ast_cli(a->fd, "  Connection init     : %d\n", sub->connection_init);
 		ast_cli(a->fd, "  Codec used          : %s\n", chan_voicemngr_get_codec_string(sub->codec));
 		ast_cli(a->fd, "  RTP sequence number : %d\n", sub->sequence_number);
-		ast_cli(a->fd, "  RTP Far End SSRC    : %d\n", sub->far_end_ssrc);
-		ast_cli(a->fd, "  RTP DSP SSRC        : %d\n", sub->dsp_ssrc);
 		ast_cli(a->fd, "  RTP timestamp       : %d\n", sub->time_stamp);
 		ast_cli(a->fd, "  CW Timer id         : %d\n", sub->cw_timer_id);
 		ast_cli(a->fd, "  CW Beep Timer id    : %d\n", sub->cw_tone_timer_id);
@@ -5358,9 +5357,6 @@ static int chan_voicemngr_signal_callerid(struct ast_channel *chan, struct chan_
 
 static int chan_voicemngr_create_connection(struct chan_voicemngr_subchannel *sub) {
 	if (!sub->connection_init) {
-		/* generate random nr for rtp header */
-		sub->far_end_ssrc = rand();
-
 		ast_debug(1, "Creating virtual Asterisk connection for pvt line_id=%i connection_id=%d\n", sub->parent->line_id, sub->connection_id);
 		sub->connection_init = 1;
 		sub->remote_jitter_count = 0;
@@ -5616,7 +5612,7 @@ static int chan_voicemngr_close_connection(struct chan_voicemngr_subchannel *sub
 }
 
 /* Generate rtp payload, 12 bytes of header and 160 bytes of ulaw payload */
-static void chan_voicemngr_generate_rtp_packet(struct chan_voicemngr_subchannel *sub, uint8_t *packet_buf, int type, int seqno, unsigned int rtp_timestamp)
+static void chan_voicemngr_generate_rtp_packet(struct chan_voicemngr_subchannel *sub, uint8_t *packet_buf, int type, int seqno, unsigned int rtp_timestamp, unsigned int ssrc)
 {
 	unsigned short* packet_buf16 = (unsigned short*)packet_buf;
 	unsigned int*   packet_buf32 = (unsigned int*)packet_buf;
@@ -5630,7 +5626,7 @@ static void chan_voicemngr_generate_rtp_packet(struct chan_voicemngr_subchannel
 	packet_buf16[1] = htons(seqno ? seqno : sub->sequence_number++); //Add sequence number
 	packet_buf32[1] = htonl(rtp_timestamp ? rtp_timestamp : sub->time_stamp); //Add timestamp
 	sub->time_stamp += sub->period*8;
-	packet_buf32[2] = sub->far_end_ssrc;
+	packet_buf32[2] = htonl(ssrc);
 }
 
 /*
@@ -5644,7 +5640,6 @@ static void chan_voicemngr_process_incoming_rtcp_packet(struct chan_voicemngr_su
 {
 	struct rtcp_header_t *rtcp_hdr = (struct rtcp_header_t *)rtcp_frame;
 	uint8_t *packet_end = rtcp_frame + rtcp_size;
-	unsigned int*   packet_buf32 = (unsigned int*)rtcp_frame;
 
 	while ((uint8_t *)rtcp_hdr + sizeof(struct rtcp_header_t) <= packet_end && // Minimum RTCP packet size validation
 			RTCP_GET_VERSION(rtcp_hdr) == RTP_VERSION &&  // RTP version validation
@@ -5654,14 +5649,11 @@ static void chan_voicemngr_process_incoming_rtcp_packet(struct chan_voicemngr_su
 				p->remote_jitter_count++;
 				p->farEndInterarrivalJitter = RTCP_SR_GET_INTERARRIVAL_JITTER(rtcp_hdr);
 				p->totalFarEndInterarrivalJitter += p->farEndInterarrivalJitter;
-				packet_buf32[7] = p->dsp_ssrc;	// replace Source Identifier with dsp's SSRC
 				/* Intentional fall through */
 			case RTCP_RR:
 			case RTCP_SDES:
 			case RTCP_XR:
 			case RTCP_BYE:
-				// Replace SSRC with far end  SSRC for all types of RTCP packets above
-				rtcp_hdr->ssrc = p->far_end_ssrc;
 				break;
 
 			default:
diff --git a/src/channels/chan_voicemngr.h b/src/channels/chan_voicemngr.h
index 8daab08..38343ab 100644
--- a/src/channels/chan_voicemngr.h
+++ b/src/channels/chan_voicemngr.h
@@ -152,8 +152,6 @@ struct chan_voicemngr_subchannel {
 	uint16_t sequence_number;	/* Endpoint RTP sequence number state */
 	unsigned int time_stamp;	/* Endpoint RTP time stamp state */
 	unsigned int period;		/* Endpoint RTP period */
-	unsigned int far_end_ssrc;	/* Endpoint RTP synchronization source of far end */
-	unsigned int dsp_ssrc;		/* Endpoint RTP synchronization source of DUT's DSP */
 	int codec;			/* Used codec */
 	struct chan_voicemngr_pvt *parent;	/* chan_voicemngr_line owning this subchannel */
 	int cw_timer_id;			/* Current call waiting timer id, -1 if no active timer */
-- 
GitLab