Beispiel #1
0
/**
 * Process <break>- this is a period of silence
 */
static int process_break(struct ssml_parser *parsed_data, char **atts)
{
	if (atts) {
		int i = 0;
		while (atts[i]) {
			if (!strcmp("time", atts[i])) {
				char *t = atts[i + 1];
				if (!zstr(t) && parsed_data->num_files < parsed_data->max_files) {
					int timeout_ms = 0;
					char *unit;
					if ((unit = strstr(t, "ms"))) {
						*unit = '\0';
						if (switch_is_number(t)) {
							timeout_ms = atoi(t);
						}
					} else if ((unit = strstr(t, "s"))) {
						*unit = '\0';
						if (switch_is_number(t)) {
							timeout_ms = atoi(t) * 1000;
						}
					}
					if (timeout_ms > 0) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding <break>: \"%s\"\n", t);
						parsed_data->files[parsed_data->num_files].name = switch_core_sprintf(parsed_data->pool, "silence_stream://%i", timeout_ms);
						parsed_data->files[parsed_data->num_files++].prefix = NULL;
					}
				}
				return IKS_OK;
			}
			i += 2;
		}
	}
	return IKS_OK;
}
Beispiel #2
0
SWITCH_DECLARE(switch_log_level_t) switch_log_str2level(const char *str)
{
	int x = 0;
	switch_log_level_t level = SWITCH_LOG_INVALID;

	if (switch_is_number(str)) {
		x = atoi(str);

		if (x > SWITCH_LOG_INVALID) {
			return SWITCH_LOG_INVALID - 1;
		} else if (x < 0) {
			return 0;
		} else {
			return x;
		}
	}


	for (x = 0;; x++) {
		if (!LEVELS[x]) {
			break;
		}

		if (!strcasecmp(LEVELS[x], str)) {
			level = (switch_log_level_t) x;
			break;
		}
	}

	return level;
}
/*! set text parameter */
static void pocketsphinx_asr_text_param(switch_asr_handle_t *ah, char *param, const char *val)
{
	pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
	if (!zstr(param) && !zstr(val)) {
		if (!strcasecmp("no-input-timeout", param) && switch_is_number(val)) {
			ps->no_input_timeout = atoi(val);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no-input-timeout = %d\n", ps->no_input_timeout);
		} else if (!strcasecmp("speech-timeout", param) && switch_is_number(val)) {
			ps->speech_timeout = atoi(val);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "speech-timeout = %d\n", ps->speech_timeout);
		} else if (!strcasecmp("start-input-timers", param)) {
			ps->start_input_timers = switch_true(val);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "start-input-timers = %d\n", ps->start_input_timers);
		} else if (!strcasecmp("confidence-threshold", param) && switch_is_number(val)) {
			ps->confidence_threshold = atoi(val);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "confidence-threshold = %d\n", ps->confidence_threshold);
		}
	}
}
/**
 * Wraps file with interface that can be controlled by fileman flags
 * @param handle
 * @param path the file to play
 * @return SWITCH_STATUS_SUCCESS if opened
 */
static switch_status_t fileman_file_open(switch_file_handle_t *handle, const char *path)
{
	int start_offset_ms = 0;
	switch_status_t status = SWITCH_STATUS_FALSE;
	struct fileman_file_context *context = switch_core_alloc(handle->memory_pool, sizeof(*context));
	handle->private_info = context;

	if (handle->params) {
		const char *id = switch_event_get_header(handle->params, "id");
		const char *uuid = switch_event_get_header(handle->params, "session");
		const char *start_offset_ms_str = switch_event_get_header(handle->params, "start_offset_ms");
		if (!zstr(id)) {
			context->id = switch_core_strdup(handle->memory_pool, id);
		}
		if (!zstr(uuid)) {
			context->uuid = switch_core_strdup(handle->memory_pool, uuid);
		}
		if (!zstr(start_offset_ms_str) && switch_is_number(start_offset_ms_str)) {
			start_offset_ms = atoi(start_offset_ms_str);
			if (start_offset_ms < 0) {
				start_offset_ms = 0;
			}
		}
	}

	switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Got path %s\n", path);

	if ((status = switch_core_file_open(&context->fh, path, handle->channels, handle->samplerate, handle->flags, NULL)) != SWITCH_STATUS_SUCCESS) {
		return status;
	}

	/* set up handle for external control */
	if (!context->id) {
		/* use filename as ID */
		context->id = switch_core_strdup(handle->memory_pool, path);
	}
	switch_mutex_lock(fileman_globals.mutex);
	if (!switch_core_hash_find(fileman_globals.hash, context->id)) {
		switch_core_hash_insert(fileman_globals.hash, context->id, handle);
	} else {
		switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_WARNING, "Duplicate fileman ID: %s\n", context->id);
		return SWITCH_STATUS_FALSE;
	}
	switch_mutex_unlock(fileman_globals.mutex);

	context->max_frame_len = (handle->samplerate / 1000 * SWITCH_MAX_INTERVAL);
	switch_zmalloc(context->abuf, FILE_STARTBYTES * sizeof(*context->abuf));

	if (!context->fh.audio_buffer) {
		switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Create audio buffer\n");
		switch_buffer_create_dynamic(&context->fh.audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0);
		switch_assert(context->fh.audio_buffer);
	}

	handle->samples = context->fh.samples;
	handle->format = context->fh.format;
	handle->sections = context->fh.sections;
	handle->seekable = context->fh.seekable;
	handle->speed = context->fh.speed;
	handle->vol = context->fh.vol;
	handle->offset_pos = context->fh.offset_pos;
	handle->interval = context->fh.interval;

	if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
		switch_set_flag(handle, SWITCH_FILE_NATIVE);
	} else {
		switch_clear_flag(handle, SWITCH_FILE_NATIVE);
	}

	if (handle->params && switch_true(switch_event_get_header(handle->params, "pause"))) {
		switch_set_flag(handle, SWITCH_FILE_PAUSE);
	}

	if (handle->seekable && start_offset_ms) {
		unsigned int pos = 0;
		int32_t target = start_offset_ms * (handle->samplerate / 1000);
		switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", target);
		switch_core_file_seek(&context->fh, &pos, target, SEEK_SET);
	}

	return status;
}
/**
 * Handle fax completion event from FreeSWITCH core
 * @param event received from FreeSWITCH core.  It will be destroyed by the core after this function returns.
 */
static void on_execute_complete_event(switch_event_t *event)
{
	const char *application = switch_event_get_header(event, "Application");
	
	if (!zstr(application) && (!strcmp(application, "rxfax") || !strcmp(application, "txfax"))) {
		int is_rxfax = !strcmp(application, "rxfax");
		const char *uuid = switch_event_get_header(event, "Unique-ID");
		const char *fax_jid = switch_event_get_header(event, "variable_rayo_fax_jid");
		struct rayo_actor *component;
		if (!zstr(fax_jid) && (component = RAYO_LOCATE(fax_jid))) {
			iks *result;
			iks *complete;
			iks *fax;
			int have_fax_document = 1;
			switch_core_session_t *session;
			switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid);

			/* clean up channel */
			session = switch_core_session_locate(uuid);
			if (session) {
				switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL);
				switch_core_session_rwunlock(session);
			}

			/* RX only: transfer HTTP document and delete local copy */
			if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) {
				switch_stream_handle_t stream = { 0 };
				SWITCH_STANDARD_STREAM(stream);
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename);
				switch_api_execute("http_put", RECEIVEFAX_COMPONENT(component)->filename, NULL, &stream);
				/* check if successful */
				if (!zstr(stream.data) && strncmp(stream.data, "+OK", 3)) {
					/* PUT failed */
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename, (char *)stream.data);
					have_fax_document = 0;
				}
				switch_safe_free(stream.data)
				switch_file_remove(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component));
			}

			/* successful fax? */
			if (have_fax_document && switch_true(switch_event_get_header(event, "variable_fax_success"))) {
				result = rayo_component_create_complete_event(RAYO_COMPONENT(component), FAX_FINISH);
			} else if (have_fax_document && FAX_COMPONENT(component)->stop)  {
				result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP);
			} else {
				result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR);
			}
			complete = iks_find(result, "complete");

			/* RX only: add fax document information */
			if (is_rxfax && have_fax_document) {
				const char *pages = switch_event_get_header(event, "variable_fax_document_transferred_pages");
				if (!zstr(pages) && switch_is_number(pages) && atoi(pages) > 0) {
					const char *resolution = switch_event_get_header(event, "variable_fax_file_image_resolution");
					const char *size = switch_event_get_header(event, "variable_fax_image_size");

					fax = iks_insert(complete, "fax");
					iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS);

					if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive) {
						iks_insert_attrib(fax, "url", RECEIVEFAX_COMPONENT(component)->filename);
					} else {
						/* convert absolute path to file:// URI */
						iks_insert_attrib_printf(fax, "url", "file://%s", RECEIVEFAX_COMPONENT(component)->filename);
					}

					if (!zstr(resolution)) {
						iks_insert_attrib(fax, "resolution", resolution);
					}
					if (!zstr(size)) {
						iks_insert_attrib(fax, "size", size);
					}
					iks_insert_attrib(fax, "pages", pages);
				}
			}

			/* add metadata from event */
			insert_fax_metadata(event, "fax_success", complete);
			insert_fax_metadata(event, "fax_result_code", complete);
			insert_fax_metadata(event, "fax_result_text", complete);
			insert_fax_metadata(event, "fax_document_transferred_pages", complete);
			insert_fax_metadata(event, "fax_document_total_pages", complete);
			insert_fax_metadata(event, "fax_image_resolution", complete);
			insert_fax_metadata(event, "fax_image_size", complete);
			insert_fax_metadata(event, "fax_bad_rows", complete);
			insert_fax_metadata(event, "fax_transfer_rate", complete);
			insert_fax_metadata(event, "fax_ecm_used", complete);
			insert_fax_metadata(event, "fax_local_station_id", complete);
			insert_fax_metadata(event, "fax_remote_station_id", complete);

			/* flag faxing as done */
			rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0);

			rayo_component_send_complete_event(RAYO_COMPONENT(component), result);

			RAYO_UNLOCK(component);
		}
	}
}
Beispiel #6
0
/**
 * read default settings from speex.conf
 */
static void load_configuration()
{
	switch_xml_t xml = NULL, cfg = NULL;

	if ((xml = switch_xml_open_cfg("speex.conf", &cfg, NULL))) {
		switch_xml_t x_lists;
		if ((x_lists = switch_xml_child(cfg, "settings"))) {
			const char *settings_name = switch_xml_attr(x_lists, "name");
			switch_xml_t x_list;
			if (zstr(settings_name)) {
				settings_name = "";
			}
			for (x_list = switch_xml_child(x_lists, "param"); x_list; x_list = x_list->next) {
				const char *name = switch_xml_attr(x_list, "name");
				const char *value = switch_xml_attr(x_list, "value");
				if (zstr(name)) {
					continue;
				}

				if (zstr(value)) {
					continue;
				}

				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s %s = %s\n", settings_name, name, value);

				if (!strcasecmp("quality", name)) {
					/* compression quality, integer 0-10 */
					int tmp = atoi(value);
					if (switch_is_number(value) && tmp >= 0 && tmp <= 10) {
						default_codec_settings.quality = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid quality value: %s\n", value);
					}
				} else if (!strcasecmp("complexity", name)) {
					/* compression complexity, integer 1-10 */
					int tmp = atoi(value);
					if (switch_is_number(value) && tmp >= 1 && tmp <= 10) {
						default_codec_settings.complexity = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid complexity value: %s\n", value);
					}
				} else if (!strcasecmp("enhancement", name)) {
					/* enable perceptual enhancement, boolean */
					default_codec_settings.enhancement = switch_true(value);
				} else if (!strcasecmp("vad", name)) {
					/* enable voice activity detection, boolean */
					default_codec_settings.vad = switch_true(value);
				} else if (!strcasecmp("vbr", name)) {
					/* enable variable bit rate, boolean */
					default_codec_settings.vbr = switch_true(value);
				} else if (!strcasecmp("vbr-quality", name)) {
					/* variable bit rate quality, float 0-10 */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0 && tmp <= 10) {
						default_codec_settings.vbr_quality = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid vbr-quality value: %s\n", value);
					}
				} else if (!strcasecmp("abr", name)) {
					/* average bit rate, integer bits per sec */
					int tmp = atoi(value);
					if (switch_is_number(value) && tmp >= 0) {
						default_codec_settings.abr = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid abr value: %s\n", value);
					}
				} else if (!strcasecmp("dtx", name)) {
					/* discontinuous transmit, boolean */
					default_codec_settings.dtx = switch_true(value);
				} else if (!strcasecmp("preproc", name)) {
					/* enable preprocessor, boolean */
					default_codec_settings.preproc = switch_true(value);
				} else if (!strcasecmp("pp-vad", name)) {
					/* enable preprocessor VAD, boolean */
					default_codec_settings.pp_vad = switch_true(value);
				} else if (!strcasecmp("pp-agc", name)) {
					/* enable preprocessor automatic gain control, boolean */
					default_codec_settings.pp_agc = switch_true(value);
				} else if (!strcasecmp("pp-agc-level", name)) {
					/* agc level, float */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0.0f) {
						default_codec_settings.pp_agc_level = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-agc-level value: %s\n", value);
					}
				} else if (!strcasecmp("pp-denoise", name)) {
					/* enable preprocessor denoiser, boolean */
					default_codec_settings.pp_denoise = switch_true(value);
				} else if (!strcasecmp("pp-dereverb", name)) {
					/* enable preprocessor reverberation removal, boolean */
					default_codec_settings.pp_dereverb = switch_true(value);
				} else if (!strcasecmp("pp-dereverb-decay", name)) {
					/* reverberation removal decay, float */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0.0f) {
						default_codec_settings.pp_dereverb_decay = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-decay value: %s\n", value);
					}
				} else if (!strcasecmp("pp-dereverb-level", name)) {
					/* reverberation removal level, float */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0.0f) {
						default_codec_settings.pp_dereverb_level = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-level value: %s\n", value);
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid unknown param: %s = %s\n", name, value);
				}
			}
		}
		switch_xml_free(xml);
	}
}
Beispiel #7
0
static switch_status_t switch_speex_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
{
	speex_codec_settings_t *codec_settings = NULL;
	int x, argc;
	char *argv[10];
	char *fmtp_dup = NULL;

	if (!codec_fmtp) {
		return SWITCH_STATUS_FALSE;
	}

	/* load default settings */
	if (codec_fmtp->private_info) {
		codec_settings = codec_fmtp->private_info;
		memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings));
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "codec_fmtp->private_info is NULL\n");
		return SWITCH_STATUS_SUCCESS;
	}

	if (!fmtp) {
		return SWITCH_STATUS_SUCCESS;
	}

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got fmtp: %s\n", fmtp);

	fmtp_dup = strdup(fmtp);
	switch_assert(fmtp_dup);

	/* parse ; separated fmtp args */
	argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
	for (x = 0; x < argc; x++) {
		char *data = argv[x];
		char *arg;
		switch_assert(data);
		while (*data == ' ') {
			data++;
		}
		if (!(arg = strchr(data, '='))) {
			continue;
		}
		*arg++ = '\0';
		if (zstr(arg)) {
			continue;
		}

		if (!strcasecmp("vbr", data)) {
			/* vbr can be on/off/vad */
			if (!strcasecmp("vad", arg)) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "enabling speex vbr=vad\n");
				codec_settings->vbr = 0;
				codec_settings->vad = 1;
				codec_settings->pp_vad = 1;
			} else {
				if (switch_true(arg)) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "enabling speex vbr\n");
					codec_settings->vbr = 1;
					codec_settings->vad = 0;
					codec_settings->pp_vad = 1;
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "disabling speex vbr\n");
					codec_settings->vbr = 0;
					codec_settings->vad = 0;
					codec_settings->pp_vad = 0;
				}
			}
		} else if (!strcasecmp("cng", data)) {
			/* TODO don't know how to turn on CNG */
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "speex cng is unsupported\n");
		} else if (!strcasecmp("mode", data)) {
			/* mode is a comma-separate list of preferred modes.  Use the first mode in the list */
			char *arg_dup;
			char *mode[2];
			if (!strncasecmp("any", arg, 3)) {
				/* "any", keep the default setting */
				continue;
			}
			arg_dup = strdup(arg);
			if (switch_separate_string(arg_dup, ',', mode, (sizeof(mode) / sizeof(mode[0])))) {
				int mode_num = -1;
				char *mode_str = mode[0];
				if (mode_str[0] == '"') {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "mode starts with \"\n");
					mode_str++;
				}
				if (switch_is_number(mode_str)) {
					mode_num = atoi(mode_str);
				}
				/* TODO there might be a way to set the mode directly instead of changing the quality */
				if (codec_fmtp->actual_samples_per_second == 8000) {
					switch (mode_num) {
					case 1:
						codec_settings->quality = 0;
						break;
					case 2:
						codec_settings->quality = 2;
						break;
					case 3:
						codec_settings->quality = 4;
						break;
					case 4:
						codec_settings->quality = 6;
						break;
					case 5:
						codec_settings->quality = 8;
						break;
					case 6:
						codec_settings->quality = 9;
						break;
					case 7:
						codec_settings->quality = 10;
						break;
					case 8:
						codec_settings->quality = 1;
						break;
					default:
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ignoring invalid speex/8000 mode %s\n", mode_str);
						continue;
					}
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "choosing speex/8000 mode %s\n", mode_str);
					codec_settings->quality = codec_settings->quality;
					codec_settings->vbr_quality = codec_settings->quality;
				} else {
					if (mode_num >= 0 && mode_num <= 10) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "choosing speex/%d mode %s\n", codec_fmtp->actual_samples_per_second, mode_str);
						codec_settings->quality = mode_num;
						codec_settings->vbr_quality = mode_num;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ignoring invalid speex/%d mode %s\n", codec_fmtp->actual_samples_per_second, mode_str);
						continue;
					}
				}
			}
			free(arg_dup);
		}
	}
	free(fmtp_dup);
	/*codec_fmtp->bits_per_second = bit_rate;*/
	return SWITCH_STATUS_SUCCESS;
}
Beispiel #8
0
switch_status_t ladspa_session(switch_core_session_t *session, const char *flags, const char *plugin_name, const char *label, const char *params)
{
    switch_channel_t *channel = switch_core_session_get_channel(session);
    switch_media_bug_t *bug;
    switch_status_t status;
    switch_ladspa_t *pvt = { 0 };
    switch_codec_implementation_t read_impl = { 0 };
    int i, bflags = SMBF_READ_REPLACE | SMBF_ANSWER_REQ;
    char *pstr;
    int argc;
    char *argv[50];
    char *dparams = NULL;

    if (zstr(plugin_name)) {
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s INVALID PLUGIN\n", switch_channel_get_name(channel));
        return SWITCH_STATUS_FALSE;
    }

    if (zstr(flags)) {
        flags = "r";
    }

    if (strchr(flags, 'w')) {
        bflags = SMBF_WRITE_REPLACE;
    }

    switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "FLAGS: %s PLUGIN: %s LABEL: %s PARAMS: %s\n",
                      flags, plugin_name, label, params);

    switch_core_session_get_read_impl(session, &read_impl);

    pvt = switch_core_session_alloc(session, sizeof(*pvt));

    pvt->session = session;
    if (!zstr(label)) {
        pvt->label_name = switch_core_session_strdup(session, label);
    } else {
        char *p;
        pvt->label_name = switch_core_session_strdup(session, plugin_name);
        if ((p = strrchr(pvt->label_name, '.'))) {
            *p = '\0';
        }
    }

    if (strstr(plugin_name, ".so")) {
        pvt->plugin_name = switch_core_session_strdup(session, plugin_name);
    } else {
        pvt->plugin_name = switch_core_session_sprintf(session, "%s.so", plugin_name);
    }

    dparams = switch_core_session_strdup(session, params);

    argc = switch_split(dparams, ' ', argv);

    for (i = 0; i < argc; i++) {
        if (switch_is_number(argv[i])) {
            if (pvt->num_idx < MAX_INDEX) {
                pvt->config[pvt->num_idx] = atof(argv[i]);
                pvt->has_config[pvt->num_idx] = 1;
                pvt->num_idx++;
            }
        } else {
            if (pvt->str_idx < MAX_INDEX) {
                pvt->str_config[pvt->str_idx++] = switch_core_session_strdup(session, argv[i]);
            }
        }
    }

    if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
        return SWITCH_STATUS_FALSE;
    }

    pstr = switch_core_session_sprintf(session, "%s|%s|%s|%s", flags, plugin_name, label, params);

    if ((status = switch_core_media_bug_add(session, "ladspa", pstr,
                                            ladspa_callback, pvt, 0, bflags | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) {
        return status;
    }

    switch_channel_set_private(channel, "ladspa", bug);

    return SWITCH_STATUS_SUCCESS;
}
switch_status_t spandsp_inband_dtmf_session(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_media_bug_t *bug;
	switch_status_t status;
	switch_inband_dtmf_t *pvt;
	switch_codec_implementation_t read_impl = { 0 };
	const char *value;

	switch_core_session_get_read_impl(session, &read_impl);

	if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) {
		return SWITCH_STATUS_MEMERR;
	}

	pvt->session = session;

	/* get detector params */
	pvt->min_dup_digit_spacing = 0;
	value = switch_channel_get_variable(channel, "min_dup_digit_spacing_ms");
	if (!zstr(value) && switch_is_number(value)) {
		int val = atoi(value) * 8; /* convert from ms to samples */
		if (val < 0) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "min_dup_digit_spacing_ms must be >= 0\n");
		} else {
			pvt->min_dup_digit_spacing = val;
		}
	}

	pvt->threshold = -100;
	value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_threshold");
	if (!zstr(value) && switch_is_number(value)) {
		int val = atoi(value);
		if (val < -99) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "spandsp_dtmf_rx_threshold must be >= -99 dBm0\n");
		} else {
			pvt->threshold = val;
		}
	}

	pvt->twist = -1;
	value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_twist");
	if (!zstr(value) && switch_is_number(value)) {
		int val = atoi(value);
		if (val < 0) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "spandsp_dtmf_rx_twist must be >= 0 dB\n");
		} else {
			pvt->twist = val;
		}
	}

	pvt->reverse_twist = -1;
	value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_reverse_twist");
	if (!zstr(value) && switch_is_number(value)) {
		int val = atoi(value);
		if (val < 0) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "spandsp_dtmf_rx_reverse_twist must be >= 0 dB\n");
		} else {
			pvt->reverse_twist = val;
		}
	}

	pvt->filter_dialtone = -1;
	value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_filter_dialtone");
	if (switch_true(value)) {
		pvt->filter_dialtone = 1;
	} else if (switch_false(value)) {
		pvt->filter_dialtone = 0;
	}

	if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
		return SWITCH_STATUS_FALSE;
	}

	if ((status = switch_core_media_bug_add(session, "spandsp_dtmf_detect", NULL,
						inband_dtmf_callback, pvt, 0, SMBF_READ_REPLACE | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) {
		return status;
	}

	switch_channel_set_private(channel, "dtmf", bug);

	return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *event, int count, switch_bool_t reload,
															  switch_xml_config_item_t *instructions)
{
	switch_xml_config_item_t *item;
	int matched_count = 0;

	for (item = instructions; item->key; item++) {
		const char *value = switch_event_get_header(event, item->key);
		switch_bool_t changed = SWITCH_FALSE;
		switch_xml_config_callback_t callback = (switch_xml_config_callback_t) item->function;
		void *ptr = item->ptr;

		//switch_assert(ptr);

		if (value) {
			matched_count++;
		}

		if (reload && !switch_test_flag(item, CONFIG_RELOADABLE)) {
			continue;
		}

		if (!value && switch_test_flag(item, CONFIG_REQUIRED)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Required parameter [%s] is missing\n", item->key);
			return SWITCH_STATUS_FALSE;
		}

		switch (item->type) {
		case SWITCH_CONFIG_INT:
			{
				switch_xml_config_int_options_t *int_options = (switch_xml_config_int_options_t *) item->data;
				int *dest = (int *) ptr;
				int intval;
				if (value) {
					if (switch_is_number(value)) {
						intval = atoi(value);
					} else {
						intval = (int) (intptr_t) item->defaultvalue;
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%d]\n",
										  value, item->key, intval);
					}

					if (int_options) {
						/* Enforce validation options */
						if ((int_options->enforce_min && !(intval >= int_options->min)) || (int_options->enforce_max && !(intval <= int_options->max))) {
							/* Validation failed, set default */
							intval = (int) (intptr_t) item->defaultvalue;
							/* Then complain */
							if (int_options->enforce_min && int_options->enforce_max) {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
												  "Invalid value [%s] for parameter [%s], should be between [%d] and [%d], setting default [%d]\n", value,
												  item->key, int_options->min, int_options->max, intval);
							} else {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
												  "Invalid value [%s] for parameter [%s], should be %s [%d], setting default [%d]\n", value, item->key,
												  int_options->enforce_min ? "at least" : "at max",
												  int_options->enforce_min ? int_options->min : int_options->max, intval);
							}
						}
					}
				} else {
					intval = (int) (intptr_t) item->defaultvalue;
				}

				if (*dest != intval) {
					*dest = intval;
					changed = SWITCH_TRUE;
				}
			}
			break;
		case SWITCH_CONFIG_ATOMIC:
			{
				switch_xml_config_atomic_options_t *atomic_options = (switch_xml_config_atomic_options_t *) item->data;
				switch_atomic_t *dest = (switch_atomic_t *) ptr;
				uint32_t uintval;
				if (value) {
					if (switch_is_number(value)) {
						uintval = (uint32_t) strtol(value, NULL, 10);
					} else {
						uintval = (uint32_t) (uintptr_t) item->defaultvalue;
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%u]\n",
										  value, item->key, uintval);
					}

					if (atomic_options) {
						/* Enforce validation options */
						if ((atomic_options->enforce_min && !(uintval >= atomic_options->min)) || (atomic_options->enforce_max && !(uintval <= atomic_options->max))) {
							/* Validation failed, set default */
							uintval = (uint32_t) (uintptr_t) item->defaultvalue;
							/* Then complain */
							if (atomic_options->enforce_min && atomic_options->enforce_max) {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
												  "Invalid value [%s] for parameter [%s], should be between [%u] and [%u], setting default [%u]\n", value,
												  item->key, atomic_options->min, atomic_options->max, uintval);
							} else {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
												  "Invalid value [%s] for parameter [%s], should be %s [%u], setting default [%u]\n", value, item->key,
												  atomic_options->enforce_min ? "at least" : "at max",
												  atomic_options->enforce_min ? atomic_options->min : atomic_options->max, uintval);
							}
						}
					}
				} else {
					uintval = (uint32_t) (uintptr_t) item->defaultvalue;
				}

				if (switch_atomic_read(dest) != uintval) {
					switch_atomic_set(dest, uintval);
					changed = SWITCH_TRUE;
				}
			}
			break;
		case SWITCH_CONFIG_STRING:
			{
				switch_xml_config_string_options_t string_options_default = { 0 };
				switch_xml_config_string_options_t *string_options =
					item->data ? (switch_xml_config_string_options_t *) item->data : &string_options_default;
				const char *newstring = NULL;

				/* Perform validation */
				if (value) {
					if (!zstr(string_options->validation_regex)) {
						if (switch_regex_match(value, string_options->validation_regex) == SWITCH_STATUS_SUCCESS) {
							newstring = value;	/* Regex match, accept value */
						} else {
							newstring = (char *) item->defaultvalue;	/* Regex failed */
							if (newstring) {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%s]\n",
												  value, item->key, newstring);
							} else {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s]\n", value, item->key);
							}
							switch_xml_config_item_print_doc(SWITCH_LOG_ERROR, item);
						}
					} else {
						newstring = value;	/* No validation */
					}
				} else {
					newstring = (char *) item->defaultvalue;
				}

				if (string_options->length > 0) {
					/* We have a preallocated buffer */
					char *dest = (char *) ptr;

					if (newstring) {
						if (strncasecmp(dest, newstring, string_options->length)) {
							switch_copy_string(dest, newstring, string_options->length);
							changed = SWITCH_TRUE;
						}
					} else {
						if (*dest != '\0') {
							*dest = '\0';
							changed = SWITCH_TRUE;
						}
					}
				} else if (string_options->pool) {
					/* Pool-allocated buffer */
					char **dest = (char **) ptr;

					if (newstring) {
						if (!*dest || strcmp(*dest, newstring)) {
							*dest = switch_core_strdup(string_options->pool, newstring);
						}
					} else {
						if (*dest) {
							changed = SWITCH_TRUE;
							*dest = NULL;
						}
					}
				} else {
					/* Dynamically allocated buffer */
					char **dest = (char **) ptr;

					if (newstring) {
						if (!*dest || strcmp(*dest, newstring)) {
							switch_safe_free(*dest);
							*dest = strdup(newstring);
							changed = SWITCH_TRUE;
						}
					} else {
						if (*dest) {
							switch_safe_free(*dest);
							changed = SWITCH_TRUE;
						}
					}
				}
			}
			break;
		case SWITCH_CONFIG_BOOL:
			{
				switch_bool_t *dest = (switch_bool_t *) ptr;
				switch_bool_t newval = SWITCH_FALSE;

				if (value && switch_true(value)) {
					newval = SWITCH_TRUE;
				} else if (value && switch_false(value)) {
					newval = SWITCH_FALSE;
				} else if (value) {
					/* Value isnt true or false */
					newval = (switch_bool_t) (intptr_t) item->defaultvalue;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%s]\n",
									  value, item->key, newval ? "true" : "false");
					switch_xml_config_item_print_doc(SWITCH_LOG_ERROR, item);
				} else {
					newval = (switch_bool_t) (intptr_t) item->defaultvalue;
				}

				if (*dest != newval) {
					*dest = newval;
					changed = SWITCH_TRUE;
				}
			}
			break;
		case SWITCH_CONFIG_CUSTOM:
			break;
		case SWITCH_CONFIG_ENUM:
			{
				switch_xml_config_enum_item_t *enum_options = (switch_xml_config_enum_item_t *) item->data;
				int *dest = (int *) ptr;
				int newval = 0;
				switch_status_t lookup_result = SWITCH_STATUS_SUCCESS;

				if (value) {
					lookup_result = switch_xml_config_enum_str2int(enum_options, value, &newval);
				} else {
					newval = (int) (intptr_t) item->defaultvalue;
				}

				if (lookup_result != SWITCH_STATUS_SUCCESS) {
					newval = (int) (intptr_t) item->defaultvalue;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s]\n", value, item->key);
					switch_xml_config_item_print_doc(SWITCH_LOG_ERROR, item);
				}

				if (*dest != newval) {
					changed = SWITCH_TRUE;
					*dest = newval;
				}
			}
			break;
		case SWITCH_CONFIG_FLAG:
			{
				int32_t *dest = (int32_t *) ptr;
				int index = (int) (intptr_t) item->data;
				int8_t currentval = (int8_t) ! !(*dest & index);
				int newval = 0;

				if (value) {
					newval = switch_true(value);
				} else {
					newval = (switch_bool_t) (intptr_t) item->defaultvalue;
				}

				if (newval != currentval) {
					changed = SWITCH_TRUE;
					if (newval) {
						*dest |= (1 << index);
					} else {
						*dest &= ~(1 << index);
					}
				}
			}
			break;
		case SWITCH_CONFIG_FLAGARRAY:
			{
				int8_t *dest = (int8_t *) ptr;
				unsigned int index = (unsigned int) (intptr_t) item->data;
				int8_t newval = value ? !!switch_true(value) : (int8_t) ((intptr_t) item->defaultvalue);
				if (dest[index] != newval) {
					changed = SWITCH_TRUE;
					dest[index] = newval;
				}
			}
			break;
		case SWITCH_CONFIG_LAST:
			break;
		default:
			break;
		}

		if (callback) {
			callback(item, value, (reload ? CONFIG_RELOAD : CONFIG_LOAD), changed);
		}
	}

	if (count != matched_count) {
		/* User made a mistake, find it */
		switch_event_header_t *header;
		for (header = event->headers; header; header = header->next) {
			switch_bool_t found = SWITCH_FALSE;
			for (item = instructions; item->key; item++) {
				if (!strcasecmp(header->name, item->key)) {
					found = SWITCH_TRUE;
					break;
				}
			}

			if (!found) {
				/* Tell the user */
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
								  "Configuration parameter [%s] is unfortunately not valid, you might want to double-check that.\n", header->name);
			}
		}
	}

	return SWITCH_STATUS_SUCCESS;
}
Beispiel #11
0
/**
 * Configure module
 */
static switch_status_t do_config(void)
{
	switch_xml_t cfg, xml, settings;

	if (!(xml = switch_xml_open_cfg("graylog2.conf", &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of graylog2.conf failed\n");
		return SWITCH_STATUS_TERM;
	}

	/* set defaults */
	globals.log_level = SWITCH_LOG_WARNING;
	globals.server_host = "127.0.0.1";
	globals.server_port = 12201;
	globals.send_uncompressed_header = 0;

	if ((settings = switch_xml_child(cfg, "settings"))) {
		switch_xml_t param;
		switch_xml_t fields;
		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
			char *name = (char *) switch_xml_attr_soft(param, "name");
			char *value = (char *) switch_xml_attr_soft(param, "value");

			if (zstr(name)) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring empty param\n");
				continue;
			}

			if (zstr(value)) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring empty value for param \"%s\"\n", name); 
				continue;
			}

			if (!strcmp(name, "server-host")) {
				globals.server_host = switch_core_strdup(globals.pool, value);
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\" = \"%s\"\n", name, value); 
			} else if (!strcasecmp(name, "server-port")) {
				int port = -1;
				if (switch_is_number(value)) {
					port = atoi(value);
				}
				if (port > 0 && port <= 65535) {
					globals.server_port = port;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\" = \"%s\"\n", name, value); 
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid port: \"%s\"\n", value); 
				}
			} else if (!strcasecmp(name, "loglevel")) {
				switch_log_level_t log_level = switch_log_str2level(value);
				if (log_level == SWITCH_LOG_INVALID) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring invalid log level: \"%s\"\n", value);
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\" = \"%s\"\n", name, value); 
					globals.log_level = log_level;
				}
			} else if (!strcasecmp(name, "send-uncompressed-header")) {
				globals.send_uncompressed_header = switch_true(value);
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\" = \"%s\"\n", name, value); 
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring unknown param: \"%s\"\n", name);
			}
		}

		/* map session fields to channel variables */
		if ((fields = switch_xml_child(settings, "fields"))) {
			switch_xml_t field;
			for (field = switch_xml_child(fields, "field"); field; field = field->next) {
				char *name = (char *) switch_xml_attr_soft(field, "name");
				char *variable = (char *) switch_xml_attr_soft(field, "variable");
				if (zstr(name)) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring unnamed session field\n");
					continue;
				}
				if (zstr(variable)) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring empty channel variable for session field \"%s\"\n", name);
					continue;
				}
				switch_event_add_header_string(globals.session_fields, SWITCH_STACK_BOTTOM,
					switch_core_strdup(globals.pool, name), switch_core_strdup(globals.pool, variable));
			}
		}
	}
	switch_xml_free(xml);
	return SWITCH_STATUS_SUCCESS;
}