예제 #1
0
static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number)
{
	char *cmd;
	char *name = NULL;
	char *area = NULL;
	char *src = NULL;
	cid_data_t *cid = NULL;
	switch_stream_handle_t stream = { 0 };

	SWITCH_STANDARD_STREAM(stream);

	cmd = switch_core_sprintf(pool, "get fs:cidlookup:name:%s", number);
	if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
		if (strncmp("-ERR", stream.data, 4)) {
			name = switch_core_strdup(pool, stream.data);
		} else {
			name = NULL;
		}
	}

	SWITCH_REWIND_STREAM(stream);
	cmd = switch_core_sprintf(pool, "get fs:cidlookup:area:%s", number);
	if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
		if (strncmp("-ERR", stream.data, 4)) {
			area = switch_core_strdup(pool, stream.data);
		} else {
			area = NULL;
		}
	}

	SWITCH_REWIND_STREAM(stream);
	cmd = switch_core_sprintf(pool, "get fs:cidlookup:src:%s", number);
	if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
		if (strncmp("-ERR", stream.data, 4)) {
			src = switch_core_strdup(pool, stream.data);
		} else {
			src = NULL;
		}
	}

	if (name || area || src) {
		cid = switch_core_alloc(pool, sizeof(cid_data_t));
		switch_assert(cid);
		cid->name = name;
		cid->area = area;
		cid->src = src;
	}

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "memcache: k:'%s', vn:'%s', va:'%s', vs:'%s'\n",
					  cmd, (name) ? name : "(null)", (area) ? area : "(null)", (src) ? src : "(null)");
	switch_safe_free(stream.data);
	return cid;
}
예제 #2
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;
}
static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
												switch_caller_profile_t *outbound_profile,
												switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
												switch_call_cause_t *cancel_cause)
{
	const char *profile;
	char *dup_profile = NULL;

	if (session) {
		profile = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_profile");
	} else {
		dup_profile = switch_core_get_variable_dup("sip_profile");
		profile = dup_profile;
	}
	if (zstr(profile)) {
		profile = "default";
	}

	outbound_profile->destination_number = switch_core_sprintf(outbound_profile->pool, "%s/%s", profile, outbound_profile->destination_number);

	UNPROTECT_INTERFACE(sip_endpoint_interface);

	switch_safe_free(dup_profile);

	return switch_core_session_outgoing_channel(session, var_event, "sofia", outbound_profile, new_session, pool, SOF_NONE, cancel_cause);
}
static switch_status_t switch_sangoma_init_ilbc(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
	int mode = codec->implementation->microseconds_per_packet / 1000;
	if (codec->fmtp_in) {
		int x, argc;
		char *argv[10];
		argc = switch_separate_string(codec->fmtp_in, ';', 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, '='))) {
				*arg++ = '\0';
				if (!strcasecmp(data, "mode")) {
					mode = atoi(arg);
				}
			}
		}
	}
	codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "mode=%d", mode);
	return switch_sangoma_init(codec, flags, codec_settings);
}
static switch_status_t load_config(switch_bool_t reload)
{
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	switch_xml_t cfg, xml = NULL, settings, param, x_profiles, x_profile;
	switch_cache_db_handle_t *dbh = NULL;

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

	switch_mutex_lock(globals.mutex);
	if ((settings = switch_xml_child(cfg, "settings"))) {
		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
			char *var = (char *) switch_xml_attr_soft(param, "name");
			char *val = (char *) switch_xml_attr_soft(param, "value");

			if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) {
				if (switch_odbc_available()) {
					switch_set_string(globals.odbc_dsn, val);
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
				}
			} else if (!strcasecmp(var, "dbname") && !zstr(val)) {
				globals.dbname = switch_core_strdup(globals.pool, val);
			}

			if (!strcasecmp(var, "debug")) {
				globals.debug = atoi(val);
			}
		}
	}

	if ((x_profiles = switch_xml_child(cfg, "profiles"))) {
		for (x_profile = switch_xml_child(x_profiles, "profile"); x_profile; x_profile = x_profile->next) {
			load_profile(switch_xml_attr_soft(x_profile, "name"));
		}
	}

	if (zstr(globals.odbc_dsn) && zstr(globals.dbname)) {
		globals.dbname = switch_core_sprintf(globals.pool, "directory");
	}

	dbh = directory_get_db_handle();
	if (dbh) {
		if (!reload) {
			switch_cache_db_test_reactive(dbh, "delete from directory_search where uuid != '' and name_visible != '' ", "drop table directory_search", dir_sql);
		}
		switch_cache_db_release_db_handle(&dbh);
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!2\n");
		status = SWITCH_STATUS_TERM;
		goto end;
	}
end:
	switch_mutex_unlock(globals.mutex);

	switch_xml_free(xml);
	return status;
}
예제 #6
0
switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *cid)
{
	char *cmd;
	switch_bool_t success = SWITCH_TRUE;
	switch_stream_handle_t stream = { 0 };

	SWITCH_STANDARD_STREAM(stream);

	cmd = switch_core_sprintf(pool, "set fs:cidlookup:name:%s '%s' %d", number, cid->name, globals.cache_expire);
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "memcache: %s\n", cmd);
	if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
		if (strncmp("-ERR", stream.data, 4)) {
			success = SWITCH_TRUE;
		} else {
			success = SWITCH_FALSE;
			goto done;
		}
	}

	SWITCH_REWIND_STREAM(stream);
	cmd = switch_core_sprintf(pool, "set fs:cidlookup:area:%s '%s' %d", number, cid->area, globals.cache_expire);
	if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
		if (strncmp("-ERR", stream.data, 4)) {
			success = SWITCH_TRUE;
		} else {
			success = SWITCH_FALSE;
			goto done;
		}
	}

	SWITCH_REWIND_STREAM(stream);
	cmd = switch_core_sprintf(pool, "set fs:cidlookup:src:%s '%s' %d", number, cid->src, globals.cache_expire);
	if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
		if (strncmp("-ERR", stream.data, 4)) {
			success = SWITCH_TRUE;
		} else {
			success = SWITCH_FALSE;
			goto done;
		}
	}

  done:
	switch_safe_free(stream.data);
	return success;
}
예제 #7
0
/**
 * Get TTS file for voice
 */
static int get_file_from_voice(struct ssml_parser *parsed_data, char *to_say)
{
	struct ssml_node *cur_node = parsed_data->cur_node;
	char *file = switch_core_sprintf(parsed_data->pool, "%s%s", cur_node->tts_voice->prefix, to_say);
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding <%s>: \"%s\"\n", cur_node->tag_name, file);
	parsed_data->files[parsed_data->num_files].name = file;
	parsed_data->files[parsed_data->num_files++].prefix = NULL;
	return 1;
}
예제 #8
0
static switch_status_t config_validate_spool_dir(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
{
    if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)) {
        if (zstr(newvalue)) {
            globals.spool_dir = switch_core_sprintf(globals.pool, "%s%scdr-pg-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
        }
    }

    return SWITCH_STATUS_SUCCESS;
}
예제 #9
0
/**
 * Start input component timers
 */
static void start_input_timers(struct prompt_component *prompt)
{
	iks *x;
	iks *iq = iks_new("iq");
	iks_insert_attrib(iq, "from", RAYO_JID(prompt));
	iks_insert_attrib(iq, "to", prompt->input_jid);
	iks_insert_attrib(iq, "type", "set");
	prompt->start_timers_request_id = switch_core_sprintf(RAYO_POOL(prompt), "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt));
	iks_insert_attrib(iq, "id", prompt->start_timers_request_id);
	x = iks_insert(iq, "start-timers");
	iks_insert_attrib(x, "xmlns", RAYO_INPUT_NS);
	RAYO_SEND_MESSAGE(prompt, prompt->input_jid, iq);
}
예제 #10
0
static switch_status_t tts_commandline_speech_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags)
{
	switch_status_t ret=SWITCH_STATUS_SUCCESS;
	char *message, *tmp, *mtmp, *rate;
	tts_commandline_t *info = (tts_commandline_t *) sh->private_info;

	assert(info != NULL);

	if (switch_test_flag(info->fh, SWITCH_FILE_OPEN)) {
		switch_core_file_close(info->fh);
		unlink(info->file);
	}

	tmp = switch_util_quote_shell_arg(text);
	message = switch_string_replace(globals.command, "${text}", tmp);
	switch_safe_free(tmp); mtmp=message;

	tmp = switch_util_quote_shell_arg(info->voice_name);
	message = switch_string_replace(mtmp, "${voice}", tmp);
	switch_safe_free(tmp); switch_safe_free(mtmp); mtmp=message;

	rate = switch_core_sprintf(sh->memory_pool, "%d", info->rate);
	message = switch_string_replace(mtmp, "${rate}", rate);
	switch_safe_free(mtmp); mtmp=message;

	tmp = switch_util_quote_shell_arg(info->file);
	message = switch_string_replace(mtmp, "${file}", tmp);
	switch_safe_free(tmp); switch_safe_free(mtmp); mtmp=message;

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing: %s\n", message);

	if (switch_system(message, SWITCH_TRUE) < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute command: %s\n", message);
		ret = SWITCH_STATUS_FALSE; goto done;
	}

	if (switch_core_file_open(info->fh, info->file, 0,	//number_of_channels,
							  info->rate,	//samples_per_second,
							  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file: %s\n", info->file);
		ret = SWITCH_STATUS_FALSE; goto done;
	}

	sh->private_info = info;

 done:
	switch_safe_free(mtmp);
	return ret;
}
예제 #11
0
static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_callback_func_t callback, callback_t *cbt, char **err)
{
	switch_bool_t retval = SWITCH_FALSE;
	switch_cache_db_handle_t *dbh = NULL;

	if (!zstr(globals.odbc_dsn) && (dbh = cidlookup_get_db_handle())) {
		if (switch_cache_db_execute_sql_callback(dbh, sql, callback, (void *) cbt, err) != SWITCH_STATUS_SUCCESS) {
			retval = SWITCH_FALSE;
		} else {
			retval = SWITCH_TRUE;
		}
	} else {
		*err = switch_core_sprintf(cbt->pool, "Unable to get ODBC handle.  dsn: %s, dbh is %s\n", globals.odbc_dsn, dbh ? "not null" : "null");
	}

	switch_cache_db_release_db_handle(&dbh);
	return retval;
}
bool WSClientParser::GetHandShakeRespond(char** buffer, int& len) {
	if( mState == WSClientState_Handshake ) {
		mState = WSClientState_Data;

		char input[256] = "";
		unsigned char output[SHA1_HASH_SIZE] = "";
		char b64[256] = "";

		snprintf(input, sizeof(input), "%s%s", mWebSocketKey, WEBSOCKET_GUID);
		sha1_digest(output, input);
		b64encode((unsigned char *)output, SHA1_HASH_SIZE, (unsigned char *)b64, sizeof(b64));

		char* temp = switch_core_sprintf(
				mpPool,
				"HTTP/1.1 101 Switching Protocols\r\n"
				"Upgrade: websocket\r\n"
				"Connection: Upgrade\r\n"
				"Sec-WebSocket-Accept: %s\r\n"
				"\r\n",
				b64
				);

		*buffer = temp;
		len = strlen(temp);

		switch_log_printf(
				SWITCH_CHANNEL_UUID_LOG(this->uuid),
				SWITCH_LOG_INFO,
				"WSClientParser::GetHandShakeRespond( "
				"this : %p, "
				"len : %d, "
				"buffer : \n%s\n"
				") \n",
				this,
				len,
				*buffer
				);

		return true;
	}
	return false;
}
예제 #13
0
/**
 * Process module XML configuration
 * @param pool memory pool to allocate from
 * @param config_file to use
 * @return SWITCH_STATUS_SUCCESS on successful configuration
 */
static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file)
{
	switch_xml_t cfg, xml;

	/* set defaults */
	globals.file_prefix = switch_core_sprintf(pool, "%s%s", SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_PATH_SEPARATOR);

	if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file);
		return SWITCH_STATUS_TERM;
	}

	/* get params */
	{
		switch_xml_t settings = switch_xml_child(cfg, "fax");
		if (settings) {
			switch_xml_t param;
			for (param = switch_xml_child(settings, "param"); param; param = param->next) {
				const char *var = switch_xml_attr_soft(param, "name");
				const char *val = switch_xml_attr_soft(param, "value");
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val);
				if (!strcasecmp(var, "receivefax-file-prefix")) {
					if (!zstr(val)) {
						globals.file_prefix = switch_core_strdup(pool, val);
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var);
				}
			}
		}
	}

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax-file-prefix = %s\n", globals.file_prefix);

	switch_xml_free(xml);

	return SWITCH_STATUS_SUCCESS;
}
예제 #14
0
static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
	struct siren_context *context = NULL;
	int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
	int decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
	int bit_rate = codec->implementation->bits_per_second;

	if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
		return SWITCH_STATUS_FALSE;
	}

	codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate);

	if (encoding) {
		g722_1_encode_init(&context->encoder_object, bit_rate, codec->implementation->samples_per_second);
	}

	if (decoding) {
		g722_1_decode_init(&context->decoder_object, bit_rate, codec->implementation->samples_per_second);
	}

	codec->private_info = context;
	return SWITCH_STATUS_SUCCESS;
}
예제 #15
0
switch_status_t mod_format_cdr_load_profile_xml(switch_xml_t xprofile)
{
	switch_memory_pool_t *pool = NULL;
	cdr_profile_t *profile = NULL;
	switch_xml_t settings, param;
	char *profile_name = (char *) switch_xml_attr_soft(xprofile, "name");

	if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n");
		return SWITCH_STATUS_TERM;
	}

	profile = switch_core_alloc(pool, sizeof(cdr_profile_t));
	memset(profile, 0, sizeof(cdr_profile_t));

	profile->pool = pool;
	profile->name = switch_core_strdup(profile->pool, profile_name);

	profile->log_http_and_disk = 0;
	profile->log_b = 1;
	profile->disable100continue = 0;
	profile->auth_scheme = CURLAUTH_BASIC;

	switch_thread_rwlock_create(&profile->log_path_lock, pool);

	if ((settings = switch_xml_child(xprofile, "settings"))) {
		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
			char *var = (char *) switch_xml_attr_soft(param, "name");
			char *val = (char *) switch_xml_attr_soft(param, "value");

			if (!strcasecmp(var, "cred") && !zstr(val)) {
				profile->cred = switch_core_strdup(profile->pool, val);
			} else if (!strcasecmp(var, "format") && !zstr(val)) {
				profile->format = switch_core_strdup(profile->pool, val);
			} else if (!strcasecmp(var, "url") && !zstr(val)) {
				if (profile->url_count >= MAX_URLS) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum urls configured!\n");
				} else {
					profile->urls[profile->url_count++] = switch_core_strdup(profile->pool, val);
				}
			} else if (!strcasecmp(var, "log-http-and-disk")) {
				profile->log_http_and_disk = switch_true(val);
			} else if (!strcasecmp(var, "timeout")) {
				int tmp = atoi(val);
				if (tmp >= 0) {
					profile->timeout = tmp;
				} else {
					profile->timeout = 0;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set a negative timeout!\n");
				}
			} else if (!strcasecmp(var, "delay") && !zstr(val)) {
				profile->delay = switch_atoui(val);
			} else if (!strcasecmp(var, "log-b-leg")) {
				profile->log_b = switch_true(val);
			} else if (!strcasecmp(var, "prefix-a-leg")) {
				profile->prefix_a = switch_true(val);
			} else if (!strcasecmp(var, "disable-100-continue") && switch_true(val)) {
				profile->disable100continue = 1;
			} else if (!strcasecmp(var, "encode") && !zstr(val)) {
				if (!strcasecmp(val, "base64")) {
					profile->encode = ENCODING_BASE64;
				} else if (!strcasecmp(val, "textxml")) {
					profile->encode = ENCODING_TEXTXML;
				} else if (!strcasecmp(val, "appljson")) {
					profile->encode = ENCODING_APPLJSON;
				} else {
					profile->encode = switch_true(val) ? ENCODING_DEFAULT : ENCODING_NONE;
				}
			} else if (!strcasecmp(var, "retries") && !zstr(val)) {
				profile->retries = switch_atoui(val);
			} else if (!strcasecmp(var, "rotate") && !zstr(val)) {
				profile->rotate = switch_true(val);
			} else if (!strcasecmp(var, "log-dir")) {
				if (zstr(val)) {
					profile->base_log_dir = switch_core_sprintf(profile->pool, "%s%sformat_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
				} else {
					if (switch_is_file_path(val)) {
						profile->base_log_dir = switch_core_strdup(profile->pool, val);
					} else {
						profile->base_log_dir = switch_core_sprintf(profile->pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val);
					}
				}
			} else if (!strcasecmp(var, "err-log-dir")) {
				if (profile->err_dir_count >= MAX_ERR_DIRS) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum error directories configured!\n");
				} else {

					if (zstr(val)) {
						profile->base_err_log_dir[profile->err_dir_count++] = switch_core_sprintf(profile->pool, "%s%sformat_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
					} else {
						if (switch_is_file_path(val)) {
							profile->base_err_log_dir[profile->err_dir_count++] = switch_core_strdup(profile->pool, val);
						} else {
							profile->base_err_log_dir[profile->err_dir_count++] = switch_core_sprintf(profile->pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val);
						}
					}
					
				}
			} else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) {
				profile->enable_cacert_check = 1;
			} else if (!strcasecmp(var, "ssl-cert-path")) {
				profile->ssl_cert_file = switch_core_strdup(profile->pool, val);
			} else if (!strcasecmp(var, "ssl-key-path")) {
				profile->ssl_key_file = switch_core_strdup(profile->pool, val);
			} else if (!strcasecmp(var, "ssl-key-password")) {
				profile->ssl_key_password = switch_core_strdup(profile->pool, val);
			} else if (!strcasecmp(var, "ssl-version")) {
				profile->ssl_version = switch_core_strdup(profile->pool, val);
			} else if (!strcasecmp(var, "ssl-cacert-file")) {
				profile->ssl_cacert_file = switch_core_strdup(profile->pool, val);
			} else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) {
				profile->enable_ssl_verifyhost = 1;
			} else if (!strcasecmp(var, "auth-scheme")) {
				if (*val == '=') {
					profile->auth_scheme = 0;
					val++;
				}

				if (!strcasecmp(val, "basic")) {
					profile->auth_scheme |= CURLAUTH_BASIC;
				} else if (!strcasecmp(val, "digest")) {
					profile->auth_scheme |= CURLAUTH_DIGEST;
				} else if (!strcasecmp(val, "NTLM")) {
					profile->auth_scheme |= CURLAUTH_NTLM;
				} else if (!strcasecmp(val, "GSS-NEGOTIATE")) {
					profile->auth_scheme |= CURLAUTH_GSSNEGOTIATE;
				} else if (!strcasecmp(val, "any")) {
					profile->auth_scheme = CURLAUTH_ANY;
				}
			} else if (!strcasecmp(var, "encode-values") && !zstr(val)) {
				profile->encode_values = switch_true(val) ? ENCODING_DEFAULT : ENCODING_NONE;
			}
		}
		
		if (!profile->err_dir_count) {
			if (!zstr(profile->base_log_dir)) {
				profile->base_err_log_dir[profile->err_dir_count++] = switch_core_strdup(profile->pool, profile->base_log_dir);
			} else {
				profile->base_err_log_dir[profile->err_dir_count++] = switch_core_sprintf(profile->pool, "%s%sformat_cdr", 
					SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
			}
		}
	}

	if (profile->retries && profile->delay == 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retries set but delay 0 setting to 5 seconds\n");
		profile->delay = 5;
	}

	if ( ! profile->format || (strcasecmp(profile->format,"json") && strcasecmp(profile->format,"xml")) )
	{
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No valid format_cdr format specified, defaulting to xml.\n");
		profile->format = switch_core_strdup(profile->pool,"xml");
	}

	profile->retries++;

	switch_mutex_lock(globals.mutex);
    switch_core_hash_insert(globals.profile_hash, profile->name, profile);
    switch_mutex_unlock(globals.mutex);

	set_format_cdr_log_dirs(profile);

	return SWITCH_STATUS_SUCCESS;
}
예제 #16
0
SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line,
															  switch_file_handle_t *fh,
															  const char *file_path,
															  uint32_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool)
{
	char *ext;
	switch_status_t status = SWITCH_STATUS_FALSE;
	char stream_name[128] = "";
	char *rhs = NULL;
	const char *spool_path = NULL;
	int is_stream = 0;
	char *fp = NULL;
	int to = 0;

	if (switch_test_flag(fh, SWITCH_FILE_OPEN)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Handle already open\n");
		return SWITCH_STATUS_FALSE;
	}

	fh->samples_in = 0;

	if (!fh->samplerate) {
		if (!(fh->samplerate = rate)) {
			fh->samplerate = 8000;
		}
	}

	if (zstr(file_path)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Filename\n");
		return SWITCH_STATUS_FALSE;
	}

	fh->flags = flags;

	if (pool) {
		fh->memory_pool = pool;
	} else {
		if ((status = switch_core_new_memory_pool(&fh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
			UNPROTECT_INTERFACE(fh->file_interface);
			return status;
		}
		switch_set_flag(fh, SWITCH_FILE_FLAG_FREE_POOL);
	}

	if (*file_path == '{') {
		char *timeout;
		char *new_fp;
		fp = switch_core_strdup(fh->memory_pool, file_path);

		if (switch_event_create_brackets(fp, '{', '}', ',', &fh->params, &new_fp, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
			if ((timeout = switch_event_get_header(fh->params, "timeout"))) {
				if ((to = atoi(timeout)) < 1) {
					to = 0;
				}
			}
		} else {
			new_fp = fp;
		}

		file_path = new_fp;
	}

	if (switch_directory_exists(file_path, fh->memory_pool) == SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] is a directory not a file.\n", file_path);
		status = SWITCH_STATUS_GENERR;
		goto fail;
	}

	if ((rhs = strstr(file_path, SWITCH_URL_SEPARATOR))) {
		switch_copy_string(stream_name, file_path, (rhs + 1) - file_path);
		ext = stream_name;
		file_path = rhs + 3;
		fh->file_path = switch_core_strdup(fh->memory_pool, file_path);
		is_stream = 1;
	} else {
		if ((flags & SWITCH_FILE_FLAG_WRITE)) {

			char *p, *e;

			fh->file_path = switch_core_strdup(fh->memory_pool, file_path);
			p = fh->file_path;

			if (*p == '[' && *(p + 1) == *SWITCH_PATH_SEPARATOR) {
				e = switch_find_end_paren(p, '[', ']');

				if (e) {
					*e = '\0';
					spool_path = p + 1;
					fh->file_path = e + 1;
				}
			}

			if (!spool_path) {
				spool_path = switch_core_get_variable_pdup(SWITCH_AUDIO_SPOOL_PATH_VARIABLE, fh->memory_pool);
			}

			file_path = fh->file_path;
		}

		if ((ext = strrchr(file_path, '.')) == 0) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown file Format [%s]\n", file_path);
			switch_goto_status(SWITCH_STATUS_FALSE, fail);
		}
		ext++;
		fh->file_path = switch_core_strdup(fh->memory_pool, file_path);
	}



	if ((fh->file_interface = switch_loadable_module_get_file_interface(ext)) == 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid file format [%s] for [%s]!\n", ext, file_path);
		switch_goto_status(SWITCH_STATUS_GENERR, fail);
	}

	fh->file = file;
	fh->func = func;
	fh->line = line;


	if (spool_path) {
		char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
		switch_uuid_t uuid;
		switch_uuid_get(&uuid);
		switch_uuid_format(uuid_str, &uuid);

		fh->spool_path = switch_core_sprintf(fh->memory_pool, "%s%s%s.%s", spool_path, SWITCH_PATH_SEPARATOR, uuid_str, ext);
	} else {
		fh->spool_path = NULL;
	}

	if (rhs) {
		fh->handler = switch_core_strdup(fh->memory_pool, rhs);
	} else {
		fh->handler = NULL;
	}

	if (channels) {
		fh->channels = channels;
	} else {
		fh->channels = 1;
	}

	file_path = fh->spool_path ? fh->spool_path : fh->file_path;

	if ((status = fh->file_interface->file_open(fh, file_path)) != SWITCH_STATUS_SUCCESS) {
		if (fh->spool_path) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Spool dir is set.  Make sure [%s] is also a valid path\n", fh->spool_path);
		}
		UNPROTECT_INTERFACE(fh->file_interface);
		switch_goto_status(status, fail);
	}

	fh->real_channels = fh->channels;

	if (channels) {
		fh->channels = channels;
	}

	if ((flags & SWITCH_FILE_FLAG_WRITE) && !is_stream && (status = switch_file_exists(file_path, fh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] not created!\n", file_path);
		fh->file_interface->file_close(fh);
		UNPROTECT_INTERFACE(fh->file_interface);
		switch_goto_status(status, fail);
	}

	if (to) {
		fh->max_samples = (fh->samplerate / 1000) * to;
	}


	if ((flags & SWITCH_FILE_FLAG_READ)) {
		fh->native_rate = fh->samplerate;
	} else {
		fh->native_rate = rate;
	}

	if (fh->samplerate && rate && fh->samplerate != rate) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "File %s sample rate %d doesn't match requested rate %d\n", file_path, fh->samplerate, rate);
		if ((flags & SWITCH_FILE_FLAG_READ)) {
			fh->samplerate = rate;
		}
	}

	if (fh->pre_buffer_datalen) {
		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen);
		switch_buffer_create_dynamic(&fh->pre_buffer, fh->pre_buffer_datalen * fh->channels, fh->pre_buffer_datalen * fh->channels, 0);
		fh->pre_buffer_data = switch_core_alloc(fh->memory_pool, fh->pre_buffer_datalen * fh->channels);
	}


	if (fh->real_channels != fh->channels && (flags & SWITCH_FILE_FLAG_READ) && !(fh->flags & SWITCH_FILE_NOMUX)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File has %d channels, muxing to %d channel%s will occur.\n", fh->real_channels, fh->channels, fh->channels == 1 ? "" : "s");
	}

	switch_set_flag(fh, SWITCH_FILE_OPEN);
	return status;

  fail:

	switch_clear_flag(fh, SWITCH_FILE_OPEN);

	if (fh->params) {
		switch_event_destroy(&fh->params);
	}

	fh->samples_in = 0;
	fh->max_samples = 0;
	
	if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
		switch_core_destroy_memory_pool(&fh->memory_pool);
	}

	return status;
}
예제 #17
0
static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, switch_bool_t skipurl, switch_bool_t skipcitystate)
{
	char *number = NULL;
	char *name = NULL;
	char *url_query = NULL;
	cid_data_t *cid = NULL;
	cid_data_t *cidtmp = NULL;
	switch_bool_t save_cache = SWITCH_FALSE;

	cid = switch_core_alloc(pool, sizeof(cid_data_t));
	switch_assert(cid);

	number = string_digitsonly(pool, num);
	switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "caller_id_number", number);

	/* database always wins */
	if (switch_odbc_available() && globals.odbc_dsn && globals.sql) {
		name = do_db_lookup(pool, event, number, globals.sql);
		if (name) {
			cid->name = name;
			cid->src = "phone_database";
			goto done;
		}
	}

	if (globals.cache) {
		cidtmp = check_cache(pool, number);
		if (cidtmp) {
			cid = cidtmp;
			cid->src = switch_core_sprintf(pool, "%s (cache)", cid->src);
			goto done;
		}
	}

	if (!skipurl && globals.whitepages_apikey) {
		cid = do_whitepages_lookup(pool, event, number);
		if (cid && cid->name) {	/* only cache if we have a name */
			save_cache = SWITCH_TRUE;
			goto done;
		}
	}

	if (!skipurl && globals.url) {
		url_query = switch_event_expand_headers(event, globals.url);
		do_lookup_url(pool, event, &name, url_query, NULL, NULL, 0);
		if (name) {
			cid->name = name;
			cid->src = "url";

			save_cache = SWITCH_TRUE;
		}
		if (url_query != globals.url) {
			switch_safe_free(url_query);
		}
	}

  done:
	if (!cid) {
		cid = switch_core_alloc(pool, sizeof(cid_data_t));
		switch_assert(cid);
	}
	/* append area if we can */
	if (!cid->area && !skipcitystate && strlen(number) == 11 && number[0] == '1' && switch_odbc_available() && globals.odbc_dsn && globals.citystate_sql) {

		/* yes, this is really area */
		name = do_db_lookup(pool, event, number, globals.citystate_sql);
		if (name) {
			cid->area = name;
			if (cid->src) {
				cid->src = switch_core_sprintf(pool, "%s,%s", cid->src, "npanxx_database");
			} else {
				cid->src = "npanxx_database";
			}
		}
	}

	if (!cid->area) {
		cid->area = "UNKNOWN";
	}
	if (!cid->name) {
		if (skipcitystate) {
			if (strlen(number) == 11 && number[0] == '1') {
				int a, b, c;
				sscanf(number, "1%3d%3d%4d", &a, &b, &c);
				cid->name = switch_core_sprintf(pool, "%03d-%03d-%04d", a, b, c);
			} else {
				cid->name = number;
			}
		} else {
			cid->name = cid->area;
		}
	}
	if (!cid->src) {
		cid->src = "UNKNOWN";
	}

	if (globals.cache && save_cache) {
		set_cache(pool, number, cid);
	}


	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "cidlookup source: %s\n", cid->src);
	return cid;
}
예제 #18
0
static cid_data_t *do_whitepages_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num)
{
	char *xml_s = NULL;
	char *query = NULL;
	char *name = NULL;
	char *city = NULL;
	char *state = NULL;
	char *area = NULL;
	switch_xml_t xml = NULL;
	switch_xml_t node = NULL;
	cid_data_t *cid = NULL;

	/* NANPA check */
	if (strlen(num) == 11 && num[0] == '1') {
		num++;					/* skip past leading 1 */
	} else {
		goto done;
	}

	switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "whitepages-cid", num);
	switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "whitepages-api-key", globals.whitepages_apikey);

	query = switch_event_expand_headers(event, "http://api.whitepages.com/reverse_phone/1.0/?phone=${whitepages-cid};api_key=${whitepages-api-key}");
	do_lookup_url(pool, event, &xml_s, query, NULL, NULL, 0);
	
	if (zstr(xml_s)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No XML returned for number %s\n", num);
		goto done;
	}
	
	xml = switch_xml_parse_str_dup(xml_s);

	if (!xml) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to parse XML: %s\n", xml_s);
		goto done;
	}

	/* try for bizname first */
	node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:business", 0, "wp:businessname", -1);
	if (node) {
		name = switch_core_strdup(pool, switch_xml_txt(node));
		goto area;
	}

	node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:displayname", -1);
	if (node) {
		name = switch_core_strdup(pool, switch_xml_txt(node));
	}

  area:

	node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:address", 0, "wp:city", -1);
	if (node) {
		city = switch_xml_txt(node);
	}

	node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:address", 0, "wp:state", -1);
	if (node) {
		state = switch_xml_txt(node);
	}

	if (city || state) {
		area = switch_core_sprintf(pool, "%s %s", city ? city : "", state ? state : "");
	}

  done:

	if (query) {
		switch_safe_free(query);
	}
	if (xml) {
		switch_xml_free(xml);
	}
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "whitepages XML: %s\n", xml_s);
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "whitepages name: %s, area: %s\n", name ? name : "(null)", area ? area : "(null)");

	cid = switch_core_alloc(pool, sizeof(cid_data_t));
	switch_assert(cid);

	cid->name = name;
	cid->area = area;
	cid->src = "whitepages";
	return cid;
}
예제 #19
0
/**
 * 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_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid);

			/* 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) {
				char *cmd = switch_core_sprintf(RAYO_POOL(component), "%s %s", RECEIVEFAX_COMPONENT(component)->filename, RECEIVEFAX_COMPONENT(component)->local_filename);
				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", cmd, NULL, &stream);
				/* check if successful */
				if (!zstr(stream.data) && strncmp(stream.data, "+OK", 3)) {
					/* PUT failed */
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s PUT fax %s to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->local_filename, 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(component->parent), 0);

			rayo_component_send_complete_event(RAYO_COMPONENT(component), result);

			RAYO_RELEASE(component);
		}
	}
}
예제 #20
0
SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memory_pool_t **pool, const char *file, const char *func, int line)
{
	char *tmp;
#ifdef INSTANTLY_DESTROY_POOLS
	apr_pool_create(pool, NULL);
	switch_assert(*pool != NULL);
#else

#ifdef PER_POOL_LOCK
	apr_allocator_t *my_allocator = NULL;
	apr_thread_mutex_t *my_mutex;
#else
	void *pop = NULL;
#endif

#ifdef USE_MEM_LOCK
	switch_mutex_lock(memory_manager.mem_lock);
#endif
	switch_assert(pool != NULL);

#ifndef PER_POOL_LOCK
	if (switch_queue_trypop(memory_manager.pool_recycle_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
		*pool = (switch_memory_pool_t *) pop;
	} else {
#endif

#ifdef PER_POOL_LOCK
		if ((apr_allocator_create(&my_allocator)) != APR_SUCCESS) {
			abort();
		}

		if ((apr_pool_create_ex(pool, NULL, NULL, my_allocator)) != APR_SUCCESS) {
			abort();
		}

		if ((apr_thread_mutex_create(&my_mutex, APR_THREAD_MUTEX_NESTED, *pool)) != APR_SUCCESS) {
			abort();
		}

		apr_allocator_mutex_set(my_allocator, my_mutex);
		apr_allocator_owner_set(my_allocator, *pool);

		apr_pool_mutex_set(*pool, my_mutex);

#else
		apr_pool_create(pool, NULL);
		switch_assert(*pool != NULL);
	}
#endif
#endif

	tmp = switch_core_sprintf(*pool, "%s:%d", file, line);
	apr_pool_tag(*pool, tmp);

#ifdef DEBUG_ALLOC2
	switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p New Pool %s\n", (void *) *pool, apr_pool_tag(*pool, NULL));
#endif


#ifdef USE_MEM_LOCK
	switch_mutex_unlock(memory_manager.mem_lock);
#endif

	return SWITCH_STATUS_SUCCESS;
}
예제 #21
0
/**
 * Start execution of call receivefax component
 * @param call the call to receive fax from
 * @param msg the original request
 * @param session_data the call's session
 */
static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data)
{
	iks *iq = msg->payload;
	switch_core_session_t *session = (switch_core_session_t *)session_data;
	struct receivefax_component *receivefax_component = NULL;
	iks *receivefax = iks_find(iq, "receivefax");
	iks *response = NULL;
	switch_event_t *execute_event = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_memory_pool_t *pool;
	int file_no;

	/* validate attributes */
	if (!VALIDATE_RAYO_RECEIVEFAX(receivefax)) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	/* fax is only allowed if the call is not currently joined */
	if (rayo_call_is_joined(RAYO_CALL(call))) {
		return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't receive fax on a joined call");
	}

	if (rayo_call_is_faxing(RAYO_CALL(call))) {
		return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress");
	}

	/* create receivefax component */
	switch_core_new_memory_pool(&pool);
	receivefax_component = switch_core_alloc(pool, sizeof(*receivefax_component));
	rayo_component_init((struct rayo_component *)receivefax_component, pool, RAT_CALL_COMPONENT, "receivefax", NULL, call, iks_find_attrib(iq, "from"));
	file_no = rayo_actor_seq_next(call);
	receivefax_component->filename = switch_core_sprintf(pool, "%s%s%s-%d.tif",
		globals.file_prefix, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no);
	if (!strncmp(receivefax_component->filename, "http://", 7) || !strncmp(receivefax_component->filename, "https://", 8)) {
		/* This is an HTTP URL, need to PUT after fax is received */
		receivefax_component->local_filename = switch_core_sprintf(pool, "%s%s%s-%d",
			SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no);
		receivefax_component->http_put_after_receive = 1;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to HTTP URL\n", RAYO_JID(receivefax_component));
	} else {
		/* assume file.. */
		receivefax_component->local_filename = receivefax_component->filename;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to local file\n", RAYO_JID(receivefax_component));
	}

	/* add channel variable so that fax component can be located from fax events */
	switch_channel_set_variable(channel, "rayo_fax_jid", RAYO_JID(receivefax_component));

	/* clear fax result variables */
	switch_channel_set_variable(channel, "fax_success", NULL);
	switch_channel_set_variable(channel, "fax_result_code", NULL);
	switch_channel_set_variable(channel, "fax_result_text", NULL);
	switch_channel_set_variable(channel, "fax_document_transferred_pages", NULL);
	switch_channel_set_variable(channel, "fax_document_total_pages", NULL);
	switch_channel_set_variable(channel, "fax_image_resolution", NULL);
	switch_channel_set_variable(channel, "fax_image_size", NULL);
	switch_channel_set_variable(channel, "fax_bad_rows", NULL);
	switch_channel_set_variable(channel, "fax_transfer_rate", NULL);
	switch_channel_set_variable(channel, "fax_ecm_used", NULL);
	switch_channel_set_variable(channel, "fax_local_station_id", NULL);
	switch_channel_set_variable(channel, "fax_remote_station_id", NULL);

	/* clear fax interrupt variable */
	switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL);

	rayo_call_set_faxing(RAYO_CALL(call), 1);

	/* execute rxfax APP */
	if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
		switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute");
		switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "rxfax");
		switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", receivefax_component->local_filename);
		if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) {
			switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA);
		}

		if (switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
			response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to rxfax (queue event failed)");
			if (execute_event) {
				switch_event_destroy(&execute_event);
			}
			rayo_call_set_faxing(RAYO_CALL(call), 0);
			RAYO_UNLOCK(receivefax_component);
		} else {
			/* component starting... */
			rayo_component_send_start(RAYO_COMPONENT(receivefax_component), iq);
		}
	} else {
		response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create rxfax event");
		rayo_call_set_faxing(RAYO_CALL(call), 0);
		RAYO_UNLOCK(receivefax_component);
	}

	return response;
}
예제 #22
0
static switch_status_t webm_file_open(switch_file_handle_t *handle, const char *path)
{
	webm_file_context_t *context;
	char *ext;
	unsigned int flags = 0;
	const char *tmp = NULL;
	char *fmtp;

	if ((ext = strrchr((char *)path, '.')) == 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n");
		return SWITCH_STATUS_GENERR;
	}
	ext++;

	if ((context = (webm_file_context_t *)switch_core_alloc(handle->memory_pool, sizeof(webm_file_context_t))) == 0) {
		return SWITCH_STATUS_MEMERR;
	}

	memset(context, 0, sizeof(webm_file_context_t));

	context->offset = -100;
	if (handle->params && (tmp = switch_event_get_header(handle->params, "webmv2_video_offset"))) {
		context->offset = atoi(tmp);
	}

	switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
	switch_core_timer_init(&context->timer, "soft", 1, 1000, context->pool);
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n");

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		flags |= SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE;
		if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(handle, SWITCH_FILE_WRITE_OVER)) {
			flags |= SWITCH_FOPEN_READ;
		} else {
			flags |= SWITCH_FOPEN_TRUNCATE;
		}
	}

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) {
		flags |= SWITCH_FOPEN_READ;
	}

	context->writer = new mkvmuxer::MkvWriter();

	if (!context->writer->Open(path)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening file %s\n", path);
		return SWITCH_STATUS_GENERR;
	}

	context->segment = new mkvmuxer::Segment();

	if (!context->segment || !context->segment->Init(context->writer)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error init segment\n");
		return SWITCH_STATUS_GENERR;
	}

	// context->segment.set_mode(mkvmuxer::Segment::kLive);
	context->segment->set_mode(mkvmuxer::Segment::kFile);
	context->segment->OutputCues(true);

	mkvmuxer::SegmentInfo* const info = context->segment->GetSegmentInfo();
	info->set_timecode_scale(1000000);
	info->set_muxing_app("FreeSWITCH");
	info->set_writing_app(switch_version_full());

	context->audio_track_id = context->segment->AddAudioTrack(handle->samplerate, handle->channels, 0);
	if (!context->audio_track_id) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error add audio track!\n");
		goto end;
	}
	context->audio = static_cast<mkvmuxer::AudioTrack*>(context->segment->GetTrackByNumber(context->audio_track_id));
	context->audio->set_codec_id("A_" AUDIO_CODEC);
	switch_buffer_create_dynamic(&context->audio_buffer, 512, 512, 0);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sample rate: %d, channels: %d\n", handle->samplerate, handle->channels);

	handle->format = 0;
	handle->sections = 0;
	handle->seekable = 0;
	handle->speed = 0;
	handle->pos = 0;
	handle->private_info = context;
	context->pool = handle->memory_pool;
	// handle->flags |= SWITCH_FILE_NATIVE;

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n",
		path, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : "");

	fmtp = switch_core_sprintf(context->pool,
							   "useinbandfec=1;minptime=20;ptime=20;samplerate=%d%s", handle->samplerate, handle->channels == 2 ? ",stereo=1" : "");

	if (switch_core_codec_init(&context->audio_codec,
							   AUDIO_CODEC,
							   NULL,
							   fmtp,
							   handle->samplerate,
							   20,//ms
							   handle->channels, SWITCH_CODEC_FLAG_ENCODE,
							   NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n");
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n");
		goto end;
	}

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) {
		if (switch_core_codec_init(&context->video_codec,
							   "VP8",
							   NULL,
							   NULL,
							   90000,
							   0,//ms
							   1, SWITCH_CODEC_FLAG_ENCODE,
							   NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Codec H264 Activation Success\n");
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video Codec H264 Activation Fail\n");
			goto end;
		}
	}

	if (!strcmp(AUDIO_CODEC, "VORBIS")) {
		uint16_t size = 0;
		uint8_t *codec_private_data = NULL;
		switch_core_codec_control(&context->audio_codec, SCC_GET_CODEC_PRIVATE, SCCT_INT, (void *)&size, NULL, (void **)&codec_private_data);
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "======codec_private_data size: %d data: %p\n", size, codec_private_data);
		context->audio->SetCodecPrivate(codec_private_data, size);
	}

	if (1) { // for better quality?
		int bw = 4096;
		switch_core_codec_control(&context->video_codec, SCC_VIDEO_BANDWIDTH, SCCT_INT, (void *)&bw, NULL, NULL);
	}

	switch_buffer_create_dynamic(&context->buf, 512, 512, 1024000);

	return SWITCH_STATUS_SUCCESS;

end:

	if (context->segment) delete context->segment;
	if (context->writer) delete context->writer;

	return SWITCH_STATUS_GENERR;
}
static switch_status_t load_config(switch_memory_pool_t *pool)
{
	char *cf = "cdr_csv.conf";
	switch_xml_t cfg, xml, settings, param;
	switch_status_t status = SWITCH_STATUS_SUCCESS;

	memset(&globals, 0, sizeof(globals));
	switch_core_hash_init(&globals.fd_hash, pool);
	switch_core_hash_init(&globals.template_hash, pool);

	globals.pool = pool;

	switch_core_hash_insert(globals.template_hash, "default", default_template);
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n");
	globals.legs = CDR_LEG_A;

	if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {

		if ((settings = switch_xml_child(cfg, "settings"))) {
			for (param = switch_xml_child(settings, "param"); param; param = param->next) {
				char *var = (char *) switch_xml_attr_soft(param, "name");
				char *val = (char *) switch_xml_attr_soft(param, "value");
				if (!strcasecmp(var, "debug")) {
					globals.debug = switch_true(val);
				} else if (!strcasecmp(var, "legs")) {
					globals.legs = 0;

					if (strchr(val, 'a')) {
						globals.legs |= CDR_LEG_A;
					}

					if (strchr(val, 'b')) {
						globals.legs |= CDR_LEG_B;
					}
				} else if (!strcasecmp(var, "log-base")) {
					globals.log_dir = switch_core_sprintf(pool, "%s%scdr-csv", val, SWITCH_PATH_SEPARATOR);
				} else if (!strcasecmp(var, "rotate-on-hup")) {
					globals.rotate = switch_true(val);
				} else if (!strcasecmp(var, "default-template")) {
					globals.default_template = switch_core_strdup(pool, val);
				} else if (!strcasecmp(var, "master-file-only")) {
					globals.masterfileonly = switch_true(val);
				}
			}
		}

		if ((settings = switch_xml_child(cfg, "templates"))) {
			for (param = switch_xml_child(settings, "template"); param; param = param->next) {
				char *var = (char *) switch_xml_attr(param, "name");
				if (var) {
					char *tpl;
					size_t len = strlen(param->txt) + 2;
					if (end_of(param->txt) != '\n') {
						tpl = switch_core_alloc(pool, len);
						switch_snprintf(tpl, len, "%s\n", param->txt);
					} else {
						tpl = switch_core_strdup(pool, param->txt);
					}

					switch_core_hash_insert(globals.template_hash, var, tpl);
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var);
				}
			}
		}
		switch_xml_free(xml);
	}


	if (zstr(globals.default_template)) {
		globals.default_template = switch_core_strdup(pool, "default");
	}

	if (!globals.log_dir) {
		globals.log_dir = switch_core_sprintf(pool, "%s%scdr-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
	}

	return status;
}
예제 #24
0
static switch_status_t switch_silk_init(switch_codec_t *codec,
                                        switch_codec_flag_t freeswitch_flags,
                                        const switch_codec_settings_t *codec_settings)
{
    struct silk_context *context = NULL;
    SKP_int useinbandfec = 0, usedtx = 0, maxaveragebitrate = 0, plpct =0;
    SKP_int32 encSizeBytes;
    SKP_int32 decSizeBytes;
    int encoding = (freeswitch_flags & SWITCH_CODEC_FLAG_ENCODE);
    int decoding = (freeswitch_flags & SWITCH_CODEC_FLAG_DECODE);

    if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
        return SWITCH_STATUS_FALSE;
    }

    if (codec->fmtp_in) {
        int x, argc;
        char *argv[10];
        argc = switch_separate_string(codec->fmtp_in, ';', 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, '='))) {
                *arg++ = '\0';
                if (!strcasecmp(data, "useinbandfec")) {
                    if (switch_true(arg)) {
                        useinbandfec = 1;
                        plpct = 10;// 10% for now
                    }
                }
                if (!strcasecmp(data, "usedtx")) {
                    if (switch_true(arg)) {
                        usedtx = 1;
                    }
                }
                if (!strcasecmp(data, "maxaveragebitrate")) {
                    maxaveragebitrate = atoi(arg);
                    switch(codec->implementation->actual_samples_per_second) {
                    case 8000:
                    {
                        if(maxaveragebitrate < 6000 || maxaveragebitrate > 20000) {
                            maxaveragebitrate = 20000;
                        }
                        break;
                    }
                    case 12000:
                    {
                        if(maxaveragebitrate < 7000 || maxaveragebitrate > 25000) {
                            maxaveragebitrate = 25000;
                        }
                        break;
                    }
                    case 16000:
                    {
                        if(maxaveragebitrate < 8000 || maxaveragebitrate > 30000) {
                            maxaveragebitrate = 30000;
                        }
                        break;
                    }
                    case 24000:
                    {
                        if(maxaveragebitrate < 12000 || maxaveragebitrate > 40000) {
                            maxaveragebitrate = 40000;
                        }
                        break;
                    }

                    default:
                        /* this should never happen but 20000 is common among all rates */
                        maxaveragebitrate = 20000;
                        break;
                    }

                }
            }
        }
    }

    codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "useinbandfec=%s; usedtx=%s; maxaveragebitrate=%d",
                                          useinbandfec ? "true" : "false",
                                          usedtx ? "true" : "false",
                                          maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second);

    if (encoding) {
        if (SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes)) {
            return SWITCH_STATUS_FALSE;
        }

        context->enc_state = switch_core_alloc(codec->memory_pool, encSizeBytes);

        if (SKP_Silk_SDK_InitEncoder(context->enc_state, &context->encoder_object)) {
            return SWITCH_STATUS_FALSE;
        }

        context->encoder_object.sampleRate = codec->implementation->actual_samples_per_second;
        context->encoder_object.packetSize = codec->implementation->samples_per_packet;
        context->encoder_object.useInBandFEC = useinbandfec;
        context->encoder_object.complexity = 2;
        context->encoder_object.bitRate = maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second;
        context->encoder_object.useDTX = usedtx;
        context->encoder_object.packetLossPercentage = plpct;;
    }

    if (decoding) {
        if (SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes)) {
            return SWITCH_STATUS_FALSE;
        }
        context->dec_state = switch_core_alloc(codec->memory_pool, decSizeBytes);

        if (SKP_Silk_SDK_InitDecoder(context->dec_state)) {
            return SWITCH_STATUS_FALSE;
        }
        context->decoder_object.sampleRate = codec->implementation->actual_samples_per_second;
    }

    codec->private_info = context;

    return SWITCH_STATUS_SUCCESS;
}
예제 #25
0
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	cJSON *json_cdr = NULL;
	char *json_text = NULL;
	char *path = NULL;
	char *curl_json_text = NULL;
	const char *logdir = NULL;
	char *json_text_escaped = NULL;
	int fd = -1, err_dir_index;
	uint32_t cur_try;
	long httpRes;
	CURL *curl_handle = NULL;
	switch_curl_slist_t *headers = NULL;
	switch_curl_slist_t *slist = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_status_t status = SWITCH_STATUS_FALSE;
	int is_b;
	const char *a_prefix = "";

	if (globals.shutdown) {
		return SWITCH_STATUS_SUCCESS;
	}

	is_b = channel && switch_channel_get_originator_caller_profile(channel);
	if (!globals.log_b && is_b) {
		const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE);
		if (!switch_true(force_cdr)) {
			return SWITCH_STATUS_SUCCESS;
		}
	}
	if (!is_b && globals.prefix_a)
		a_prefix = "a_";


	if (switch_ivr_generate_json_cdr(session, &json_cdr, globals.encode_values == ENCODING_DEFAULT) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Generating Data!\n");
		return SWITCH_STATUS_FALSE;
	}
	
	json_text = cJSON_PrintUnformatted(json_cdr);

	if (!json_text) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
		goto error;
	}

	switch_thread_rwlock_rdlock(globals.log_path_lock);

	if (!(logdir = switch_channel_get_variable(channel, "json_cdr_base"))) {
		logdir = globals.log_dir;
	}

	if (!zstr(logdir) && (globals.log_http_and_disk || !globals.url_count)) {
		path = switch_mprintf("%s%s%s%s.cdr.json", logdir, SWITCH_PATH_SEPARATOR, a_prefix, switch_core_session_get_uuid(session));
		switch_thread_rwlock_unlock(globals.log_path_lock);
		if (path) {
#ifdef _MSC_VER
			if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
#else
			if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) {
#endif
				int wrote;
				wrote = write(fd, json_text, (unsigned) strlen(json_text));
				close(fd);
				fd = -1;
				if(wrote < 0) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s]\n",path);
				}
			} else {
				char ebuf[512] = { 0 };
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n",
						path, switch_strerror_r(errno, ebuf, sizeof(ebuf)));
			}
			switch_safe_free(path);
		}
	} else {
		switch_thread_rwlock_unlock(globals.log_path_lock);
	}

	/* try to post it to the web server */
	if (globals.url_count) {
		char *destUrl = NULL;
		curl_handle = switch_curl_easy_init();

		if (globals.encode) {
			switch_size_t need_bytes = strlen(json_text) * 3;

			json_text_escaped = malloc(need_bytes);
			switch_assert(json_text_escaped);
			memset(json_text_escaped, 0, need_bytes);
			if (globals.encode == ENCODING_DEFAULT) {
				headers = switch_curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
				switch_url_encode(json_text, json_text_escaped, need_bytes);
			} else {
				headers = switch_curl_slist_append(headers, "Content-Type: application/x-www-form-base64-encoded");
				switch_b64_encode((unsigned char *) json_text, need_bytes / 3, (unsigned char *) json_text_escaped, need_bytes);
			}

			switch_safe_free(json_text);
			json_text = json_text_escaped;

			if (!(curl_json_text = switch_mprintf("cdr=%s", json_text))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
				goto error;
			}

		} else {
			headers = switch_curl_slist_append(headers, "Content-Type: application/json");
			curl_json_text = (char *)json_text;
		}


		if (!zstr(globals.cred)) {
			switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, globals.auth_scheme);
			switch_curl_easy_setopt(curl_handle, CURLOPT_USERPWD, globals.cred);
		}

		switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
		switch_curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
		switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
		switch_curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, curl_json_text);
		switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-json/1.0");
		switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, httpCallBack);

		if (globals.disable100continue) {
			slist = switch_curl_slist_append(slist, "Expect:");
			switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist);
		}

		if (globals.ssl_cert_file) {
			switch_curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, globals.ssl_cert_file);
		}

		if (globals.ssl_key_file) {
			switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, globals.ssl_key_file);
		}

		if (globals.ssl_key_password) {
			switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEYPASSWD, globals.ssl_key_password);
		}

		if (globals.ssl_version) {
			if (!strcasecmp(globals.ssl_version, "SSLv3")) {
				switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
			} else if (!strcasecmp(globals.ssl_version, "TLSv1")) {
				switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
			}
		}

		if (globals.ssl_cacert_file) {
			switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, globals.ssl_cacert_file);
		}

		/* these were used for testing, optionally they may be enabled if someone desires
		   switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120); // tcp timeout
		   switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); // 302 recursion level
		 */

		for (cur_try = 0; cur_try < globals.retries; cur_try++) {
			if (cur_try > 0) {
				switch_yield(globals.delay * 1000000);
			}

			destUrl = switch_mprintf("%s?uuid=%s", globals.urls[globals.url_index], switch_core_session_get_uuid(session));
			switch_curl_easy_setopt(curl_handle, CURLOPT_URL, destUrl);

			if (!strncasecmp(destUrl, "https", 5)) {
				switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
				switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
			}

			if (globals.enable_cacert_check) {
				switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, TRUE);
			}

			if (globals.enable_ssl_verifyhost) {
				switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
			}

			switch_curl_easy_perform(curl_handle);
			switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
			switch_safe_free(destUrl);
			if (httpRes >= 200 && httpRes < 300) {
				goto success;
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Got error [%ld] posting to web server [%s]\n",
								  httpRes, globals.urls[globals.url_index]);
				globals.url_index++;
				switch_assert(globals.url_count <= MAX_URLS);
				if (globals.url_index >= globals.url_count) {
					globals.url_index = 0;
				}
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retry will be with url [%s]\n", globals.urls[globals.url_index]);
			}
		}
		switch_curl_easy_cleanup(curl_handle);
		switch_curl_slist_free_all(headers);
		switch_curl_slist_free_all(slist);
		slist = NULL;
		headers = NULL;
		curl_handle = NULL;

		/* if we are here the web post failed for some reason */
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n");

		for (err_dir_index = 0; err_dir_index < globals.err_dir_count; err_dir_index++) {
			switch_thread_rwlock_rdlock(globals.log_path_lock);
			path = switch_mprintf("%s%s%s%s.cdr.json", globals.err_log_dir[err_dir_index], SWITCH_PATH_SEPARATOR, a_prefix, switch_core_session_get_uuid(session));
			switch_thread_rwlock_unlock(globals.log_path_lock);
			if (path) {
#ifdef _MSC_VER
				if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
#else
				if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) {
#endif
					int wrote;
					wrote = write(fd, json_text, (unsigned) strlen(json_text));
					close(fd);
					fd = -1;
					if(wrote < 0) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s]\n",path);
					}
					break;
				} else {
					char ebuf[512] = { 0 };
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s! [%s]\n",
							path, switch_strerror_r(errno, ebuf, sizeof(ebuf)));

				}

				switch_safe_free(path);
			}
		}	
	}
  success:
	status = SWITCH_STATUS_SUCCESS;

  error:
	if (curl_handle) {
		switch_curl_easy_cleanup(curl_handle);
	}
	if (headers) {
		switch_curl_slist_free_all(headers);
	}
	if (slist) {
		switch_curl_slist_free_all(slist);
	}
	if (curl_json_text != json_text) {
		switch_safe_free(curl_json_text);
	}
	
	cJSON_Delete(json_cdr);
	switch_safe_free(json_text);

	return status;
}

static void event_handler(switch_event_t *event)
{
	const char *sig = switch_event_get_header(event, "Trapped-Signal");

	if (sig && !strcmp(sig, "HUP")) {
		if (globals.rotate) {
			set_json_cdr_log_dirs();
		}
	}
}

static switch_state_handler_table_t state_handlers = {
	/*.on_init */ NULL,
	/*.on_routing */ NULL,
	/*.on_execute */ NULL,
	/*.on_hangup */ NULL,
	/*.on_exchange_media */ NULL,
	/*.on_soft_execute */ NULL,
	/*.on_consume_media */ NULL,
	/*.on_hibernate */ NULL,
	/*.on_reset */ NULL,
	/*.on_park */ NULL,
	/*.on_reporting */ my_on_reporting
};

SWITCH_MODULE_LOAD_FUNCTION(mod_json_cdr_load)
{
	char *cf = "json_cdr.conf";
	switch_xml_t cfg, xml, settings, param;
	switch_status_t status = SWITCH_STATUS_SUCCESS;

	/* test global state handlers */
	switch_core_add_state_handler(&state_handlers);

	*module_interface = switch_loadable_module_create_module_interface(pool, modname);

	memset(&globals, 0, sizeof(globals));

	if (switch_event_bind_removable(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
		return SWITCH_STATUS_GENERR;
	}

	globals.log_http_and_disk = 0;
	globals.log_b = 1;
	globals.disable100continue = 0;
	globals.pool = pool;
	globals.auth_scheme = CURLAUTH_BASIC;
	globals.encode_values = ENCODING_DEFAULT;

	switch_thread_rwlock_create(&globals.log_path_lock, pool);

	/* parse the config */
	if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
		return SWITCH_STATUS_TERM;
	}

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

			if (!strcasecmp(var, "cred") && !zstr(val)) {
				globals.cred = switch_core_strdup(globals.pool, val);
			} else if (!strcasecmp(var, "url") && !zstr(val)) {
				if (globals.url_count >= MAX_URLS) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum urls configured!\n");
				} else {
					globals.urls[globals.url_count++] = switch_core_strdup(globals.pool, val);
				}
			} else if (!strcasecmp(var, "log-http-and-disk")) {
				globals.log_http_and_disk = switch_true(val);
			} else if (!strcasecmp(var, "delay") && !zstr(val)) {
				globals.delay = (uint32_t) atoi(val);
			} else if (!strcasecmp(var, "log-b-leg")) {
				globals.log_b = switch_true(val);
			} else if (!strcasecmp(var, "prefix-a-leg")) {
				globals.prefix_a = switch_true(val);
			} else if (!strcasecmp(var, "disable-100-continue") && switch_true(val)) {
				globals.disable100continue = 1;
			} else if (!strcasecmp(var, "encode") && !zstr(val)) {
				if (!strcasecmp(val, "base64")) {
					globals.encode = ENCODING_BASE64;
				} else {
					globals.encode = switch_true(val) ? ENCODING_DEFAULT : ENCODING_NONE;
				}
			} else if (!strcasecmp(var, "retries") && !zstr(val)) {
				globals.retries = (uint32_t) atoi(val);
			} else if (!strcasecmp(var, "rotate") && !zstr(val)) {
				globals.rotate = switch_true(val);
			} else if (!strcasecmp(var, "log-dir")) {
				if (zstr(val)) {
					globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
				} else {
					if (switch_is_file_path(val)) {
						globals.base_log_dir = switch_core_strdup(globals.pool, val);
					} else {
						globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val);
					}
				}
			} else if (!strcasecmp(var, "err-log-dir")) {
				if (globals.err_dir_count >= MAX_ERR_DIRS) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum error directories configured!\n");
				} else {

					if (zstr(val)) {
						globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
					} else {
						if (switch_is_file_path(val)) {
							globals.base_err_log_dir[globals.err_dir_count++] = switch_core_strdup(globals.pool, val);
						} else {
							globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val);
						}
					}
					
				}
			} else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) {
				globals.enable_cacert_check = 1;
			} else if (!strcasecmp(var, "ssl-cert-path")) {
				globals.ssl_cert_file = switch_core_strdup(globals.pool, val);
			} else if (!strcasecmp(var, "ssl-key-path")) {
				globals.ssl_key_file = switch_core_strdup(globals.pool, val);
			} else if (!strcasecmp(var, "ssl-key-password")) {
				globals.ssl_key_password = switch_core_strdup(globals.pool, val);
			} else if (!strcasecmp(var, "ssl-version")) {
				globals.ssl_version = switch_core_strdup(globals.pool, val);
			} else if (!strcasecmp(var, "ssl-cacert-file")) {
				globals.ssl_cacert_file = switch_core_strdup(globals.pool, val);
			} else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) {
				globals.enable_ssl_verifyhost = 1;
			} else if (!strcasecmp(var, "auth-scheme")) {
				if (*val == '=') {
					globals.auth_scheme = 0;
					val++;
				}

				if (!strcasecmp(val, "basic")) {
					globals.auth_scheme |= CURLAUTH_BASIC;
				} else if (!strcasecmp(val, "digest")) {
					globals.auth_scheme |= CURLAUTH_DIGEST;
				} else if (!strcasecmp(val, "NTLM")) {
					globals.auth_scheme |= CURLAUTH_NTLM;
				} else if (!strcasecmp(val, "GSS-NEGOTIATE")) {
					globals.auth_scheme |= CURLAUTH_GSSNEGOTIATE;
				} else if (!strcasecmp(val, "any")) {
					globals.auth_scheme = CURLAUTH_ANY;
				}
			} else if (!strcasecmp(var, "encode-values") && !zstr(val)) {
				globals.encode_values = switch_true(val) ? ENCODING_DEFAULT : ENCODING_NONE;
			}

		}

		if (!globals.err_dir_count) {
			if (!zstr(globals.base_log_dir)) {
				globals.base_err_log_dir[globals.err_dir_count++] = switch_core_strdup(globals.pool, globals.base_log_dir);
			} else {
				globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
			}
		}
	}

	if (globals.retries && !globals.delay) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retries set but delay 0 setting to 5 seconds\n");
		globals.delay = 5;
	}

	globals.retries++;

	set_json_cdr_log_dirs();

	switch_xml_free(xml);
	return status;
}

SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_json_cdr_shutdown)
{
	int err_dir_index = 0;

	globals.shutdown = 1;

	switch_safe_free(globals.log_dir);
	
	for (;err_dir_index < globals.err_dir_count; err_dir_index++) {
		switch_safe_free(globals.err_log_dir[err_dir_index]);
	}

	switch_event_unbind(&globals.node);
	switch_core_remove_state_handler(&state_handlers);

	switch_thread_rwlock_destroy(globals.log_path_lock);

	return SWITCH_STATUS_SUCCESS;
}
예제 #26
0
static switch_status_t switch_silk_init(switch_codec_t *codec, 
										switch_codec_flag_t freeswitch_flags, 
										const switch_codec_settings_t *codec_settings)
{
	struct silk_context *context = NULL;
	switch_codec_fmtp_t codec_fmtp;
	silk_codec_settings_t silk_codec_settings;
	SKP_int32 encSizeBytes;
	SKP_int32 decSizeBytes;
	int encoding = (freeswitch_flags & SWITCH_CODEC_FLAG_ENCODE);
	int decoding = (freeswitch_flags & SWITCH_CODEC_FLAG_DECODE);

	if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
		return SWITCH_STATUS_FALSE;
	}

	memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
	codec_fmtp.private_info = &silk_codec_settings;
	switch_silk_fmtp_parse(codec->fmtp_in, &codec_fmtp);
	
	codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "useinbandfec=%s; usedtx=%s; maxaveragebitrate=%d",
										  silk_codec_settings.useinbandfec ? "1" : "0",
										  silk_codec_settings.usedtx ? "1" : "0",
										  silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second);

	if (encoding) {
		if (SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes)) {
			return SWITCH_STATUS_FALSE;
		}
		
		context->enc_state = switch_core_alloc(codec->memory_pool, encSizeBytes);

		if (SKP_Silk_SDK_InitEncoder(context->enc_state, &context->encoder_object)) {
			return SWITCH_STATUS_FALSE;
		}
		

		context->encoder_object.API_sampleRate = codec->implementation->actual_samples_per_second;
		context->encoder_object.maxInternalSampleRate = codec->implementation->actual_samples_per_second;
		context->encoder_object.packetSize = codec->implementation->samples_per_packet;
		context->encoder_object.useInBandFEC = silk_codec_settings.useinbandfec;
		context->encoder_object.complexity = 0;
		context->encoder_object.bitRate = silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second;
		context->encoder_object.useDTX = silk_codec_settings.usedtx;
		context->encoder_object.packetLossPercentage = silk_codec_settings.plpct;
	}

	if (decoding) {
		if (SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes)) {
			return SWITCH_STATUS_FALSE;
		}
		context->dec_state = switch_core_alloc(codec->memory_pool, decSizeBytes);

		if (SKP_Silk_SDK_InitDecoder(context->dec_state)) {
			return SWITCH_STATUS_FALSE;
		}
		context->decoder_object.API_sampleRate = codec->implementation->actual_samples_per_second;
	}

	codec->private_info = context;

	return SWITCH_STATUS_SUCCESS;
}
예제 #27
0
SWITCH_DECLARE(const char *) switch_caller_get_field_by_name(switch_caller_profile_t *caller_profile, const char *name)
{
	if (!strcasecmp(name, "dialplan")) {
		return caller_profile->dialplan;
	}
	if (!strcasecmp(name, "username")) {
		return caller_profile->username;
	}
	if (!strcasecmp(name, "caller_id_name")) {
		return caller_profile->caller_id_name;
	}
	if (!strcasecmp(name, "caller_id_number")) {
		return caller_profile->caller_id_number;
	}
	if (!strcasecmp(name, "orig_caller_id_name")) {
		return caller_profile->orig_caller_id_name;
	}
	if (!strcasecmp(name, "orig_caller_id_number")) {
		return caller_profile->orig_caller_id_number;
	}
	if (!strcasecmp(name, "callee_id_name")) {
		return caller_profile->callee_id_name;
	}
	if (!strcasecmp(name, "callee_id_number")) {
		return caller_profile->callee_id_number;
	}
	if (!strcasecmp(name, "ani")) {
		return caller_profile->ani;
	}
	if (!strcasecmp(name, "aniii")) {
		return caller_profile->aniii;
	}
	if (!strcasecmp(name, "network_addr")) {
		return caller_profile->network_addr;
	}
	if (!strcasecmp(name, "rdnis")) {
		return caller_profile->rdnis;
	}
	if (!strcasecmp(name, "destination_number")) {
		return caller_profile->destination_number;
	}
	if (!strcasecmp(name, "uuid")) {
		return caller_profile->uuid;
	}
	if (!strcasecmp(name, "source")) {
		return caller_profile->source;
	}
	if (!strcasecmp(name, "transfer_source")) {
		return caller_profile->transfer_source;
	}
	if (!strcasecmp(name, "context")) {
		return caller_profile->context;
	}

	if (!strcasecmp(name, "chan_name")) {
		return caller_profile->chan_name;
	}

	if (!strcasecmp(name, "profile_index")) {
		return caller_profile->profile_index;
	}

	if (!strcasecmp(name, "caller_ton")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->caller_ton);
	}
	if (!strcasecmp(name, "caller_numplan")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->caller_numplan);
	}
	if (!strcasecmp(name, "destination_number_ton")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->destination_number_ton);
	}
	if (!strcasecmp(name, "destination_number_numplan")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->destination_number_numplan);
	}
	if (!strcasecmp(name, "ani_ton")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->ani_ton);
	}
	if (!strcasecmp(name, "ani_numplan")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->ani_numplan);
	}
	if (!strcasecmp(name, "rdnis_ton")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->rdnis_ton);
	}
	if (!strcasecmp(name, "rdnis_numplan")) {
		return switch_core_sprintf(caller_profile->pool, "%u", caller_profile->rdnis_numplan);
	}
	if (!strcasecmp(name, "screen_bit")) {
		return switch_test_flag(caller_profile, SWITCH_CPF_SCREEN) ? "true" : "false";
	}
	if (!strcasecmp(name, "privacy_hide_name")) {
		return switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NAME) ? "true" : "false";
	}
	if (!strcasecmp(name, "privacy_hide_number")) {
		return switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER) ? "true" : "false";
	}
	if (!strcasecmp(name, "profile_created_time")) {
		return switch_core_sprintf(caller_profile->pool, "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created);
	}
	if (!strcasecmp(name, "created_time")) {
		return switch_core_sprintf(caller_profile->pool, "%" SWITCH_TIME_T_FMT, caller_profile->times->created);
	}
	if (!strcasecmp(name, "answered_time")) {
		return switch_core_sprintf(caller_profile->pool, "%" SWITCH_TIME_T_FMT, caller_profile->times->answered);
	}
	if (!strcasecmp(name, "progress_time")) {
		return switch_core_sprintf(caller_profile->pool, "%" SWITCH_TIME_T_FMT, caller_profile->times->progress);
	}
	if (!strcasecmp(name, "progress_media_time")) {
		return switch_core_sprintf(caller_profile->pool, "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media);
	}
	if (!strcasecmp(name, "hungup_time")) {
		return switch_core_sprintf(caller_profile->pool, "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup);
	}
	if (!strcasecmp(name, "transferred_time")) {
		return switch_core_sprintf(caller_profile->pool, "%" SWITCH_TIME_T_FMT, caller_profile->times->transferred);
	}


	return NULL;
}
예제 #28
0
static switch_status_t shout_file_open(switch_file_handle_t *handle, const char *path)
{
	shout_context_t *context;
	char *host, *file;
	char *username, *password, *port;
	char *err = NULL;
	const char *mpg123err = NULL;
	int portno = 0;

	if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) {
		return SWITCH_STATUS_MEMERR;
	}

	if (!handle->samplerate) {
		handle->samplerate = 8000;
	}

	context->memory_pool = handle->memory_pool;
	context->samplerate = handle->samplerate;
	context->handle = handle;

	switch_thread_rwlock_create(&(context->rwlock), context->memory_pool);

	switch_thread_rwlock_rdlock(context->rwlock);

	switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->memory_pool);

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) {
		if (switch_buffer_create_dynamic(&context->audio_buffer, TC_BUFFER_SIZE, TC_BUFFER_SIZE * 2, 0) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
			goto error;
		}

		context->mh = our_mpg123_new(NULL, NULL);
		if (mpg123_format_all(context->mh) != MPG123_OK) {
			MPGERROR();
		}
		if (mpg123_param(context->mh, MPG123_FORCE_RATE, context->samplerate, 0) != MPG123_OK) {
			MPGERROR();
		}

		if (handle->handler) {
			if (mpg123_param(context->mh, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_MONO_MIX, 0) != MPG123_OK) {
				MPGERROR();
			}
			if (mpg123_open_feed(context->mh) != MPG123_OK) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening mpg feed\n");
				mpg123err = mpg123_strerror(context->mh);
				goto error;
			}
			context->stream_url = switch_core_sprintf(context->memory_pool, "http://%s", path);
			context->prebuf = handle->prebuf;
			launch_read_stream_thread(context);
		} else {
			handle->seekable = 1;
			if (mpg123_param(context->mh, MPG123_FLAGS, MPG123_MONO_MIX, 0) != MPG123_OK) {
				MPGERROR();
			}
			if (mpg123_open(context->mh, path) != MPG123_OK) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path);
				mpg123err = mpg123_strerror(context->mh);
				goto error;
			}

		}
	} else if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Appending to MP3 not supported.\n");
		}
		if (!(context->gfp = lame_init())) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate lame\n");
			goto error;
		}

		if (!handle->handler) {
			id3tag_init(context->gfp);
			id3tag_v2_only(context->gfp);
			id3tag_pad_v2(context->gfp);

		}
		context->channels = handle->channels;
		lame_set_brate(context->gfp, 16 * (handle->samplerate / 8000) * handle->channels);
		lame_set_num_channels(context->gfp, handle->channels);
		lame_set_in_samplerate(context->gfp, handle->samplerate);
		lame_set_out_samplerate(context->gfp, handle->samplerate);

		if (handle->channels == 2) {
			lame_set_mode(context->gfp, STEREO);
		} else {
			lame_set_mode(context->gfp, MONO);
		}
		lame_set_quality(context->gfp, 2);	/* 2=high  5 = medium  7=low */

		lame_set_errorf(context->gfp, log_error);
		lame_set_debugf(context->gfp, log_debug);
		lame_set_msgf(context->gfp, log_msg);

		if (handle->handler) {
			if (switch_buffer_create_dynamic(&context->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
				goto error;
			}
			lame_set_bWriteVbrTag(context->gfp, 0);
			lame_mp3_tags_fid(context->gfp, NULL);

			username = switch_core_strdup(handle->memory_pool, path);
			if (!(password = strchr(username, ':'))) {
				err = "invalid url";
				goto error;
			}
			*password++ = '\0';

			if (!(host = strchr(password, '@'))) {
				err = "invalid url";
				goto error;
			}
			*host++ = '\0';

			if ((file = strchr(host, '/'))) {
				*file++ = '\0';
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL: %s\n", path);
				goto error;
			}

			if ((port = strchr(host, ':'))) {
				*port++ = '\0';
				if (port) {
					portno = atoi(port);
				}
			}

			if (!portno) {
				portno = 8000;
			}

			if (!(context->shout = shout_new())) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate shout_t\n");
				goto error;
			}

			if (shout_set_host(context->shout, host) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting hostname: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_protocol(context->shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting protocol: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_port(context->shout, portno) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting port: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_password(context->shout, password) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting password: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_mount(context->shout, file) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting mount: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_user(context->shout, username) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting user: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_url(context->shout, "http://www.freeswitch.org") != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_description(context->shout, "FreeSWITCH mod_shout Broadcasting Module") != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting description: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_audio_info(context->shout, "bitrate", "24000") != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting bitrate: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_format(context->shout, SHOUT_FORMAT_MP3) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting format: %s\n", shout_get_error(context->shout));
				goto error;
			}

		} else {
			/* lame being lame and all has FILE * coded into it's API for some functions so we gotta use it */
			if (!(context->fp = fopen(path, "wb+"))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path);
				goto error;
			}
		}
	}

	handle->samples = 0;
	handle->format = 0;
	handle->sections = 0;
	handle->speed = 0;
	handle->private_info = context;
	switch_thread_rwlock_unlock(context->rwlock);

	return SWITCH_STATUS_SUCCESS;

  error:
	switch_thread_rwlock_unlock(context->rwlock);
	if (err) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: %s\n", err);
	}
	if (mpg123err) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error from mpg123: %s\n", mpg123err);
	}
	free_context(context);
	return SWITCH_STATUS_GENERR;

}
예제 #29
0
static switch_status_t do_config(void)
{
	char *cf = "xml_scgi.conf";
	switch_xml_t cfg, xml, bindings_tag, binding_tag, param;
	xml_binding_t *binding = NULL;
	int x = 0;
	int need_vars_map = 0;
	switch_hash_t *vars_map = NULL;

	if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
		return SWITCH_STATUS_TERM;
	}

	if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <bindings> tag!\n");
		goto done;
	}

	for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) {
		char *bname = (char *) switch_xml_attr_soft(binding_tag, "name");
		char *host = "127.0.0.1";
		char *port = "8080";
		char *bind_mask = NULL;
		int timeout = 0;
		char *server = NULL;

		hash_node_t *hash_node;
		need_vars_map = 0;
		vars_map = NULL;

		for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) {
			char *var = (char *) switch_xml_attr_soft(param, "name");
			char *val = (char *) switch_xml_attr_soft(param, "value");

			if (!strcasecmp(var, "host")) {
				bind_mask = (char *) switch_xml_attr_soft(param, "bindings");
				if (val) {
					host = val;
				}
			} else if (!strcasecmp(var, "port")) {
				port = val;
			} else if (!strcasecmp(var, "timeout")) {
				int tmp = atoi(val);
				if (tmp >= 0) {
					timeout = tmp;
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set a negative timeout!\n");
				}
			} else if (!strcasecmp(var, "enable-post-var")) {
				if (!vars_map && need_vars_map == 0) {
					if (switch_core_hash_init(&vars_map, globals.pool) != SWITCH_STATUS_SUCCESS) {
						need_vars_map = -1;
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n");
						continue;
					}
					need_vars_map = 1;
				}

				if (vars_map && val) {
					if (switch_core_hash_insert(vars_map, val, ENABLE_PARAM_VALUE) != SWITCH_STATUS_SUCCESS) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't add %s to params hash!\n", val);
					}
				}
			} else if (!strcasecmp(var, "server")) {
				server = val;
			}
		}

		if (!host) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Binding has no host!\n");
			if (vars_map) {
				switch_core_hash_destroy(&vars_map);
			}
			continue;
		}

		if (!(binding = switch_core_alloc(globals.pool, sizeof(*binding)))) {
			if (vars_map) {
				switch_core_hash_destroy(&vars_map);
			}
			goto done;
		}
		memset(binding, 0, sizeof(*binding));

		binding->timeout = timeout;
		binding->host = switch_core_strdup(globals.pool, host);
		binding->port = atoi(port);
		binding->vars_map = vars_map;
		binding->uri = switch_core_sprintf(globals.pool, "/%s", bname);
		binding->url = switch_core_sprintf(globals.pool, "scgi://%s:%s/%s", host, port, bname);

		if (server) {
			binding->server = switch_core_strdup(globals.pool, server);
		}

        if (bind_mask) {
			binding->bindings = switch_core_strdup(globals.pool, bind_mask);
		}                                         

		if (vars_map) {
			switch_zmalloc(hash_node, sizeof(hash_node_t));
			hash_node->hash = vars_map;
			hash_node->next = NULL;

			if (!globals.hash_root) {
				globals.hash_root = hash_node;
				globals.hash_tail = globals.hash_root;
			}

			else {
				globals.hash_tail->next = hash_node;
				globals.hash_tail = globals.hash_tail->next;
			}

		}

		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n",
						  zstr(bname) ? "N/A" : bname, binding->url, binding->bindings ? binding->bindings : "all");
		switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(binding->bindings), binding);
		
		if (binding->server) {
			launch_monitor_thread(binding);
		}

		binding->next = globals.bindings;
		globals.bindings = binding;
		

		x++;
		binding = NULL;
	}

  done:
	switch_xml_free(xml);

	return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}