[Asterisk-code-review] res pjsip: Add fax detect timeout endpoint option. (asterisk[master])

Richard Mudgett asteriskteam at digium.com
Tue Jul 19 12:25:03 CDT 2016


Richard Mudgett has uploaded a new change for review.

  https://gerrit.asterisk.org/3238

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

res_pjsip: Add fax_detect_timeout endpoint option.

The new endpoint option allows the PJSIP channel driver's fax_detect
endpoint option to timeout on a call after the specified number of
seconds into a call.  The new feature is disabled if the timeout is set
to zero.  The option is disabled by default.

ASTERISK-26214
Reported by: Richard Mudgett

Change-Id: Id5a87375fb2c4f9dc1d4b44c78ec8735ba65453d
---
M CHANGES
M channels/chan_pjsip.c
M configs/samples/pjsip.conf.sample
A contrib/ast-db-manage/config/versions/4a6c67fa9b7a_add_fax_detect_timeout_option.py
M include/asterisk/res_pjsip.h
M include/asterisk/res_pjsip_session.h
M main/channel.c
M res/res_pjsip.c
M res/res_pjsip/pjsip_configuration.c
9 files changed, 105 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/38/3238/1

diff --git a/CHANGES b/CHANGES
index 9caa524..62d8178 100644
--- a/CHANGES
+++ b/CHANGES
@@ -366,6 +366,10 @@
 
 res_pjsip
 ------------------
+ * Added "fax_detect_timeout" to endpoint.
+   The option determines how many seconds into a call before fax_detect
+   is disabled for the call.  Setting the value to zero disables the timeout.
+
  * Added "subscribe_context" to endpoint.
    If specified, incoming SUBSCRIBE requests will be searched for the matching
    extension in the indicated context. If no "subscribe_context" is specified,
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 5ad1174..5a341f8 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -612,10 +612,12 @@
 {
 	const char *target_context;
 	int exists;
+	int dsp_features;
 
-	/* If we only needed this DSP for fax detection purposes we can just drop it now */
-	if (session->endpoint->dtmf == AST_SIP_DTMF_INBAND || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) {
-		ast_dsp_set_features(session->dsp, DSP_FEATURE_DIGIT_DETECT);
+	dsp_features = ast_dsp_get_features(session->dsp);
+	dsp_features &= ~DSP_FEATURE_FAX_DETECT;
+	if (dsp_features) {
+		ast_dsp_set_features(session->dsp, dsp_features);
 	} else {
 		ast_dsp_free(session->dsp);
 		session->dsp = NULL;
@@ -660,6 +662,7 @@
 static struct ast_frame *chan_pjsip_read(struct ast_channel *ast)
 {
 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct ast_sip_session *session;
 	struct chan_pjsip_pvt *pvt = channel->pvt;
 	struct ast_frame *f;
 	struct ast_sip_session_media *media = NULL;
@@ -697,22 +700,42 @@
 		return f;
 	}
 
-	if (ast_format_cap_iscompatible_format(channel->session->endpoint->media.codecs, f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+	session = channel->session;
+
+	if (ast_format_cap_iscompatible_format(session->endpoint->media.codecs, f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
 		ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when endpoint '%s' is not configured for it\n",
 			ast_format_get_name(f->subclass.format), ast_channel_name(ast),
-			ast_sorcery_object_get_id(channel->session->endpoint));
+			ast_sorcery_object_get_id(session->endpoint));
 
 		ast_frfree(f);
 		return &ast_null_frame;
 	}
 
-	if (channel->session->dsp) {
-		f = ast_dsp_process(ast, channel->session->dsp, f);
+	if (session->dsp) {
+		int dsp_features;
 
+		dsp_features = ast_dsp_get_features(session->dsp);
+		if ((dsp_features & DSP_FEATURE_FAX_DETECT)
+			&& session->endpoint->faxdetect_timeout
+			&& session->endpoint->faxdetect_timeout <= ast_channel_get_up_time(ast)) {
+			dsp_features &= ~DSP_FEATURE_FAX_DETECT;
+			if (dsp_features) {
+				ast_dsp_set_features(session->dsp, dsp_features);
+			} else {
+				ast_dsp_free(session->dsp);
+				session->dsp = NULL;
+			}
+			ast_debug(3, "Channel driver fax CNG detection timeout on %s\n",
+				ast_channel_name(ast));
+		}
+	}
+	if (session->dsp) {
+		f = ast_dsp_process(ast, session->dsp, f);
 		if (f && (f->frametype == AST_FRAME_DTMF)) {
 			if (f->subclass.integer == 'f') {
-				ast_debug(3, "Fax CNG detected on %s\n", ast_channel_name(ast));
-				f = chan_pjsip_cng_tone_detected(channel->session, f);
+				ast_debug(3, "Channel driver fax CNG detected on %s\n",
+					ast_channel_name(ast));
+				f = chan_pjsip_cng_tone_detected(session, f);
 			} else {
 				ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
 					ast_channel_name(ast));
diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample
index 9069a66..4c42e8a 100644
--- a/configs/samples/pjsip.conf.sample
+++ b/configs/samples/pjsip.conf.sample
@@ -693,6 +693,10 @@
 ;t38_udptl_maxdatagram=0        ; T 38 UDPTL maximum datagram size (default:
                                 ; "0")
 ;fax_detect=no  ; Whether CNG tone detection is enabled (default: "no")
+;fax_detect_timeout=30  ; How many seconds into a call before fax_detect is
+                        ; disabled for the call.
+                        ; Zero disables the timeout.
+                        ; (default: "0")
 ;t38_udptl_nat=no       ; Whether NAT support is enabled on UDPTL sessions
                         ; (default: "no")
 ;t38_udptl_ipv6=no      ; Whether IPv6 is used for UDPTL Sessions (default:
diff --git a/contrib/ast-db-manage/config/versions/4a6c67fa9b7a_add_fax_detect_timeout_option.py b/contrib/ast-db-manage/config/versions/4a6c67fa9b7a_add_fax_detect_timeout_option.py
new file mode 100644
index 0000000..91774c4
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/4a6c67fa9b7a_add_fax_detect_timeout_option.py
@@ -0,0 +1,23 @@
+"""add fax_detect_timeout option
+
+Revision ID: 4a6c67fa9b7a
+Revises: 9deac0ae4717
+Create Date: 2016-07-18 18:20:44.249491
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '4a6c67fa9b7a'
+down_revision = '9deac0ae4717'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.add_column('ps_endpoints', sa.Column('fax_detect_timeout', sa.Integer))
+
+
+def downgrade():
+    op.drop_column('ps_endpoints', 'fax_detect_timeout')
+
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 6f59283..9dd70db 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -753,6 +753,8 @@
 	struct ast_acl_list *acl;
 	/* Restrict what IPs are allowed in the Contact header (for registration) */
 	struct ast_acl_list *contact_acl;
+	/*! The number of seconds into call to disable fax detection.  (0 = disabled) */
+	unsigned int faxdetect_timeout;
 };
 
 /*!
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index 5ca2c99..26dd451 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -139,7 +139,7 @@
 	struct ast_party_id id;
 	/*! Requested capabilities */
 	struct ast_format_cap *req_caps;
-	/*! Optional DSP, used only for inband DTMF detection if configured */
+	/*! Optional DSP, used only for inband DTMF/Fax-CNG detection if configured */
 	struct ast_dsp *dsp;
 	/*! Whether the termination of the session should be deferred */
 	unsigned int defer_terminate:1;
diff --git a/main/channel.c b/main/channel.c
index f654e4d..911c269 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -2692,10 +2692,28 @@
 	ast_channel_unref(chan);
 }
 
+/*!
+ * \internal
+ * \brief Set channel answered time if not already set.
+ * \since 13.11.0
+ *
+ * \param chan Channel to set answered time.
+ *
+ * \return Nothing
+ */
+static void set_channel_answer_time(struct ast_channel *chan)
+{
+	if (ast_tvzero(ast_channel_answertime(chan))) {
+		struct timeval answertime;
+
+		answertime = ast_tvnow();
+		ast_channel_answertime_set(chan, &answertime);
+	}
+}
+
 int ast_raw_answer(struct ast_channel *chan)
 {
 	int res = 0;
-	struct timeval answertime;
 
 	ast_channel_lock(chan);
 
@@ -2711,8 +2729,11 @@
 		return -1;
 	}
 
-	answertime = ast_tvnow();
-	ast_channel_answertime_set(chan, &answertime);
+	/*
+	 * Mark when incoming channel answered so we can know how
+	 * long the channel has been up.
+	 */
+	set_channel_answer_time(chan);
 
 	ast_channel_unlock(chan);
 
@@ -3911,6 +3932,12 @@
 					ast_frfree(f);
 					f = &ast_null_frame;
 				} else {
+					/*
+					 * Mark when outgoing channel answered so we can know how
+					 * long the channel has been up.
+					 */
+					set_channel_answer_time(chan);
+
 					ast_setstate(chan, AST_STATE_UP);
 				}
 			} else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index af2f937..4034faf 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -600,6 +600,14 @@
 						detected.
 					</para></description>
 				</configOption>
+				<configOption name="fax_detect_timeout">
+					<synopsis>How long into a call before fax_detect is disabled for the call</synopsis>
+					<description><para>
+						The option determines how many seconds into a call before the
+						fax_detect option is disabled for the call.  Setting the value
+						to zero disables the timeout.
+					</para></description>
+				</configOption>
 				<configOption name="t38_udptl_nat" default="no">
 					<synopsis>Whether NAT support is enabled on UDPTL sessions</synopsis>
 					<description><para>
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index d399f0b..16405eb 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1849,6 +1849,7 @@
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "t38_udptl_ec", "none", t38udptl_ec_handler, t38udptl_ec_to_str, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38_udptl_maxdatagram", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.t38.maxdatagram));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "fax_detect", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, faxdetect));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "fax_detect_timeout", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, faxdetect_timeout));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38_udptl_nat", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.t38.nat));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38_udptl_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.t38.ipv6));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tone_zone", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, zone));

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id5a87375fb2c4f9dc1d4b44c78ec8735ba65453d
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Richard Mudgett <rmudgett at digium.com>



More information about the asterisk-code-review mailing list