Revision
15220
Author
anthm
Date
2009-10-23 17:37:49 -0500 (Fri, 23 Oct 2009)

Log Message

add campon_stop_key and campon_announce_sound to tell the user how to force it to the end of the waiting period

Modified Paths

Diff

Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (15219 => 15220)


--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	2009-10-23 22:30:19 UTC (rev 15219)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	2009-10-23 22:37:49 UTC (rev 15220)
@@ -2054,9 +2054,29 @@
 /*								Bridge Functions								*/
 /********************************************************************************/
 
+static switch_status_t camp_fire(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
+{
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF:
+		{
+			switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
+			char *key = (char *) buf;
+
+			if (dtmf->digit == *key) {
+				return SWITCH_STATUS_BREAK;
+			}
+		}
+	default:
+		break;
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 struct camping_stake {
 	switch_core_session_t *session;
 	int running;
+	int do_xfer;
 	const char *moh;
 };
 
@@ -2065,18 +2085,44 @@
 	struct camping_stake *stake = (struct camping_stake *) obj;
 	switch_core_session_t *session = stake->session;
 	switch_channel_t *channel = switch_core_session_get_channel(stake->session);
-	const char *moh = stake->moh;
+	const char *moh = stake->moh, *greet = NULL;
+	switch_input_args_t args = { 0 };
+	char dbuf[2] = "";
+	switch_status_t status = SWITCH_STATUS_FALSE;
+	const char *stop;
 
+	if ((stop = switch_channel_get_variable(channel, "campon_stop_key"))) {
+		*dbuf = *stop;
+	}
+
+	args.input_callback = camp_fire;
+	args.buf = dbuf;
+	args.buflen = sizeof(dbuf);
+	
 	switch_core_session_read_lock(session);
+
+	/* don't set this to a local_stream:// or you will not be happy */
+	if ((greet = switch_channel_get_variable(channel, "campon_announce_sound"))) {
+		status = switch_ivr_play_file(session, NULL, greet, &args);
+	}
+	
 	while(stake->running && switch_channel_ready(channel)) {
-		if (!strcasecmp(moh, "silence")) {
-			switch_ivr_collect_digits_callback(session, NULL, 0, 0);
-		} else {
-			switch_ivr_play_file(session, NULL, stake->moh, NULL);
+		if (status != SWITCH_STATUS_BREAK) {
+			if (!strcasecmp(moh, "silence")) {
+				status = switch_ivr_collect_digits_callback(session, &args, 0, 0);
+			} else {
+				status = switch_ivr_play_file(session, NULL, stake->moh, &args);
+			}
 		}
+
+		if (status == SWITCH_STATUS_BREAK) {
+			switch_channel_set_flag(channel, CF_NOT_READY);
+			stake->do_xfer = 1;
+		}
 	}
 	switch_core_session_rwunlock(session);
 
+	stake->running = 0;
 	return NULL;
 }
 
@@ -2087,7 +2133,7 @@
 	const char *continue_on_fail = NULL, *failure_causes = NULL, 
 		*v_campon = NULL, *v_campon_retries, *v_campon_sleep, *v_campon_timeout, *v_campon_fallback_exten = NULL;
 	switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
-	int campon_retries = 100, campon_timeout = 10, campon_sleep = 10, tmp, do_xfer = 0, camping = 0, fail = 0, thread_started = 0;
+	int campon_retries = 100, campon_timeout = 10, campon_sleep = 10, tmp, camping = 0, fail = 0, thread_started = 0;
 	struct camping_stake stake = { 0 };
 	const char *moh = NULL;
 	switch_thread_t *thread = NULL;
@@ -2190,31 +2236,32 @@
 				}
 
 
-				if (--campon_retries <= 0) {
+				if (--campon_retries <= 0 || stake.do_xfer) {
 					camping = 0;
-					do_xfer = 1;
+					stake.do_xfer = 1;
 					break;
 				}
 
 				if (fail) {
 					int64_t wait = campon_sleep * 1000000;
 					
-					while(wait > 0 && switch_channel_ready(caller_channel)) {
+					while(stake.running && wait > 0 && switch_channel_ready(caller_channel)) {
 						switch_yield(100000);
 						wait -= 100000;
 					}
 				}
 			}
-		} while (camping);
+		} while (camping && switch_channel_ready(caller_channel));
 		
 		if (thread) {
 			stake.running = 0;
 			switch_channel_set_flag(caller_channel, CF_NOT_READY);
 			switch_thread_join(&status, thread);
-			switch_channel_clear_flag(caller_channel, CF_NOT_READY);
 		}
+
+		switch_channel_clear_flag(caller_channel, CF_NOT_READY);
 		
-		if (do_xfer && !zstr(v_campon_fallback_exten)) {
+		if (stake.do_xfer && !zstr(v_campon_fallback_exten)) {
 			switch_ivr_session_transfer(session, 
 										v_campon_fallback_exten, 
 										switch_channel_get_variable(caller_channel, "campon_fallback_dialplan"),