[Asterisk-code-review] chan pjsip: add a new function PJSIPDtmfMode() (asterisk[13])

Torrey Searle asteriskteam at digium.com
Mon Jun 26 07:56:49 CDT 2017


Torrey Searle has uploaded this change for review. ( https://gerrit.asterisk.org/5909


Change subject: chan_pjsip: add a new function PJSIPDtmfMode()
......................................................................

chan_pjsip: add a new function PJSIPDtmfMode()

This function is a replica of SIPDtmfMode, allowing the DTMF mode of a
PJSIP call to be modified on a per-call basis

Change-Id: I20eef5da3e5d1d3e58b304416bc79683f87e7612
---
M CHANGES
M channels/chan_pjsip.c
2 files changed, 106 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/09/5909/1

diff --git a/CHANGES b/CHANGES
index 1b87dbf..95420b8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -44,6 +44,9 @@
    from the SDP, unless the remote side sends a different codec and we will
    switch to match.
 
+ * New dialplan function PJSIPDtmfMode added to change the dtmf mode of a
+   channel on a per-call basis
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.15.0 to Asterisk 13.16.0 ----------
 ------------------------------------------------------------------------------
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 486a237..8be0764 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -105,6 +105,7 @@
 static int chan_pjsip_devicestate(const char *data);
 static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
 static const char *chan_pjsip_get_uniqueid(struct ast_channel *ast);
+static int pjsip_dtmfmode(struct ast_channel *chan, const char *data);
 
 /*! \brief PBX interface structure for channel registration */
 struct ast_channel_tech chan_pjsip_tech = {
@@ -1700,7 +1701,6 @@
 	struct chan_pjsip_pvt *pvt = channel->pvt;
 	struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
 	int res = 0;
-
 	switch (channel->session->endpoint->dtmf) {
 	case AST_SIP_DTMF_RFC_4733:
 		if (!media || !media->rtp) {
@@ -1819,7 +1819,6 @@
 	case AST_SIP_DTMF_INFO:
 	{
 		struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
-
 		if (!dtmf_data) {
 			return -1;
 		}
@@ -2617,6 +2616,102 @@
 	.write = pjsip_acf_session_refresh_write,
 };
 
+
+/*** DOCUMENTATION
+	<application name="PJSIPDtmfMode" language="en_US">
+		<synopsis>
+			Change the dtmfmode for a SIP call.
+		</synopsis>
+		<syntax>
+			<parameter name="mode" required="true">
+				<enumlist>
+					<enum name="inband" />
+					<enum name="info" />
+					<enum name="rfc2833" />
+				</enumlist>
+			</parameter>
+		</syntax>
+		<description>
+			<para>Changes the dtmfmode for a SIP call.</para>
+		</description>
+	</application>
+ ***/
+
+static char *app_pjdtmfmode = "PJSIPDtmfMode";
+/*! \brief Set the DTMFmode for an outbound SIP call (application) */
+static int pjsip_dtmfmode(struct ast_channel *chan, const char *data)
+{
+	struct ast_sip_channel_pvt *pchannel;
+	struct chan_pjsip_pvt *pjsip_pvt;
+	const char *mode = data;
+	int dsp_features = 0;
+
+	if (!data) {
+		ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
+		return 0;
+	}
+	ast_channel_lock(chan);
+	if (ast_channel_tech(chan) != &chan_pjsip_tech) {
+		ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
+		ast_channel_unlock(chan);
+		return 0;
+	}
+	pchannel = ast_channel_tech_pvt(chan);
+	if (!pchannel) {
+		ast_log(LOG_WARNING, "ast_sip_channel_pvt not assigned \n");
+		ast_channel_unlock(chan);
+		return 0;
+	}
+	if (!strcasecmp(mode, "info")) {
+		pchannel->session->endpoint->dtmf= AST_SIP_DTMF_INFO;
+	} else if (!strcasecmp(mode, "rfc2833")) {
+		pchannel->session->endpoint->dtmf= AST_SIP_DTMF_RFC_4733;
+	} else if (!strcasecmp(mode, "inband")) {
+		pchannel->session->endpoint->dtmf= AST_SIP_DTMF_INBAND;
+	} else {
+		ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode);
+	}
+	pjsip_pvt = pchannel->pvt;
+	if (pjsip_pvt->media && pjsip_pvt->media[SIP_MEDIA_AUDIO]  && (pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp) {
+		if (pchannel->session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733) {
+			ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 1);
+			ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_RFC2833);
+		} else if (pchannel->session->endpoint->dtmf == AST_SIP_DTMF_INFO) {
+			ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 0);
+			ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_NONE);
+		} else if (pchannel->session->endpoint->dtmf == AST_SIP_DTMF_INBAND) {
+			ast_rtp_instance_set_prop((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_PROPERTY_DTMF, 0);
+			ast_rtp_instance_dtmf_mode_set((pjsip_pvt->media[SIP_MEDIA_AUDIO])->rtp, AST_RTP_DTMF_MODE_INBAND);
+		}
+	}
+
+	if (pchannel->session->dsp){
+		dsp_features = ast_dsp_get_features(pchannel->session->dsp);
+	}
+	if ((pchannel->session->endpoint->dtmf == AST_SIP_DTMF_INBAND) ||
+		(pchannel->session->endpoint->dtmf == AST_SIP_DTMF_AUTO)) {
+		dsp_features |= DSP_FEATURE_DIGIT_DETECT;
+	} else {
+		dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
+	}
+	if (dsp_features) {
+		if (!pchannel->session->dsp) {
+			if (!(pchannel->session->dsp = ast_dsp_new())) {
+				/* Release the ref held by session->inv_session */
+				ao2_ref(pchannel->session, -1);
+				ast_channel_unlock(chan);
+				return 0;
+			}
+		}
+		ast_dsp_set_features(pchannel->session->dsp, dsp_features);
+	} else if (pchannel->session->dsp) {
+		ast_dsp_free(pchannel->session->dsp);
+		pchannel->session->dsp = NULL;
+	}
+	ast_channel_unlock(chan);
+	return 0;
+}
+
 /*!
  * \brief Load the module
  *
@@ -2710,6 +2805,9 @@
 		ao2_ref(endpoints, -1);
 	}
 
+	/* Register dialplan applications */
+	ast_register_application_xml(app_pjdtmfmode, pjsip_dtmfmode);
+
 	return 0;
 
 end:
@@ -2745,6 +2843,9 @@
 	ao2_ref(chan_pjsip_tech.capabilities, -1);
 	ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
 
+	/* Unregister dial plan applications */
+	ast_unregister_application(app_pjdtmfmode);
+
 	return 0;
 }
 

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

Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-MessageType: newchange
Gerrit-Change-Id: I20eef5da3e5d1d3e58b304416bc79683f87e7612
Gerrit-Change-Number: 5909
Gerrit-PatchSet: 1
Gerrit-Owner: Torrey Searle <tsearle at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20170626/d096299f/attachment-0001.html>


More information about the asterisk-code-review mailing list