[Asterisk-code-review] res pjsip: Add rtp keepalive endpoint option. (asterisk[certified/13.1])

Mark Michelson asteriskteam at digium.com
Thu Jul 9 14:39:18 CDT 2015


Mark Michelson has uploaded a new change for review.

  https://gerrit.asterisk.org/862

Change subject: res_pjsip: Add rtp_keepalive endpoint option.
......................................................................

res_pjsip: Add rtp_keepalive endpoint option.

This adds an "rtp_keepalive" option for PJSIP endpoints. Similar to the
chan_sip option, this specifies an interval, in seconds, at which we
will send RTP comfort noise frames. This can be useful for keeping RTP
sessions alive as well as keeping NAT associations alive during lulls.

ASTERISK-25242 #close
Reported by Mark Michelson

Change-Id: I5e5e31d8d5f3464e07e20555cb5435fe9736284f
---
M CHANGES
M include/asterisk/res_pjsip.h
M include/asterisk/res_pjsip_session.h
M res/res_pjsip.c
M res/res_pjsip/pjsip_configuration.c
M res/res_pjsip_sdp_rtp.c
M res/res_pjsip_session.c
7 files changed, 42 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/62/862/1

diff --git a/CHANGES b/CHANGES
index a5076aa..3b6aa4c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -17,6 +17,12 @@
  * Added the Linkedid header to the common channel headers listed for each
    channel in AMI events.
 
+res_pjsip
+------------------
+* A new 'rtp_keepalive' endpoint option has been added. This option specifies
+  an interval, in seconds, at which we will send RTP comfort noise packets to
+  the endpoint. This functions identically to chan_sip's "rtpkeepalive" option.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.1.0-cert1 to Asterisk 13.1-cert2 --
 ------------------------------------------------------------------------------
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 1fa313b..4eec344 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -487,6 +487,8 @@
 	enum ast_sip_session_media_encryption encryption;
 	/*! Do we want to optimistically support encryption if possible? */
 	unsigned int encryption_optimistic;
+	/*! Number of seconds between RTP keepalive packets */
+	unsigned int keepalive;
 };
 
 /*!
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index 48d5a47..488f36e 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -77,6 +77,8 @@
 	enum ast_sip_session_media_encryption encryption;
 	/*! \brief The media transport in use for this stream */
 	pj_str_t transport;
+	/*! \brief Scheduler ID for RTP keepalive */
+	int keepalive_sched_id;
 	/*! \brief Stream is on hold */
 	unsigned int held:1;
 	/*! \brief Stream type this session media handles */
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 7ced26f..ed4de95 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -748,6 +748,14 @@
 						have this accountcode set on it.
 					</para></description>
 				</configOption>
+				<configOption name="rtp_keepalive">
+					<synopsis>Number of seconds between RTP comfort noise keepalive packets.</synopsis>
+					<description><para>
+						At the specified interval, Asterisk will send an RTP comfort noise frame. This may
+						be useful for situations where Asterisk is behind a NAT and must keep a hole open
+						in order to allow for media to arrive at Asterisk.
+					</para></description>
+				</configOption>
 			</configObject>
 			<configObject name="auth">
 				<synopsis>Authentication type</synopsis>
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 30d7702..b2445dd 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1726,6 +1726,7 @@
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_avpf", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.use_avpf));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "force_avp", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.force_avp));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "media_use_received_transport", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.use_received_transport));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_keepalive", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.rtp.keepalive));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "one_touch_recording", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, info.recording.enabled));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "inband_progress", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, inband_progress));
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "call_group", "", group_handler, callgroup_to_str, NULL, 0, 0);
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index a85d1e8..50d8a63 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -106,6 +106,15 @@
 	}
 }
 
+static int send_keepalive(const void *data)
+{
+	struct ast_rtp_instance *rtp = (struct ast_rtp_instance *) data;
+
+	ast_rtp_instance_sendcng(rtp, 0);
+
+	return ast_rtp_instance_get_keepalive(rtp) * 1000;
+}
+
 /*! \brief Internal function which creates an RTP instance */
 static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, unsigned int ipv6)
 {
@@ -141,6 +150,16 @@
 			(session->endpoint->media.tos_video || session->endpoint->media.cos_video)) {
 		ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_video,
 				session->endpoint->media.cos_video, "SIP RTP Video");
+	}
+
+	if (session->endpoint->media.rtp.keepalive > 0) {
+		ast_rtp_instance_set_keepalive(session_media->rtp, session->endpoint->media.rtp.keepalive);
+		/* Schedule the initial keepalive early in case this is being used to punch holes through
+		 * a NAT. This way there won't be an awkward delay before media starts flowing in some
+		 * scenarios.
+		 */
+		session_media->keepalive_sched_id = ast_sched_add(sched, 500, send_keepalive,
+			session_media->rtp);
 	}
 
 	return 0;
@@ -1248,6 +1267,9 @@
 	if (session_media->rtp) {
 		ast_rtp_instance_stop(session_media->rtp);
 		ast_rtp_instance_destroy(session_media->rtp);
+		if (session_media->keepalive_sched_id != -1) {
+			AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
+		}
 	}
 	session_media->rtp = NULL;
 }
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 75cd7de..a2fddae 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -1035,6 +1035,7 @@
 		return CMP_STOP;
 	}
 	session_media->encryption = session->endpoint->media.rtp.encryption;
+	session_media->keepalive_sched_id = -1;
 	/* Safe use of strcpy */
 	strcpy(session_media->stream_type, handler_list->stream_type);
 	ao2_link(session->media, session_media);

-- 
To view, visit https://gerrit.asterisk.org/862
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5e5e31d8d5f3464e07e20555cb5435fe9736284f
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: certified/13.1
Gerrit-Owner: Mark Michelson <mmichelson at digium.com>



More information about the asterisk-code-review mailing list