[asterisk-commits] dbailey: trunk r216094 - in /trunk: channels/ include/asterisk/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 3 14:40:56 CDT 2009


Author: dbailey
Date: Thu Sep  3 14:40:37 2009
New Revision: 216094

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=216094
Log:
Added detection DTMF CID without polarity change alert.

Added detection of DTMF tone energy levels on FXO channels in chan_dahdi
monitoring loop so DTMF CID can be detected without the need of a polarity
change precursor.  

(closes issue #9096)
Reported by: fleed
Patches:
      9096-chan_dahdi-trunk.diff uploaded by dbailey (license 819)
Tested by: cyberplant, sum, maturs

Modified:
    trunk/channels/chan_dahdi.c
    trunk/channels/sig_analog.c
    trunk/channels/sig_analog.h
    trunk/include/asterisk/callerid.h

Modified: trunk/channels/chan_dahdi.c
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/channels/chan_dahdi.c?view=diff&rev=216094&r1=216093&r2=216094
==============================================================================
--- trunk/channels/chan_dahdi.c (original)
+++ trunk/channels/chan_dahdi.c Thu Sep  3 14:40:37 2009
@@ -416,6 +416,7 @@
 static int numbufs = 4;
 
 static int mwilevel = 512;
+static int dtmfcid_level = 256;
 
 #ifdef HAVE_PRI
 #ifdef PRI_GETSET_TIMERS
@@ -1081,7 +1082,9 @@
 	int span;					/*!< Span number */
 	time_t guardtime;				/*!< Must wait this much time before using for new call */
 	int cid_signalling;				/*!< CID signalling type bell202 or v23 */
-	int cid_start;					/*!< CID start indicator, polarity or ring */
+	int cid_start;					/*!< CID start indicator, polarity or ring or DTMF without warning event */
+	int dtmfcid_holdoff_state;		/*!< State indicator that allows for line to settle before checking for dtmf energy */
+	struct timeval	dtmfcid_delay;  /*!< Time value used for allow line to settle */
 	int callingpres;				/*!< The value of calling presentation that we're going to use when placing a PRI call */
 	int callwaitingrepeat;				/*!< How many samples to wait before repeating call waiting */
 	int cidcwexpire;				/*!< When to expire our muting for CID/CW */
@@ -8924,7 +8927,8 @@
 		/* If we want caller id, we're in a prering state due to a polarity reversal
 		 * and we're set to use a polarity reversal to trigger the start of caller id,
 		 * grab the caller id and wait for ringing to start... */
-		} else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN))) {
+		} else if (p->use_callerid && (chan->_state == AST_STATE_PRERING &&
+						 (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN || p->cid_start == CID_START_DTMF_NOALERT))) {
 			/* If set to use DTMF CID signalling, listen for DTMF */
 			if (p->cid_signalling == CID_SIG_DTMF) {
 				int k = 0;
@@ -10082,8 +10086,10 @@
 						pfds[count].events = POLLPRI;
 						pfds[count].revents = 0;
 						/* Message waiting or r2 channels also get watched for reading */
-						if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk)
+						if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 
+							(i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
 							pfds[count].events |= POLLIN;
+						}
 						count++;
 					}
 				} else {
@@ -10094,8 +10100,10 @@
 						pfds[count].revents = 0;
 						/* If we are monitoring for VMWI or sending CID, we need to
 						   read from the channel as well */
-						if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk)
+						if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk ||
+							(i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
 							pfds[count].events |= POLLIN;
+						}
 						count++;
 					}
 				}
@@ -10185,7 +10193,7 @@
 						i = i->next;
 						continue;
 					}
-					if (!i->mwimonitor_fsk && !i->mwisendactive) {
+					if (!i->mwimonitor_fsk && !i->mwisendactive  && i->cid_start != CID_START_DTMF_NOALERT) {
 						ast_log(LOG_WARNING, "Whoa....  I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd);
 						i = i->next;
 						continue;
@@ -10211,6 +10219,50 @@
 										ast_free(mtd);
 									}
 									i->mwimonitoractive = 1;
+								}
+							}
+						/* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */
+						} else if (i->cid_start == CID_START_DTMF_NOALERT) {
+							int energy;
+							struct timeval now;
+							/* State machine dtmfcid_holdoff_state allows for the line to settle
+							 * before checking agin for dtmf energy.  Presently waits for 500 mS before checking again 
+							*/
+							if (1 == i->dtmfcid_holdoff_state) {
+								gettimeofday(&i->dtmfcid_delay, NULL);
+								i->dtmfcid_holdoff_state = 2;
+							} else if (2 == i->dtmfcid_holdoff_state) {
+								gettimeofday(&now, NULL);
+								if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) {
+									i->dtmfcid_holdoff_state = 0;
+								}
+							} else {
+								energy = calc_energy((unsigned char *) buf, res, AST_LAW(i));
+								if (!i->mwisendactive && energy > dtmfcid_level) {
+									pthread_t threadid;
+									struct ast_channel *chan;
+									ast_mutex_unlock(&iflock);
+									if (analog_lib_handles(i->sig, i->radio, i->oprmode)) {
+										res = analog_handle_init_event(i->sig_pvt, ANALOG_EVENT_DTMFCID);  
+										if (res) {
+											ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
+										} else {
+											i->dtmfcid_holdoff_state = 1;
+										}
+									} else {
+										chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0, NULL);
+										if (!chan) {
+											ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
+										} else {
+											res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan);
+											if (res) {
+												ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
+											} else {
+												i->dtmfcid_holdoff_state = 1;
+											}
+										}
+									}
+									ast_mutex_lock(&iflock);
 								}
 							}
 						}
@@ -11191,7 +11243,19 @@
 				analog_p->echotraining = conf->chan.echotraining;
 				analog_p->cid_signalling = conf->chan.cid_signalling;
 				analog_p->stripmsd = conf->chan.stripmsd;
-				analog_p->cid_start = ANALOG_CID_START_RING;
+				switch (conf->chan.cid_start) {
+					case CID_START_POLARITY:
+						analog_p->cid_start = ANALOG_CID_START_POLARITY;
+						break;
+					case CID_START_POLARITY_IN:
+						analog_p->cid_start = ANALOG_CID_START_POLARITY_IN;
+						break;
+					case CID_START_DTMF_NOALERT:
+						analog_p->cid_start = ANALOG_CID_START_DTMF_NOALERT;
+						break;
+					default:
+						analog_p->cid_start = ANALOG_CID_START_RING;
+				}
 				analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid;
 				analog_p->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection;
 				analog_p->ringt = conf->chan.ringt;
@@ -15181,6 +15245,8 @@
 				confp->chan.cid_start = CID_START_POLARITY_IN;
 			else if (!strcasecmp(v->value, "polarity"))
 				confp->chan.cid_start = CID_START_POLARITY;
+			else if (!strcasecmp(v->value, "dtmf"))
+				confp->chan.cid_start = CID_START_DTMF_NOALERT;
 			else if (ast_true(v->value))
 				confp->chan.cid_start = CID_START_RING;
 		} else if (!strcasecmp(v->name, "threewaycalling")) {
@@ -16016,6 +16082,8 @@
 				ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
 			} else if (!strcasecmp(v->name, "mwilevel")) {
 				mwilevel = atoi(v->value);
+			} else if (!strcasecmp(v->name, "dtmfcidlevel")) {
+				dtmfcid_level = atoi(v->value);
 			}
 		} else if (!(options & PROC_DAHDI_OPT_NOWARN) )
 			ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno);

Modified: trunk/channels/sig_analog.c
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/channels/sig_analog.c?view=diff&rev=216094&r1=216093&r2=216094
==============================================================================
--- trunk/channels/sig_analog.c (original)
+++ trunk/channels/sig_analog.c Thu Sep  3 14:40:37 2009
@@ -193,6 +193,8 @@
 		return ANALOG_CID_START_POLARITY;
 	} else if (!strcasecmp(value, "polarity_in")) {
 		return ANALOG_CID_START_POLARITY_IN;
+	} else if (!strcasecmp(value, "dtmf")) {
+		return ANALOG_CID_START_DTMF_NOALERT;
 	}
 
 	return 0;
@@ -207,6 +209,8 @@
 		return "Polarity";
 	case ANALOG_CID_START_POLARITY_IN:
 		return "Polarity_In";
+	case ANALOG_CID_START_DTMF_NOALERT:
+		return "DTMF";
 	}
 
 	return "Unknown";
@@ -2032,7 +2036,8 @@
 		/* If we want caller id, we're in a prering state due to a polarity reversal
 		 * and we're set to use a polarity reversal to trigger the start of caller id,
 		 * grab the caller id and wait for ringing to start... */
-		if (p->use_callerid && (chan->_state == AST_STATE_PRERING && (p->cid_start == ANALOG_CID_START_POLARITY || p->cid_start == ANALOG_CID_START_POLARITY_IN))) {
+		if (p->use_callerid && (chan->_state == AST_STATE_PRERING &&
+				  (p->cid_start == ANALOG_CID_START_POLARITY || p->cid_start == ANALOG_CID_START_POLARITY_IN || p->cid_start == ANALOG_CID_START_DTMF_NOALERT))) {
 			/* If set to use DTMF CID signalling, listen for DTMF */
 			if (p->cid_signalling == CID_SIG_DTMF) {
 				int i = 0;
@@ -3239,7 +3244,7 @@
 		case ANALOG_SIG_SF_FEATB:
 		case ANALOG_SIG_SF:
 			/* Check for callerid, digits, etc */
-			if (i->cid_start == ANALOG_CID_START_POLARITY_IN) {
+			if (i->cid_start == ANALOG_CID_START_POLARITY_IN || i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
 				chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
 			} else {
 				chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL, NULL);
@@ -3356,6 +3361,27 @@
 				"interface %d\n", i->channel);
 		}
 		break;
+	case ANALOG_EVENT_DTMFCID:
+		switch (i->sig) {
+			case ANALOG_SIG_FXSLS:
+			case ANALOG_SIG_FXSKS:
+			case ANALOG_SIG_FXSGS:
+				if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
+					ast_verbose(VERBOSE_PREFIX_2 "Starting DTMF CID detection on channel %d\n",
+								i->channel);
+					chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
+					i->ss_astchan = chan;
+					if (chan && ast_pthread_create(&threadid, &attr, __analog_ss_thread, i)) {
+						ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
+					}
+				}
+				break;
+			default:
+				ast_log(LOG_WARNING, "handle_init_event detected "
+						"dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) "
+								"interface %d\n", i->channel);
+		}
+		break;
 	case ANALOG_EVENT_NEONMWI_ACTIVE:
 		analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_ACTIVE);
 		break;

Modified: trunk/channels/sig_analog.h
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/channels/sig_analog.h?view=diff&rev=216094&r1=216093&r2=216094
==============================================================================
--- trunk/channels/sig_analog.h (original)
+++ trunk/channels/sig_analog.h Thu Sep  3 14:40:37 2009
@@ -80,6 +80,7 @@
 	ANALOG_EVENT_ERROR,
 	ANALOG_EVENT_NEONMWI_ACTIVE,
 	ANALOG_EVENT_NEONMWI_INACTIVE,
+	ANALOG_EVENT_DTMFCID,
 };
 
 enum analog_sub {
@@ -97,6 +98,7 @@
 	ANALOG_CID_START_POLARITY = 1,
 	ANALOG_CID_START_POLARITY_IN,
 	ANALOG_CID_START_RING,
+	ANALOG_CID_START_DTMF_NOALERT,
 };
 
 #define ANALOG_MAX_CID 300
@@ -187,6 +189,7 @@
 	void (* const decrease_ss_count)(void);
 
 	int (* const distinctive_ring)(struct ast_channel *chan, void *pvt, int idx, int *ringdata);
+	/* Sets the specified sub-channel in and out of signed linear mode, returns the value that was overwritten */
 	int (* const set_linear_mode)(void *pvt, int idx, int linear_mode);
 	void (* const get_and_handle_alarms)(void *pvt);
 	void * (* const get_sigpvt_bridged_channel)(struct ast_channel *chan);

Modified: trunk/include/asterisk/callerid.h
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/include/asterisk/callerid.h?view=diff&rev=216094&r1=216093&r2=216094
==============================================================================
--- trunk/include/asterisk/callerid.h (original)
+++ trunk/include/asterisk/callerid.h Thu Sep  3 14:40:37 2009
@@ -60,9 +60,10 @@
 #define CID_SIG_V23_JP	4
 #define CID_SIG_SMDI	5
 
-#define CID_START_RING	1
-#define CID_START_POLARITY 2
-#define CID_START_POLARITY_IN 3
+#define CID_START_RING			1
+#define CID_START_POLARITY 		2
+#define CID_START_POLARITY_IN 	3
+#define CID_START_DTMF_NOALERT	4
 
 /* defines dealing with message waiting indication generation */
 /*! MWI SDMF format */




More information about the asterisk-commits mailing list