Example #1
0
SWITCH_DECLARE(int) CoreSession::streamFile(char *file, int starting_sample_count) {

    switch_status_t status;
    //switch_file_handle_t fh = { 0 };
	const char *prebuf;
	switch_file_handle_t local_fh;

	this_check(-1);
    sanity_check(-1);
	
	memset(&local_fh, 0, sizeof(local_fh));
	fhp = &local_fh;
    local_fh.samples = starting_sample_count;


	if ((prebuf = switch_channel_get_variable(this->channel, "stream_prebuffer"))) {
        int maybe = atoi(prebuf);
        if (maybe > 0) {
            local_fh.prebuf = maybe;
        }
	}

    begin_allow_threads();
    status = switch_ivr_play_file(session, fhp, file, ap);
    end_allow_threads();

	fhp = NULL;
	
    return status == SWITCH_STATUS_SUCCESS ? 1 : 0;

}
Example #2
0
int fs_ivr_play_file2(switch_core_session_t *session, char *file)
{
	switch_status_t status;

	status = switch_ivr_play_file(session, NULL, file, NULL);
	return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}
Example #3
0
int fs_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, char *file, switch_input_args_t *args)
{
	switch_status_t status;

	status = switch_ivr_play_file(session, fh, file, args);
	return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}
Example #4
0
static switch_status_t spy_on_park(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const char *moh = switch_channel_get_variable(channel, "hold_music");

	while (switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_PARK) {
		if (moh) {
			switch_status_t status = switch_ivr_play_file(session, NULL, moh, NULL);
			if (!SWITCH_READ_ACCEPTABLE(status)) {
				break;
			}
		}
	}
	return SWITCH_STATUS_FALSE;
}
Example #5
0
static switch_status_t spy_on_park(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const char *moh = switch_channel_get_hold_music(channel);

	while (switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_PARK) {
		switch_status_t status = SWITCH_STATUS_SUCCESS;
		if (moh) {
			status = switch_ivr_play_file(session, NULL, moh, NULL);
		} else {
			status = switch_ivr_sleep(session, 10000, SWITCH_FALSE, NULL);
		}
		if (!SWITCH_READ_ACCEPTABLE(status)) {
			break;
		}
	}
	return SWITCH_STATUS_FALSE;
}
Example #6
0
/* PL */
static switch_status_t pl_say(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
{

	switch_new_say_callback_t say_cb = NULL;
	char *string = NULL;

	switch_status_t status = SWITCH_STATUS_FALSE;

	say_cb = choose_callback(say_args);

	if (say_cb) {
		status = run_callback(say_cb, tosay, say_args, session, &string);
		if (session && string) {
			status = switch_ivr_play_file(session, NULL, string, args);
		}
		
		switch_safe_free(string);
	}

	return status;
}
Example #7
0
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *session, switch_ivr_menu_t *stack, char *name, void *obj)
{
	int reps = 0, errs = 0, timeouts = 0, match = 0, running = 1;
	char *greeting_sound = NULL, *aptr = NULL;
	char arg[512];
	switch_ivr_action_t todo = SWITCH_IVR_ACTION_DIE;
	switch_ivr_menu_action_t *ap;
	switch_ivr_menu_t *menu;
	switch_channel_t *channel;
	switch_status_t status = SWITCH_STATUS_SUCCESS;

	if (++stack->stack_count > 12) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Too many levels of recursion.\n");
		switch_goto_status(SWITCH_STATUS_FALSE, end);
	}

	if (!session || !stack || zstr(name)) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid menu context\n");
		switch_goto_status(SWITCH_STATUS_FALSE, end);
	}

	channel = switch_core_session_get_channel(session);

	if (!(menu = switch_ivr_menu_find(stack, name))) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Menu!\n");
		switch_goto_status(SWITCH_STATUS_FALSE, end);
	}

	if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
		switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
		switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
	}

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name);
	switch_channel_set_variable(channel, "ivr_menu_status", "success");

	for (reps = 0; running && status == SWITCH_STATUS_SUCCESS; reps++) {
		if (!switch_channel_ready(channel)) {
			break;
		}
		if (errs == menu->max_failures) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum failures\n");
			switch_channel_set_variable(channel, "ivr_menu_status", "failure");
			break;
		}
		if (timeouts == menu->max_timeouts) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum timeouts\n");
			switch_channel_set_variable(channel, "ivr_menu_status", "timeout");
			break;
		}

		if (reps > 0 && menu->short_greeting_sound) {
			greeting_sound = menu->short_greeting_sound;
		} else {
			greeting_sound = menu->greeting_sound;
		}

		match = 0;
		aptr = NULL;

		memset(arg, 0, sizeof(arg));

		memset(menu->buf, 0, menu->inlen + 1);

		if (play_and_collect(session, menu, greeting_sound, menu->inlen) == SWITCH_STATUS_TIMEOUT && *menu->buf == '\0') {
			timeouts++;
			continue;
		}

		if (*menu->buf != '\0') {

			for (ap = menu->actions; ap; ap = ap->next) {
				int ok = 0;
				char substituted[1024];
				char *use_arg = ap->arg;

				if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
					switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
					switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
				}

				if (ap->re) {
					switch_regex_t *re = NULL;
					int ovector[30];

					if ((ok = switch_regex_perform(menu->buf, ap->bind, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
						switch_perform_substitution(re, ok, ap->arg, menu->buf, substituted, sizeof(substituted), ovector);
						use_arg = substituted;
					}
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "action regex [%s] [%s] [%d]\n", menu->buf, ap->bind, ok);

					switch_regex_safe_free(re);
				} else {
					ok = !strcmp(menu->buf, ap->bind);
				}

				if (ok) {
					match++;
					errs = 0;
					if (ap->function) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
										  "IVR function on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, use_arg);
						todo = ap->function(menu, use_arg, arg, sizeof(arg), obj);
						aptr = arg;
					} else {
						todo = ap->ivr_action;
						aptr = use_arg;
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
										  "IVR action on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, aptr);
					}

					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "switch_ivr_menu_execute todo=[%d]\n", todo);

					switch (todo) {
					case SWITCH_IVR_ACTION_DIE:
						status = SWITCH_STATUS_FALSE;
						break;
					case SWITCH_IVR_ACTION_PLAYSOUND:
						status = switch_ivr_play_file(session, NULL, aptr, NULL);
						break;
					case SWITCH_IVR_ACTION_EXECMENU:
						if (!strcmp(aptr, menu->name)) {
							status = SWITCH_STATUS_SUCCESS;
						} else {
							reps = -1;
							status = switch_ivr_menu_execute(session, stack, aptr, obj);
						}
						break;
					case SWITCH_IVR_ACTION_EXECAPP:
						{
							switch_application_interface_t *application_interface;
							char *app_name;
							char *app_arg = NULL;

							status = SWITCH_STATUS_FALSE;

							if (!zstr(aptr)) {
								app_name = switch_core_session_strdup(session, aptr);
								if ((app_arg = strchr(app_name, ' '))) {
									*app_arg++ = '\0';
								}

								if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
									switch_core_session_exec(session, application_interface, app_arg);
									UNPROTECT_INTERFACE(application_interface);
									status = SWITCH_STATUS_SUCCESS;
								}
							}
						}
						break;
					case SWITCH_IVR_ACTION_BACK:
						running = 0;
						status = SWITCH_STATUS_SUCCESS;
						break;
					case SWITCH_IVR_ACTION_TOMAIN:
						switch_set_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);
						status = SWITCH_STATUS_BREAK;
						break;
					case SWITCH_IVR_ACTION_NOOP:
						status = SWITCH_STATUS_SUCCESS;
						break;
					default:
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid TODO!\n");
						break;
					}
				}
			}

			if (switch_test_flag(menu, SWITCH_IVR_MENU_FLAG_STACK)) {	/* top level */
				if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN)) {	/* catch the fallback and recover */
					switch_clear_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);
					status = SWITCH_STATUS_SUCCESS;
					running = 1;
					continue;
				}
			}
		}
		if (!match) {
			if (*menu->buf) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' caught invalid input '%s'\n", menu->name,
								  menu->buf);
				if (menu->invalid_sound) {
					play_and_collect(session, menu, menu->invalid_sound, 0);
				}
			} else {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name);
			}
			errs++;

			/* breaks are ok too */
			if (SWITCH_STATUS_IS_BREAK(status)) {
				status = SWITCH_STATUS_SUCCESS;
			}
		}
	}

	if (stack->stack_count == 1) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "exit-sound '%s'\n", menu->exit_sound);
		if (!zstr(menu->exit_sound)) {
			status = play_and_collect(session, menu, menu->exit_sound, 0);
		}
	}

  end:

	stack->stack_count--;

	return status;
}
Example #8
0
static switch_status_t play_and_collect(switch_core_session_t *session, switch_ivr_menu_t *menu, char *sound, switch_size_t need)
{
	char terminator;
	uint32_t len;
	char *ptr;
	switch_status_t status = SWITCH_STATUS_FALSE;
	switch_input_args_t args = { 0 };
	switch_channel_t *channel;
	char *sound_expanded = sound;
	switch_size_t menu_buf_len = 0;
	const char *terminator_str = "#";

	if (!session || !menu || zstr(sound)) {
		return status;
	}

	if ((channel = switch_core_session_get_channel(session))) {
		const char *tmp;
		sound_expanded = switch_channel_expand_variables(channel, sound);
		if ((tmp = switch_channel_get_variable(channel, "ivr_menu_terminator")) && !zstr(tmp)) {
			terminator_str = tmp;
		}
	}

	memset(menu->buf, 0, menu->inlen + 1);
	menu->ptr = menu->buf;

	if (!need) {
		len = 1;
		ptr = NULL;
	} else {
		len = (uint32_t) menu->inlen + 1;
		ptr = menu->ptr;
	}
	args.buf = ptr;
	args.buflen = len;

	status = switch_ivr_play_file(session, NULL, sound_expanded, &args);

	if (sound_expanded != sound) {
		switch_safe_free(sound_expanded);
	}

	if (!need) {
		return status;
	}

	menu_buf_len = strlen(menu->buf);

	menu->ptr += menu_buf_len;
	if (menu_buf_len < need) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "waiting for %u/%u digits t/o %d\n",
						  (uint32_t) (menu->inlen - strlen(menu->buf)), (uint32_t) need, menu->inter_timeout);
		status = switch_ivr_collect_digits_count(session, menu->ptr, menu->inlen - strlen(menu->buf),
												 need, terminator_str, &terminator, menu_buf_len ? menu->inter_timeout : menu->timeout,
												 menu->inter_timeout, menu->timeout);
	}

	if (menu->confirm_macro && status == SWITCH_STATUS_SUCCESS && *menu->buf != '\0') {
		switch_input_args_t confirm_args = { 0 }, *ap = NULL;
		char buf[10] = "";
		char terminator_key;
		int att = menu->confirm_attempts;

		while (att) {
			confirm_args.buf = buf;
			confirm_args.buflen = sizeof(buf);
			memset(buf, 0, confirm_args.buflen);

			if (menu->confirm_key) {
				ap = &confirm_args;
			}

			switch_ivr_phrase_macro(session, menu->confirm_macro, menu->buf, NULL, ap);

			if (menu->confirm_key && *buf == '\0') {
				switch_ivr_collect_digits_count(session, buf, sizeof(buf), 1, terminator_str, &terminator_key, menu->timeout, 0, 0);
			}

			if (menu->confirm_key && *buf != '\0') {
				if (*menu->confirm_key == *buf) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
									  "approving digits '%s' via confirm key %s\n", menu->buf, menu->confirm_key);
					break;
				} else {
					att = 0;
					break;
				}
			}
			att--;
		}
		if (!att) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "rejecting digits '%s' via confirm key %s\n", menu->buf,
							  menu->confirm_key);
			*menu->buf = '\0';
		}
	}

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "digits '%s'\n", menu->buf);

	return status;
}