[svn-commits] oej: branch oej/pinesounds-dtmf-feature-delay-1.4 r305983 - /team/oej/pinesou...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Feb 3 02:56:49 CST 2011


Author: oej
Date: Thu Feb  3 02:56:46 2011
New Revision: 305983

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=305983
Log:
Adding patch

Modified:
    team/oej/pinesounds-dtmf-feature-delay-1.4/res/res_features.c

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/res/res_features.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/res/res_features.c?view=diff&rev=305983&r1=305982&r2=305983
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/res/res_features.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/res/res_features.c Thu Feb  3 02:56:46 2011
@@ -1528,7 +1528,7 @@
 	int res = FEATURE_RETURN_PASSDIGITS;
 	int feature_detected = 0;
 
-	if (!(peer && chan && config) && operation) {
+	if (!(peer && chan && config) && operation == 1) {
 		return -1; /* can not run feature operation */
 	}
 
@@ -1541,10 +1541,15 @@
 				if (option_debug > 2) {
 					ast_log(LOG_DEBUG, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
 				}
-				if (operation) {
+				if (operation == 2) {
+					res = FEATURE_RETURN_SUCCESS; /* We found something */
+				} else if (operation) {
 					res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
 				}
-				memcpy(feature, &builtin_features[x], sizeof(feature));
+				if (feature) {
+					memcpy(feature, &builtin_features[x], sizeof(feature));
+				}
+
 				feature_detected = 1;
 				break;
 			} else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
@@ -1573,10 +1578,14 @@
 			if (option_debug > 2) {
 				ast_log(LOG_NOTICE, " Feature Found: %s exten: %s\n",tmpfeature->sname, tok);
 			}
-			if (operation) {
+			if (operation == 2) {
+				res = FEATURE_RETURN_SUCCESS; /* We found something */
+			} else if (operation) {
 				res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
 			}
-			memcpy(feature, tmpfeature, sizeof(feature));
+			if (feature) {
+				memcpy(feature, &builtin_features[x], sizeof(feature));
+			}
 			if (res != FEATURE_RETURN_KEEPTRYING) {
 				AST_RWLIST_UNLOCK(&feature_list);
 				break;
@@ -1633,6 +1642,12 @@
 int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, char *code, struct ast_call_feature *feature) {
 
 	return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, 0, feature);
+}
+
+/*! \brief Check if a feature exists */
+static int ast_feature_check(struct ast_channel *chan, struct ast_flags *features, char *code, struct ast_call_feature *feature) {
+
+	return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, 2, feature);
 }
 
 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
@@ -2086,6 +2101,7 @@
 	int hasfeatures=0;
 	int hadfeatures=0;
 	int autoloopflag;
+	int sendingdtmfdigit = 0;
 	struct ast_option_header *aoh;
 	struct ast_bridge_config backup_config;
 	struct ast_cdr *bridge_cdr = NULL;
@@ -2268,11 +2284,11 @@
 					if (option_debug)
 						ast_log(LOG_DEBUG, "Timed out for feature!\n");
 					if (!ast_strlen_zero(peer_featurecode)) {
-						ast_dtmf_stream(chan, peer, peer_featurecode, 0);
+						ast_dtmf_stream(chan, peer, peer_featurecode, f->len);
 						memset(peer_featurecode, 0, sizeof(peer_featurecode));
 					}
 					if (!ast_strlen_zero(chan_featurecode)) {
-						ast_dtmf_stream(peer, chan, chan_featurecode, 0);
+						ast_dtmf_stream(peer, chan, chan_featurecode, f->len);
 						memset(chan_featurecode, 0, sizeof(chan_featurecode));
 					}
 					if (f)
@@ -2338,9 +2354,7 @@
 				}
 				break;
 			}
-		} else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
-			/* eat it */
-		} else if (f->frametype == AST_FRAME_DTMF) {
+		} else if (f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_DTMF_BEGIN) {
 			char *featurecode;
 			int sense;
 
@@ -2357,47 +2371,76 @@
 			 * not overflowing it. 
 			 * \todo XXX how do we guarantee the latter ?
 			 */
-			featurecode[strlen(featurecode)] = f->subclass;
-			/* Get rid of the frame before we start doing "stuff" with the channels */
-			ast_frfree(f);
-			f = NULL;
-			config->feature_timer = backup_config.feature_timer;
-			res = feature_interpret(chan, peer, config, featurecode, sense);
-			switch(res) {
-			case FEATURE_RETURN_PASSDIGITS:
-				ast_dtmf_stream(other, who, featurecode, 0);
-				/* Fall through */
-			case FEATURE_RETURN_SUCCESS:
-				memset(featurecode, 0, sizeof(chan_featurecode));
-				break;
-			}
-			if (res >= FEATURE_RETURN_PASSDIGITS) {
-				res = 0;
-			} else 
-				break;
-			hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
-			if (hadfeatures && !hasfeatures) {
-				/* Restore backup */
-				memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
-				memset(&backup_config, 0, sizeof(struct ast_bridge_config));
-			} else if (hasfeatures) {
-				if (!hadfeatures) {
-					/* Backup configuration */
-					memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
-					/* Setup temporary config options */
-					config->play_warning = 0;
-					ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
-					ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
-					config->warning_freq = 0;
-					config->warning_sound = NULL;
-					config->end_sound = NULL;
-					config->start_sound = NULL;
-					config->firstpass = 0;
+ 			if (f->frametype == AST_FRAME_DTMF_BEGIN) {
+				char dtmfcode[2];
+				dtmfcode[0] = f->subclass;
+				dtmfcode[1] = '\0';
+
+				/* Take a peek if this is the beginning of a feature. If not, just pass this DTMF along untouched. */
+				res = ast_feature_check(chan, sense == FEATURE_SENSE_CHAN ? &(config->features_caller) : &(config->features_callee), &dtmfcode[0], NULL);
+				if (res == FEATURE_RETURN_PASSDIGITS) {
+					if (option_debug > 3) {
+						ast_log(LOG_DEBUG, "Passing DTMF through, since it is not a feature code\n");
+					}
+					ast_write(other, f);
+					sendingdtmfdigit = 1;
+				} else {
+					if (option_debug > 3) {
+						ast_log(LOG_DEBUG, "Not passing DTMF through, since it is a feature code\n");
+					}
 				}
-				config->start_time = ast_tvnow();
-				config->feature_timer = featuredigittimeout;
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer);
+			} else {
+				if (sendingdtmfdigit == 1) {
+					/* We let the BEGIN go through happily, so let's not bother with the END, since we already
+					   know it's not something we bother with */
+					ast_write(other, f);
+					sendingdtmfdigit = 0;
+				} else {
+					featurecode[strlen(featurecode)] = f->subclass;
+					/* Get rid of the frame before we start doing "stuff" with the channels */
+					ast_frfree(f);
+					f = NULL;
+					config->feature_timer = backup_config.feature_timer;
+					res = feature_interpret(chan, peer, config, featurecode, sense);
+					switch(res) {
+					case FEATURE_RETURN_PASSDIGITS:
+						ast_dtmf_stream(other, who, featurecode, 0);
+						/* Fall through */
+					case FEATURE_RETURN_SUCCESS:
+						memset(featurecode, 0, sizeof(chan_featurecode));
+						break;
+					}
+					if (res >= FEATURE_RETURN_PASSDIGITS) {
+						res = 0;
+					} else {
+						break;
+					}
+					hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
+					if (hadfeatures && !hasfeatures) {
+						/* Restore backup */
+						memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
+						memset(&backup_config, 0, sizeof(struct ast_bridge_config));
+					} else if (hasfeatures) {
+						if (!hadfeatures) {
+							/* Backup configuration */
+							memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
+							/* Setup temporary config options */
+							config->play_warning = 0;
+							ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
+							ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
+							config->warning_freq = 0;
+							config->warning_sound = NULL;
+							config->end_sound = NULL;
+							config->start_sound = NULL;
+							config->firstpass = 0;
+						}
+						config->start_time = ast_tvnow();
+						config->feature_timer = featuredigittimeout;
+						if (option_debug) {
+							ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer);
+						}
+					}
+				}
 			}
 		}
 		if (f)




More information about the svn-commits mailing list