Project "FreeSWITCH Source" received a push.

branch: master updated

       via: 80cbfe6fa3f3e11852436d9fdbd44811775ac074 (commit)
       via: 93b85b5a4c8abff3be692288176a40fda5b13c3f (commit)
       via: 6a524a1d567f9e73d10d14067212bda5f67b7ffb (commit)
       via: d72cde9b76a856cf002366300bea02c26db44ffb (commit)
       via: 2404dd295aa0b6ef2e9da1598a4b3d479ee6317f (commit)
       via: 45b3adda57a9281d0dd4389884d2a42eebc7dbba (commit)
       via: 52bf0423e2231e7e16126baa13b8fef14132ac57 (commit)
       via: 33848eb01c327b04ad3c34bb5165bb1e01891863 (commit)
       via: 2d6161e889fdaf8b03608fefdd7ef480a56ddf8b (commit)
       via: e88b9639624cef4f35901146241f515730b3b118 (commit)
       via: 86d5e441da872719faf72e24afdda85d8491406b (commit)
       via: 9470e70057c549598d6d5e768d6cb08a2ba82104 (commit)
       via: 1f1541b474c549d6a13b6a943d13f046d463751a (commit)
       via: 766f2d61651f161b074fad2f987b4f10532a9a7a (commit)
       via: 1623e5d2952d63e2e49d454cd6fdf921a8516227 (commit)
       via: 256a82dbf2d7f4b4e1d7527f1e6a15d8d0d38a21 (commit)
       via: c8f5c66c3520ecda8f8dbc07dc01f1d4035058e4 (commit)
       via: 2ad81ac82f3c3c989e4d7d11f788c43c2c6f20d8 (commit)
       via: 49a5effcdf2cea9e0ddcf146cf3fe85d1872e654 (commit)
       via: be3483b924a674e4c4f0f05734e7e4917634f3ca (commit)
       via: e6e4bcea734fbfb54b901ff8b1107ddfe76b7010 (commit)
       via: 068d36a5c95c5a4143f423b7c36cbe6d5cea36d5 (commit)
       via: 9986f4ebf2a0c40cc99bc7f9f03f2dec6ae74645 (commit)
       via: 6d3abd41cadef3a2bff8175487c094c80d7d9cf7 (commit)
       via: b3ac44f555a80f8278c5f915cfb36766903905a4 (commit)
       via: 9e6503a482ff533ff214b01a07c3432be14ff1ce (commit)
       via: 97a2b4f9025099bdab5718a13ee36d15a6152411 (commit)
       via: 68b2756970bd4280eba700b7439afdff374fd9e3 (commit)
       via: 9b0c16b5d48a7b9d0ea15ac429a8ca4c8eef8693 (commit)
       via: f05fe55594ffca6edc8f4e74204650aa219ed1ac (commit)
       via: 08f494b80802aacf101705382f149ca4b028eb57 (commit)
       via: daa28cfccae9b171221408f3af4f8c10283e67b3 (commit)
       via: c64b78577f65b586ff6d7af711c79d0427fc61c5 (commit)
       via: 9ade16e9291aa74b4483bb9b9d9db266e082f7cc (commit)
       via: 314a2a1e2061ef321fa5f9b32a9c70ef0040cdb8 (commit)
       via: 48c02b7cd2770f6aee1d6e89f5ecfe207231f398 (commit)
       via: f954d21ab8f84ea3518525d6f8a5a25c5cd39d6b (commit)
       via: f8254f81607c9b2fe8ece3c48cb6dff700bcbead (commit)
       via: 608be370bcca24023ee9d05ee4a99c133044f0d3 (commit)
       via: 02082c930cc08cd65b3ac51d2e8231e502bd8f31 (commit)
       via: 89253a139117b32fa0a6dc101e53e9b830361048 (commit)
       via: 15e65cfafb8a46caca8bb8a63d55edf817f17f2d (commit)
       via: 92a9bacc44576e7b1d41c48752af597801e41d21 (commit)
       via: 8f483f41c78ae3dd1bad7c3378733f04438f6af1 (commit)
       via: 0f39c8f9c3d8e8bce05c551e0168e476ce29437a (commit)
       via: 6d7e019b5c0244f53c16361d2667049b430adb55 (commit)
       via: 128d53c2e6a73a6136efcfffa4e880e6635e43f1 (commit)
       via: 4cbdfbe481d7f9b448663418dccc88b017f9ce69 (commit)
       via: e719ae662b7cb08ebd7f8e732a140e9aeb502960 (commit)
       via: 439df43cae04a053a1c22befdd7f1009f6cb6dfa (commit)
       via: d395b654fb0abab4889d5b8c239728683e772959 (commit)
       via: acd56d2fe2a0458801010cc6b03c524023cbc597 (commit)
      from: 05a8a9455695ae8e6b63fe78bead1a92bee9183b (commit)


= COMMIT LOG ===========================================================
committer: Michael S Collins
comments: 
Merge branch 'master' of git://git.freeswitch.org/freeswitch
committer: David Yat Sin
comments: 
Merge branch 'master' of git.freeswitch.org:freeswitch
committer: David Yat Sin
comments: 
chlog: freetdm: Fix for only checking first progress indicator for early-media flag

diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
index 0b52011..578677a 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
@@ -385,8 +385,12 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
 				case FTDM_CHANNEL_STATE_DIALING:
 				case FTDM_CHANNEL_STATE_PROCEED:
 				case FTDM_CHANNEL_STATE_PROGRESS:
-				case FTDM_CHANNEL_STATE_RINGING:					
-					if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
+				case FTDM_CHANNEL_STATE_RINGING:
+					if ((cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) ||
+						(cnStEvnt->progInd1.eh.pres && cnStEvnt->progInd1.progDesc.val == IN_PD_IBAVAIL) ||
+						(cnStEvnt->progInd2.eh.pres && cnStEvnt->progInd2.progDesc.val == IN_PD_IBAVAIL) ||
+						(cnStEvnt->progInd3.eh.pres && cnStEvnt->progInd3.progDesc.val == IN_PD_IBAVAIL)) {
+						
 						ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n");
 						sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
 					} else {
committer: Anthony Minessale
comments: 
only execute execute_on_[answer|media|ring] async when its expressed in app::arg form vs 'app arg form'

diff --git a/src/switch_channel.c b/src/switch_channel.c
index de472a9..70b1879 100644
--- a/src/switch_channel.c
+++ b/src/switch_channel.c
@@ -2595,14 +2595,15 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi
 		if (var) {
 			char *arg = NULL;
 			app = switch_core_session_strdup(channel->session, var);
-			if ((arg = strchr(app, ' '))) {
-				*arg++ = '\0';
-			}
 
-			if (switch_core_session_in_thread(channel->session)) {
-				switch_core_session_execute_application(channel->session, app, arg);
-			} else {
+			if (strstr(app, "::")) {
 				switch_core_session_execute_application_async(channel->session, app, arg);
+			} else {
+				if ((arg = strchr(app, ' '))) {
+					*arg++ = '\0';
+				}
+				
+				switch_core_session_execute_application(channel->session, app, arg);
 			}
 		}
 
@@ -2653,14 +2654,16 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_
 			 (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))) && !zstr(var)) {
 			char *arg = NULL;
 			app = switch_core_session_strdup(channel->session, var);
-			if ((arg = strchr(app, ' '))) {
-				*arg++ = '\0';
-			}
 
-			if (switch_core_session_in_thread(channel->session)) {
-				switch_core_session_execute_application(channel->session, app, arg);
-			} else {
+
+			if (strstr(app, "::")) {
 				switch_core_session_execute_application_async(channel->session, app, arg);
+			} else {
+				if ((arg = strchr(app, ' '))) {
+					*arg++ = '\0';
+				}
+				
+				switch_core_session_execute_application(channel->session, app, arg);
 			}
 		}
 
@@ -2825,27 +2828,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan
 		 (!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))))
 		&& !zstr(var)) {
 		char *arg = NULL;
-		char *colon = NULL;
 
 		app = switch_core_session_strdup(channel->session, var);
 
-		arg = strchr(app, ' ');
-		colon = strchr(app, ':');
-		if (colon && (!arg || arg > colon) && *(colon + 1) == ':') {
-			switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s (BROADCAST)\n", channel->name, app);
-			switch_ivr_broadcast(switch_core_session_get_uuid(channel->session), app, SMF_NONE);
+		if (strstr(app, "::")) {
+			switch_core_session_execute_application_async(channel->session, app, arg);
 		} else {
-			if (arg) {
+			if ((arg = strchr(app, ' '))) {
 				*arg++ = '\0';
 			}
-			switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s(%s)\n", channel->name, app,
-							  switch_str_nil(arg));
-
-			if (switch_core_session_in_thread(channel->session)) {
-				switch_core_session_execute_application(channel->session, app, arg);
-			} else {
-				switch_core_session_execute_application_async(channel->session, app, arg);
-			}
+			
+			switch_core_session_execute_application(channel->session, app, arg);
 		}
 	}
 
committer: Anthony Minessale
comments: 
try another approach to previous mod_loopback fix ... FS-3011

diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c
index f875f6b..727de27 100644
--- a/src/mod/endpoints/mod_loopback/mod_loopback.c
+++ b/src/mod/endpoints/mod_loopback/mod_loopback.c
@@ -608,9 +608,9 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
 			if (encode_status != SWITCH_STATUS_SUCCESS) {
 				switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 			}
-
+		} else {
+			switch_set_flag((&tech_pvt->cng_frame), SFF_CNG);
 		}
-		//switch_set_flag((&tech_pvt->cng_frame), SFF_CNG);
 		switch_clear_flag_locked(tech_pvt, TFLAG_CNG);
 	}
 
@@ -642,7 +642,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
 	tech_pvt = switch_core_session_get_private(session);
 	switch_assert(tech_pvt != NULL);
 
-	if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) {
+	if (switch_test_flag(frame, SFF_CNG) || 
+		switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) {
+		switch_core_timer_sync(&tech_pvt->timer);
+		switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer);
 		return SWITCH_STATUS_SUCCESS;
 	}
 
committer: Anthony Minessale
comments: 
revert 02d1af647bac6b937de02608d53ea1831f51b968

diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c
index aa57668..f875f6b 100644
--- a/src/mod/endpoints/mod_loopback/mod_loopback.c
+++ b/src/mod/endpoints/mod_loopback/mod_loopback.c
@@ -77,11 +77,11 @@ struct private_object {
 
 	switch_frame_t cng_frame;
 	unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+	switch_timer_t timer;
 	switch_caller_profile_t *caller_profile;
 	int32_t bowout_frame_count;
 	char *other_uuid;
 	switch_queue_t *frame_queue;
-	switch_codec_implementation_t read_impl;
 };
 
 typedef struct private_object private_t;
@@ -111,6 +111,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
 	int interval = 20;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 	switch_channel_t *channel = switch_core_session_get_channel(session);
+	const switch_codec_implementation_t *read_impl;
 
 	if (codec) {
 		iananame = codec->implementation->iananame;
@@ -165,7 +166,15 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
 	switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
 	switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
 
-	tech_pvt->read_impl = *tech_pvt->read_codec.implementation;
+	if (tech_pvt->flag_mutex) {
+		switch_core_timer_destroy(&tech_pvt->timer);
+	}
+
+	read_impl = tech_pvt->read_codec.implementation;
+
+	switch_core_timer_init(&tech_pvt->timer, "soft",
+						   read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet * 4, switch_core_session_get_pool(session));
+
 
 	if (!tech_pvt->flag_mutex) {
 		switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
@@ -367,6 +376,7 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
 	tech_pvt = switch_core_session_get_private(session);
 
 	if (tech_pvt) {
+		switch_core_timer_destroy(&tech_pvt->timer);
 
 		if (switch_core_codec_ready(&tech_pvt->read_codec)) {
 			switch_core_codec_destroy(&tech_pvt->read_codec);
@@ -558,10 +568,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
 		goto end;
 	}
 
-	mutex = tech_pvt->mutex;
+	switch_core_timer_next(&tech_pvt->timer);
 
+	mutex = tech_pvt->mutex;
+	switch_mutex_lock(mutex);
 
-	if (switch_queue_pop_timeout(tech_pvt->frame_queue, &pop, tech_pvt->read_impl.microseconds_per_packet) == SWITCH_STATUS_SUCCESS && pop) {
+	if (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
 		if (tech_pvt->write_frame) {
 			switch_frame_free(&tech_pvt->write_frame);
 		}
@@ -573,8 +585,6 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
 		switch_set_flag(tech_pvt, TFLAG_CNG);
 	}
 
-	switch_mutex_lock(mutex);
-
 	if (switch_test_flag(tech_pvt, TFLAG_CNG)) {
 		unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE];
 		uint32_t flag = 0;
@@ -765,6 +775,8 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
 				switch_frame_free(&frame);
 			}
 
+			switch_core_timer_sync(&tech_pvt->timer);
+
 		}
 		break;
 	default:
committer: Anthony Minessale
comments: 
try to fix SOA problem with early and answer audio with dissimilar sdp

diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 6c91ce1..8bceb3b 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -707,11 +707,20 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
 		cid = generate_pai_str(tech_pvt);
 
 
-		if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp && strcmp(tech_pvt->early_sdp, tech_pvt->local_sdp_str)) {
-			/* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless 
-			   we do so in this case we will abandon the SOA rules and go rogue.
-			 */
-			sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
+		if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp) {
+			char *a, *b;
+			
+			/* start at the s= line to avoid some devices who update the o= between messages */
+			a = strstr(tech_pvt->early_sdp, "s=");
+			b = strstr(tech_pvt->local_sdp_str, "s=");
+
+			if (!a || !b || strcmp(a, b)) {
+
+				/* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless 
+				   we do so in this case we will abandon the SOA rules and go rogue.
+				*/
+				sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
+			}
 		}
 
 		if (sofia_use_soa(tech_pvt)) {
committer: Mathieu Parent
comments: 
Skinny: handle Enbloc messages

diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h
index 20e7d7f..1a26558 100644
--- a/src/mod/endpoints/mod_skinny/skinny_protocol.h
+++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h
@@ -68,6 +68,13 @@ struct PACKED keypad_button_message {
     uint32_t call_id;
 };
 
+/* EnblocCallMessage */
+#define ENBLOC_CALL_MESSAGE 0x0004
+struct PACKED enbloc_call_message {
+    char called_party[24];
+    uint32_t line_instance;
+};
+
 /* StimulusMessage */
 #define STIMULUS_MESSAGE 0x0005
 struct PACKED stimulus_message {
@@ -562,6 +569,7 @@ union skinny_data {
     struct register_message reg;
     struct port_message port;
     struct keypad_button_message keypad_button;
+    struct enbloc_call_message enbloc_call;
     struct stimulus_message stimulus;
     struct off_hook_message off_hook;
     struct on_hook_message on_hook;
diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c
index 5874be4..e7c761d 100644
--- a/src/mod/endpoints/mod_skinny/skinny_server.c
+++ b/src/mod/endpoints/mod_skinny/skinny_server.c
@@ -1171,6 +1171,29 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny
 	return SWITCH_STATUS_SUCCESS;
 }
 
+switch_status_t skinny_handle_enbloc_call_message(listener_t *listener, skinny_message_t *request)
+{
+	uint32_t line_instance = 1;
+	switch_core_session_t *session = NULL;
+
+	skinny_check_data_length(request, sizeof(request->data.enbloc_call.called_party));
+
+	if(skinny_check_data_length_soft(request, sizeof(request->data.enbloc_call))) {
+		if (request->data.enbloc_call.line_instance > 0) {
+			line_instance = request->data.enbloc_call.line_instance;
+		}
+	}
+
+	session = skinny_profile_find_session(listener->profile, listener, &line_instance, 0);
+
+	if(session) {
+		skinny_session_process_dest(session, listener, line_instance, request->data.enbloc_call.called_party, '\0', 0);
+		switch_core_session_rwunlock(session);
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request)
 {
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
@@ -2004,6 +2027,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
 			return skinny_handle_port_message(listener, request);
 		case KEYPAD_BUTTON_MESSAGE:
 			return skinny_handle_keypad_button_message(listener, request);
+		case ENBLOC_CALL_MESSAGE:
+			return skinny_handle_enbloc_call_message(listener, request);
 		case STIMULUS_MESSAGE:
 			return skinny_handle_stimulus_message(listener, request);
 		case OFF_HOOK_MESSAGE:
diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c
index 053b350..466a705 100644
--- a/src/mod/endpoints/mod_skinny/skinny_tables.c
+++ b/src/mod/endpoints/mod_skinny/skinny_tables.c
@@ -39,6 +39,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
     {"RegisterMessage", REGISTER_MESSAGE},
     {"PortMessage", PORT_MESSAGE},
     {"KeypadButtonMessage", KEYPAD_BUTTON_MESSAGE},
+    {"EnblocCallMessage", ENBLOC_CALL_MESSAGE},
     {"StimulusMessage", STIMULUS_MESSAGE},
     {"OffHookMessage", OFF_HOOK_MESSAGE},
     {"OnHookMessage", ON_HOOK_MESSAGE},
diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h
index c119e1f..bc92f9f 100644
--- a/src/mod/endpoints/mod_skinny/skinny_tables.h
+++ b/src/mod/endpoints/mod_skinny/skinny_tables.h
@@ -87,7 +87,7 @@ uint32_t func(const char *str)\
     }
 
 
-extern struct skinny_table SKINNY_MESSAGE_TYPES[66];
+extern struct skinny_table SKINNY_MESSAGE_TYPES[67];
 const char *skinny_message_type2str(uint32_t id);
 uint32_t skinny_str2message_type(const char *str);
 #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES)
committer: Marc Olivier Chouinard
comments: 
switch_xml: Fix a lock on reloadxml when stderr write is blocked.  Also remove an error parsing print since reason generated were wrong and duplicate.

diff --git a/src/switch_xml.c b/src/switch_xml.c
index fe6a199..964a769 100644
--- a/src/switch_xml.c
+++ b/src/switch_xml.c
@@ -1286,9 +1286,7 @@ static int preprocess_glob(const char *cwd, const char *pattern, int write_fd, i
 	}
 
 	if (glob(pattern, GLOB_NOCHECK, NULL, &glob_data) != 0) {
-		if (stderr) {
-			fprintf(stderr, "Error including %s\n", pattern);
-		}
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error including %s\n", pattern);
 		goto end;
 	}
 
@@ -1299,11 +1297,9 @@ static int preprocess_glob(const char *cwd, const char *pattern, int write_fd, i
 			*e = '\0';
 		}
 		if (preprocess(dir_path, glob_data.gl_pathv[n], write_fd, rlevel) < 0) {
-			const char *reason = strerror(errno);
 			if (rlevel > 100) {
-				reason = "Maximum recursion limit reached";
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error including %s (Maximum recursion limit reached)\n", pattern);
 			}
-			fprintf(stderr, "Error including %s (%s)\n", pattern, reason);
 		}
 		free(dir_path);
 	}
committer: Jeff Lenk
comments: 
vs2010 reswig

diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx
index 9ebd6ff..808d548 100644
--- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx
+++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx
@@ -8947,6 +8947,22 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed(void * jarg1, void * jarg
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed_dtmf(void * jarg1, void * jarg2, void * jarg3) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  switch_dtmf_t *arg2 = (switch_dtmf_t *) 0 ;
+  switch_asr_flag_t *arg3 = (switch_asr_flag_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  arg2 = (switch_dtmf_t *)jarg2; 
+  arg3 = (switch_asr_flag_t *)jarg3; 
+  result = (switch_status_t)switch_core_asr_feed_dtmf(arg1,(switch_dtmf_t const *)arg2,arg3);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_check_results(void * jarg1, void * jarg2) {
   int jresult ;
   switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
@@ -9007,6 +9023,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_unload_grammar(void * jarg1, c
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_enable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_core_asr_enable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_core_asr_disable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_all_grammars(void * jarg1) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  result = (switch_status_t)switch_core_asr_disable_all_grammars(arg1);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_pause(void * jarg1) {
   int jresult ;
   switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
@@ -18313,6 +18369,94 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_next_get(void * jarg1)
 }
 
 
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; 
+  if (arg1) (arg1)->asr_enable_grammar = arg2;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_enable_grammar);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; 
+  if (arg1) (arg1)->asr_disable_grammar = arg2;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_disable_grammar);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *) = (switch_status_t (*)(switch_asr_handle_t *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *))jarg2; 
+  if (arg1) (arg1)->asr_disable_all_grammars = arg2;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *)) ((arg1)->asr_disable_all_grammars);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *))jarg2; 
+  if (arg1) (arg1)->asr_feed_dtmf = arg2;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) ((arg1)->asr_feed_dtmf);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
 SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_asr_interface() {
   void * jresult ;
   switch_asr_interface *result = 0 ;
@@ -26320,6 +26464,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_unload_grammar(void *
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_enable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_ivr_detect_speech_enable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_ivr_detect_speech_disable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_all_grammars(void * jarg1) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  result = (switch_status_t)switch_ivr_detect_speech_disable_all_grammars(arg1);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg1, char * jarg2, char * jarg3) {
   int jresult ;
   switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
@@ -26336,6 +26520,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_start_input_timers(void * jarg1) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  result = (switch_status_t)switch_ivr_detect_speech_start_input_timers(arg1);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_session(void * jarg1, char * jarg2, unsigned long jarg3, void * jarg4) {
   int jresult ;
   switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs
index 059fb89..61c0a4e 100644
--- a/src/mod/languages/mod_managed/managed/swig.2010.cs
+++ b/src/mod/languages/mod_managed/managed/swig.2010.cs
@@ -2000,6 +2000,11 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_core_asr_feed_dtmf(switch_asr_handle ah, switch_dtmf_t dtmf, SWIGTYPE_p_unsigned_long flags) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_feed_dtmf(switch_asr_handle.getCPtr(ah), switch_dtmf_t.getCPtr(dtmf), SWIGTYPE_p_unsigned_long.getCPtr(flags));
+    return ret;
+  }
+
   public static switch_status_t switch_core_asr_check_results(switch_asr_handle ah, SWIGTYPE_p_unsigned_long flags) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_check_results(switch_asr_handle.getCPtr(ah), SWIGTYPE_p_unsigned_long.getCPtr(flags));
     return ret;
@@ -2020,6 +2025,21 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_core_asr_enable_grammar(switch_asr_handle ah, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_enable_grammar(switch_asr_handle.getCPtr(ah), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_core_asr_disable_grammar(switch_asr_handle ah, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_grammar(switch_asr_handle.getCPtr(ah), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_core_asr_disable_all_grammars(switch_asr_handle ah) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_all_grammars(switch_asr_handle.getCPtr(ah));
+    return ret;
+  }
+
   public static switch_status_t switch_core_asr_pause(switch_asr_handle ah) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_pause(switch_asr_handle.getCPtr(ah));
     return ret;
@@ -4070,11 +4090,31 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session session, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session session, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session.getCPtr(session));
+    return ret;
+  }
+
   public static switch_status_t switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session session, string name, string val) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session.getCPtr(session), name, val);
     return ret;
   }
 
+  public static switch_status_t switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session.getCPtr(session));
+    return ret;
+  }
+
   public static switch_status_t switch_ivr_record_session(SWIGTYPE_p_switch_core_session session, string file, uint limit, switch_file_handle fh) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_record_session(SWIGTYPE_p_switch_core_session.getCPtr(session), file, limit, switch_file_handle.getCPtr(fh));
     return ret;
@@ -7907,6 +7947,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed")]
   public static extern int switch_core_asr_feed(HandleRef jarg1, HandleRef jarg2, uint jarg3, HandleRef jarg4);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed_dtmf")]
+  public static extern int switch_core_asr_feed_dtmf(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_check_results")]
   public static extern int switch_core_asr_check_results(HandleRef jarg1, HandleRef jarg2);
 
@@ -7919,6 +7962,15 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_unload_grammar")]
   public static extern int switch_core_asr_unload_grammar(HandleRef jarg1, string jarg2);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_enable_grammar")]
+  public static extern int switch_core_asr_enable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_grammar")]
+  public static extern int switch_core_asr_disable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_all_grammars")]
+  public static extern int switch_core_asr_disable_all_grammars(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_pause")]
   public static extern int switch_core_asr_pause(HandleRef jarg1);
 
@@ -10196,6 +10248,30 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_next_get")]
   public static extern IntPtr switch_asr_interface_next_get(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_set")]
+  public static extern void switch_asr_interface_asr_enable_grammar_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_get")]
+  public static extern IntPtr switch_asr_interface_asr_enable_grammar_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_set")]
+  public static extern void switch_asr_interface_asr_disable_grammar_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_get")]
+  public static extern IntPtr switch_asr_interface_asr_disable_grammar_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_set")]
+  public static extern void switch_asr_interface_asr_disable_all_grammars_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_get")]
+  public static extern IntPtr switch_asr_interface_asr_disable_all_grammars_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_set")]
+  public static extern void switch_asr_interface_asr_feed_dtmf_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_get")]
+  public static extern IntPtr switch_asr_interface_asr_feed_dtmf_get(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_new_switch_asr_interface")]
   public static extern IntPtr new_switch_asr_interface();
 
@@ -12140,9 +12216,21 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_unload_grammar")]
   public static extern int switch_ivr_detect_speech_unload_grammar(HandleRef jarg1, string jarg2);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_enable_grammar")]
+  public static extern int switch_ivr_detect_speech_enable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_grammar")]
+  public static extern int switch_ivr_detect_speech_disable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_all_grammars")]
+  public static extern int switch_ivr_detect_speech_disable_all_grammars(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_set_param_detect_speech")]
   public static extern int switch_ivr_set_param_detect_speech(HandleRef jarg1, string jarg2, string jarg3);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_start_input_timers")]
+  public static extern int switch_ivr_detect_speech_start_input_timers(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_record_session")]
   public static extern int switch_ivr_record_session(HandleRef jarg1, string jarg2, uint jarg3, HandleRef jarg4);
 
@@ -14967,6 +15055,36 @@ namespace FreeSWITCH.Native {
 using System;
 using System.Runtime.InteropServices;
 
+public class SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t {
+  private HandleRef swigCPtr;
+
+  internal SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(IntPtr cPtr, bool futureUse) {
+    swigCPtr = new HandleRef(this, cPtr);
+  }
+
+  protected SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t() {
+    swigCPtr = new HandleRef(null, IntPtr.Zero);
+  }
+
+  internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t obj) {
+    return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
+  }
+}
+
+}
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+namespace FreeSWITCH.Native {
+
+using System;
+using System.Runtime.InteropServices;
+
 public class SWIGTYPE_p_f_p_switch_asr_handle_p_unsigned_long__switch_status_t {
   private HandleRef swigCPtr;
 
@@ -19993,6 +20111,50 @@ public class switch_asr_interface : IDisposable {
     } 
   }
 
+  public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_enable_grammar {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_disable_grammar {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t asr_disable_all_grammars {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t asr_feed_dtmf {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
   public switch_asr_interface() : this(freeswitchPINVOKE.new_switch_asr_interface(), true) {
   }
 
@@ -28589,7 +28751,8 @@ public enum switch_rtp_bug_flag_t {
   RTP_BUG_IGNORE_MARK_BIT = (1 << 2),
   RTP_BUG_SEND_LINEAR_TIMESTAMPS = (1 << 3),
   RTP_BUG_START_SEQ_AT_ZERO = (1 << 4),
-  RTP_BUG_NEVER_SEND_MARKER = (1 << 5)
+  RTP_BUG_NEVER_SEND_MARKER = (1 << 5),
+  RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6)
 }
 
 }
@@ -30446,7 +30609,7 @@ public enum switch_status_t {
   SWITCH_STATUS_FALSE,
   SWITCH_STATUS_TIMEOUT,
   SWITCH_STATUS_RESTART,
-  SWITCH_STATUS_TERM,
+  SWITCH_STATUS_INTR,
   SWITCH_STATUS_NOTIMPL,
   SWITCH_STATUS_MEMERR,
   SWITCH_STATUS_NOOP,
@@ -30463,6 +30626,7 @@ public enum switch_status_t {
   SWITCH_STATUS_TOO_SMALL,
   SWITCH_STATUS_FOUND,
   SWITCH_STATUS_CONTINUE,
+  SWITCH_STATUS_TERM,
   SWITCH_STATUS_NOT_INITALIZED
 }
 
committer: Michael Jerris
comments: 
add more details to xml_curl errors

diff --git a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
index 9bf837e..bc143d7 100644
--- a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
+++ b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
@@ -293,12 +293,12 @@ static switch_xml_t xml_url_fetch(const char *section, const char *tag_name, con
 	}
 
 	if (config_data.err) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered!\n");
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered! [%s]\ndata: [%s]\n", binding->url, data);
 		xml = NULL;
 	} else {
 		if (httpRes == 200) {
 			if (!(xml = switch_xml_parse_file(filename))) {
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result! [%s]\ndata: [%s]\n", binding->url, data);
 			}
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received HTTP error %ld trying to fetch %s\ndata: [%s]\n", httpRes, binding->url,
committer: Brian West
comments: 
swigall

diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
index 3ee6ff6..e91de6d 100644
--- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx
+++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
@@ -9238,6 +9238,22 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed(void * jarg1, void * jarg
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed_dtmf(void * jarg1, void * jarg2, void * jarg3) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  switch_dtmf_t *arg2 = (switch_dtmf_t *) 0 ;
+  switch_asr_flag_t *arg3 = (switch_asr_flag_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  arg2 = (switch_dtmf_t *)jarg2; 
+  arg3 = (switch_asr_flag_t *)jarg3; 
+  result = (switch_status_t)switch_core_asr_feed_dtmf(arg1,(switch_dtmf_t const *)arg2,arg3);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_check_results(void * jarg1, void * jarg2) {
   int jresult ;
   switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
@@ -9298,6 +9314,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_unload_grammar(void * jarg1, c
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_enable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_core_asr_enable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_core_asr_disable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_all_grammars(void * jarg1) {
+  int jresult ;
+  switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_asr_handle_t *)jarg1; 
+  result = (switch_status_t)switch_core_asr_disable_all_grammars(arg1);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_pause(void * jarg1) {
   int jresult ;
   switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ;
@@ -18820,6 +18876,98 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_next_get(void * jarg1)
 }
 
 
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; 
+  if (arg1) (arg1)->asr_enable_grammar = arg2;
+  
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_enable_grammar);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; 
+  if (arg1) (arg1)->asr_disable_grammar = arg2;
+  
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_disable_grammar);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *) = (switch_status_t (*)(switch_asr_handle_t *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *))jarg2; 
+  if (arg1) (arg1)->asr_disable_all_grammars = arg2;
+  
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *)) ((arg1)->asr_disable_all_grammars);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_set(void * jarg1, void * jarg2) {
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*arg2)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  arg2 = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *))jarg2; 
+  if (arg1) (arg1)->asr_feed_dtmf = arg2;
+  
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_get(void * jarg1) {
+  void * jresult ;
+  switch_asr_interface *arg1 = (switch_asr_interface *) 0 ;
+  switch_status_t (*result)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = 0 ;
+  
+  arg1 = (switch_asr_interface *)jarg1; 
+  result = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) ((arg1)->asr_feed_dtmf);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
 SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_asr_interface() {
   void * jresult ;
   switch_asr_interface *result = 0 ;
@@ -27013,6 +27161,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_unload_grammar(void *
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_enable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_ivr_detect_speech_enable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_grammar(void * jarg1, char * jarg2) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (switch_status_t)switch_ivr_detect_speech_disable_grammar(arg1,(char const *)arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_all_grammars(void * jarg1) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  result = (switch_status_t)switch_ivr_detect_speech_disable_all_grammars(arg1);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg1, char * jarg2, char * jarg3) {
   int jresult ;
   switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
@@ -27029,6 +27217,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_start_input_timers(void * jarg1) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  result = (switch_status_t)switch_ivr_detect_speech_start_input_timers(arg1);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_session(void * jarg1, char * jarg2, unsigned long jarg3, void * jarg4) {
   int jresult ;
   switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs
index 48d585e..1f02c3f 100644
--- a/src/mod/languages/mod_managed/managed/swig.cs
+++ b/src/mod/languages/mod_managed/managed/swig.cs
@@ -1990,6 +1990,11 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_core_asr_feed_dtmf(switch_asr_handle ah, switch_dtmf_t dtmf, SWIGTYPE_p_unsigned_long flags) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_feed_dtmf(switch_asr_handle.getCPtr(ah), switch_dtmf_t.getCPtr(dtmf), SWIGTYPE_p_unsigned_long.getCPtr(flags));
+    return ret;
+  }
+
   public static switch_status_t switch_core_asr_check_results(switch_asr_handle ah, SWIGTYPE_p_unsigned_long flags) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_check_results(switch_asr_handle.getCPtr(ah), SWIGTYPE_p_unsigned_long.getCPtr(flags));
     return ret;
@@ -2010,6 +2015,21 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_core_asr_enable_grammar(switch_asr_handle ah, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_enable_grammar(switch_asr_handle.getCPtr(ah), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_core_asr_disable_grammar(switch_asr_handle ah, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_grammar(switch_asr_handle.getCPtr(ah), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_core_asr_disable_all_grammars(switch_asr_handle ah) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_all_grammars(switch_asr_handle.getCPtr(ah));
+    return ret;
+  }
+
   public static switch_status_t switch_core_asr_pause(switch_asr_handle ah) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_pause(switch_asr_handle.getCPtr(ah));
     return ret;
@@ -4060,11 +4080,31 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session session, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session session, string name) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name);
+    return ret;
+  }
+
+  public static switch_status_t switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session.getCPtr(session));
+    return ret;
+  }
+
   public static switch_status_t switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session session, string name, string val) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session.getCPtr(session), name, val);
     return ret;
   }
 
+  public static switch_status_t switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session.getCPtr(session));
+    return ret;
+  }
+
   public static switch_status_t switch_ivr_record_session(SWIGTYPE_p_switch_core_session session, string file, uint limit, switch_file_handle fh) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_record_session(SWIGTYPE_p_switch_core_session.getCPtr(session), file, limit, switch_file_handle.getCPtr(fh));
     return ret;
@@ -7893,6 +7933,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed")]
   public static extern int switch_core_asr_feed(HandleRef jarg1, HandleRef jarg2, uint jarg3, HandleRef jarg4);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed_dtmf")]
+  public static extern int switch_core_asr_feed_dtmf(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_check_results")]
   public static extern int switch_core_asr_check_results(HandleRef jarg1, HandleRef jarg2);
 
@@ -7905,6 +7948,15 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_unload_grammar")]
   public static extern int switch_core_asr_unload_grammar(HandleRef jarg1, string jarg2);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_enable_grammar")]
+  public static extern int switch_core_asr_enable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_grammar")]
+  public static extern int switch_core_asr_disable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_all_grammars")]
+  public static extern int switch_core_asr_disable_all_grammars(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_pause")]
   public static extern int switch_core_asr_pause(HandleRef jarg1);
 
@@ -10182,6 +10234,30 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_next_get")]
   public static extern IntPtr switch_asr_interface_next_get(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_set")]
+  public static extern void switch_asr_interface_asr_enable_grammar_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_get")]
+  public static extern IntPtr switch_asr_interface_asr_enable_grammar_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_set")]
+  public static extern void switch_asr_interface_asr_disable_grammar_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_get")]
+  public static extern IntPtr switch_asr_interface_asr_disable_grammar_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_set")]
+  public static extern void switch_asr_interface_asr_disable_all_grammars_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_get")]
+  public static extern IntPtr switch_asr_interface_asr_disable_all_grammars_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_set")]
+  public static extern void switch_asr_interface_asr_feed_dtmf_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_get")]
+  public static extern IntPtr switch_asr_interface_asr_feed_dtmf_get(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_new_switch_asr_interface")]
   public static extern IntPtr new_switch_asr_interface();
 
@@ -12126,9 +12202,21 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_unload_grammar")]
   public static extern int switch_ivr_detect_speech_unload_grammar(HandleRef jarg1, string jarg2);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_enable_grammar")]
+  public static extern int switch_ivr_detect_speech_enable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_grammar")]
+  public static extern int switch_ivr_detect_speech_disable_grammar(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_all_grammars")]
+  public static extern int switch_ivr_detect_speech_disable_all_grammars(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_set_param_detect_speech")]
   public static extern int switch_ivr_set_param_detect_speech(HandleRef jarg1, string jarg2, string jarg3);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_start_input_timers")]
+  public static extern int switch_ivr_detect_speech_start_input_timers(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_record_session")]
   public static extern int switch_ivr_record_session(HandleRef jarg1, string jarg2, uint jarg3, HandleRef jarg4);
 
@@ -14943,6 +15031,36 @@ namespace FreeSWITCH.Native {
 using System;
 using System.Runtime.InteropServices;
 
+public class SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t {
+  private HandleRef swigCPtr;
+
+  internal SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(IntPtr cPtr, bool futureUse) {
+    swigCPtr = new HandleRef(this, cPtr);
+  }
+
+  protected SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t() {
+    swigCPtr = new HandleRef(null, IntPtr.Zero);
+  }
+
+  internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t obj) {
+    return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
+  }
+}
+
+}
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.35
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+namespace FreeSWITCH.Native {
+
+using System;
+using System.Runtime.InteropServices;
+
 public class SWIGTYPE_p_f_p_switch_asr_handle_p_unsigned_long__switch_status_t {
   private HandleRef swigCPtr;
 
@@ -19959,6 +20077,50 @@ public class switch_asr_interface : IDisposable {
     } 
   }
 
+  public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_enable_grammar {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_disable_grammar {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t asr_disable_all_grammars {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t asr_feed_dtmf {
+    set {
+      freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_get(swigCPtr);
+      SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(cPtr, false);
+      return ret;
+    } 
+  }
+
   public switch_asr_interface() : this(freeswitchPINVOKE.new_switch_asr_interface(), true) {
   }
 
committer: Travis Cross
comments: 
lower log-level of a mod_spy message
When a session loses a race to bridge a call, the CHANNEL_BRIDGE event
handler is still run, yet session_locate is going to return null as it
won't get a read-lock on the peer's session.  Since this is a normal
and common condition, let's log this as a debug message rather than as
an error condition.

diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c
index e0a9317..1797539 100644
--- a/src/mod/applications/mod_spy/mod_spy.c
+++ b/src/mod/applications/mod_spy/mod_spy.c
@@ -201,7 +201,7 @@ static void event_handler(switch_event_t *event)
 		}
 
 		if (!(peer_session = switch_core_session_locate(peer_uuid))) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't locate peer session for uuid %s\n", peer_uuid);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Can't locate peer session for uuid %s\n", peer_uuid);
 			return;
 		}
 
committer: Travis Cross
comments: 
fix typo: cant -> can't

diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c
index 9986703..e0a9317 100644
--- a/src/mod/applications/mod_spy/mod_spy.c
+++ b/src/mod/applications/mod_spy/mod_spy.c
@@ -201,14 +201,14 @@ static void event_handler(switch_event_t *event)
 		}
 
 		if (!(peer_session = switch_core_session_locate(peer_uuid))) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cant locate peer session for uuid %s\n", peer_uuid);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't locate peer session for uuid %s\n", peer_uuid);
 			return;
 		}
 
 		peer_channel = switch_core_session_get_channel(peer_session);
 		
 		if (switch_event_create(&peer_event, SWITCH_EVENT_CHANNEL_BRIDGE) != SWITCH_STATUS_SUCCESS) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cant create bridge event for peer channel %s\n", peer_uuid);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't create bridge event for peer channel %s\n", peer_uuid);
 			goto end;
 		}
 
@@ -249,7 +249,7 @@ SWITCH_STANDARD_APP(userspy_function)
 			status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) uuid);
 
 			if ((status != SWITCH_STATUS_SUCCESS)) {
-				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cant insert to spy hash\n");
+				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't insert to spy hash\n");
 				switch_channel_hangup(channel, SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED);
 				switch_thread_rwlock_unlock(globals.spy_hash_lock);
 				return;
committer: Brian West
comments: 
Merge branch 'openmethods-merged-dtmf-20110126' of git://scm.dashjr.org/var/scmroot/git/freeswitch
committer: Jeff Lenk
comments: 
OPENZAP-140 VS2010 build cleanup

diff --git a/libs/freetdm/msvc/testboost/testboost.2010.vcxproj b/libs/freetdm/msvc/testboost/testboost.2010.vcxproj
index 6206148..314440b 100644
--- a/libs/freetdm/msvc/testboost/testboost.2010.vcxproj
+++ b/libs/freetdm/msvc/testboost/testboost.2010.vcxproj
@@ -105,7 +105,7 @@
       <DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>..\..\debug\freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -162,7 +162,7 @@
       <DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -199,7 +199,7 @@
       <DataExecutionPrevention>
       </DataExecutionPrevention>
       <TargetMachine>MachineX64</TargetMachine>
-      <AdditionalDependencies>freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
diff --git a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj b/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj
index 5994da6..4077a60 100644
--- a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj
+++ b/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj
@@ -105,7 +105,7 @@
       <DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>..\..\debug\freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -162,7 +162,7 @@
       <DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -199,7 +199,7 @@
       <DataExecutionPrevention>
       </DataExecutionPrevention>
       <TargetMachine>MachineX64</TargetMachine>
-      <AdditionalDependencies>freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj
index 78689c3..684e432 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj
@@ -61,11 +61,11 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
@@ -102,7 +102,7 @@
       <DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
@@ -151,7 +151,7 @@
       <DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>freetdm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj
index 40d0a73..a21be22 100644
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj
+++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj
@@ -61,14 +61,14 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
committer: Daniel Swarbrick
comments: 
mostly complete implementation of channel list via SNMP

diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB
index 11c3999..8448526 100644
--- a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB
+++ b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB
@@ -3,11 +3,14 @@ FREESWITCH-MIB DEFINITIONS ::= BEGIN
 IMPORTS
     OBJECT-TYPE, MODULE-IDENTITY,
     Integer32, Gauge32, Counter32, Counter64, TimeTicks,
-    enterprises,
+    enterprises
         FROM SNMPv2-SMI
 
-    DisplayString
+    DisplayString, DateAndTime
         FROM SNMPv2-TC
+
+    InetAddressType, InetAddress
+        FROM INET-ADDRESS-MIB
 ;
 
 
@@ -109,13 +112,27 @@ maxSessionsPerSecond OBJECT-TYPE
 
 
 ChannelEntry ::= SEQUENCE {
-    chanUUID        DisplayString,
-    chanDirection   DisplayString,
-    chanCreated     DisplayString,
-    chanName        DisplayString,
-    chanState       DisplayString,
-    chanCIDName     DisplayString,
-    chanCIDNum      DisplayString
+    chanIndex           Integer32,
+    chanUUID            DisplayString,
+    chanDirection       DisplayString,
+    chanCreated         DateAndTime,
+    chanName            DisplayString,
+    chanState           DisplayString,
+    chanCIDName         DisplayString,
+    chanCIDNum          DisplayString,
+    chanInetAddressType InetAddressType,
+    chanInetAddress     InetAddress,
+    chanDest            DisplayString,
+    chanApplication     DisplayString,
+    chanAppData         DisplayString,
+    chanDialplan        DisplayString,
+    chanContext         DisplayString,
+    chanReadCodec       DisplayString,
+    chanReadRate        Gauge32,
+    chanReadBitRate     Gauge32,
+    chanWriteCodec      DisplayString,
+    chanWriteRate       Gauge32,
+    chanWriteBitRate    Gauge32
 }
 
 channelList OBJECT-TYPE
@@ -135,60 +152,172 @@ channelEntry OBJECT-TYPE
     INDEX { chanIndex }
     ::= { channelList 1 }
 
+chanIndex OBJECT-TYPE
+    SYNTAX      Integer32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel SNMP index."
+    ::= { channelEntry 1 }
+
 chanUUID OBJECT-TYPE
     SYNTAX      DisplayString
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
-        "The channel UUID."
-    ::= { channelEntry 1 }
+        "Channel UUID."
+    ::= { channelEntry 2 }
 
 chanDirection OBJECT-TYPE
     SYNTAX      DisplayString
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
-        "The channel direction."
-    ::= { channelEntry 2 }
+        "Channel direction."
+    ::= { channelEntry 3 }
 
 chanCreated OBJECT-TYPE
-    SYNTAX      DisplayString
+    SYNTAX      DateAndTime
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
         "Channel creation timestamp."
-    ::= { channelEntry 3 }
+    ::= { channelEntry 4 }
 
 chanName OBJECT-TYPE
     SYNTAX      DisplayString
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
-        "The channel name."
-    ::= { channelEntry 4 }
+        "Channel name."
+    ::= { channelEntry 5 }
 
 chanState OBJECT-TYPE
     SYNTAX      DisplayString
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
-        "The channel state."
-    ::= { channelEntry 5 }
+        "Channel state."
+    ::= { channelEntry 6 }
 
 chanCIDName OBJECT-TYPE
     SYNTAX      DisplayString
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
-        "The channel caller ID name."
-    ::= { channelEntry 6 }
+        "Channel caller ID name."
+    ::= { channelEntry 7 }
 
 chanCIDNum OBJECT-TYPE
     SYNTAX      DisplayString
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
-        "The channel caller ID number."
-    ::= { channelEntry 7 }
+        "Channel caller ID number."
+    ::= { channelEntry 8 }
+
+chanInetAddressType OBJECT-TYPE
+    SYNTAX      InetAddressType
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel originator's IP address type (IPv4 or IPv6)."
+    ::= { channelEntry 9 }
+
+chanInetAddress OBJECT-TYPE
+    SYNTAX      InetAddress
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel originator's IP address."
+    ::= { channelEntry 10 }
+
+chanDest OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel destination."
+    ::= { channelEntry 11 }
+
+chanApplication OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel application."
+    ::= { channelEntry 12 }
+
+chanAppData OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel application data."
+    ::= { channelEntry 13 }
+
+chanDialplan OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel dialplan."
+    ::= { channelEntry 14 }
+
+chanContext OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel dialplan context."
+    ::= { channelEntry 15 }
+
+chanReadCodec OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel read codec."
+    ::= { channelEntry 16 }
+
+chanReadRate OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel read samples per second."
+    ::= { channelEntry 17 }
+
+chanReadBitRate OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel read bits per second."
+    ::= { channelEntry 18 }
+
+chanWriteCodec OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel write codec."
+    ::= { channelEntry 19 }
+
+chanWriteRate OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel write samples per second."
+    ::= { channelEntry 20 }
+
+chanWriteBitRate OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel write bits per second."
+    ::= { channelEntry 21 }
 
 END
diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c
index 7b9faa7..43975ee 100644
--- a/src/mod/event_handlers/mod_snmp/subagent.c
+++ b/src/mod/event_handlers/mod_snmp/subagent.c
@@ -42,6 +42,17 @@ netsnmp_handler_registration *ch_reginfo;
 uint32_t idx;
 
 
+static void time_t_to_datetime(time_t epoch, char *buf, switch_size_t buflen)
+{
+	struct tm *dt;
+	uint16_t year;
+
+	dt = gmtime(&epoch);
+	year = dt->tm_year + 1900;
+	switch_snprintf(buf, buflen, "%c%c%c%c%c%c%c%c+%c%c", year >> 8, year & 0xff, dt->tm_mon + 1, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec, 0, 0, 0);
+}
+
+
 static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNames)
 {
 	uint32_t *count = (uint32_t *) pArg;
@@ -69,11 +80,31 @@ static int channelList_callback(void *pArg, int argc, char **argv, char **column
 	entry->idx = idx++;
 	strncpy(entry->uuid, argv[0], sizeof(entry->uuid));
 	strncpy(entry->direction, argv[1], sizeof(entry->direction));
-	strncpy(entry->created, argv[2], sizeof(entry->created));
+	entry->created_epoch = atoi(argv[3]);
 	strncpy(entry->name, argv[4], sizeof(entry->name));
 	strncpy(entry->state, argv[5], sizeof(entry->state));
 	strncpy(entry->cid_name, argv[6], sizeof(entry->cid_name));
 	strncpy(entry->cid_num, argv[7], sizeof(entry->cid_num));
+	strncpy(entry->dest, argv[9], sizeof(entry->dest));
+	strncpy(entry->application, argv[10], sizeof(entry->application));
+	strncpy(entry->application_data, argv[11], sizeof(entry->application_data));
+	strncpy(entry->dialplan, argv[12], sizeof(entry->dialplan));
+	strncpy(entry->context, argv[13], sizeof(entry->context));
+	strncpy(entry->read_codec, argv[14], sizeof(entry->read_codec));
+	entry->read_rate = atoi(argv[15]);
+	entry->read_bitrate = atoi(argv[16]);
+	strncpy(entry->write_codec, argv[17], sizeof(entry->write_codec));
+	entry->write_rate = atoi(argv[18]);
+	entry->write_bitrate = atoi(argv[19]);
+
+	memset(&entry->ip_addr, 0, sizeof(entry->ip_addr));
+	if (strchr(argv[8], ':')) {
+		switch_inet_pton(AF_INET6, argv[8], &entry->ip_addr);
+		entry->addr_family = AF_INET6;
+	} else {
+		switch_inet_pton(AF_INET, argv[8], &entry->ip_addr);
+		entry->addr_family = AF_INET;
+	}
 
 	netsnmp_tdata_row_add_index(row, ASN_INTEGER, &entry->idx, sizeof(entry->idx));
 	netsnmp_tdata_add_row(ch_table, row);
@@ -128,9 +159,9 @@ void init_subagent(switch_memory_pool_t *pool)
 	netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7);
 
 	ch_table_info = switch_core_alloc(pool, sizeof(netsnmp_table_registration_info));
-	netsnmp_table_helper_add_index(ch_table_info, ASN_INTEGER);
-	ch_table_info->min_column = 1;
-	ch_table_info->max_column = 7;
+	netsnmp_table_helper_add_indexes(ch_table_info, ASN_INTEGER, 0);
+	ch_table_info->min_column = CH_INDEX;
+	ch_table_info->max_column = CH_WRITE_BITRATE;
 	ch_table = netsnmp_tdata_create_table("channelList", 0);
 	ch_reginfo = netsnmp_create_handler_registration("channelList", handle_channelList, channelList_oid, OID_LENGTH(channelList_oid), HANDLER_CAN_RONLY);
 	netsnmp_tdata_register(ch_reginfo, ch_table, ch_table_info);
@@ -191,15 +222,15 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 			break;
 		case SS_SESSIONS_SINCE_STARTUP:
 			int_val = switch_core_session_id() - 1;
-			snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val));
+			snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER, int_val);
 			break;
 		case SS_CURRENT_SESSIONS:
 			int_val = switch_core_session_count();
-			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+			snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val);
 			break;
 		case SS_MAX_SESSIONS:
 			switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);
-			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+			snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val);
 			break;
 		case SS_CURRENT_CALLS:
 			{
@@ -213,17 +244,17 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 			gethostname(hostname, sizeof(hostname));
 			sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", hostname);
 			switch_cache_db_execute_sql_callback(dbh, sql, sql_count_callback, &int_val, NULL);
-			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+			snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val);
 			switch_cache_db_release_db_handle(&dbh);
 			}
 			break;
 		case SS_SESSIONS_PER_SECOND:
 			switch_core_session_ctl(SCSC_LAST_SPS, &int_val);
-			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+			snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val);
 			break;
 		case SS_MAX_SESSIONS_PER_SECOND:
 			switch_core_session_ctl(SCSC_SPS, &int_val);
-			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+			snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val);
 			break;
 		default:
 			snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
@@ -246,6 +277,7 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 	netsnmp_request_info *request;
 	netsnmp_table_request_info *table_info;
 	chan_entry_t *entry;
+	char dt_str[12];
 
 	switch (reqinfo->mode) {
 	case MODE_GET:
@@ -254,6 +286,9 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 			entry = (chan_entry_t *) netsnmp_tdata_extract_entry(request);
 
 			switch (table_info->colnum) {
+			case CH_INDEX:
+				snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->idx);
+				break;
 			case CH_UUID:
 				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->uuid, strlen(entry->uuid));
 				break;
@@ -261,7 +296,8 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->direction, strlen(entry->direction));
 				break;
 			case CH_CREATED:
-				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->created, strlen(entry->created));
+				time_t_to_datetime(entry->created_epoch, (char *) &dt_str, sizeof(dt_str));
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) &dt_str, sizeof(dt_str));
 				break;
 			case CH_NAME:
 				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->name, strlen(entry->name));
@@ -275,6 +311,53 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 			case CH_CID_NUM:
 				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->cid_num, strlen(entry->cid_num));
 				break;
+			case CH_IP_ADDR_TYPE:
+				if (entry->addr_family == AF_INET6) {
+					snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, INETADDRESSTYPE_IPV6);
+				} else {
+					snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, INETADDRESSTYPE_IPV4);
+				}
+				break;
+			case CH_IP_ADDR:
+				if (entry->addr_family == AF_INET6) {
+					snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) &entry->ip_addr.v6, sizeof(entry->ip_addr.v6));
+				} else {
+					snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) &entry->ip_addr.v4, sizeof(entry->ip_addr.v4));
+				}
+				break;
+			case CH_DEST:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->dest, strlen(entry->dest));
+				break;
+			case CH_APPLICATION:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->application, strlen(entry->application));
+				break;
+			case CH_APPLICATION_DATA:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->application_data, strlen(entry->application_data));
+				break;
+			case CH_DIALPLAN:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->dialplan, strlen(entry->dialplan));
+				break;
+			case CH_CONTEXT:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->context, strlen(entry->context));
+				break;
+			case CH_READ_CODEC:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->read_codec, strlen(entry->read_codec));
+				break;
+			case CH_READ_RATE:
+				snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->read_rate, sizeof(entry->read_rate));
+				break;
+			case CH_READ_BITRATE:
+				snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->read_bitrate, sizeof(entry->read_bitrate));
+				break;
+			case CH_WRITE_CODEC:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->write_codec, strlen(entry->write_codec));
+				break;
+			case CH_WRITE_RATE:
+				snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->write_rate, sizeof(entry->write_rate));
+				break;
+			case CH_WRITE_BITRATE:
+				snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->write_bitrate, sizeof(entry->write_bitrate));
+				break;
 			default:
 				snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", table_info->colnum);
 				netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h
index 0070b2c..5da87a6 100644
--- a/src/mod/event_handlers/mod_snmp/subagent.h
+++ b/src/mod/event_handlers/mod_snmp/subagent.h
@@ -15,23 +15,58 @@
 #define SS_MAX_SESSIONS_PER_SECOND	7
 
 /* .1.3.6.1.4.1.27880.1.9 */
-#define CH_UUID				1
-#define CH_DIRECTION			2
-#define CH_CREATED			3
-#define CH_NAME				4
-#define CH_STATE			5
-#define CH_CID_NAME			6
-#define CH_CID_NUM			7
+#define CH_INDEX			1
+#define CH_UUID				2
+#define CH_DIRECTION			3
+#define CH_CREATED			4
+#define CH_NAME				5
+#define CH_STATE			6
+#define CH_CID_NAME			7
+#define CH_CID_NUM			8
+#define CH_IP_ADDR_TYPE			9
+#define CH_IP_ADDR			10
+#define CH_DEST				11
+#define CH_APPLICATION			12
+#define CH_APPLICATION_DATA		13
+#define CH_DIALPLAN			14
+#define CH_CONTEXT			15
+#define CH_READ_CODEC			16
+#define CH_READ_RATE			17
+#define CH_READ_BITRATE			18
+#define CH_WRITE_CODEC			19
+#define CH_WRITE_RATE			20
+#define CH_WRITE_BITRATE		21
+
+/* Why aren't these in net-snmp-includes.h ? */
+#define INETADDRESSTYPE_UNKNOWN		0
+#define INETADDRESSTYPE_IPV4		1
+#define INETADDRESSTYPE_IPV6		2
+#define INETADDRESSTYPE_IPV4Z		3
+#define INETADDRESSTYPE_IPV6Z		4
+#define INETADDRESSTYPE_DNS		16
 
 typedef struct {
 	uint32_t idx;
 	char uuid[38];
 	char direction[32];
-	char created[128];
+	time_t created_epoch;
 	char name[1024];
 	char state[64];
 	char cid_name[1024];
 	char cid_num[256];
+	ip_t ip_addr;
+	uint8_t addr_family;
+	char dest[1024];
+	char application[128];
+	char application_data[4096];
+	char dialplan[128];
+	char context[128];
+	char read_codec[128];
+	uint32_t read_rate;
+	uint32_t read_bitrate;
+	char write_codec[128];
+	uint32_t write_rate;
+	uint32_t write_bitrate;
 } chan_entry_t;
 
 void init_subagent(switch_memory_pool_t *pool);
committer: Anthony Minessale
comments: 
fix || where it should be or in sql stmt that may cause stray records in the calls table

diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c
index 4167b4a..35311c9 100644
--- a/src/switch_core_sqldb.c
+++ b/src/switch_core_sqldb.c
@@ -1160,15 +1160,14 @@ static void core_event_handler(switch_event_t *event)
 	case SWITCH_EVENT_CHANNEL_DESTROY:
 		{
 			const char *uuid = switch_event_get_header(event, "unique-id");
-			const char *sig = switch_event_get_header(event, "signal_bridge");
 			
 			if (uuid) {
 				new_sql() = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'",
 										   uuid, switch_core_get_variable("hostname"));
-				if (switch_true(sig)) {
-					new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' || callee_uuid='%q') and hostname='%q'",
-											   uuid, uuid, switch_core_get_variable("hostname"));
-				}
+
+				new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'",
+										   uuid, uuid, switch_core_get_variable("hostname"));
+
 			}
 		}
 		break;
@@ -1410,7 +1409,7 @@ static void core_event_handler(switch_event_t *event)
 		}
 		break;
 	case SWITCH_EVENT_CHANNEL_UNBRIDGE:
-		new_sql() = switch_mprintf("delete from calls where caller_uuid='%s' and hostname='%q'",
+		new_sql() = switch_mprintf("delete from calls where (caller_uuid='%s' or callee_uuid='%q') and hostname='%q'",
 								   switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname"));
 		break;
 	case SWITCH_EVENT_SHUTDOWN:
committer: Marc Olivier Chouinard
comments: 
mod_callcenter: Add error response for queue load and queue reload (FS-2988)

diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c
index d1de632..61305bb 100644
--- a/src/mod/applications/mod_callcenter/mod_callcenter.c
+++ b/src/mod/applications/mod_callcenter/mod_callcenter.c
@@ -2625,8 +2625,10 @@ SWITCH_STANDARD_API(cc_config_api_function)
 				cc_queue_t *queue = NULL;
 				if ((queue = get_queue(queue_name))) {
 					queue_rwunlock(queue);
+					stream->write_function(stream, "%s", "+OK\n");
+				} else {
+					stream->write_function(stream, "%s", "-ERR Invalid Queue not found!\n");
 				}
-				stream->write_function(stream, "%s", "+OK\n");
 			}
 		} else if (action && !strcasecmp(action, "unload")) {
 			if (argc-initial_argc < 1) {
@@ -2648,8 +2650,10 @@ SWITCH_STANDARD_API(cc_config_api_function)
 				destroy_queue(queue_name, SWITCH_FALSE);
 				if ((queue = get_queue(queue_name))) {
 					queue_rwunlock(queue);
+					stream->write_function(stream, "%s", "+OK\n");
+				} else {
+					stream->write_function(stream, "%s", "-ERR Invalid Queue not found!\n");
 				}
-				stream->write_function(stream, "%s", "+OK\n");
 			}
 		} else if (action && !strcasecmp(action, "list")) {
 			if (argc-initial_argc < 1) {
@@ -2671,7 +2675,6 @@ SWITCH_STANDARD_API(cc_config_api_function)
 				goto done;
 			} else {
 				const char *queue_name = argv[0 + initial_argc];
-
 				struct list_result cbt;
 				cbt.row_process = 0;
 				cbt.stream = stream;
committer: Raymond Chandler
comments: 
Merge branch 'master' of fs-git:freeswitch
committer: Raymond Chandler
comments: 
TEST-002

diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 5fc9402..6914128 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -61,5 +61,4 @@
       <X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
     </macros>
   </section>
-
 </document>
committer: Daniel Swarbrick
comments: 
partial implementation of channel list via snmp

diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB
index 9584c8b..11c3999 100644
--- a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB
+++ b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB
@@ -107,4 +107,88 @@ maxSessionsPerSecond OBJECT-TYPE
         "Maximum permissible sessions per second"
     ::= { systemStats 7 }
 
+
+ChannelEntry ::= SEQUENCE {
+    chanUUID        DisplayString,
+    chanDirection   DisplayString,
+    chanCreated     DisplayString,
+    chanName        DisplayString,
+    chanState       DisplayString,
+    chanCIDName     DisplayString,
+    chanCIDNum      DisplayString
+}
+
+channelList OBJECT-TYPE
+    SYNTAX      SEQUENCE OF ChannelEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+        "A table containing a list of active channels"
+    ::= { core 9 }
+
+channelEntry OBJECT-TYPE
+    SYNTAX      ChannelEntry
+    MAX-ACCESS  not-accessible
+    STATUS      current
+    DESCRIPTION
+        "A channel entry"
+    INDEX { chanIndex }
+    ::= { channelList 1 }
+
+chanUUID OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The channel UUID."
+    ::= { channelEntry 1 }
+
+chanDirection OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The channel direction."
+    ::= { channelEntry 2 }
+
+chanCreated OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Channel creation timestamp."
+    ::= { channelEntry 3 }
+
+chanName OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The channel name."
+    ::= { channelEntry 4 }
+
+chanState OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The channel state."
+    ::= { channelEntry 5 }
+
+chanCIDName OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The channel caller ID name."
+    ::= { channelEntry 6 }
+
+chanCIDNum OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The channel caller ID number."
+    ::= { channelEntry 7 }
+
 END
diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c
index 56c7be1..d415d4f 100644
--- a/src/mod/event_handlers/mod_snmp/mod_snmp.c
+++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c
@@ -109,7 +109,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
 	 */
 	netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 2);
 
-	init_subagent();  
+	init_subagent(pool);
 	init_snmp("mod_snmp");
 
 	return status;
diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c
index bad3dc6..7b9faa7 100644
--- a/src/mod/event_handlers/mod_snmp/subagent.c
+++ b/src/mod/event_handlers/mod_snmp/subagent.c
@@ -36,27 +36,108 @@
 #include <net-snmp/agent/net-snmp-agent-includes.h>
 #include "subagent.h"
 
+netsnmp_table_registration_info *ch_table_info;
+netsnmp_tdata *ch_table;
+netsnmp_handler_registration *ch_reginfo;
+uint32_t idx;
 
-void init_subagent(void)
+
+static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNames)
 {
-	static oid identity_oid[] = { 1,3,6,1,4,1,27880,1,1 };
-	static oid systemStats_oid[] = { 1,3,6,1,4,1,27880,1,2 };
+	uint32_t *count = (uint32_t *) pArg;
+	*count = atoi(argv[0]);
+	return 0;
+}
 
-	DEBUGMSGTL(("init_subagent", "Initializing\n"));
 
-	netsnmp_register_scalar_group(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY), 1, 2);
-	netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7);
+static int channelList_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+	chan_entry_t *entry;
+	netsnmp_tdata_row *row;
+
+	switch_zmalloc(entry, sizeof(chan_entry_t));
+	if (!entry)
+		return 0;
+
+	row = netsnmp_tdata_create_row();
+	if (!row) {
+		switch_safe_free(entry);
+		return 0;
+	}
+	row->data = entry;
+
+	entry->idx = idx++;
+	strncpy(entry->uuid, argv[0], sizeof(entry->uuid));
+	strncpy(entry->direction, argv[1], sizeof(entry->direction));
+	strncpy(entry->created, argv[2], sizeof(entry->created));
+	strncpy(entry->name, argv[4], sizeof(entry->name));
+	strncpy(entry->state, argv[5], sizeof(entry->state));
+	strncpy(entry->cid_name, argv[6], sizeof(entry->cid_name));
+	strncpy(entry->cid_num, argv[7], sizeof(entry->cid_num));
+
+	netsnmp_tdata_row_add_index(row, ASN_INTEGER, &entry->idx, sizeof(entry->idx));
+	netsnmp_tdata_add_row(ch_table, row);
+	return 0;
 }
 
 
-static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNames)
+void channelList_free(netsnmp_cache *cache, void *magic)
 {
-	uint32_t *count = (uint32_t *) pArg;
-	*count = atoi(argv[0]);
+	netsnmp_tdata_row *row = netsnmp_tdata_row_first(ch_table);
+
+	/* Delete table rows one by one */
+	while (row) {
+		netsnmp_tdata_remove_and_delete_row(ch_table, row);
+		switch_safe_free(row->data);
+		row = netsnmp_tdata_row_first(ch_table);
+	}
+}
+
+
+int channelList_load(netsnmp_cache *cache, void *vmagic)
+{
+	switch_cache_db_handle_t *dbh;
+	char sql[1024] = "", hostname[256] = "";
+
+	channelList_free(cache, NULL);
+
+	if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) {
+		return 0;
+	}
+
+	idx = 1;
+	gethostname(hostname, sizeof(hostname));
+	sprintf(sql, "SELECT * FROM channels WHERE hostname='%s' ORDER BY created_epoch", hostname);
+	switch_cache_db_execute_sql_callback(dbh, sql, channelList_callback, NULL, NULL);
+
+	switch_cache_db_release_db_handle(&dbh);
+
 	return 0;
 }
 
 
+void init_subagent(switch_memory_pool_t *pool)
+{
+	static oid identity_oid[] = { 1,3,6,1,4,1,27880,1,1 };
+	static oid systemStats_oid[] = { 1,3,6,1,4,1,27880,1,2 };
+	static oid channelList_oid[] = { 1,3,6,1,4,1,27880,1,9 };
+
+	DEBUGMSGTL(("init_subagent", "mod_snmp subagent initializing\n"));
+
+	netsnmp_register_scalar_group(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY), 1, 2);
+	netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7);
+
+	ch_table_info = switch_core_alloc(pool, sizeof(netsnmp_table_registration_info));
+	netsnmp_table_helper_add_index(ch_table_info, ASN_INTEGER);
+	ch_table_info->min_column = 1;
+	ch_table_info->max_column = 7;
+	ch_table = netsnmp_tdata_create_table("channelList", 0);
+	ch_reginfo = netsnmp_create_handler_registration("channelList", handle_channelList, channelList_oid, OID_LENGTH(channelList_oid), HANDLER_CAN_RONLY);
+	netsnmp_tdata_register(ch_reginfo, ch_table, ch_table_info);
+	netsnmp_inject_handler(ch_reginfo, netsnmp_get_cache_handler(5, channelList_load, channelList_free, channelList_oid, OID_LENGTH(channelList_oid)));
+}
+
+
 int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests)
 {
 	netsnmp_request_info *request = NULL;
@@ -97,7 +178,7 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 	netsnmp_request_info *request = NULL;
 	oid subid;
 	switch_time_t uptime;
-	uint32_t int_val;
+	uint32_t int_val = 0;
 
 	switch(reqinfo->mode) {
 	case MODE_GET:
@@ -160,6 +241,55 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 }
 
 
+int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests)
+{
+	netsnmp_request_info *request;
+	netsnmp_table_request_info *table_info;
+	chan_entry_t *entry;
+
+	switch (reqinfo->mode) {
+	case MODE_GET:
+		for (request = requests; request; request = request->next) {
+			table_info = netsnmp_extract_table_info(request);
+			entry = (chan_entry_t *) netsnmp_tdata_extract_entry(request);
+
+			switch (table_info->colnum) {
+			case CH_UUID:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->uuid, strlen(entry->uuid));
+				break;
+			case CH_DIRECTION:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->direction, strlen(entry->direction));
+				break;
+			case CH_CREATED:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->created, strlen(entry->created));
+				break;
+			case CH_NAME:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->name, strlen(entry->name));
+				break;
+			case CH_STATE:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->state, strlen(entry->state));
+				break;
+			case CH_CID_NAME:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->cid_name, strlen(entry->cid_name));
+				break;
+			case CH_CID_NUM:
+				snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->cid_num, strlen(entry->cid_num));
+				break;
+			default:
+				snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", table_info->colnum);
+				netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+			}
+		}
+		break;
+	default:
+		/* we should never get here, so this is a really bad error */
+		snmp_log(LOG_ERR, "Unknown mode (%d) in handle_foo\n", reqinfo->mode );
+		return SNMP_ERR_GENERR;
+	}
+
+	return SNMP_ERR_NOERROR;
+}
+
 
 /* For Emacs:
  * Local Variables:
diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h
index 3315378..0070b2c 100644
--- a/src/mod/event_handlers/mod_snmp/subagent.h
+++ b/src/mod/event_handlers/mod_snmp/subagent.h
@@ -14,9 +14,29 @@
 #define SS_SESSIONS_PER_SECOND		6
 #define SS_MAX_SESSIONS_PER_SECOND	7
 
+/* .1.3.6.1.4.1.27880.1.9 */
+#define CH_UUID				1
+#define CH_DIRECTION			2
+#define CH_CREATED			3
+#define CH_NAME				4
+#define CH_STATE			5
+#define CH_CID_NAME			6
+#define CH_CID_NUM			7
 
-void init_subagent(void);
+typedef struct {
+	uint32_t idx;
+	char uuid[38];
+	char direction[32];
+	char created[128];
+	char name[1024];
+	char state[64];
+	char cid_name[1024];
+	char cid_num[256];
+} chan_entry_t;
+
+void init_subagent(switch_memory_pool_t *pool);
 Netsnmp_Node_Handler handle_identity;
 Netsnmp_Node_Handler handle_systemStats;
+Netsnmp_Node_Handler handle_channelList;
 
 #endif /* subagent_H */
committer: Raymond Chandler
comments: 
Merge branch 'master' of fs-git:freeswitch
committer: Raymond Chandler
comments: 
TEST-001

diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 6ed99ef..5fc9402 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -63,4 +63,3 @@
   </section>
 
 </document>
-
committer: Daniel Swarbrick
comments: 
add support for getting current call count

diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c
index 8f08baf..bad3dc6 100644
--- a/src/mod/event_handlers/mod_snmp/subagent.c
+++ b/src/mod/event_handlers/mod_snmp/subagent.c
@@ -49,6 +49,14 @@ void init_subagent(void)
 }
 
 
+static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+	uint32_t *count = (uint32_t *) pArg;
+	*count = atoi(argv[0]);
+	return 0;
+}
+
+
 int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests)
 {
 	netsnmp_request_info *request = NULL;
@@ -113,13 +121,20 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
 			break;
 		case SS_CURRENT_CALLS:
-			/*
-			 * This is zero for now, since there is no convenient way to get total call
-			 * count (not to be confused with session count), without touching the
-			 * database.
-			 */
-			int_val = 0;
+			{
+			switch_cache_db_handle_t *dbh;
+			char sql[1024] = "", hostname[256] = "";
+
+			if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) {
+				return SNMP_ERR_GENERR;
+			}
+
+			gethostname(hostname, sizeof(hostname));
+			sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", hostname);
+			switch_cache_db_execute_sql_callback(dbh, sql, sql_count_callback, &int_val, NULL);
 			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+			switch_cache_db_release_db_handle(&dbh);
+			}
 			break;
 		case SS_SESSIONS_PER_SECOND:
 			switch_core_session_ctl(SCSC_LAST_SPS, &int_val);
committer: Raymond Chandler
comments: 
test

diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 80e7728..6ed99ef 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -64,4 +64,3 @@
 
 </document>
 
-
committer: Raymond Chandler
comments: 
test

diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 6ed99ef..80e7728 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -64,3 +64,4 @@
 
 </document>
 
+
committer: Raymond Chandler
comments: 
test

diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 5fc9402..6ed99ef 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -63,3 +63,4 @@
   </section>
 
 </document>
+
committer: Raymond Chandler
comments: 
test

diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 6ed99ef..5fc9402 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -63,4 +63,3 @@
   </section>
 
 </document>
-
committer: Raymond Chandler
comments: 
test

diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index 80e7728..6ed99ef 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -64,4 +64,3 @@
 
 </document>
 
-
committer: Daniel Swarbrick
comments: 
typo

diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c
index 2da9ebe..8f08baf 100644
--- a/src/mod/event_handlers/mod_snmp/subagent.c
+++ b/src/mod/event_handlers/mod_snmp/subagent.c
@@ -109,7 +109,7 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
 			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
 			break;
 		case SS_MAX_SESSIONS:
-			switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);;
+			switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);
 			snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
 			break;
 		case SS_CURRENT_CALLS:
committer: Jeff Lenk
comments: 
add missing files

diff --git a/libs/freetdm/msvc/freetdm.2010.vcxproj b/libs/freetdm/msvc/freetdm.2010.vcxproj
index 71eb6db..aecb9ef 100644
--- a/libs/freetdm/msvc/freetdm.2010.vcxproj
+++ b/libs/freetdm/msvc/freetdm.2010.vcxproj
@@ -188,6 +188,7 @@
     <ClInclude Include="..\src\include\ftdm_os.h" />
     <ClInclude Include="..\src\include\private\ftdm_sched.h" />
     <ClInclude Include="..\src\include\ftdm_threadmutex.h" />
+    <ClInclude Include="..\src\include\private\ftdm_state.h" />
     <ClInclude Include="..\src\include\private\ftdm_types.h" />
     <ClInclude Include="..\src\include\private\g711.h" />
     <ClInclude Include="..\src\include\private\hashtable.h" />
@@ -209,6 +210,7 @@
     <ClCompile Include="..\src\ftdm_io.c" />
     <ClCompile Include="..\src\ftdm_queue.c" />
     <ClCompile Include="..\src\ftdm_sched.c" />
+    <ClCompile Include="..\src\ftdm_state.c" />
     <ClCompile Include="..\src\ftdm_threadmutex.c" />
     <ClCompile Include="..\src\g711.c" />
     <ClCompile Include="..\src\hashtable.c" />
diff --git a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters b/libs/freetdm/msvc/freetdm.2010.vcxproj.filters
index ed642ba..e6dc40d 100644
--- a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters
+++ b/libs/freetdm/msvc/freetdm.2010.vcxproj.filters
@@ -71,6 +71,9 @@
     <ClInclude Include="..\src\include\private\uart.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\include\private\ftdm_state.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\src\fsk.c">
@@ -124,5 +127,8 @@
     <ClCompile Include="..\src\uart.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\ftdm_state.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
committer: Travis Cross
comments: 
.gitignore compressed files

diff --git a/.gitignore b/.gitignore
index 304b42c..c53d07d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,6 +33,12 @@
 *.ilk
 *.bsc
 *.pch
+*.tar
+*.gz
+*.tgz
+*.xz
+*.bz2
+*.tbz2
 core.*
 /Path
 /w32/Library/lastversion
@@ -79,7 +85,6 @@ configure.lineno
 /scripts/fsxs
 /scripts/gentls_cert
 /a.out.dSYM
-/freeswitch-sounds-*
 src/mod/applications/mod_easyroute/Makefile
 src/mod/applications/mod_lcr/Makefile
 src/mod/applications/mod_nibblebill/Makefile
diff --git a/src/mod/endpoints/mod_gsmopen/.gitignore b/src/mod/endpoints/mod_gsmopen/.gitignore
index 9fdeeb1..fe8dc68 100644
--- a/src/mod/endpoints/mod_gsmopen/.gitignore
+++ b/src/mod/endpoints/mod_gsmopen/.gitignore
@@ -1,2 +1,4 @@
 !/gsmlib/gsmlib-*/aclocal.m4
 !/gsmlib/gsmlib-*/configure
+!/gsmlib/gsmlib-1.10.tar.gz
+!/gsmlib/gsmlib_1.10-12ubuntu1.diff.gz
committer: Brian West
comments: 
swigall

diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
index aa2a84f..3ee6ff6 100644
--- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx
+++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
@@ -7413,6 +7413,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_dmachine(void * jar
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_set_codec_slin(void * jarg1, void * jarg2) {
+  int jresult ;
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  switch_slin_data_t *arg2 = (switch_slin_data_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  arg2 = (switch_slin_data_t *)jarg2; 
+  result = (switch_status_t)switch_core_session_set_codec_slin(arg1,arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_uuid() {
   char * jresult ;
   char *result = 0 ;
@@ -22794,6 +22808,119 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_api_interface(void * jarg1) {
 }
 
 
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_session_set(void * jarg1, void * jarg2) {
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  switch_core_session_t *arg2 = (switch_core_session_t *) 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  arg2 = (switch_core_session_t *)jarg2; 
+  if (arg1) (arg1)->session = arg2;
+  
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_session_get(void * jarg1) {
+  void * jresult ;
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  switch_core_session_t *result = 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  result = (switch_core_session_t *) ((arg1)->session);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_write_frame_set(void * jarg1, void * jarg2) {
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  switch_frame_t *arg2 = (switch_frame_t *) 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  arg2 = (switch_frame_t *)jarg2; 
+  if (arg1) (arg1)->write_frame = *arg2;
+  
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_write_frame_get(void * jarg1) {
+  void * jresult ;
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  switch_frame_t *result = 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  result = (switch_frame_t *)& ((arg1)->write_frame);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_codec_set(void * jarg1, void * jarg2) {
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  switch_codec_t *arg2 = (switch_codec_t *) 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  arg2 = (switch_codec_t *)jarg2; 
+  if (arg1) (arg1)->codec = *arg2;
+  
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_codec_get(void * jarg1) {
+  void * jresult ;
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  switch_codec_t *result = 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  result = (switch_codec_t *)& ((arg1)->codec);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_frame_data_set(void * jarg1, char * jarg2) {
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  char *arg2 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  arg2 = (char *)jarg2; 
+  {
+    if (arg2) strncpy((char *)arg1->frame_data, (const char *)arg2, 4096);
+    else arg1->frame_data[0] = 0;
+  }
+}
+
+
+SWIGEXPORT char * SWIGSTDCALL CSharp_switch_slin_data_frame_data_get(void * jarg1) {
+  char * jresult ;
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  char *result = 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  result = (char *)(char *) ((arg1)->frame_data);
+  jresult = SWIG_csharp_string_callback((const char *)result); 
+  return jresult;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_slin_data() {
+  void * jresult ;
+  switch_slin_data *result = 0 ;
+  
+  result = (switch_slin_data *)new switch_slin_data();
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_slin_data(void * jarg1) {
+  switch_slin_data *arg1 = (switch_slin_data *) 0 ;
+  
+  arg1 = (switch_slin_data *)jarg1; 
+  delete arg1;
+  
+}
+
+
 SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_profile_created_set(void * jarg1, void * jarg2) {
   switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ;
   switch_time_t arg2 ;
diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs
index 5a2188a..48d585e 100644
--- a/src/mod/languages/mod_managed/managed/swig.cs
+++ b/src/mod/languages/mod_managed/managed/swig.cs
@@ -1357,6 +1357,11 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session session, switch_slin_data data) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_slin_data.getCPtr(data));
+    return ret;
+  }
+
   public static string switch_core_get_uuid() {
     string ret = freeswitchPINVOKE.switch_core_get_uuid();
     return ret;
@@ -7504,6 +7509,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_dmachine")]
   public static extern IntPtr switch_core_session_get_dmachine(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_codec_slin")]
+  public static extern int switch_core_session_set_codec_slin(HandleRef jarg1, HandleRef jarg2);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_uuid")]
   public static extern string switch_core_get_uuid();
 
@@ -11188,6 +11196,36 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_api_interface")]
   public static extern void delete_switch_api_interface(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_set")]
+  public static extern void switch_slin_data_session_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_get")]
+  public static extern IntPtr switch_slin_data_session_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_set")]
+  public static extern void switch_slin_data_write_frame_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_get")]
+  public static extern IntPtr switch_slin_data_write_frame_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_set")]
+  public static extern void switch_slin_data_codec_set(HandleRef jarg1, HandleRef jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_get")]
+  public static extern IntPtr switch_slin_data_codec_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_set")]
+  public static extern void switch_slin_data_frame_data_set(HandleRef jarg1, string jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_get")]
+  public static extern string switch_slin_data_frame_data_get(HandleRef jarg1);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_new_switch_slin_data")]
+  public static extern IntPtr new_switch_slin_data();
+
+  [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_slin_data")]
+  public static extern void delete_switch_slin_data(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_profile_created_set")]
   public static extern void switch_channel_timetable_profile_created_set(HandleRef jarg1, HandleRef jarg2);
 
@@ -28401,7 +28439,8 @@ public enum switch_rtp_bug_flag_t {
   RTP_BUG_IGNORE_MARK_BIT = (1 << 2),
   RTP_BUG_SEND_LINEAR_TIMESTAMPS = (1 << 3),
   RTP_BUG_START_SEQ_AT_ZERO = (1 << 4),
-  RTP_BUG_NEVER_SEND_MARKER = (1 << 5)
+  RTP_BUG_NEVER_SEND_MARKER = (1 << 5),
+  RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6)
 }
 
 }
@@ -29437,6 +29476,96 @@ public enum switch_signal_t {
 
 namespace FreeSWITCH.Native {
 
+using System;
+using System.Runtime.InteropServices;
+
+public class switch_slin_data : IDisposable {
+  private HandleRef swigCPtr;
+  protected bool swigCMemOwn;
+
+  internal switch_slin_data(IntPtr cPtr, bool cMemoryOwn) {
+    swigCMemOwn = cMemoryOwn;
+    swigCPtr = new HandleRef(this, cPtr);
+  }
+
+  internal static HandleRef getCPtr(switch_slin_data obj) {
+    return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
+  }
+
+  ~switch_slin_data() {
+    Dispose();
+  }
+
+  public virtual void Dispose() {
+    lock(this) {
+      if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) {
+        swigCMemOwn = false;
+        freeswitchPINVOKE.delete_switch_slin_data(swigCPtr);
+      }
+      swigCPtr = new HandleRef(null, IntPtr.Zero);
+      GC.SuppressFinalize(this);
+    }
+  }
+
+  public SWIGTYPE_p_switch_core_session session {
+    set {
+      freeswitchPINVOKE.switch_slin_data_session_set(swigCPtr, SWIGTYPE_p_switch_core_session.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_session_get(swigCPtr);
+      SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public switch_frame write_frame {
+    set {
+      freeswitchPINVOKE.switch_slin_data_write_frame_set(swigCPtr, switch_frame.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_write_frame_get(swigCPtr);
+      switch_frame ret = (cPtr == IntPtr.Zero) ? null : new switch_frame(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public switch_codec codec {
+    set {
+      freeswitchPINVOKE.switch_slin_data_codec_set(swigCPtr, switch_codec.getCPtr(value));
+    } 
+    get {
+      IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_codec_get(swigCPtr);
+      switch_codec ret = (cPtr == IntPtr.Zero) ? null : new switch_codec(cPtr, false);
+      return ret;
+    } 
+  }
+
+  public string frame_data {
+    set {
+      freeswitchPINVOKE.switch_slin_data_frame_data_set(swigCPtr, value);
+    } 
+    get {
+      string ret = freeswitchPINVOKE.switch_slin_data_frame_data_get(swigCPtr);
+      return ret;
+    } 
+  }
+
+  public switch_slin_data() : this(freeswitchPINVOKE.new_switch_slin_data(), true) {
+  }
+
+}
+
+}
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.35
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+namespace FreeSWITCH.Native {
+
 [System.Flags] public enum switch_speech_flag_enum_t {
   SWITCH_SPEECH_FLAG_NONE = 0,
   SWITCH_SPEECH_FLAG_HASTEXT = (1 << 0),
@@ -30146,7 +30275,7 @@ public enum switch_status_t {
   SWITCH_STATUS_FALSE,
   SWITCH_STATUS_TIMEOUT,
   SWITCH_STATUS_RESTART,
-  SWITCH_STATUS_TERM,
+  SWITCH_STATUS_INTR,
   SWITCH_STATUS_NOTIMPL,
   SWITCH_STATUS_MEMERR,
   SWITCH_STATUS_NOOP,
@@ -30163,6 +30292,7 @@ public enum switch_status_t {
   SWITCH_STATUS_TOO_SMALL,
   SWITCH_STATUS_FOUND,
   SWITCH_STATUS_CONTINUE,
+  SWITCH_STATUS_TERM,
   SWITCH_STATUS_NOT_INITALIZED
 }
 
committer: Brian West
comments: 
FS-3004

diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
index 21c6a68..4dd936b 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
@@ -40,6 +40,9 @@
 #define MAX_FEC_ENTRIES             4
 #define MAX_FEC_SPAN                4
 
+#define SPANDSP_EVENT_TXFAXRESULT "spandsp::txfaxresult"
+#define SPANDSP_EVENT_RXFAXRESULT "spandsp::rxfaxresult"
+
 /*****************************************************************************
 	OUR DEFINES AND STRUCTS
 *****************************************************************************/
@@ -305,7 +308,14 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
 	switch_core_session_t *session;
 	switch_channel_t *channel;
 	pvt_t *pvt;
-	char *tmp;
+	char *fax_document_transferred_pages = NULL;
+	char *fax_document_total_pages = NULL;
+	char *fax_image_resolution = NULL;
+	char *fax_image_size = NULL;
+	char *fax_bad_rows = NULL;
+	char *fax_transfer_rate = NULL;
+	char *fax_result_code = NULL;
+	switch_event_t *event;
 
 	pvt = (pvt_t *) user_data;
 	switch_assert(pvt);
@@ -353,13 +363,12 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
 	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==============================================================================\n");
 
 	/*
-	   Set our channel variables
+	   Set our channel variables, variables are also used in event
 	 */
 
-	tmp = switch_mprintf("%i", result);
-	if (tmp) {
-		switch_channel_set_variable(channel, "fax_result_code", tmp);
-		switch_safe_free(tmp);
+	fax_result_code = switch_core_session_sprintf(session, "%i", result);
+	if (fax_result_code) {
+		switch_channel_set_variable(channel, "fax_result_code", fax_result_code);
 	}
 
 	switch_channel_set_variable(channel, "fax_result_text", t30_completion_code_to_str(result));
@@ -368,49 +377,56 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
 	switch_channel_set_variable(channel, "fax_local_station_id", local_ident);
 	switch_channel_set_variable(channel, "fax_remote_station_id", far_ident);
 
-	tmp = switch_mprintf("%i", pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx);
-	if (tmp) {
-		switch_channel_set_variable(channel, "fax_document_transferred_pages", tmp);
-		switch_safe_free(tmp);
+	fax_document_transferred_pages = switch_core_session_sprintf(session, "%i", pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx);
+	if (fax_document_transferred_pages) {
+		switch_channel_set_variable(channel, "fax_document_transferred_pages", fax_document_transferred_pages);
 	}
 
-	tmp = switch_mprintf("%i", t.pages_in_file);
-	if (tmp) {
-		switch_channel_set_variable(channel, "fax_document_total_pages", tmp);
-		switch_safe_free(tmp);
+	fax_document_total_pages = switch_core_session_sprintf(session, "%i", t.pages_in_file);
+	if (fax_document_total_pages) {
+		switch_channel_set_variable(channel, "fax_document_total_pages", fax_document_total_pages);
 	}
 
-	tmp = switch_mprintf("%ix%i", t.x_resolution, t.y_resolution);
-	if (tmp) {
-		switch_channel_set_variable(channel, "fax_image_resolution", tmp);
-		switch_safe_free(tmp);
+	fax_image_resolution = switch_core_session_sprintf(session, "%ix%i", t.x_resolution, t.y_resolution);
+	if (fax_image_resolution) {
+		switch_channel_set_variable(channel, "fax_image_resolution", fax_image_resolution);
 	}
 
-	tmp = switch_mprintf("%d", t.image_size);
-	if (tmp) {
-		switch_channel_set_variable(channel, "fax_image_size", tmp);
-		switch_safe_free(tmp);
+	fax_image_size = switch_core_session_sprintf(session, "%d", t.image_size);
+	if (fax_image_size) {
+		switch_channel_set_variable(channel, "fax_image_size", fax_image_size);
 	}
 
-	tmp = switch_mprintf("%d", t.bad_rows);
-	if (tmp) {
-		switch_channel_set_variable(channel, "fax_bad_rows", tmp);
-		switch_safe_free(tmp);
+	fax_bad_rows = switch_core_session_sprintf(session, "%d", t.bad_rows);
+	if (fax_bad_rows) {
+		switch_channel_set_variable(channel, "fax_bad_rows", fax_bad_rows);
 	}
 
-	tmp = switch_mprintf("%i", t.bit_rate);
-	if (tmp) {
-		switch_channel_set_variable(channel, "fax_transfer_rate", tmp);
-		switch_safe_free(tmp);
+	fax_transfer_rate = switch_core_session_sprintf(session, "%i", t.bit_rate);
+	if (fax_transfer_rate) {
+		switch_channel_set_variable(channel, "fax_transfer_rate", fax_transfer_rate);
 	}
 
 	/* switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); */
 
 	pvt->done = 1;
 
-	/*
-	   TODO Fire events
-	 */
+	/* Fire event */
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXRESULT : SPANDSP_EVENT_RXFAXRESULT) == SWITCH_STATUS_SUCCESS) {
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-transferred-pages", fax_document_transferred_pages);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-total-pages", fax_document_total_pages);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_image_resolution);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-size", fax_image_size);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-bad-rows", fax_bad_rows);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-transfer-rate", fax_transfer_rate);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-code", fax_result_code);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-text", t30_completion_code_to_str(result));
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-ecm-used", (t.error_correcting_mode) ? "on" : "off");
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-local-station-id", local_ident);
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-remote-station-id", far_ident);
+		switch_core_session_queue_private_event(session, &event, SWITCH_FALSE);
+	}
 }
 
 static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
@@ -1026,7 +1042,6 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Fax TX filename not set.\n");
 			goto done;
 		} else if (pvt->app_mode == FUNCTION_RX) {
-			char *fname;
 			const char *prefix;
 			switch_time_t time;
 
@@ -1036,11 +1051,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
 				prefix = globals.prepend_string;
 			}
 
-			fname = switch_mprintf("%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time);
-			if (fname) {
-				pvt->filename = switch_core_session_strdup(session, fname);
-				switch_safe_free(fname);
-			} else {
+			if (!(pvt->filename = switch_core_session_sprintf(session, "%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time))) {
 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot automatically set fax RX destination file\n");
 				goto done;
 			}
committer: Raymond Chandler
comments: 
test

diff --git a/build/modules.conf.in b/build/modules.conf.in
index b46c2ff..84a9e9a 100644
--- a/build/modules.conf.in
+++ b/build/modules.conf.in
@@ -112,4 +112,3 @@ say/mod_say_ru
 
 ## Experimental Modules (don't cry if they're broken)
 #../../contrib/mod/xml_int/mod_xml_odbc
-
committer: Raymond Chandler
comments: 
Merge branch 'master' of fs-git:freeswitch
committer: Raymond Chandler
comments: 
test

diff --git a/build/modules.conf.in b/build/modules.conf.in
index 84a9e9a..b46c2ff 100644
--- a/build/modules.conf.in
+++ b/build/modules.conf.in
@@ -112,3 +112,4 @@ say/mod_say_ru
 
 ## Experimental Modules (don't cry if they're broken)
 #../../contrib/mod/xml_int/mod_xml_odbc
+
committer: Daniel Swarbrick
comments: 
reduce agentx heartbeat to 2s, add management hook for mutex lock/unlock

diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c
index 0310637..56c7be1 100644
--- a/src/mod/event_handlers/mod_snmp/mod_snmp.c
+++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c
@@ -48,6 +48,20 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime);
 SWITCH_MODULE_DEFINITION(mod_snmp, mod_snmp_load, mod_snmp_shutdown, mod_snmp_runtime);
 
 
+static switch_status_t snmp_manage(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
+{
+	if (action == SMA_GET) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mutex lock request from relative OID %s.\n", relative_oid);
+		switch_mutex_lock(globals.mutex);
+	} else if (action == SMA_SET) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mutex unlock request from relative OID %s.\n", relative_oid);
+		switch_mutex_unlock(globals.mutex);
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
 static int snmp_callback_log(int major, int minor, void *serverarg, void *clientarg)
 {
 	struct snmp_log_message *slm = (struct snmp_log_message *) serverarg;
@@ -71,10 +85,14 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
 SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
 {
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	switch_management_interface_t *management_interface;
 
 	load_config(pool);
 
 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
+	management_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_MANAGEMENT_INTERFACE);
+	management_interface->relative_oid = "1000";
+	management_interface->management_function = snmp_manage;
 
 	/* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */
 	snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, snmp_callback_log, NULL);
@@ -86,10 +104,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
 	init_agent("mod_snmp");
 
 	/*
-	 * Override master/subagent ping interval to 5s, to ensure that
+	 * Override master/subagent ping interval to 2s, to ensure that
 	 * agent_check_and_process() never blocks for longer than that.
 	 */
-	netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 5);
+	netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 2);
 
 	init_subagent();  
 	init_snmp("mod_snmp");
@@ -107,6 +125,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime)
 		switch_mutex_unlock(globals.mutex);
 	}
 
+	switch_yield(5000);
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
committer: Luke Dashjr
comments: 
MERGE: OpenMethods DTMF recognition via ASR modules
committer: Luke Dashjr
comments: 
MERGE: OpenMethods ASR enhancements: multiple concurrent grammars and dialplan access to start-input-timers

diff --cc src/mod/applications/mod_dptools/mod_dptools.c
index 5a3be03,fe089a6..928a9b8
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@@ -95,181 -96,7 +96,181 @@@ SWITCH_STANDARD_DIALPLAN(inline_dialpla
  	return extension;
  }
  
 +struct action_binding {
 +	char *realm;
 +	char *input;
 +	char *string;
 +	char *value;
 +	switch_core_session_t *session;
 +};
 +
 +static switch_status_t digit_nomatch_action_callback(switch_ivr_dmachine_match_t *match)
 +{
 +	switch_core_session_t *session = (switch_core_session_t *) match->user_data;
 +	switch_channel_t *channel = switch_core_session_get_channel(session);
 +	char str[DMACHINE_MAX_DIGIT_LEN + 2];
 +	switch_event_t *event;
 +	switch_status_t status;
 +
 +	switch_channel_set_variable(channel, "last_non_matching_digits", match->match_digits);
 +
 +	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Digit NOT match binding [%s]\n", 
 +					  switch_channel_get_name(channel), match->match_digits);
 +
 +	if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
 +		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "digits", match->match_digits);
 +
 +		if ((status = switch_core_session_queue_event(session, &event)) != SWITCH_STATUS_SUCCESS) {
 +			switch_event_destroy(&event);
 +			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s event queue faiure.\n", 
 +							  switch_core_session_get_name(session));
 +		}
 +	}
 +
 +	/* send it back around flagged to skip the dmachine */
 +	switch_snprintf(str, sizeof(str), "!%s", match->match_digits);
 +	
 +	switch_channel_queue_dtmf_string(channel, str);
 +	
 +	return SWITCH_STATUS_SUCCESS;
 +}
 +
 +static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
 +{
 +	struct action_binding *act = (struct action_binding *) match->user_data;
 +	switch_event_t *event;
 +	switch_status_t status;
 +	int exec = 0;
 +	char *string = act->string;
 +	switch_channel_t *channel = switch_core_session_get_channel(act->session);
 +
 +	switch_channel_set_variable(channel, "last_matching_digits", match->match_digits);
 +	
 +	if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
 +		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_DEBUG, "%s Digit match binding [%s][%s]\n", 
 +						  switch_channel_get_name(channel), act->string, act->value);
 +
 +		if (!strncasecmp(string, "exec:", 5)) {
 +			string += 5;
 +			exec = 1;
 +		}
 +
 +		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, string, act->value);
 +		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "digits", match->match_digits);
 +
 +		if (exec) {
 +			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute", exec == 2 ? "non-blocking" : "blocking");
 +		} 
 +
 +		if ((status = switch_core_session_queue_event(act->session, &event)) != SWITCH_STATUS_SUCCESS) {
 +			switch_event_destroy(&event);
 +			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_WARNING, "%s event queue faiure.\n", 
 +							  switch_core_session_get_name(act->session));
 +		}
 +	}
 +
 +	if (exec) {
 +		char *cmd = switch_core_session_sprintf(act->session, "%s::%s", string, act->value);
 +		switch_ivr_broadcast_in_thread(act->session, cmd, SMF_ECHO_ALEG|SMF_HOLD_BLEG);
 +	}
 +	
 +	return SWITCH_STATUS_SUCCESS;
 +}
 +
 +#define CLEAR_DIGIT_ACTION_USAGE "<realm>|all"
 +SWITCH_STANDARD_APP(clear_digit_action_function)
 +{
 +	//switch_channel_t *channel = switch_core_session_get_channel(session);
 +	switch_ivr_dmachine_t *dmachine;
 +	char *realm = (char *) data;
 +
 +	if ((dmachine = switch_core_session_get_dmachine(session))) {
 +		if (zstr(realm) || !strcasecmp(realm, "all")) {
 +			switch_core_session_set_dmachine(session, NULL);
 +			switch_ivr_dmachine_destroy(&dmachine);
 +		} else {
 +			switch_ivr_dmachine_clear_realm(dmachine, realm);
 +		}
 +	}
 +}
 +
 +#define DIGIT_ACTION_SET_REALM_USAGE "<realm>"
 +SWITCH_STANDARD_APP(digit_action_set_realm_function)
 +{
 +	switch_ivr_dmachine_t *dmachine;
 +	char *realm = (char *) data;
 +
 +	if (zstr(data)) {
 +		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", DIGIT_ACTION_SET_REALM_USAGE);
 +		return;
 +	}
 +	
 +	if ((dmachine = switch_core_session_get_dmachine(session))) {
 +		switch_ivr_dmachine_set_realm(dmachine, realm);
 +	}
 +
 +}
 +
 +#define BIND_DIGIT_ACTION_USAGE "<realm>,<digits|~regex>,<string>,<value>"
 +SWITCH_STANDARD_APP(bind_digit_action_function)
 +{
 +	switch_channel_t *channel = switch_core_session_get_channel(session);
 +	switch_ivr_dmachine_t *dmachine;
 +	char *mydata;
 +	int argc = 0;
 +	char *argv[4] = { 0 };
 +	struct action_binding *act;
 +
 +	if (zstr(data)) {
 +		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
 +		return;
 +	}
 +
 +	mydata = switch_core_session_strdup(session, data);
 +
 +	argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
 +	
 +	if (argc < 4 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2]) || zstr(argv[3])) {
 +		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
 +		return;
 +	}
 +
 +	
 +	if (!(dmachine = switch_core_session_get_dmachine(session))) {
 +		uint32_t digit_timeout = 1500;
 +		uint32_t input_timeout = 0;
 +		const char *var;
 +		uint32_t tmp;
 +
 +		if ((var = switch_channel_get_variable(channel, "bind_digit_digit_timeout"))) {
 +			tmp = (uint32_t) atol(var);
 +			if (tmp < 0) tmp = 0;
 +			digit_timeout = tmp;
 +		}
 +		
 +		if ((var = switch_channel_get_variable(channel, "bind_digit_input_timeout"))) {
 +			tmp = (uint32_t) atol(var);
 +			if (tmp < 0) tmp = 0;
 +			input_timeout = tmp;
 +		}
 +		
 +		switch_ivr_dmachine_create(&dmachine, "DPTOOLS", NULL, digit_timeout, input_timeout, NULL, digit_nomatch_action_callback, session);
 +		switch_core_session_set_dmachine(session, dmachine);
 +	}
 +
 +	
 +	act = switch_core_session_alloc(session, sizeof(*act));
 +	act->realm = argv[0];
 +	act->input = argv[1];
 +	act->string = argv[2];
 +	act->value = argv[3];
 +	act->session = session;
 +	
 +	switch_ivr_dmachine_bind(dmachine, act->realm, act->input, 0, digit_action_callback, act);
 +}
 +
 +
- #define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR pause OR resume OR stop OR param <name> <value>"
+ #define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR grammaron/grammaroff <gram_name> OR grammarsalloff OR pause OR resume OR start_input_timers OR stop OR param <name> <value>"
  SWITCH_STANDARD_APP(detect_speech_function)
  {
  	char *argv[4];
committer: Luke Dashjr
comments: 
MERGE: DTMF recognition via ASR modules (implemented in UniMRCP)

diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 26a048c..a3d74e9 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -1715,6 +1715,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_close(switch_asr_handle_t *ah, s
 SWITCH_DECLARE(switch_status_t) switch_core_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags);
 
 /*!
+  \brief Feed DTMF to an asr handle
+  \param ah the handle to feed data to
+  \param dtmf a string of DTMF digits
+  \param flags flags to influence behaviour
+  \return SWITCH_STATUS_SUCCESS
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags);
+
+/*!
   \brief Check an asr handle for results
   \param ah the handle to check
   \param flags flags to influence behaviour
diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h
index e0119b4..8303af7 100644
--- a/src/include/switch_module_interfaces.h
+++ b/src/include/switch_module_interfaces.h
@@ -400,6 +400,8 @@ struct switch_asr_interface {
 	switch_status_t (*asr_disable_grammar) (switch_asr_handle_t *ah, const char *name);
 	/*! function to disable all grammars to the asr interface */
 	switch_status_t (*asr_disable_all_grammars) (switch_asr_handle_t *ah);
+	/*! function to feed DTMF to the ASR */
+	switch_status_t (*asr_feed_dtmf) (switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags);
 };
 
 /*! an abstract representation of an asr speech interface. */
diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
index b9cecd1..b3679cf 100644
--- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
+++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
@@ -49,6 +49,7 @@
 #include "mrcp_resource_loader.h"
 #include "mpf_engine.h"
 #include "mpf_codec_manager.h"
+#include "mpf_dtmf_generator.h"
 #include "mpf_rtp_termination_factory.h"
 #include "mrcp_sofiasip_client_agent.h"
 #include "mrcp_unirtsp_client_agent.h"
@@ -442,6 +443,12 @@ struct recognizer_data {
 	int start_of_input;
 	/** true, if input timers have started */
 	int timers_started;
+	/** UniMRCP mpf stream */
+	mpf_audio_stream_t *unimrcp_stream;
+	/** DTMF generator */
+	mpf_dtmf_generator_t *dtmf_generator;
+	/** true, if presently transmitting DTMF */
+	char dtmf_generator_active;
 };
 typedef struct recognizer_data recognizer_data_t;
 
@@ -457,6 +464,7 @@ static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const
 static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah);
 static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags);
 static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags);
+static switch_status_t recog_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags);
 #if 0
 static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name);
 #endif
@@ -472,6 +480,7 @@ static void recog_asr_float_param(switch_asr_handle_t *ah, char *param, double v
 /* recognizer's interface for UniMRCP */
 static apt_bool_t recog_message_handler(const mrcp_app_message_t *app_message);
 static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message);
+static apt_bool_t recog_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec);
 static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame);
 
 /* recognizer specific speech_channel_funcs */
@@ -3114,6 +3123,9 @@ static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_
 	speech_channel_destroy(schannel);
 	switch_core_hash_destroy(&r->grammars);
 	switch_core_hash_destroy(&r->enabled_grammars);
+	if (r->dtmf_generator) {
+		mpf_dtmf_generator_destroy(r->dtmf_generator);
+	}
 
 	/* this lets FreeSWITCH's speech_thread know the handle is closed */
 	switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
@@ -3134,6 +3146,39 @@ static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsig
 	return speech_channel_write(schannel, data, &slen);
 }
 
+/**
+ * Process asr_feed_dtmf request from FreeSWITCH
+ *
+ * @param ah the FreeSWITCH speech recognition handle
+ * @return SWITCH_STATUS_SUCCESS if successful 
+ */
+static switch_status_t recog_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags)
+{
+	speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
+	recognizer_data_t *r = (recognizer_data_t *) schannel->data;
+	char digits[2];
+
+	if (!r->dtmf_generator) {
+		if (!r->unimrcp_stream) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Cannot queue DTMF: No UniMRCP stream object open\n", schannel->name);
+			return SWITCH_STATUS_FALSE;
+		}
+		r->dtmf_generator = mpf_dtmf_generator_create(r->unimrcp_stream, schannel->unimrcp_session->pool);
+		if (!r->dtmf_generator) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Cannot queue DTMF: Failed to create DTMF generator\n", schannel->name);
+			return SWITCH_STATUS_FALSE;
+		}
+	}
+
+	digits[0] = dtmf->digit;
+	digits[1] = '\0';
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Queued DTMF: %s\n", schannel->name, digits);
+	mpf_dtmf_generator_enqueue(r->dtmf_generator, digits);
+	r->dtmf_generator_active = 1;
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 #if 0
 /**
  * Process asr_start request from FreeSWITCH
@@ -3380,6 +3425,23 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp
 }
 
 /**
+ * UniMRCP callback requesting open for speech recognition
+ *
+ * @param stream the UniMRCP stream
+ * @param codec the codec
+ * @return TRUE
+ */
+static apt_bool_t recog_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec)
+{
+	speech_channel_t *schannel = (speech_channel_t *) stream->obj;
+	recognizer_data_t *r = (recognizer_data_t *) schannel->data;
+	
+	r->unimrcp_stream = stream;
+	
+	return TRUE;
+}
+
+/**
  * UniMRCP callback requesting next frame for speech recognition
  *
  * @param stream the UniMRCP stream
@@ -3389,6 +3451,7 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp
 static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame)
 {
 	speech_channel_t *schannel = (speech_channel_t *) stream->obj;
+	recognizer_data_t *r = (recognizer_data_t *) schannel->data;
 	switch_size_t to_read = frame->codec_frame.size;
 
 	/* grab the data.  pad it if there isn't enough */
@@ -3398,6 +3461,13 @@ static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *fra
 		}
 		frame->type |= MEDIA_FRAME_TYPE_AUDIO;
 	}
+	
+	if (r->dtmf_generator_active) {
+		if (!mpf_dtmf_generator_put_frame(r->dtmf_generator, frame)) {
+			if (!mpf_dtmf_generator_sending(r->dtmf_generator))
+				r->dtmf_generator_active = 0;
+		}
+	}
 
 	return TRUE;
 }
@@ -3421,6 +3491,7 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int
 	asr_interface->asr_disable_all_grammars = recog_asr_disable_all_grammars;
 	asr_interface->asr_close = recog_asr_close;
 	asr_interface->asr_feed = recog_asr_feed;
+	asr_interface->asr_feed_dtmf = recog_asr_feed_dtmf;
 #if 0
 	asr_interface->asr_start = recog_asr_start;
 #endif
@@ -3443,7 +3514,7 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int
 	globals.recog.dispatcher.on_channel_remove = speech_on_channel_remove;
 	globals.recog.dispatcher.on_message_receive = recog_on_message_receive;
 	globals.recog.audio_stream_vtable.destroy = NULL;
-	globals.recog.audio_stream_vtable.open_rx = NULL;
+	globals.recog.audio_stream_vtable.open_rx = recog_stream_open;
 	globals.recog.audio_stream_vtable.close_rx = NULL;
 	globals.recog.audio_stream_vtable.read_frame = recog_stream_read;
 	globals.recog.audio_stream_vtable.open_tx = NULL;
diff --git a/src/switch_core_asr.c b/src/switch_core_asr.c
index 691011a..7f231ef 100644
--- a/src/switch_core_asr.c
+++ b/src/switch_core_asr.c
@@ -239,6 +239,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_feed(switch_asr_handle_t *ah, vo
 	return ah->asr_interface->asr_feed(ah, data, len, flags);
 }
 
+SWITCH_DECLARE(switch_status_t) switch_core_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags)
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+	switch_assert(ah != NULL);
+
+	if (ah->asr_interface->asr_feed_dtmf) {
+		status = ah->asr_interface->asr_feed_dtmf(ah, dtmf, flags);
+	}
+
+	return status;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_core_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
 {
 	switch_assert(ah != NULL);
diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c
index 66cd369..5df7af3 100644
--- a/src/switch_ivr_async.c
+++ b/src/switch_ivr_async.c
@@ -2660,6 +2660,20 @@ static switch_bool_t speech_callback(switch_media_bug_t *bug, void *user_data, s
 	return SWITCH_TRUE;
 }
 
+static switch_status_t speech_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
+{
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+	struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
+
+	if (switch_core_asr_feed_dtmf(sth->ah, dtmf, &flags) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Feeding DTMF\n");
+	}
+
+	return status;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_ivr_stop_detect_speech(switch_core_session_t *session)
 {
 	switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -2875,6 +2889,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *
 		return status;
 	}
 
+	if ((status = switch_core_event_hook_add_recv_dtmf(session, speech_on_dtmf)) != SWITCH_STATUS_SUCCESS) {
+		switch_ivr_stop_detect_speech(session);
+		return status;
+	}
+
 	switch_channel_set_private(channel, SWITCH_SPEECH_KEY, sth);
 
 	return SWITCH_STATUS_SUCCESS;
committer: Luke Dashjr
comments: 
MERGE: expose ASR start_input_timers to dialplan via IVR and mod_dptools

diff --cc src/mod/applications/mod_dptools/mod_dptools.c
index f573661,2f49630..fe089a6
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@@ -96,7 -96,7 +96,7 @@@ SWITCH_STANDARD_DIALPLAN(inline_dialpla
  	return extension;
  }
  
- #define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR grammaron/grammaroff <gram_name> OR grammarsalloff OR pause OR resume OR stop OR param <name> <value>"
 -#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume OR start_input_timers"
++#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR grammaron/grammaroff <gram_name> OR grammarsalloff OR pause OR resume OR start_input_timers OR stop OR param <name> <value>"
  SWITCH_STANDARD_APP(detect_speech_function)
  {
  	char *argv[4];
committer: Luke Dashjr
comments: 
MERGE: document all of detect_speech's valid syntax

diff --cc src/mod/applications/mod_dptools/mod_dptools.c
index e942bc6,6d014fa..f573661
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@@ -96,7 -96,7 +96,7 @@@ SWITCH_STANDARD_DIALPLAN(inline_dialpla
  	return extension;
  }
  
- #define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume OR grammaron/grammaroff <gram_name> OR grammarsalloff"
 -#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR pause OR resume OR stop OR param <name> <value>"
++#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR grammaron/grammaroff <gram_name> OR grammarsalloff OR pause OR resume OR stop OR param <name> <value>"
  SWITCH_STANDARD_APP(detect_speech_function)
  {
  	char *argv[4];
committer: Luke Dashjr
comments: 
expose ASR enable/disable grammar (and disable all grammars) to dialplan via mod_dptools

diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 5a1b8c5..e942bc6 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -28,6 +28,7 @@
  * Michael Murdock <mike at mmurdock dot org>
  * Neal Horman <neal at wanlink dot com>
  * Bret McDanel <trixter AT 0xdecafbad dot com>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * mod_dptools.c -- Raw Audio File Streaming Application Module
  *
@@ -95,7 +96,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
 	return extension;
 }
 
-#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume"
+#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume OR grammaron/grammaroff <gram_name> OR grammarsalloff"
 SWITCH_STANDARD_APP(detect_speech_function)
 {
 	char *argv[4];
@@ -108,6 +109,12 @@ SWITCH_STANDARD_APP(detect_speech_function)
 			switch_ivr_detect_speech_load_grammar(session, argv[1], argv[2]);
 		} else if (!strcasecmp(argv[0], "nogrammar")) {
 			switch_ivr_detect_speech_unload_grammar(session, argv[1]);
+		} else if (!strcasecmp(argv[0], "grammaron")) {
+			switch_ivr_detect_speech_enable_grammar(session, argv[1]);
+		} else if (!strcasecmp(argv[0], "grammaroff")) {
+			switch_ivr_detect_speech_disable_grammar(session, argv[1]);
+		} else if (!strcasecmp(argv[0], "grammarsalloff")) {
+			switch_ivr_detect_speech_disable_all_grammars(session);
 		} else if (!strcasecmp(argv[0], "pause")) {
 			switch_ivr_pause_detect_speech(session);
 		} else if (!strcasecmp(argv[0], "resume")) {
committer: Luke Dashjr
comments: 
switch_ivr interfaces to enable/disable grammar: switch_ivr_detect_speech_enable_grammar, switch_ivr_detect_speech_disable_grammar, and switch_ivr_detect_speech_disable_all_grammars

diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h
index 40ba1dc..8641766 100644
--- a/src/include/switch_ivr.h
+++ b/src/include/switch_ivr.h
@@ -26,6 +26,7 @@
  * Anthony Minessale II <anthm@freeswitch.org>
  * Neal Horman <neal at wanlink dot com>
  * Bret McDanel <trixter AT 0xdecafbad dot com>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * switch_ivr.h -- IVR Library
  *
@@ -198,6 +199,29 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_load_grammar(switch_cor
 */
 SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_core_session_t *session, const char *name);
 
+/*!
+  \brief Enable a grammar on a background speech detection handle
+  \param session The session to change the grammar on
+  \param name the grammar name
+  \return SWITCH_STATUS_SUCCESS if all is well
+*/
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_enable_grammar(switch_core_session_t *session, const char *name);
+
+/*!
+  \brief Disable a grammar on a background speech detection handle
+  \param session The session to change the grammar on
+  \param name the grammar name
+  \return SWITCH_STATUS_SUCCESS if all is well
+*/
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_grammar(switch_core_session_t *session, const char *name);
+
+/*!
+  \brief Disable all grammars on a background speech detection handle
+  \param session The session to change the grammar on
+  \return SWITCH_STATUS_SUCCESS if all is well
+*/
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_all_grammars(switch_core_session_t *session);
+
 SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_session_t *session, const char *name, const char *val);
 
 /*!
diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c
index 4fe5732..672750a 100644
--- a/src/switch_ivr_async.c
+++ b/src/switch_ivr_async.c
@@ -26,6 +26,7 @@
  * Anthony Minessale II <anthm@freeswitch.org>
  * Michael Jerris <mike@jerris.com>
  * Bret McDanel <bret AT 0xdecafbad dot com>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * switch_ivr_async.c -- IVR Library (async operations)
  *
@@ -2745,6 +2746,57 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_c
 	return SWITCH_STATUS_FALSE;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_enable_grammar(switch_core_session_t *session, const char *name)
+{
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+	switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
+	struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
+	switch_status_t status;
+
+	if (sth) {
+		if ((status = switch_core_asr_enable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error enabling Grammar\n");
+			switch_core_asr_close(sth->ah, &flags);
+		}
+		return status;
+	}
+	return SWITCH_STATUS_FALSE;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_grammar(switch_core_session_t *session, const char *name)
+{
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+	switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
+	struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
+	switch_status_t status;
+
+	if (sth) {
+		if ((status = switch_core_asr_disable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling Grammar\n");
+			switch_core_asr_close(sth->ah, &flags);
+		}
+		return status;
+	}
+	return SWITCH_STATUS_FALSE;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_all_grammars(switch_core_session_t *session)
+{
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+	switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
+	struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
+	switch_status_t status;
+
+	if (sth) {
+		if ((status = switch_core_asr_disable_all_grammars(sth->ah)) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling all Grammars\n");
+			switch_core_asr_close(sth->ah, &flags);
+		}
+		return status;
+	}
+	return SWITCH_STATUS_FALSE;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *session,
 														 const char *mod_name,
 														 const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah)
committer: Luke Dashjr
comments: 
Implement UniMRCP asr_enable_grammar, asr_disable_grammar, and asr_disable_all_grammars which allow for multiple grammar recognition

diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
index a27ddf0..b9cecd1 100644
--- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
+++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
@@ -434,8 +434,8 @@ static const char *grammar_type_to_mime(grammar_type_t type, profile_t *profile)
 struct recognizer_data {
 	/** the available grammars */
 	switch_hash_t *grammars;
-	/** the last grammar used (for pause/resume) */
-	grammar_t *last_grammar;
+	/** the enabled grammars */
+	switch_hash_t *enabled_grammars;
 	/** recognize result */
 	char *result;
 	/** true, if voice has started */
@@ -452,6 +452,9 @@ static switch_status_t recog_shutdown();
 static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec, int rate, const char *dest, switch_asr_flag_t *flags);
 static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name);
 static switch_status_t recog_asr_unload_grammar(switch_asr_handle_t *ah, const char *name);
+static switch_status_t recog_asr_enable_grammar(switch_asr_handle_t *ah, const char *name);
+static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const char *name);
+static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah);
 static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags);
 static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags);
 #if 0
@@ -472,9 +475,12 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp
 static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame);
 
 /* recognizer specific speech_channel_funcs */
-static switch_status_t recog_channel_start(speech_channel_t *schannel, const char *name);
+static switch_status_t recog_channel_start(speech_channel_t *schannel);
 static switch_status_t recog_channel_load_grammar(speech_channel_t *schannel, const char *name, grammar_type_t type, const char *data);
 static switch_status_t recog_channel_unload_grammar(speech_channel_t *schannel, const char *name);
+static switch_status_t recog_channel_enable_grammar(speech_channel_t *schannel, const char *name);
+static switch_status_t recog_channel_disable_grammar(speech_channel_t *schannel, const char *name);
+static switch_status_t recog_channel_disable_all_grammars(speech_channel_t *schannel);
 static switch_status_t recog_channel_check_results(speech_channel_t *schannel);
 static switch_status_t recog_channel_set_start_of_input(speech_channel_t *schannel);
 static switch_status_t recog_channel_start_input_timers(speech_channel_t *schannel);
@@ -2056,19 +2062,24 @@ static const char *grammar_type_to_mime(grammar_type_t type, profile_t *profile)
  * Start RECOGNIZE request
  *
  * @param schannel the channel to start
- * @param name the name of the grammar to use or NULL if to reuse the last grammar
  * @return SWITCH_STATUS_SUCCESS if successful
  */
-static switch_status_t recog_channel_start(speech_channel_t *schannel, const char *name)
+static switch_status_t recog_channel_start(speech_channel_t *schannel)
 {
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	switch_hash_index_t *egk;
 	mrcp_message_t *mrcp_message;
 	mrcp_recog_header_t *recog_header;
 	mrcp_generic_header_t *generic_header;
 	recognizer_data_t *r;
 	char *start_input_timers;
 	const char *mime_type;
-	grammar_t *grammar = NULL;
+	char *key;
+	switch_size_t len;
+	grammar_t *grammar;
+	switch_size_t grammar_uri_count = 0;
+	switch_size_t grammar_uri_list_len = 0;
+	char *grammar_uri_list = NULL;
 
 	switch_mutex_lock(schannel->mutex);
 	if (schannel->state != SPEECH_CHANNEL_READY) {
@@ -2089,21 +2100,55 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
 	start_input_timers = (char *) switch_core_hash_find(schannel->params, "start-input-timers");
 	r->timers_started = zstr(start_input_timers) || strcasecmp(start_input_timers, "false");
 
-	/* get the cached grammar */
-	if (zstr(name)) {
-		grammar = r->last_grammar;
-	} else {
-		grammar = (grammar_t *) switch_core_hash_find(r->grammars, name);
-		r->last_grammar = grammar;
-	}
-	if (grammar == NULL) {
-		if (name) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Undefined grammar, %s\n", schannel->name, name);
-		} else {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) No grammar specified\n", schannel->name);
+	/* count enabled grammars */
+	for (egk = switch_hash_first(NULL, r->enabled_grammars); egk; egk = switch_hash_next(egk)) {
+		// NOTE: This postponed type check is necessary to allow a non-URI-list grammar to execute alone
+		if (grammar_uri_count == 1 && grammar->type != GRAMMAR_TYPE_URI)
+			goto no_grammar_alone;
+		++grammar_uri_count;
+		switch_hash_this(egk, (void *) &key, NULL, (void *) &grammar);
+		if (grammar->type != GRAMMAR_TYPE_URI && grammar_uri_count != 1) {
+		      no_grammar_alone:
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Grammar '%s' can only be used alone (not a URI list)\n", schannel->name, key);
+			status = SWITCH_STATUS_FALSE;
+			goto done;
 		}
+		len = strlen(grammar->data);
+		if (!len)
+			continue;
+		grammar_uri_list_len += len;
+		if (grammar->data[len - 1] != '\n')
+			grammar_uri_list_len += 2;
+	}
+
+	switch (grammar_uri_count) {
+	case 0:
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) No grammar specified\n", schannel->name);
 		status = SWITCH_STATUS_FALSE;
 		goto done;
+	case 1:
+		/* grammar should already be the unique grammar */
+		break;
+	default:
+		/* get the enabled grammars list */
+		grammar_uri_list = switch_core_alloc(schannel->memory_pool, grammar_uri_list_len + 1);
+		grammar_uri_list_len = 0;
+		for (egk = switch_hash_first(NULL, r->enabled_grammars); egk; egk = switch_hash_next(egk)) {
+			switch_hash_this(egk, (void *) &key, NULL, (void *) &grammar);
+			len = strlen(grammar->data);
+			if (!len)
+				continue;
+			memcpy(&(grammar_uri_list[grammar_uri_list_len]), grammar->data, len);
+			grammar_uri_list_len += len;
+			if (grammar_uri_list[grammar_uri_list_len - 1] != '\n')
+			{
+				grammar_uri_list_len += 2;
+				grammar_uri_list[grammar_uri_list_len - 2] = '\r';
+				grammar_uri_list[grammar_uri_list_len - 1] = '\n';
+			}
+		}
+		grammar_uri_list[grammar_uri_list_len++] = '\0';
+		grammar = NULL;
 	}
 
 	/* create MRCP message */
@@ -2121,7 +2166,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
 	}
 
 	/* set Content-Type */
-	mime_type = grammar_type_to_mime(grammar->type, schannel->profile);
+	mime_type = grammar_type_to_mime(grammar ? grammar->type : GRAMMAR_TYPE_URI, schannel->profile);
 	if (zstr(mime_type)) {
 		status = SWITCH_STATUS_FALSE;
 		goto done;
@@ -2130,7 +2175,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
 	mrcp_generic_header_property_add(mrcp_message, GENERIC_HEADER_CONTENT_TYPE);
 
 	/* set Content-ID for inline grammars */
-	if (grammar->type != GRAMMAR_TYPE_URI) {
+	if (grammar && grammar->type != GRAMMAR_TYPE_URI) {
 		apt_string_assign(&generic_header->content_id, grammar->name, mrcp_message->pool);
 		mrcp_generic_header_property_add(mrcp_message, GENERIC_HEADER_CONTENT_ID);
 	}
@@ -2152,7 +2197,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
 	recog_channel_set_params(schannel, mrcp_message, generic_header, recog_header);
 
 	/* set message body */
-	apt_string_assign(&mrcp_message->body, grammar->data, mrcp_message->pool);
+	apt_string_assign(&mrcp_message->body, grammar ? grammar->data : grammar_uri_list, mrcp_message->pool);
 
 	/* Empty audio queue and send RECOGNIZE to MRCP server */
 	audio_queue_clear(schannel->audio_queue);
@@ -2287,6 +2332,7 @@ static switch_status_t recog_channel_unload_grammar(speech_channel_t *schannel,
 	} else {
 		recognizer_data_t *r = (recognizer_data_t *) schannel->data;
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Unloading grammar %s\n", schannel->name, grammar_name);
+		switch_core_hash_delete(r->enabled_grammars, grammar_name);
 		switch_core_hash_delete(r->grammars, grammar_name);
 	}
 
@@ -2294,6 +2340,77 @@ static switch_status_t recog_channel_unload_grammar(speech_channel_t *schannel,
 }
 
 /**
+ * Enable speech recognition grammar
+ *
+ * @param schannel the recognizer channel
+ * @param grammar_name the name of the grammar to enable
+ * @return SWITCH_STATUS_SUCCESS if successful
+ */
+static switch_status_t recog_channel_enable_grammar(speech_channel_t *schannel, const char *grammar_name)
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+	if (zstr(grammar_name)) {
+		status = SWITCH_STATUS_FALSE;
+	} else {
+		recognizer_data_t *r = (recognizer_data_t *) schannel->data;
+		grammar_t *grammar;
+		grammar = (grammar_t *) switch_core_hash_find(r->grammars, grammar_name);
+		if (grammar == NULL)
+		{
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Undefined grammar, %s\n", schannel->name, grammar_name);
+			status = SWITCH_STATUS_FALSE;
+		}
+		else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Enabling grammar %s\n", schannel->name, grammar_name);
+			switch_core_hash_insert(r->enabled_grammars, grammar_name, grammar);
+		}
+	}
+
+	return status;
+}
+
+/**
+ * Disable speech recognition grammar
+ *
+ * @param schannel the recognizer channel
+ * @param grammar_name the name of the grammar to disable
+ * @return SWITCH_STATUS_SUCCESS if successful
+ */
+static switch_status_t recog_channel_disable_grammar(speech_channel_t *schannel, const char *grammar_name)
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+	if (zstr(grammar_name)) {
+		status = SWITCH_STATUS_FALSE;
+	} else {
+		recognizer_data_t *r = (recognizer_data_t *) schannel->data;
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Disabling grammar %s\n", schannel->name, grammar_name);
+		switch_core_hash_delete(r->enabled_grammars, grammar_name);
+	}
+
+	return status;
+}
+
+/**
+ * Disable all speech recognition grammars
+ *
+ * @param schannel the recognizer channel
+ * @return SWITCH_STATUS_SUCCESS if successful
+ */
+static switch_status_t recog_channel_disable_all_grammars(speech_channel_t *schannel)
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+	recognizer_data_t *r = (recognizer_data_t *) schannel->data;
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Disabling all grammars\n", schannel->name);
+	switch_core_hash_destroy(&r->enabled_grammars);
+	switch_core_hash_init(&r->enabled_grammars, schannel->memory_pool);
+
+	return status;
+}
+
+/**
  * Check if recognition is complete
  *
  * @return SWITCH_STATUS_SUCCESS if results available or start of input
@@ -2740,6 +2857,7 @@ static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec
 	schannel->data = r;
 	memset(r, 0, sizeof(recognizer_data_t));
 	switch_core_hash_init(&r->grammars, ah->memory_pool);
+	switch_core_hash_init(&r->enabled_grammars, ah->memory_pool);
 
 	/* Open the channel */
 	if (zstr(profile_name)) {
@@ -2892,7 +3010,17 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha
 
 	start_recognize = (char *) switch_core_hash_find(schannel->params, "start-recognize");
 	if (zstr(start_recognize) || strcasecmp(start_recognize, "false"))
-		status = recog_channel_start(schannel, name);
+	{
+		if (recog_channel_disable_all_grammars(schannel) != SWITCH_STATUS_SUCCESS) {
+			status = SWITCH_STATUS_FALSE;
+			goto done;
+		}
+		if (recog_channel_enable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) {
+			status = SWITCH_STATUS_FALSE;
+			goto done;
+		}
+		status = recog_channel_start(schannel);
+	}
 
   done:
 
@@ -2921,6 +3049,57 @@ static switch_status_t recog_asr_unload_grammar(switch_asr_handle_t *ah, const c
 }
 
 /**
+ * Process asr_enable_grammar request from FreeSWITCH.
+ *
+ * FreeSWITCH sends this request to enable recognition on this grammar.
+ * @param ah the FreeSWITCH speech recognition handle
+ * @param name the grammar name.
+ */
+static switch_status_t recog_asr_enable_grammar(switch_asr_handle_t *ah, const char *name)
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
+	if (zstr(name) || speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_enable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) {
+		status = SWITCH_STATUS_FALSE;
+	}
+	return status;
+}
+
+/**
+ * Process asr_disable_grammar request from FreeSWITCH.
+ *
+ * FreeSWITCH sends this request to disable recognition on this grammar.
+ * @param ah the FreeSWITCH speech recognition handle
+ * @param name the grammar name.
+ */
+static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const char *name)
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
+	if (zstr(name) || speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_disable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) {
+		status = SWITCH_STATUS_FALSE;
+	}
+	return status;
+}
+
+/**
+ * Process asr_disable_all_grammars request from FreeSWITCH.
+ *
+ * FreeSWITCH sends this request to disable recognition of all grammars.
+ * @param ah the FreeSWITCH speech recognition handle
+ * @param name the grammar name.
+ */
+static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah)
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
+	if (speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_disable_all_grammars(schannel) != SWITCH_STATUS_SUCCESS) {
+		status = SWITCH_STATUS_FALSE;
+	}
+	return status;
+}
+
+/**
  * Process asr_close request from FreeSWITCH
  *
  * @param ah the FreeSWITCH speech recognition handle
@@ -2934,6 +3113,7 @@ static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_
 	speech_channel_stop(schannel);
 	speech_channel_destroy(schannel);
 	switch_core_hash_destroy(&r->grammars);
+	switch_core_hash_destroy(&r->enabled_grammars);
 
 	/* this lets FreeSWITCH's speech_thread know the handle is closed */
 	switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
@@ -2958,14 +3138,13 @@ static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsig
 /**
  * Process asr_start request from FreeSWITCH
  * @param ah the FreeSWITCH speech recognition handle
- * @param name name of the grammar to use
  * @return SWITCH_STATUS_SUCCESS if successful
  */
-static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name)
+static switch_status_t recog_asr_start(switch_asr_handle_t *ah)
 {
 	switch_status_t status;
 	speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
-	status = recog_channel_start(schannel, name);
+	status = recog_channel_start(schannel);
 	return status;
 }
 #endif
@@ -2978,7 +3157,7 @@ static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name
 static switch_status_t recog_asr_resume(switch_asr_handle_t *ah)
 {
 	speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
-	return recog_channel_start(schannel, NULL);
+	return recog_channel_start(schannel);
 }
 
 /**
@@ -3237,6 +3416,9 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int
 	asr_interface->asr_open = recog_asr_open;
 	asr_interface->asr_load_grammar = recog_asr_load_grammar;
 	asr_interface->asr_unload_grammar = recog_asr_unload_grammar;
+	asr_interface->asr_enable_grammar = recog_asr_enable_grammar;
+	asr_interface->asr_disable_grammar = recog_asr_disable_grammar;
+	asr_interface->asr_disable_all_grammars = recog_asr_disable_all_grammars;
 	asr_interface->asr_close = recog_asr_close;
 	asr_interface->asr_feed = recog_asr_feed;
 #if 0
committer: Luke Dashjr
comments: 
switch_core_asr interfaces for enable_grammar, disable_grammar, and disable_all_grammars

diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 650ffc1..26a048c 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -24,6 +24,7 @@
  * Contributor(s):
  * 
  * Anthony Minessale II <anthm@freeswitch.org>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  *
  * switch_core.h -- Core Library
@@ -1748,6 +1749,29 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_load_grammar(switch_asr_handle_t
 SWITCH_DECLARE(switch_status_t) switch_core_asr_unload_grammar(switch_asr_handle_t *ah, const char *name);
 
 /*!
+  \brief Enable a grammar from an asr handle
+  \param ah the handle to enable the grammar from
+  \param name the name of the grammar to enable
+  \return SWITCH_STATUS_SUCCESS
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_asr_enable_grammar(switch_asr_handle_t *ah, const char *name);
+
+/*!
+  \brief Disable a grammar from an asr handle
+  \param ah the handle to disable the grammar from
+  \param name the name of the grammar to disable
+  \return SWITCH_STATUS_SUCCESS
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_grammar(switch_asr_handle_t *ah, const char *name);
+
+/*!
+  \brief Disable all grammars from an asr handle
+  \param ah the handle to disable the grammars from
+  \return SWITCH_STATUS_SUCCESS
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_all_grammars(switch_asr_handle_t *ah);
+
+/*!
   \brief Pause detection on an asr handle
   \param ah the handle to pause
   \return SWITCH_STATUS_SUCCESS
diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h
index 078b83d..e0119b4 100644
--- a/src/include/switch_module_interfaces.h
+++ b/src/include/switch_module_interfaces.h
@@ -24,6 +24,7 @@
  * Contributor(s):
  * 
  * Anthony Minessale II <anthm@freeswitch.org>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  *
  * switch_module_interfaces.h -- Module Interface Definitions
@@ -393,6 +394,12 @@ struct switch_asr_interface {
 	switch_mutex_t *reflock;
 	switch_loadable_module_interface_t *parent;
 	struct switch_asr_interface *next;
+	/*! function to enable a grammar to the asr interface */
+	switch_status_t (*asr_enable_grammar) (switch_asr_handle_t *ah, const char *name);
+	/*! function to disable a grammar to the asr interface */
+	switch_status_t (*asr_disable_grammar) (switch_asr_handle_t *ah, const char *name);
+	/*! function to disable all grammars to the asr interface */
+	switch_status_t (*asr_disable_all_grammars) (switch_asr_handle_t *ah);
 };
 
 /*! an abstract representation of an asr speech interface. */
diff --git a/src/switch_core_asr.c b/src/switch_core_asr.c
index fa4446e..691011a 100644
--- a/src/switch_core_asr.c
+++ b/src/switch_core_asr.c
@@ -27,6 +27,7 @@
  * Michael Jerris <mike@jerris.com>
  * Paul D. Tinsley <pdt at jackhammer.org>
  * Christopher M. Rienzo <chris@rienzo.net>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  *
  * switch_core_asr.c -- Main Core Library (Speech Detection Interface)
@@ -160,6 +161,45 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_unload_grammar(switch_asr_handle
 	return status;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_core_asr_enable_grammar(switch_asr_handle_t *ah, const char *name)
+{
+	switch_status_t status = SWITCH_STATUS_FALSE;
+
+	switch_assert(ah != NULL);
+
+	if (ah->asr_interface->asr_enable_grammar) {
+		status = ah->asr_interface->asr_enable_grammar(ah, name);
+	}
+
+	return status;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_grammar(switch_asr_handle_t *ah, const char *name)
+{
+	switch_status_t status = SWITCH_STATUS_FALSE;
+
+	switch_assert(ah != NULL);
+
+	if (ah->asr_interface->asr_disable_grammar) {
+		status = ah->asr_interface->asr_disable_grammar(ah, name);
+	}
+
+	return status;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_all_grammars(switch_asr_handle_t *ah)
+{
+	switch_status_t status = SWITCH_STATUS_FALSE;
+
+	switch_assert(ah != NULL);
+
+	if (ah->asr_interface->asr_disable_all_grammars) {
+		status = ah->asr_interface->asr_disable_all_grammars(ah);
+	}
+
+	return status;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_core_asr_pause(switch_asr_handle_t *ah)
 {
 	switch_assert(ah != NULL);
committer: Luke Dashjr
comments: 
Allow loading grammars without sending RECOGNIZE with start-recognize=false parameter

diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
index 41c0ccd..a27ddf0 100644
--- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
+++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
@@ -26,6 +26,7 @@
  *
  * Brian West <brian@freeswitch.org>
  * Christopher M. Rienzo <chris@rienzo.net>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * mod_unimrcp.c -- UniMRCP module (MRCP client)
  *
@@ -2451,6 +2452,8 @@ static switch_status_t recog_channel_set_params(speech_channel_t *schannel, mrcp
 			if (id) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) \"%s\": \"%s\"\n", schannel->name, param_name, param_val);
 				recog_channel_set_header(schannel, id->id, param_val, msg, recog_hdr);
+			} else if (!strcasecmp(param_name, "start-recognize")) {
+				// This parameter is used internally only, not in MRCP headers
 			} else {
 				/* this is probably a vendor-specific MRCP param */
 				apt_str_t apt_param_name = { 0 };
@@ -2782,6 +2785,7 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha
 	speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
 	const char *grammar_data = NULL;
 	char *grammar_file_data = NULL;
+	char *start_recognize;
 	switch_file_t *grammar_file = NULL;
 	switch_size_t grammar_file_size = 0, to_read = 0;
 	grammar_type_t type = GRAMMAR_TYPE_UNKNOWN;
@@ -2886,7 +2890,9 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha
 		goto done;
 	}
 
-	status = recog_channel_start(schannel, name);
+	start_recognize = (char *) switch_core_hash_find(schannel->params, "start-recognize");
+	if (zstr(start_recognize) || strcasecmp(start_recognize, "false"))
+		status = recog_channel_start(schannel, name);
 
   done:
 
committer: Luke Dashjr
comments: 
document all of detect_speech's valid syntax

diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 5a1b8c5..6d014fa 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -28,6 +28,7 @@
  * Michael Murdock <mike at mmurdock dot org>
  * Neal Horman <neal at wanlink dot com>
  * Bret McDanel <trixter AT 0xdecafbad dot com>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * mod_dptools.c -- Raw Audio File Streaming Application Module
  *
@@ -95,7 +96,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
 	return extension;
 }
 
-#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume"
+#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR pause OR resume OR stop OR param <name> <value>"
 SWITCH_STANDARD_APP(detect_speech_function)
 {
 	char *argv[4];
committer: Luke Dashjr
comments: 
expose ASR start_input_timers to dialplan via mod_dptools

diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 5a1b8c5..2f49630 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -28,6 +28,7 @@
  * Michael Murdock <mike at mmurdock dot org>
  * Neal Horman <neal at wanlink dot com>
  * Bret McDanel <trixter AT 0xdecafbad dot com>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * mod_dptools.c -- Raw Audio File Streaming Application Module
  *
@@ -95,7 +96,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
 	return extension;
 }
 
-#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume"
+#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume OR start_input_timers"
 SWITCH_STANDARD_APP(detect_speech_function)
 {
 	char *argv[4];
@@ -116,6 +117,8 @@ SWITCH_STANDARD_APP(detect_speech_function)
 			switch_ivr_stop_detect_speech(session);
 		} else if (!strcasecmp(argv[0], "param")) {
 			switch_ivr_set_param_detect_speech(session, argv[1], argv[2]);
+		} else if (!strcasecmp(argv[0], "start_input_timers")) {
+			switch_ivr_detect_speech_start_input_timers(session);
 		} else if (argc >= 3) {
 			switch_ivr_detect_speech(session, argv[0], argv[1], argv[2], argv[3], NULL);
 		}
committer: Luke Dashjr
comments: 
expose ASR start_input_timers on the IVR abstraction level

diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h
index 40ba1dc..692ad8d 100644
--- a/src/include/switch_ivr.h
+++ b/src/include/switch_ivr.h
@@ -26,6 +26,7 @@
  * Anthony Minessale II <anthm@freeswitch.org>
  * Neal Horman <neal at wanlink dot com>
  * Bret McDanel <trixter AT 0xdecafbad dot com>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * switch_ivr.h -- IVR Library
  *
@@ -201,6 +202,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_c
 SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_session_t *session, const char *name, const char *val);
 
 /*!
+  \brief Start input timers on a background speech detection handle
+  \param session The session to start the timers on
+  \return SWITCH_STATUS_SUCCESS if all is well
+*/
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(switch_core_session_t *session);
+
+/*!
   \brief Record a session to disk
   \param session the session to record
   \param file the path to the file
diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c
index 4fe5732..ae23d0a 100644
--- a/src/switch_ivr_async.c
+++ b/src/switch_ivr_async.c
@@ -26,6 +26,7 @@
  * Anthony Minessale II <anthm@freeswitch.org>
  * Michael Jerris <mike@jerris.com>
  * Bret McDanel <bret AT 0xdecafbad dot com>
+ * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
  *
  * switch_ivr_async.c -- IVR Library (async operations)
  *
@@ -2728,6 +2729,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_s
 	return status;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(switch_core_session_t *session)
+{
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+	struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
+
+	if (sth) {
+		switch_core_asr_start_input_timers(sth->ah);
+		return SWITCH_STATUS_SUCCESS;
+	}
+	return SWITCH_STATUS_FALSE;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_core_session_t *session, const char *name)
 {
 	switch_channel_t *channel = switch_core_session_get_channel(session);
========================================================================

Summary of changes:
 .gitignore                                         |    7 +-
 conf/freeswitch.xml                                |    3 -
 libs/freetdm/msvc/freetdm.2010.vcxproj             |    2 +
 libs/freetdm/msvc/freetdm.2010.vcxproj.filters     |    6 +
 libs/freetdm/msvc/testboost/testboost.2010.vcxproj |    6 +-
 .../msvc/testboost/testsangomaboost.2010.vcxproj   |    6 +-
 .../ftmod_sangoma_boost.2010.vcxproj               |   12 +-
 .../ftmod_sangoma_isdn_stack_hndl.c                |    8 +-
 .../ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj |    8 +-
 src/include/switch_core.h                          |   33 ++
 src/include/switch_ivr.h                           |   31 ++
 src/include/switch_module_interfaces.h             |    9 +
 .../applications/mod_callcenter/mod_callcenter.c   |    9 +-
 src/mod/applications/mod_dptools/mod_dptools.c     |   11 +-
 src/mod/applications/mod_spandsp/mod_spandsp_fax.c |   89 +++---
 src/mod/applications/mod_spy/mod_spy.c             |    6 +-
 src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c          |  313 +++++++++++++++++--
 src/mod/endpoints/mod_gsmopen/.gitignore           |    2 +
 src/mod/endpoints/mod_loopback/mod_loopback.c      |   33 ++-
 src/mod/endpoints/mod_skinny/skinny_protocol.h     |    8 +
 src/mod/endpoints/mod_skinny/skinny_server.c       |   25 ++
 src/mod/endpoints/mod_skinny/skinny_tables.c       |    1 +
 src/mod/endpoints/mod_skinny/skinny_tables.h       |    2 +-
 src/mod/endpoints/mod_sofia/mod_sofia.c            |   19 +-
 src/mod/event_handlers/mod_snmp/FREESWITCH-MIB     |  217 +++++++++++++-
 src/mod/event_handlers/mod_snmp/mod_snmp.c         |   26 ++-
 src/mod/event_handlers/mod_snmp/subagent.c         |  260 +++++++++++++++-
 src/mod/event_handlers/mod_snmp/subagent.h         |   57 ++++-
 .../languages/mod_managed/freeswitch_wrap.2010.cxx |  196 ++++++++++++
 src/mod/languages/mod_managed/freeswitch_wrap.cxx  |  327 ++++++++++++++++++++
 src/mod/languages/mod_managed/managed/swig.2010.cs |  168 ++++++++++-
 src/mod/languages/mod_managed/managed/swig.cs      |  296 ++++++++++++++++++-
 src/mod/xml_int/mod_xml_curl/mod_xml_curl.c        |    4 +-
 src/switch_channel.c                               |   47 ++--
 src/switch_core_asr.c                              |   53 ++++
 src/switch_core_sqldb.c                            |   11 +-
 src/switch_ivr_async.c                             |   83 +++++
 src/switch_xml.c                                   |    8 +-
 38 files changed, 2225 insertions(+), 177 deletions(-)

this email was generated because of /git/your-repo.git/hooks/post-receive by the file /git-core/contrib/hooks/post-receive-email
For more info, see http://blog.chomperstomp.com/?p=630 --
FreeSWITCH Source