From c5afcb4e629c9ba4f0863ddf6f18f40ff9cfccfe Mon Sep 17 00:00:00 2001
From: "wenpeng.song" <wenpeng.song@iopsys.eu>
Date: Thu, 25 Apr 2024 15:58:53 +0200
Subject: [PATCH] dtmf payload sync

---
 include/asterisk/channel.h  |  3 +++
 main/channel_internal_api.c |  9 +++++++++
 main/config.c               |  3 ++-
 main/options.c              |  4 +++-
 main/rtp_engine.c           | 11 ++++++++---
 res/res_pjsip_sdp_rtp.c     | 19 +++++++++++++++++++
 6 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 4f94cf27a6..dcc191cf32 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -4352,6 +4352,9 @@ int ast_channel_ptime_get(const struct ast_channel *chan);
 void ast_channel_ptime_set(struct ast_channel *chan, int ptime);
 enum ast_sip_dtmf_mode ast_channel_dtmf_mode_get(const struct ast_channel *chan);
 void ast_channel_dtmf_mode_set(struct ast_channel *chan, enum ast_sip_dtmf_mode dtmf_mode);
+int ast_channel_dtmf_pt_get(const struct ast_channel *chan);
+void ast_channel_dtmf_pt_set(struct ast_channel *chan, int dtmf_pt);
+
 
 /*!
  * \pre chan is locked
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index f9f90559b8..128a9e70be 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -234,6 +234,7 @@ struct ast_channel {
 	int emergency_ongoing; /*!< indicate if an emergency session is ongoing */
 	int ptime; /*!< Negotiated ptime */
 	enum ast_sip_dtmf_mode dtmf_mode;
+	int dtmf_pt;
 };
 
 /*! \brief The monotonically increasing integer counter for channel uniqueids */
@@ -885,6 +886,14 @@ void ast_channel_dtmf_mode_set(struct ast_channel *chan, enum ast_sip_dtmf_mode
 {
 	chan->dtmf_mode = dtmf_mode;
 }
+int ast_channel_dtmf_pt_get(const struct ast_channel *chan)
+{
+	return chan->dtmf_pt;
+}
+void ast_channel_dtmf_pt_set(struct ast_channel *chan, int dtmf_pt)
+{
+	chan->dtmf_pt = dtmf_pt;
+}
 
 rtp_statistics *ast_channel_rtpStats_get(const struct ast_channel *chan)
 {
diff --git a/main/config.c b/main/config.c
index 1074407967..73a26dcfb8 100644
--- a/main/config.c
+++ b/main/config.c
@@ -3822,7 +3822,8 @@ int32_done:
 		}
 		errno = 0;
 		x = strtoul(arg, &endptr, 0);
-		if (*endptr || errno || x > UINT32_MAX) {
+
+		if (*endptr!=NULL || errno || x > UINT32_MAX) {
 			error = 1;
 			goto uint32_done;
 		}
diff --git a/main/options.c b/main/options.c
index 1507bc6ba5..da9de8e907 100644
--- a/main/options.c
+++ b/main/options.c
@@ -379,8 +379,10 @@ void load_asterisk_conf(void)
 		/* http://www.iana.org/assignments/rtp-parameters
 		 * RTP dynamic payload types start at 96 normally; extend down to 0 */
 		} else if (!strcasecmp(v->name, "rtp_pt_dynamic")) {
+		ast_log(LOG_WARNING, "============ dynamic %d, value %s======\n", ast_option_rtpptdynamic, v->value);
 			ast_parse_arg(v->value, PARSE_UINT32|PARSE_IN_RANGE,
-			              &ast_option_rtpptdynamic, 0, AST_RTP_PT_FIRST_DYNAMIC);
+			              &ast_option_rtpptdynamic, AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT - 1);
+			ast_log(LOG_WARNING, "============ dynamic %d======\n", ast_option_rtpptdynamic);
 		} else if (!strcasecmp(v->name, "maxcalls")) {
 			if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
 				ast_option_maxcalls = 0;
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 92296c6548..14b4e2b3f1 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -3236,12 +3236,13 @@ static void add_static_payload(int payload, struct ast_format *format, int rtp_c
 	 * which if negative would cause an assertion.
 	 */
 	ast_assert(payload < (int)ARRAY_LEN(static_RTP_PT));
-
+ast_log(LOG_WARNING, "============payload: %d, rtp_code: %d ======\n", payload, rtp_code);
 	if (ast_option_rtpusedynamic && payload < 0) {
 		/*
 		 * We're going to build dynamic payloads dynamically. An RTP code is
 		 * required otherwise one will be dynamically allocated per instance.
 		 */
+		 ast_log(LOG_WARNING, "============ dynamic ======\n", payload, rtp_code);
 		return;
 	}
 
@@ -3767,7 +3768,7 @@ int ast_rtp_engine_init(void)
 
 	add_static_payload(99, ast_format_h264, 0);
 	add_static_payload(100, ast_format_vp8, 0);
-	add_static_payload(101, NULL, AST_RTP_DTMF);
+	//add_static_payload(101, NULL, AST_RTP_DTMF);
 	add_static_payload(102, ast_format_siren7, 0);
 	add_static_payload(103, ast_format_h263p, 0);
 	add_static_payload(104, ast_format_mp4, 0);
@@ -3795,7 +3796,11 @@ int ast_rtp_engine_init(void)
 	add_static_payload(126, ast_format_slin48, 0);
 	add_static_payload(127, ast_format_slin96, 0);
 	/* payload types above 127 are not valid */
-
+	if (ast_option_rtpptdynamic >= AST_RTP_PT_FIRST_DYNAMIC){
+		add_static_payload(ast_option_rtpptdynamic, NULL, AST_RTP_DTMF);
+	} else {
+		add_static_payload(101, NULL, AST_RTP_DTMF);
+	}
 	debug_category_rtp_id = ast_debug_category_register(AST_LOG_CATEGORY_RTP);
 	debug_category_rtp_packet_id = ast_debug_category_register(AST_LOG_CATEGORY_RTP_PACKET);
 	debug_category_rtcp_id = ast_debug_category_register(AST_LOG_CATEGORY_RTCP);
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index f41e4906c1..d83fbfe4bd 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -2215,6 +2215,25 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session,
 		framing = pj_strtoul(pj_strltrim(&attr->value));
 		ast_channel_ptime_set(session->channel, framing);
 	}
+	pjmedia_sdp_rtpmap rtpmap;
+	for (int i = 0; i < remote_stream->desc.fmt_count; ++i) {
+		/* Look for the optional rtpmap attribute */
+		if (!(attr = pjmedia_sdp_media_find_attr2(remote_stream, "rtpmap", &remote_stream->desc.fmt[i]))) {
+			continue;
+		}
+		if ((pjmedia_sdp_attr_get_rtpmap(attr, &rtpmap)) != PJ_SUCCESS) {
+			continue;
+		}
+		char name[256];
+        ast_copy_pj_str(name, &rtpmap.enc_name, sizeof(name));
+		if ((strcmp(name, "telephone-event") == 0) && (8000 == rtpmap.clock_rate)) {
+		    char payload[4];
+		    ast_copy_pj_str(payload, &rtpmap.pt, sizeof(name));
+		    ast_channel_dtmf_pt_set(session->channel, atoi(payload));
+		    ast_log(LOG_NOTICE, "========DTMF Payload Type:%d======= \n", ast_channel_dtmf_pt_get(session->channel));
+		    break;
+		}
+	}
 
 	ast_channel_codec_set(session->channel, ast_format_get_name(ast_format_cap_get_format(ast_stream_get_formats(asterisk_stream), 0)));
 	ast_log(LOG_NOTICE, "channel %s, codec: %s, ptime: %d \n", ast_channel_name(session->channel), ast_channel_codec_get(session->channel), ast_channel_ptime_get(session->channel));
-- 
GitLab