Example #1
0
SWITCH_DECLARE(switch_status_t) switch_core_codec_init_with_bitrate(switch_codec_t *codec, const char *codec_name, const char *fmtp,
													   uint32_t rate, int ms, int channels, uint32_t bitrate, uint32_t flags,
													   const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool)
{
	switch_codec_interface_t *codec_interface;
	const switch_codec_implementation_t *iptr, *implementation = NULL;

	switch_assert(codec != NULL);
	switch_assert(codec_name != NULL);

	memset(codec, 0, sizeof(*codec));

	if (channels == 2) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Stereo is currently unsupported. please downsample audio source to mono.\n");
		return SWITCH_STATUS_GENERR;
	}

	if ((codec_interface = switch_loadable_module_get_codec_interface(codec_name)) == 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec %s!\n", codec_name);
		return SWITCH_STATUS_GENERR;
	}

	/* If no specific codec interval is requested opt for 20ms above all else because lots of stuff assumes it */
	if (!ms) {
		for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) {
			if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) &&
				(20 == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) {
				implementation = iptr;
				goto found;
			}
		}
	}

	/* Either looking for a specific interval or there was no interval specified and there wasn't one @20ms available */
	for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) {
		if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) &&
			(!ms || ms == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) {
			implementation = iptr;
			break;
		}
	}

  found:

	if (implementation) {
		switch_status_t status;
		codec->codec_interface = codec_interface;
		codec->implementation = implementation;
		codec->flags = flags;

		if (pool) {
			codec->memory_pool = pool;
		} else {
			if ((status = switch_core_new_memory_pool(&codec->memory_pool)) != SWITCH_STATUS_SUCCESS) {
				return status;
			}
			switch_set_flag(codec, SWITCH_CODEC_FLAG_FREE_POOL);
		}

		if (fmtp) {
			codec->fmtp_in = switch_core_strdup(codec->memory_pool, fmtp);
		}

		implementation->init(codec, flags, codec_settings);
		switch_mutex_init(&codec->mutex, SWITCH_MUTEX_NESTED, codec->memory_pool);
		switch_set_flag(codec, SWITCH_CODEC_FLAG_READY);
		return SWITCH_STATUS_SUCCESS;
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Codec %s Exists but not at the desired implementation. %dhz %dms\n", codec_name, rate,
						  ms);
	}

	UNPROTECT_INTERFACE(codec_interface);

	return SWITCH_STATUS_NOTIMPL;
}
Example #2
0
static void switch_core_standard_on_routing(switch_core_session_t *session)
{
	switch_dialplan_interface_t *dialplan_interface = NULL;
	switch_caller_profile_t *caller_profile;
	switch_caller_extension_t *extension = NULL;
	char *expanded = NULL;
	char *dpstr = NULL;

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard ROUTING\n", switch_channel_get_name(session->channel));

	if ((switch_channel_test_flag(session->channel, CF_ANSWERED) ||
		 switch_channel_test_flag(session->channel, CF_EARLY_MEDIA) ||
		 switch_channel_test_flag(session->channel, CF_SIGNAL_BRIDGE_TTL)) && switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
		switch_ivr_media(session->uuid_str, SMF_NONE);
	}

	if ((caller_profile = switch_channel_get_caller_profile(session->channel)) == 0) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't get profile!\n");
		switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
		return;
	} else {
		char *dp[25];
		int argc, x, count = 0;

		if (!zstr(caller_profile->dialplan)) {
			if ((dpstr = switch_core_session_strdup(session, caller_profile->dialplan))) {
				expanded = switch_channel_expand_variables(session->channel, dpstr);
				argc = switch_separate_string(expanded, ',', dp, (sizeof(dp) / sizeof(dp[0])));
				for (x = 0; x < argc; x++) {
					char *dpname = dp[x];
					char *dparg = NULL;

					if (dpname) {
						if ((dparg = strchr(dpname, ':'))) {
							*dparg++ = '\0';
						}
					} else {
						continue;
					}
					if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
						continue;
					}

					count++;

					extension = dialplan_interface->hunt_function(session, dparg, NULL);
					UNPROTECT_INTERFACE(dialplan_interface);

					if (extension) {
						switch_channel_set_caller_extension(session->channel, extension);
						switch_channel_set_state(session->channel, CS_EXECUTE);
						goto end;
					}
				}
			}
		}

		if (!count) {
			if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
				if (switch_channel_test_flag(session->channel, CF_ANSWERED)) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
									  "No Dialplan on answered channel, changing state to HANGUP\n");
					switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
				} else {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No Dialplan, changing state to CONSUME_MEDIA\n");
					switch_channel_set_state(session->channel, CS_CONSUME_MEDIA);
				}
				goto end;
			}
		}
	}

	if (!extension) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No Route, Aborting\n");
		switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
	}

  end:

	if (expanded && dpstr && expanded != dpstr) {
		free(expanded);
	}
}
Example #3
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 #4
0
static void release_backend(switch_limit_interface_t *limit) {
	if (limit) {
		UNPROTECT_INTERFACE(limit);
	}
}