From 1377b9c84d966448f0f9f786f6ca28da3b424126 Mon Sep 17 00:00:00 2001
From: David Yat Sin <dyatsin@sangoma.com>
Date: Tue, 7 Feb 2012 14:28:47 -0500
Subject: [PATCH] freetdm: support for dtmf_on_start

---
 libs/freetdm/src/ftdm_io.c                    | 17 +++++++++++++
 .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c   | 25 +++++++++++++------
 libs/freetdm/src/include/freetdm.h            |  1 +
 libs/freetdm/src/include/private/ftdm_core.h  |  2 ++
 4 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index 07def33034..2d8ca00380 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -4610,6 +4610,9 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const
 		}
 
 		span->channels[chan_index]->dtmfdetect.duration_ms = chan_config->dtmfdetect_ms;
+		if (chan_config->dtmf_on_start) {
+			span->channels[chan_index]->dtmfdetect.trigger_on_start = 1;
+		}
 	}
 
 	return FTDM_SUCCESS;
@@ -4808,9 +4811,23 @@ static ftdm_status_t load_config(void)
 				chan_config.debugdtmf = ftdm_true(val);
 				ftdm_log(FTDM_LOG_DEBUG, "Setting debugdtmf to '%s'\n", chan_config.debugdtmf ? "yes" : "no");
 			} else if (!strncasecmp(var, "dtmfdetect_ms", sizeof("dtmfdetect_ms")-1)) {
+				if (chan_config.dtmf_on_start == FTDM_TRUE) {
+					chan_config.dtmf_on_start = FTDM_FALSE;
+					ftdm_log(FTDM_LOG_WARNING, "dtmf_on_start parameter disabled because dtmfdetect_ms specified\n");
+				}
 				if (sscanf(val, "%d", &(chan_config.dtmfdetect_ms)) != 1) {
 					ftdm_log(FTDM_LOG_ERROR, "invalid dtmfdetect_ms: '%s'\n", val);
 				}
+			} else if (!strncasecmp(var, "dtmf_on_start", sizeof("dtmf_on_start")-1)) {
+				if (chan_config.dtmfdetect_ms) {
+					ftdm_log(FTDM_LOG_WARNING, "dtmf_on_start parameter ignored because dtmf_detect_ms specified\n");
+				} else {
+					if (ftdm_true(val)) {
+						chan_config.dtmf_on_start = FTDM_TRUE;
+					} else {
+						chan_config.dtmf_on_start = FTDM_FALSE;
+					}
+				}
 			} else if (!strncasecmp(var, "iostats", sizeof("iostats")-1)) {
 				if (ftdm_true(val)) {
 					chan_config.iostats = FTDM_TRUE;
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
index 3c53b0edbc..a6c6e8cd5a 100644
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
+++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
@@ -1476,20 +1476,29 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
 
 			if (tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
 				ftdm_set_flag(fchan, FTDM_CHANNEL_MUTE);
-				//fchan->dtmfdetect.start_time = ftdm_current_time_in_ms();
+				if (fchan->dtmfdetect.duration_ms) {
+					fchan->dtmfdetect.start_time = ftdm_current_time_in_ms();
+				} else if (fchan->dtmfdetect.trigger_on_start) {
+					ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
+					ftdm_channel_queue_dtmf(fchan, tmp_dtmf);
+				}
 			}
 
 			if (tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
 				ftdm_clear_flag(fchan, FTDM_CHANNEL_MUTE);
 				if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) {
-					//ftdm_time_t diff = ftdm_current_time_in_ms() - fchan->dtmfdetect.start_time;
-					//if (diff > fchan->dtmfdetect.duration_ms) {
-					//ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c (duration:%d min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
-					ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
+					if (fchan->dtmfdetect.duration_ms) {
+						ftdm_time_t diff = ftdm_current_time_in_ms() - fchan->dtmfdetect.start_time;
+						if (diff > fchan->dtmfdetect.duration_ms) {
+							ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c (duration:%d min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
+							ftdm_channel_queue_dtmf(fchan, tmp_dtmf);
+						} else {
+							ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c (duration:%d min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
+						}
+					} else if (!fchan->dtmfdetect.trigger_on_start) {
+						ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
 						ftdm_channel_queue_dtmf(fchan, tmp_dtmf);
-						//} else {
-						//ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c (duration:%d min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
-						//}
+					}
 				}
 			} 
 		}
diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h
index c7be3cb4a8..0fbc4bf29b 100755
--- a/libs/freetdm/src/include/freetdm.h
+++ b/libs/freetdm/src/include/freetdm.h
@@ -487,6 +487,7 @@ typedef struct ftdm_channel_config {
 	float rxgain;
 	float txgain;
 	uint8_t debugdtmf;
+	uint8_t dtmf_on_start;
 	uint32_t dtmfdetect_ms;
 	uint8_t iostats;
 } ftdm_channel_config_t;
diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h
index fb1a2c71b7..d27bac345b 100644
--- a/libs/freetdm/src/include/private/ftdm_core.h
+++ b/libs/freetdm/src/include/private/ftdm_core.h
@@ -362,6 +362,8 @@ typedef struct {
 typedef struct {
 	uint32_t duration_ms;
 	ftdm_time_t start_time;
+	/* If set to 1, we will send DTMF event the the tone starts, instead of waiting for end */
+	uint8_t trigger_on_start; 
 } ftdm_dtmf_detect_t;
 
 /* 2^8 table size, one for each byte (sample) value */