Esempio n. 1
0
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	struct json_object *json_cdr = NULL;
	const char *json_text = NULL;
	char *path = NULL;
	char *curl_json_text = NULL;
	const char *logdir = NULL;
	char *json_text_escaped = NULL;
	int fd = -1;
	uint32_t cur_try;
	long httpRes;
	CURL *curl_handle = NULL;
	struct curl_slist *headers = NULL;
	struct curl_slist *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) {
		return SWITCH_STATUS_SUCCESS;
	}
	if (!is_b && globals.prefix_a)
		a_prefix = "a_";


	if (generate_json_cdr(session, &json_cdr) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Generating Data!\n");
		return SWITCH_STATUS_FALSE;
	}
	
	json_text = json_object_to_json_string(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;
			} else {
				char ebuf[512] = { 0 };
#ifdef WIN32
				strerror_s(ebuf, sizeof(ebuf), errno);
#else
				strerror_r(errno, ebuf, sizeof(ebuf));
#endif
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n", path, 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 = 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 = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
				switch_url_encode(json_text, json_text_escaped, need_bytes);
			} else {
				headers = 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);
			}

			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 = curl_slist_append(headers, "Content-Type: application/x-www-form-plaintext");
			curl_json_text = (char *)json_text;
		}


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

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

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

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

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

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

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

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

		/* these were used for testing, optionally they may be enabled if someone desires
		   curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120); // tcp timeout
		   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));
			curl_easy_setopt(curl_handle, CURLOPT_URL, destUrl);

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

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

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

			curl_easy_perform(curl_handle);
			curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
			switch_safe_free(destUrl);
			if (httpRes == 200) {
				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]);
			}
		}
		curl_easy_cleanup(curl_handle);
		curl_slist_free_all(headers);
		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");

		switch_thread_rwlock_rdlock(globals.log_path_lock);
		path = switch_mprintf("%s%s%s%s.cdr.json", globals.err_log_dir, 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;
			} else {
				char ebuf[512] = { 0 };
#ifdef WIN32
				strerror_s(ebuf, sizeof(ebuf), errno);
#else
				strerror_r(errno, ebuf, sizeof(ebuf));
#endif
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
			}
		}
	}

  success:
	status = SWITCH_STATUS_SUCCESS;

  error:
	if (curl_handle) {
		curl_easy_cleanup(curl_handle);
	}
	if (headers) {
		curl_slist_free_all(headers);
	}
	if (slist) {
		curl_slist_free_all(slist);
	}
	if (curl_json_text != json_text) {
		switch_safe_free(curl_json_text);
	}
	
	json_object_put(json_cdr);
	switch_safe_free(json_text_escaped);

	switch_safe_free(path);

	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;

	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 (zstr(val)) {
					globals.base_err_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_err_log_dir = switch_core_strdup(globals.pool, val);
					} else {
						globals.base_err_log_dir = 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 = val;
			} else if (!strcasecmp(var, "ssl-key-path")) {
				globals.ssl_key_file = val;
			} else if (!strcasecmp(var, "ssl-key-password")) {
				globals.ssl_key_password = val;
			} else if (!strcasecmp(var, "ssl-version")) {
				globals.ssl_version = val;
			} else if (!strcasecmp(var, "ssl-cacert-file")) {
				globals.ssl_cacert_file = 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;
				}
			}

		}

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

	if (globals.retries < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retries is negative, setting to 0\n");
		globals.retries = 0;
	}

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

	globals.retries++;

	set_json_cdr_log_dirs();

	switch_xml_free(xml);
	return status;
}

SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_json_cdr_shutdown)
{

	globals.shutdown = 1;

	switch_safe_free(globals.log_dir);
	switch_safe_free(globals.err_log_dir);

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

	switch_thread_rwlock_destroy(globals.log_path_lock);

	return SWITCH_STATUS_SUCCESS;
}
Esempio n. 2
0
static switch_status_t set_json_cdr_log_dirs()
{
	switch_time_exp_t tm;
	char *path = NULL;
	char date[80] = "";
	switch_size_t retsize;
	switch_status_t status = SWITCH_STATUS_SUCCESS, dir_status;

	switch_time_exp_lt(&tm, switch_micro_time_now());
	switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Rotating log file paths\n");

	if (!zstr(globals.base_log_dir)) {
		if (globals.rotate) {
			if ((path = switch_mprintf("%s%s%s", globals.base_log_dir, SWITCH_PATH_SEPARATOR, date))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Rotating log file path to %s\n", path);

				dir_status = SWITCH_STATUS_SUCCESS;
				if (switch_directory_exists(path, globals.pool) != SWITCH_STATUS_SUCCESS) {
					dir_status = switch_dir_make(path, SWITCH_FPROT_OS_DEFAULT, globals.pool);
				}

				if (dir_status == SWITCH_STATUS_SUCCESS) {
					switch_thread_rwlock_wrlock(globals.log_path_lock);
					switch_safe_free(globals.log_dir);
					globals.log_dir = path;
					switch_thread_rwlock_unlock(globals.log_path_lock);
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new mod_json_cdr log_dir path\n");
					switch_safe_free(path);
					status = SWITCH_STATUS_FALSE;
				}
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to generate new mod_json_cdr log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Setting log file path to %s\n", globals.base_log_dir);
			if ((path = switch_safe_strdup(globals.base_log_dir))) {
				switch_thread_rwlock_wrlock(globals.log_path_lock);
				switch_safe_free(globals.log_dir);
				globals.log_dir = path;
				switch_thread_rwlock_unlock(globals.log_path_lock);
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		}
	}

	if (!zstr(globals.base_err_log_dir)) {
		if (globals.rotate) {
			if ((path = switch_mprintf("%s%s%s", globals.base_err_log_dir, SWITCH_PATH_SEPARATOR, date))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Rotating err log file path to %s\n", path);

				dir_status = SWITCH_STATUS_SUCCESS;
				if (switch_directory_exists(path, globals.pool) != SWITCH_STATUS_SUCCESS) {
					dir_status = switch_dir_make(path, SWITCH_FPROT_OS_DEFAULT, globals.pool);
				}

				if (dir_status == SWITCH_STATUS_SUCCESS) {
					switch_thread_rwlock_wrlock(globals.log_path_lock);
					switch_safe_free(globals.err_log_dir);
					globals.err_log_dir = path;
					switch_thread_rwlock_unlock(globals.log_path_lock);
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new mod_json_cdr err_log_dir path\n");
					switch_safe_free(path);
					status = SWITCH_STATUS_FALSE;
				}
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to generate new mod_json_cdr err_log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Setting err log file path to %s\n", globals.base_err_log_dir);
			if ((path = switch_safe_strdup(globals.base_err_log_dir))) {
				switch_thread_rwlock_wrlock(globals.log_path_lock);
				switch_safe_free(globals.err_log_dir);
				globals.err_log_dir = path;
				switch_thread_rwlock_unlock(globals.log_path_lock);
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set err_log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		}
	}

	return status;
}
Esempio n. 3
0
static switch_status_t do_config()
{
	switch_cache_db_handle_t *dbh = NULL;
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	char *sql = NULL;

	limit_config_dsn.pool = globals.pool;

	if (switch_xml_config_parse_module_settings("db.conf", SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No config file found, defaulting to sqlite\n");
	}

	if (globals.odbc_dsn) {
		if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) {
			*globals.odbc_user++ = '\0';
			if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) {
				*globals.odbc_pass++ = '\0';
			}
		}

		if (!(dbh = limit_get_db_handle())) {
			globals.odbc_dsn = globals.odbc_user = globals.odbc_pass;
		}
	}


	if (zstr(globals.odbc_dsn)) {
		globals.dbname = "call_limit";
		dbh = limit_get_db_handle();
	}


	if (dbh) {
		int x = 0;
		char *indexes[] = {
			"create index ld_hostname on limit_data (hostname)",
			"create index ld_uuid on limit_data (uuid)",
			"create index ld_realm on limit_data (realm)",
			"create index ld_id on limit_data (id)",
			"create index dd_realm on db_data (realm)",
			"create index dd_data_key on db_data (data_key)",
			"create index gd_groupname on group_data (groupname)",
			"create index gd_url on group_data (url)",
			NULL
		};



		switch_cache_db_test_reactive(dbh, "select * from limit_data", NULL, limit_sql);
		switch_cache_db_test_reactive(dbh, "select * from db_data", NULL, db_sql);
		switch_cache_db_test_reactive(dbh, "select * from group_data", NULL, group_sql);

		for (x = 0; indexes[x]; x++) {
			switch_cache_db_execute_sql(dbh, indexes[x], NULL);
		}

		switch_cache_db_release_db_handle(&dbh);

		sql = switch_mprintf("delete from limit_data where hostname='%q';", globals.hostname);
		limit_execute_sql(sql);
		switch_safe_free(sql);
	}

	return status;
}
static switch_status_t local_stream_file_open(switch_file_handle_t *handle, const char *path)
{
	local_stream_context_t *context;
	local_stream_source_t *source;
	char *alt_path = NULL;
	switch_status_t status = SWITCH_STATUS_SUCCESS;

	/* already buffering a step back, so always disable it */
	handle->pre_buffer_datalen = 0;

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing!\n");
		return SWITCH_STATUS_FALSE;
	}

	switch_mutex_lock(globals.mutex);

  top:

	alt_path = switch_mprintf("%s/%d", path, handle->samplerate);

	if ((source = switch_core_hash_find(globals.source_hash, alt_path))) {
		path = alt_path;
	} else {
		source = switch_core_hash_find(globals.source_hash, path);
	}
	if (source) {
		if (switch_thread_rwlock_tryrdlock(source->rwlock) != SWITCH_STATUS_SUCCESS) {
			source = NULL;
		}
	} else {
		if (!switch_stristr("default", alt_path) && !switch_stristr("default", path)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown source %s, trying 'default'\n", path);
			free(alt_path);
			path = "default";
			goto top;
		}
	}
	switch_mutex_unlock(globals.mutex);

	if (!source) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown source %s\n", path);
		status = SWITCH_STATUS_FALSE;
		goto end;
	}

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

	handle->samples = 0;
	handle->samplerate = source->rate;
	handle->channels = source->channels;
	handle->format = 0;
	handle->sections = 0;
	handle->seekable = 0;
	handle->speed = 0;
	handle->private_info = context;
	handle->interval = source->interval;
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opening Stream [%s] %dhz\n", path, handle->samplerate);

	switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
	if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
		status = SWITCH_STATUS_MEMERR;
		goto end;
	}

	context->source = source;
	context->file = handle->file;
	context->func = handle->func;
	context->line = handle->line;
	context->handle = handle;
	switch_mutex_lock(source->mutex);
	context->next = source->context_list;
	source->context_list = context;
	source->total++;
	switch_mutex_unlock(source->mutex);

  end:
	switch_safe_free(alt_path);
	return status;
}
/*! function to load a grammar to the asr interface */
static switch_status_t pocketsphinx_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name)
{
	char *jsgf, *dic, *model, *rate = NULL;
	pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
	switch_status_t status = SWITCH_STATUS_FALSE;

	if (switch_test_flag(ps, PSFLAG_READY)) {
		ps_end_utt(ps->ps);
		switch_clear_flag(ps, PSFLAG_READY);
	}

	if (switch_is_file_path(grammar)) {
		jsgf = switch_mprintf("%s.gram", grammar);
	} else {
		jsgf = switch_mprintf("%s%s%s.gram", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, grammar);
	}

	if (ah->rate == 8000) {
		model = switch_mprintf("%s%smodel%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, SWITCH_PATH_SEPARATOR, globals.model8k);
	} else {
		model = switch_mprintf("%s%smodel%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, SWITCH_PATH_SEPARATOR, globals.model16k);
	}

	dic = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, globals.dictionary);

	if (switch_file_exists(dic, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open dictionary %s.\n", dic);
		goto end;
	}

	if (switch_file_exists(model, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open speech model %s.\n", model);
		goto end;
	}

	if (switch_file_exists(jsgf, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open grammar file %s.\n", jsgf);
		goto end;
	}

	rate = switch_mprintf("%d", ah->rate);

	switch_assert(jsgf && dic && model);

	ps->config = cmd_ln_init(ps->config, ps_args(), FALSE,
							 "-samprate", rate,
							 "-hmm", model, "-jsgf", jsgf, "-lw", globals.language_weight, "-dict", dic, "-frate", "50", "-silprob", "0.005", NULL);

	if (ps->config == NULL) {
		status = SWITCH_STATUS_GENERR;
		goto end;
	}

	switch_mutex_lock(ps->flag_mutex);
	if (switch_test_flag(ps, PSFLAG_ALLOCATED)) {
		ps_reinit(ps->ps, ps->config);
	} else {
		if (!(ps->ps = ps_init(ps->config))) {
			switch_mutex_unlock(ps->flag_mutex);
			goto end;
		}
		switch_set_flag(ps, PSFLAG_ALLOCATED);
	}
	switch_mutex_unlock(ps->flag_mutex);

	ps_start_utt(ps->ps, NULL);
	switch_set_flag(ps, PSFLAG_READY);
	switch_safe_free(ps->grammar);
	ps->grammar = strdup(grammar);

	status = SWITCH_STATUS_SUCCESS;

  end:

	switch_safe_free(rate);
	switch_safe_free(jsgf);
	switch_safe_free(dic);
	switch_safe_free(model);

	return status;
}
Esempio n. 6
0
/*网元的变更通知/增加,删除的通知等通知类型的消息处理
*/
int cari_net_ne_statechange(int notifyCode,			//通知码
							switch_event_t *event)	//事件
{
	inner_ResultResponse_Frame	*inner_respFrame = NULL;
	char						*result			 = NULL;
	char						*neId		     = NULL;
	char						*neType	         = NULL;
	char						*neIP	         = NULL;
	char						*neDesc	         = NULL;

	neId   = switch_event_get_header(event, "neid");	//网元号
	neType = switch_event_get_header(event, "netype");  //网元类型
	neIP   = switch_event_get_header(event, "ip");	    //网元ip地址
	neDesc = switch_event_get_header(event, "desc");	//网元描述信息

	//new响应帧
	inner_respFrame = CARI_CCP_VOS_NEW(inner_ResultResponse_Frame);

	//初始化"内部响应帧"结构体
	memset(inner_respFrame, 0, sizeof(inner_ResultResponse_Frame));

	//初始化赋值,设置了"通知类型的标识"和"通知码"
	initInnerResponseFrame(inner_respFrame, event);

	//根据"通知码"进行详细的区分
	switch(notifyCode){
	//增加/修改网元
	case CARICCP_NOTIFY_ADD_EQUIP_NE:
	case CARICCP_NOTIFY_MOD_EQUIP_NE:
		{
			//Id,类型,ip为返回的集合
			result = switch_mprintf("%s%s%s%s%s%s%s%s", 
				neId, 
				CARICCP_SPECIAL_SPLIT_FLAG,
				neType,
				CARICCP_SPECIAL_SPLIT_FLAG,
				neIP,
				CARICCP_SPECIAL_SPLIT_FLAG,
				neDesc,
				CARICCP_ENTER_KEY
				);

			break;
		}
	//删除网元
	case CARICCP_NOTIFY_DEL_EQUIP_NE:
		{
		    result = neId;
			break;
		}

	default:
		goto end;
	}

	if (NULL != result) {
		inner_respFrame->m_vectTableValue.push_back(result);

		//将通知类型的事件发送给所有客户端
		CMsgProcess::getInstance()->notifyResult(inner_respFrame);
	}

end:

	//销毁"响应帧"
	CARI_CCP_VOS_DEL(inner_respFrame);
	return CARICCP_SUCCESS_STATE_CODE;
}
/* NB. this starts the input thread after some initial setup for the call leg */
void conference_loop_output(conference_member_t *member)
{
	switch_channel_t *channel;
	switch_frame_t write_frame = { 0 };
	uint8_t *data = NULL;
	switch_timer_t timer = { 0 };
	uint32_t interval;
	uint32_t samples;
	//uint32_t csamples;
	uint32_t tsamples;
	uint32_t flush_len;
	uint32_t low_count, bytes;
	call_list_t *call_list, *cp;
	switch_codec_implementation_t read_impl = { 0 };
	int sanity;
	switch_status_t st;

	switch_core_session_get_read_impl(member->session, &read_impl);


	channel = switch_core_session_get_channel(member->session);
	interval = read_impl.microseconds_per_packet / 1000;
	samples = switch_samples_per_packet(member->conference->rate, interval);
	//csamples = samples;
	tsamples = member->orig_read_impl.samples_per_packet;
	low_count = 0;
	bytes = samples * 2 * member->conference->channels;
	call_list = NULL;
	cp = NULL;

	member->loop_loop = 0;

	switch_assert(member->conference != NULL);

	flush_len = switch_samples_per_packet(member->conference->rate, member->conference->interval) * 2 * member->conference->channels * (500 / member->conference->interval);

	if (switch_core_timer_init(&timer, member->conference->timer_name, interval, tsamples, NULL) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Timer Setup Failed.  Conference Cannot Start\n");
		return;
	}

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Setup timer %s success interval: %u  samples: %u\n",
					  member->conference->timer_name, interval, tsamples);


	write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE);
	write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;


	write_frame.codec = &member->write_codec;

	/* Start the input thread */
	conference_loop_launch_input(member, switch_core_session_get_pool(member->session));

	if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) {
		const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name");
		const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number");
		const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout");
		const char *flags = switch_channel_get_variable(channel, "conference_utils_auto_outcall_flags");
		const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile");
		const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce");
		const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix");
		const char *maxwait = switch_channel_get_variable(channel, "conference_auto_outcall_maxwait");
		const char *delimiter_val = switch_channel_get_variable(channel, "conference_auto_outcall_delimiter");
		int to = 60;
		int wait_sec = 2;
		int loops = 0;

		if (ann && !switch_channel_test_app_flag_key("conference_silent", channel, CONF_SILENT_REQ)) {
			member->conference->special_announce = switch_core_strdup(member->conference->pool, ann);
		}

		switch_channel_set_private(channel, "_conference_autocall_list_", NULL);

		conference_utils_set_flag(member->conference, CFLAG_OUTCALL);

		if (toval) {
			to = atoi(toval);
			if (to < 10 || to > 500) {
				to = 60;
			}
		}

		for (cp = call_list; cp; cp = cp->next) {
			int argc;
			char *argv[512] = { 0 };
			char *cpstr = strdup(cp->string);
			int x = 0;

			switch_assert(cpstr);
			if (!zstr(delimiter_val) && strlen(delimiter_val) == 1) {
				char delimiter = *delimiter_val;
				argc = switch_separate_string(cpstr, delimiter, argv, (sizeof(argv) / sizeof(argv[0])));
			} else {
				argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0])));
			}
			for (x = 0; x < argc; x++) {
				char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]);
				switch_assert(dial_str);
				conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL,
									  profile, &member->conference->cancel_cause, NULL);
				switch_safe_free(dial_str);
			}
			switch_safe_free(cpstr);
		}

		if (maxwait) {
			int tmp = atoi(maxwait);
			if (tmp > 0) {
				wait_sec = tmp;
			}
		}


		loops = wait_sec * 10;

		switch_channel_set_app_flag(channel, CF_APP_TAGGED);
		do {
			switch_ivr_sleep(member->session, 100, SWITCH_TRUE, NULL);
		} while(switch_channel_up(channel) && (member->conference->originating && --loops));
		switch_channel_clear_app_flag(channel, CF_APP_TAGGED);

		if (!switch_channel_ready(channel)) {
			member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
			goto end;
		}

		conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE);
	}

	if (!conference_utils_test_flag(member->conference, CFLAG_ANSWERED)) {
		switch_channel_answer(channel);
	}


	sanity = 2000;
	while(!conference_utils_member_test_flag(member, MFLAG_ITHREAD) && sanity > 0) {
		switch_cond_next();
		sanity--;
	}

	/* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed,      */
	/* you better not block this thread loop for more than the duration of member->conference->timer_name!  */
	while (!member->loop_loop && conference_utils_member_test_flag(member, MFLAG_RUNNING) && conference_utils_member_test_flag(member, MFLAG_ITHREAD)
		   && switch_channel_ready(channel)) {
		switch_event_t *event;
		int use_timer = 0;
		switch_buffer_t *use_buffer = NULL;
		uint32_t mux_used = 0;


		if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) {
			switch_cond_next();
			continue;
		}

		switch_mutex_lock(member->write_mutex);


		if (switch_channel_test_flag(member->channel, CF_CONFERENCE_ADV)) {
			if (member->conference->la) {
				conference_event_adv_la(member->conference, member, SWITCH_TRUE);
			}
			switch_channel_clear_flag(member->channel, CF_CONFERENCE_ADV);
		}


		if (switch_core_session_dequeue_event(member->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
			if (event->event_id == SWITCH_EVENT_MESSAGE) {
				char *from = switch_event_get_header(event, "from");
				char *to = switch_event_get_header(event, "to");
				char *body = switch_event_get_body(event);

				if (to && from && body) {
					if (strchr(to, '+') && strncmp(to, CONF_CHAT_PROTO, strlen(CONF_CHAT_PROTO))) {
						switch_event_del_header(event, "to");
						switch_event_add_header(event, SWITCH_STACK_BOTTOM,
												"to", "%s+%s@%s", CONF_CHAT_PROTO, member->conference->name, member->conference->domain);
					} else {
						switch_event_del_header(event, "to");
						switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", member->conference->name);
					}
					chat_send(event);
				}
			}
			switch_event_destroy(&event);
		}

		if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
			/* test to see if outbound channel has answered */
			if (switch_channel_test_flag(channel, CF_ANSWERED) && !conference_utils_test_flag(member->conference, CFLAG_ANSWERED)) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG,
								  "Outbound conference channel answered, setting CFLAG_ANSWERED\n");
				conference_utils_set_flag(member->conference, CFLAG_ANSWERED);
			}
		} else {
			if (conference_utils_test_flag(member->conference, CFLAG_ANSWERED) && !switch_channel_test_flag(channel, CF_ANSWERED)) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "CLFAG_ANSWERED set, answering inbound channel\n");
				switch_channel_answer(channel);
			}
		}

		use_buffer = NULL;
		mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer);

		use_timer = 1;

		if (mux_used) {
			if (mux_used < bytes) {
				if (++low_count >= 5) {
					/* partial frame sitting around this long is useless and builds delay */
					conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
				}
			} else if (mux_used > flush_len) {
				/* getting behind, clear the buffer */
				conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
			}
		}

		if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
			conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
		} else if (mux_used >= bytes) {
			/* Flush the output buffer and write all the data (presumably muxed) back to the channel */
			switch_mutex_lock(member->audio_out_mutex);
			write_frame.data = data;
			use_buffer = member->mux_buffer;
			low_count = 0;

			if ((write_frame.datalen = (uint32_t) switch_buffer_read(use_buffer, write_frame.data, bytes))) {
				if (write_frame.datalen) {
					write_frame.samples = write_frame.datalen / 2 / member->conference->channels;

					if( !conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) {
						memset(write_frame.data, 255, write_frame.datalen);
					} else if (member->volume_out_level) { /* Check for output volume adjustments */
						switch_change_sln_volume(write_frame.data, write_frame.samples * member->conference->channels, member->volume_out_level);
					}

					write_frame.timestamp = timer.samplecount;

					if (member->fnode) {
						conference_member_add_file_data(member, write_frame.data, write_frame.datalen);
					}

					conference_member_check_channels(&write_frame, member, SWITCH_FALSE);

					if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
						switch_mutex_unlock(member->audio_out_mutex);
						break;
					}
				}
			}

			switch_mutex_unlock(member->audio_out_mutex);
		}

		if (conference_utils_member_test_flag(member, MFLAG_FLUSH_BUFFER)) {
			if (switch_buffer_inuse(member->mux_buffer)) {
				switch_mutex_lock(member->audio_out_mutex);
				switch_buffer_zero(member->mux_buffer);
				switch_mutex_unlock(member->audio_out_mutex);
			}
			conference_utils_member_clear_flag_locked(member, MFLAG_FLUSH_BUFFER);
		}

		switch_mutex_unlock(member->write_mutex);


		if (conference_utils_member_test_flag(member, MFLAG_INDICATE_MUTE)) {
			if (!zstr(member->conference->muted_sound)) {
				conference_member_play_file(member, member->conference->muted_sound, 0, SWITCH_TRUE);
			} else {
				char msg[512];

				switch_snprintf(msg, sizeof(msg), "Muted");
				conference_member_say(member, msg, 0);
			}
			conference_utils_member_clear_flag(member, MFLAG_INDICATE_MUTE);
		}

		if (conference_utils_member_test_flag(member, MFLAG_INDICATE_MUTE_DETECT)) {
			if (!zstr(member->conference->mute_detect_sound)) {
				conference_member_play_file(member, member->conference->mute_detect_sound, 0, SWITCH_TRUE);
			} else {
				char msg[512];

				switch_snprintf(msg, sizeof(msg), "Currently Muted");
				conference_member_say(member, msg, 0);
			}
			conference_utils_member_clear_flag(member, MFLAG_INDICATE_MUTE_DETECT);
		}

		if (conference_utils_member_test_flag(member, MFLAG_INDICATE_UNMUTE)) {
			if (!zstr(member->conference->unmuted_sound)) {
				conference_member_play_file(member, member->conference->unmuted_sound, 0, SWITCH_TRUE);
			} else {
				char msg[512];

				switch_snprintf(msg, sizeof(msg), "Un-Muted");
				conference_member_say(member, msg, 0);
			}
			conference_utils_member_clear_flag(member, MFLAG_INDICATE_UNMUTE);
		}

		if (switch_core_session_private_event_count(member->session)) {
			switch_channel_set_app_flag(channel, CF_APP_TAGGED);
			switch_ivr_parse_all_events(member->session);
			switch_channel_clear_app_flag(channel, CF_APP_TAGGED);
			conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
			switch_core_session_set_read_codec(member->session, &member->read_codec);
		} else {
			switch_ivr_parse_all_messages(member->session);
		}

		if (use_timer) {
			switch_core_timer_next(&timer);
		} else {
			switch_cond_next();
		}

	} /* Rinse ... Repeat */

 end:

	if (!member->loop_loop) {
		conference_utils_member_clear_flag_locked(member, MFLAG_RUNNING);

		/* Wait for the input thread to end */
		if (member->input_thread) {
			switch_thread_join(&st, member->input_thread);
			member->input_thread = NULL;
		}
	}

	switch_core_timer_destroy(&timer);

	if (member->loop_loop) {
		return;
	}

	switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Channel leaving conference, cause: %s\n",
					  switch_channel_cause2str(switch_channel_get_cause(channel)));

	/* if it's an outbound channel, store the release cause in the conference struct, we might need it */
	if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
		member->conference->bridge_hangup_cause = switch_channel_get_cause(channel);
	}
}
Esempio n. 8
0
static switch_status_t populate_database(switch_core_session_t *session, dir_profile_t *profile, const char *domain_name)
{
	switch_status_t status = SWITCH_STATUS_SUCCESS;

	char *sql = NULL;
	char *sqlvalues = NULL;
	char *sqltmp = NULL;

	switch_xml_t xml_root = NULL, x_domain;
	switch_xml_t ut;

	switch_event_t *xml_params = NULL;
	switch_xml_t group = NULL, groups = NULL, users = NULL, x_params = NULL, x_param = NULL, x_vars = NULL, x_var = NULL;
	switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS);
	switch_assert(xml_params);

	if (switch_xml_locate_domain(domain_name, xml_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain_name);
		status = SWITCH_STATUS_FALSE;
		goto end;
	}

	if ((groups = switch_xml_child(x_domain, "groups"))) {
		for (group = switch_xml_child(groups, "group"); group; group = group->next) {
			if ((users = switch_xml_child(group, "users"))) {
				for (ut = switch_xml_child(users, "user"); ut; ut = ut->next) {
					int name_visible = 1;
					int exten_visible = 1;
					const char *type = switch_xml_attr_soft(ut, "type");
					const char *id = switch_xml_attr_soft(ut, "id");
					char *fullName = NULL;
					char *caller_name = NULL;
					char *caller_name_override = NULL;
					char *firstName = NULL;
					char *lastName = NULL;
					char *fullNameDigit = NULL;
					char *firstNameDigit = NULL;
					char *lastNameDigit = NULL;

					if (!strcasecmp(type, "pointer")) {
						continue;
					}
					/* Check all the user params */
					if ((x_params = switch_xml_child(ut, "params"))) {
						for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
							const char *var = switch_xml_attr_soft(x_param, "name");
							const char *val = switch_xml_attr_soft(x_param, "value");
							if (!strcasecmp(var, "directory-visible")) {
								name_visible = switch_true(val);
							}
							if (!strcasecmp(var, "directory-exten-visible")) {
								exten_visible = switch_true(val);
							}

						}
					}
					/* Check all the user variables */
					if ((x_vars = switch_xml_child(ut, "variables"))) {
						for (x_var = switch_xml_child(x_vars, "variable"); x_var; x_var = x_var->next) {
							const char *var = switch_xml_attr_soft(x_var, "name");
							const char *val = switch_xml_attr_soft(x_var, "value");
							if (!strcasecmp(var, "effective_caller_id_name")) {
								caller_name = switch_core_session_strdup(session, val);
							}
							if (!strcasecmp(var, "directory_full_name")) {
								caller_name_override = switch_core_session_strdup(session, val);
							}
						}
					}
					if (caller_name_override) {
						fullName = caller_name_override;
					} else {
						fullName = caller_name;
					}
					if (zstr(fullName)) {
						continue;
					}
					firstName = switch_core_session_strdup(session, fullName);

					if ((lastName = strrchr(firstName, ' '))) {
						*lastName++ = '\0';
					} else {
						lastName = switch_core_session_strdup(session, firstName);
					}

					/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "FullName %s firstName [%s] lastName [%s]\n", fullName, firstName, lastName); */

					/* Generate Digits key mapping */
					fullNameDigit = string_to_keypad_digit(fullName);
					lastNameDigit = string_to_keypad_digit(lastName);
					firstNameDigit = string_to_keypad_digit(firstName);

					/* add user into DB */
					sql = switch_mprintf("insert into directory_search values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%d','%d')",
										 globals.hostname, switch_core_session_get_uuid(session), id, fullName, fullNameDigit, firstName, firstNameDigit,
										 lastName, lastNameDigit, name_visible, exten_visible);

					if (sqlvalues) {
						sqltmp = sqlvalues;
						sqlvalues = switch_mprintf("%s;%s", sqlvalues, sql);
						switch_safe_free(sqltmp);
					} else {
						sqlvalues = sql;
						sql = NULL;
					}
					switch_safe_free(sql);
					switch_safe_free(fullNameDigit);
					switch_safe_free(lastNameDigit);
					switch_safe_free(firstNameDigit);
				}
			}
		}
	}
	sql = switch_mprintf("BEGIN;%s;COMMIT;", sqlvalues);
	directory_execute_sql(sql, profile->mutex);

  end:
	switch_safe_free(sql);
	switch_safe_free(sqlvalues);
	switch_event_destroy(&xml_params);
	switch_xml_free(xml_root);

	return status;
}
Esempio n. 9
0
static switch_status_t load_config(switch_memory_pool_t *pool)
{
	char *cf = "cdr_sqlite.conf";
	switch_xml_t cfg, xml, settings, param;
	switch_cache_db_handle_t *dbh = NULL;
	char *select_sql = NULL, *create_sql = NULL;
	switch_status_t status = SWITCH_STATUS_SUCCESS;

	memset(&globals, 0, sizeof(globals));
	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, "db-name")) {
					globals.db_name = switch_core_strdup(pool, val);
				} else if (!strcasecmp(var, "db-table")) {
					globals.db_table = switch_core_strdup(pool, 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, "default-template")) {
					globals.default_template = switch_core_strdup(pool, 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;
					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.db_name)) {
		globals.db_name = switch_core_strdup(pool, "cdr");
	}

	if (zstr(globals.db_table)) {
		globals.db_table = switch_core_strdup(pool, "cdr");
	}

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

	dbh = cdr_get_db_handle();

	if (dbh) {
		select_sql = switch_mprintf("SELECT * FROM %s LIMIT 1", globals.db_table);
		assert(select_sql);

		create_sql = switch_mprintf(default_create_sql, globals.db_table);
		assert(create_sql);

		/* Check if table exists (try SELECT FROM ...) and create table if query fails */
		switch_cache_db_test_reactive(dbh, select_sql, NULL, create_sql);
		switch_safe_free(select_sql);
		switch_safe_free(create_sql);

		switch_cache_db_release_db_handle(&dbh);
	}

	return status;
}
Esempio n. 10
0
static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results, switch_channel_t *channel, switch_core_session_t *session)
{
	switch_status_t sstatus = SWITCH_STATUS_SUCCESS;
	char *mnum = NULL, *mroot = NULL, *p;
	char *server[ENUM_MAXNAMESERVERS];
	int inameserver = 0;  
	char *argv[ ENUM_MAXNAMESERVERS ] = { 0 };
	int argc;
	int x = 0;
	char *enum_nameserver_dup;
	const char *enum_nameserver = NULL;

	*results = NULL;

	mnum = switch_mprintf("%s%s", *in == '+' ? "" : "+", in);

	if ((p = strchr(mnum, '*'))) {
		*p++ = '\0';
		mroot = switch_mprintf("%s.%s", p, root ? root : globals.isn_root);
		root = mroot;
	}

	if (zstr(root)) {
		root = globals.root;
	}

	/* Empty the server array */
	for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
		server[inameserver] = NULL;
	}  

	inameserver = 0;

	/* check for enum_nameserver channel var */
	
	if (channel) {
		enum_nameserver = switch_channel_get_variable(channel, "enum_nameserver");
	}

	if (zstr(enum_nameserver)) {
		enum_nameserver = switch_core_get_variable("enum-server");
	}

	if (!zstr(enum_nameserver)) {
		/* Blank the server array */
		for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
			server[inameserver] = NULL;
		}

		enum_nameserver_dup = switch_core_session_strdup(session, enum_nameserver);
		argc = switch_separate_string(enum_nameserver_dup, ',', argv, (sizeof(argv) / sizeof(argv[0])));

		inameserver = 0;
		for (x = 0; x < argc; x++) {
			server[inameserver] = argv[x];
			inameserver++;
		}
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Enum nameserver override : %s\n", enum_nameserver);
	}

	if (!inameserver) {
		/* use config param "nameserver" ( can be up to ENUM_MAXNAMESERVERS ) */
		for(inameserver = 0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
			server[inameserver] = NULL;
			if ( globals.nameserver[inameserver] != NULL ) {
				server[inameserver] = globals.nameserver[inameserver];
			}
		}
	}

	ldns_lookup(mnum, root, server, results);

	switch_safe_free(mnum);
	switch_safe_free(mroot);

	return sstatus;
}
Esempio n. 11
0
static void pres_event_handler(switch_event_t *event)
{
	char *to = switch_event_get_header(event, "to");
	char *dup_to = NULL, *lot_name, *dup_lot_name = NULL, *domain_name;
	valet_lot_t *lot;
	int found = 0;
	
	if (!to || strncasecmp(to, "park+", 5) || !strchr(to, '@')) {
		return;
	}

	if (!(dup_to = strdup(to))) {
		return;
	}

	lot_name = dup_to + 5;

	if ((domain_name = strchr(lot_name, '@'))) {
		*domain_name++ = '\0';
	}

	dup_lot_name = switch_mprintf("%q@%q", lot_name, domain_name);

	if ((lot = valet_find_lot(lot_name, SWITCH_FALSE)) || (dup_lot_name && (lot = valet_find_lot(dup_lot_name, SWITCH_FALSE)))) {
		int count = valet_lot_count(lot);

		if (count) {
			if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
				if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", VALET_PROTO);
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", lot_name);
					switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", lot_name, domain_name);

					switch_event_add_header(event, SWITCH_STACK_BOTTOM, "force-status", "Active (%d caller%s)", count, count == 1 ? "" : "s");
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "active");
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
					switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", lot_name);
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING");
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed");
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
					switch_event_fire(&event);
				}
				found++;
			}
		} else {
			if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", VALET_PROTO);
				switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", lot_name, domain_name);

				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", "Empty");
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
				switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", lot_name);
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP");
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "terminated");
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
				switch_event_fire(&event);
			}		
		}
	} else {
		switch_console_callback_match_t *matches = NULL;
		switch_console_callback_match_node_t *m;
		switch_hash_index_t *hi;
		const void *var;
		void *val;
		const char *nvar;

		switch_mutex_lock(globals.mutex);
		for (hi = switch_hash_first(NULL, globals.hash); hi; hi = switch_hash_next(hi)) {
			switch_hash_this(hi, &var, NULL, &val);
			nvar = (const char *) var;

			if (!strchr(nvar, '@') || switch_stristr(domain_name, nvar)) {
				switch_console_push_match(&matches, nvar);
			}
		}
		switch_mutex_unlock(globals.mutex);		
		
		if (matches) {
			valet_token_t *token;
			
			for (m = matches->head; !found && m; m = m->next) {
				lot = valet_find_lot(m->val, SWITCH_FALSE);
				switch_mutex_lock(lot->mutex);

				if ((token = (valet_token_t *) switch_core_hash_find(lot->hash, lot_name)) && !token->timeout) {
					found++;
					
					if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", VALET_PROTO);
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", lot_name);
						switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", lot_name, domain_name);

						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", token->bridged == 0 ? "Holding" : "Active");
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
						switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", lot_name);
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING");
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", token->bridged == 0 ? "early" : "confirmed");
						switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", token->bridged == 0 ? "outbound" : "inbound");
						switch_event_fire(&event);
					}
				}

				switch_mutex_unlock(lot->mutex);
			}
			switch_console_free_matches(&matches);
		}
	}


	if (!found && switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", VALET_PROTO);
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", lot_name);
		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", lot_name, domain_name);

		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", "Empty");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", lot_name);
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "terminated");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
		switch_event_fire(&event);
	}

	switch_safe_free(dup_to);
	switch_safe_free(dup_lot_name);
}
Esempio n. 12
0
SWITCH_DECLARE(char *) switch_console_expand_alias(char *cmd, char *arg)
{
	char *errmsg = NULL;
	char *r = NULL;
	char *sql = NULL;
	char *exp = NULL;
	switch_cache_db_handle_t *db = NULL;
	switch_core_flag_t cflags = switch_core_flags();
	int full = 0;

	
	if (!(cflags & SCF_USE_SQL)) {
		return NULL;
	}

	if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n");
		return NULL;
	}


	if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
		sql = switch_mprintf("select command from aliases where alias='%q'", cmd);
	} else {
		sql = switch_mprintf("select command from aliases where alias='%w'", cmd);
	}

	switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg);

	if (errmsg) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg);
		free(errmsg);
	}

	switch_safe_free(sql);

	if (!r) {
		if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
			sql = switch_mprintf("select command from aliases where alias='%q %q'", cmd, arg);
		} else {
			sql = switch_mprintf("select command from aliases where alias='%w %w'", cmd, arg);
		}

		switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg);

		if (errmsg) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg);
			free(errmsg);
		}
		if (r) {
			full++;
		}
	}

	switch_safe_free(sql);

	if (r) {
		if (arg && !full) {
			exp = switch_mprintf("%s %s", r, arg);
			free(r);
		} else {
			exp = r;
		}
	} else {
		exp = cmd;
	}

	switch_cache_db_release_db_handle(&db);

	return exp;
}
Esempio n. 13
0
static int perl_parse_and_execute(PerlInterpreter * my_perl, char *input_code, char *setup_code)
{
	int error = 0;

	if (zstr(input_code)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No code to execute!\n");
		return -1;
	}

	if (setup_code) {
		error = Perl_safe_eval(my_perl, setup_code);
		if (error) {
			return error;
		}
	}

	if (*input_code == '~') {
		char *buff = input_code + 1;
		error = Perl_safe_eval(my_perl, buff);
	} else {
		char *args = strchr(input_code, ' ');
		if (args) {
			char *code = NULL;
			int x, argc;
			char *argv[128] = { 0 };
			*args++ = '\0';

			if ((argc = switch_separate_string(args, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
				switch_stream_handle_t stream = { 0 };
				SWITCH_STANDARD_STREAM(stream);

				stream.write_function(&stream, " @ARGV = ( ");
				for (x = 0; x < argc; x++) {
					stream.write_function(&stream, "'%s'%s", argv[x], x == argc - 1 ? "" : ", ");
				}
				stream.write_function(&stream, " );");
				code = stream.data;
			} else {
				code = switch_mprintf("ARGV = ();");
			}

			if (code) {
				error = Perl_safe_eval(my_perl, code);
				switch_safe_free(code);
			}
		}
		if (!error) {
			char *file = input_code;
			char *err;

			if (!switch_is_file_path(file)) {
				file = switch_mprintf("require '%s/%s';", SWITCH_GLOBAL_dirs.script_dir, file);
				switch_assert(file);
			} else {
				file = switch_mprintf("require '%s';", file);
				switch_assert(file);
			}

			error = Perl_safe_eval(my_perl, file);
			switch_safe_free(file);
		}
	}

	return error;
}
Esempio n. 14
0
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	const char *log_dir = NULL, *accountcode = NULL, *a_template_str = NULL, *g_template_str = NULL;
	char *log_line, *path = NULL;

	if (globals.shutdown) {
		return SWITCH_STATUS_SUCCESS;
	}

	if (!((globals.legs & CDR_LEG_A) && (globals.legs & CDR_LEG_B))) {
		if ((globals.legs & CDR_LEG_A)) {
			if (switch_channel_get_originator_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		} else {
			if (switch_channel_get_originatee_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		}
	}

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

	if (switch_dir_make_recursive(log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", log_dir);
		return SWITCH_STATUS_FALSE;
	}

	if (globals.debug) {
		switch_event_t *event;
		if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
			char *buf;
			switch_channel_event_set_data(channel, event);
			switch_event_serialize(event, &buf, SWITCH_FALSE);
			switch_assert(buf);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf);
			switch_event_destroy(&event);
			free(buf);
		}
	}

	g_template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template);

	if ((accountcode = switch_channel_get_variable(channel, "ACCOUNTCODE"))) {
		a_template_str = (const char *) switch_core_hash_find(globals.template_hash, accountcode);
	}

	if (!g_template_str) {
		g_template_str =
			"\"${accountcode}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${caller_id}\",\"${channel_name}\",\"${bridge_channel}\",\"${last_app}\",\"${last_arg}\",\"${start_stamp}\",\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${amaflags}\",\"${uuid}\",\"${userfield}\";";
	}

	if (!a_template_str) {
		a_template_str = g_template_str;
	}

	log_line = switch_channel_expand_variables(channel, a_template_str);

	if ((accountcode) && (!globals.masterfileonly)) {
		path = switch_mprintf("%s%s%s.csv", log_dir, SWITCH_PATH_SEPARATOR, accountcode);
		assert(path);
		write_cdr(path, log_line);
		free(path);
	}

	if (g_template_str != a_template_str) {
		if (log_line != a_template_str) {
			switch_safe_free(log_line);
		}
		log_line = switch_channel_expand_variables(channel, g_template_str);
	}

	if (!log_line) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating cdr\n");
		return SWITCH_STATUS_FALSE;
	}

	path = switch_mprintf("%s%sMaster.csv", log_dir, SWITCH_PATH_SEPARATOR);
	assert(path);
	write_cdr(path, log_line);
	free(path);


	if (log_line != g_template_str) {
		free(log_line);
	}

	return status;
}
Esempio n. 15
0
switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch_event_t *params, rc_handle *handle, VALUE_PAIR **send, switch_xml_t fields) 
{
	switch_xml_t param;
	void *av_value = NULL;
	
	if ( (param = switch_xml_child(fields, "param")) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under the fields section\n");
		goto err;		
	}
	
	for (; param; param = param->next) {
		DICT_ATTR *attribute = NULL;
		DICT_VENDOR *vendor = NULL;
		int attr_num = 0, vend_num = 0;
		
		char *var = (char *) switch_xml_attr(param, "name");
		char *vend = (char *) switch_xml_attr(param, "vendor");
		char *variable = (char *) switch_xml_attr(param, "variable");
		char *variable_secondary = (char *) switch_xml_attr(param, "variable_secondary");
		char *val_default = (char *) switch_xml_attr(param, "default");
		char *format = (char *) switch_xml_attr(param, "format");
		char *other_leg = (char *) switch_xml_attr(param, "other_leg");

		attribute = rc_dict_findattr(handle, var);
		
		if ( attribute == NULL ) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate attribute '%s' in the configured dictionary\n", var);
			goto err;
		}
		
		if ( GLOBAL_DEBUG ) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict attr '%s' value '%d' type '%d'\n", 
							  attribute->name, attribute->value, attribute->type);
		}
		
		attr_num = attribute->value;
		
		if ( vend ) {
			vendor = rc_dict_findvend(handle, vend);
			
			if ( vendor == NULL ) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate vendor '%s' in the configured dictionary %p\n", 
								  vend, vend);
				goto err;
			}			

			if ( GLOBAL_DEBUG ) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict vend name '%s' vendorpec '%d'\n", 
								  vendor->vendorname, vendor->vendorpec);
			}
			
			vend_num = vendor->vendorpec;
		} 
		
		if ( var ) {
			if ( session ) {
				switch_channel_t *channel = switch_core_session_get_channel(session);
				
				/*  Accounting only */
				if ( strncmp( var, "h323-setup-time", 15) == 0 ) {
					switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel);
					switch_time_t time = profile->times->created;
					switch_time_exp_t tm;
					
					if ( !time ) {
						goto end_loop;
					}
					
					switch_time_exp_lt(&tm, time);
					
					if ( GLOBAL_TIME_FORMAT == 1 ) {
						av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u",
												  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000,
												  GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon],
												  tm.tm_mday, tm.tm_year + 1900);
					} else {
						av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d",
												  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
												  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec,
												  tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600);
					}

					if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
						goto err;
					} 
					if ( GLOBAL_DEBUG ) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value);
					}
				} else if ( strncmp( var, "h323-connect-time", 17) == 0 ) {
					switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel);
					switch_time_t time = profile->times->answered;
					switch_time_exp_t tm;

					if ( !time ) {
						goto end_loop;
					}
					
					switch_time_exp_lt(&tm, time);

					if ( GLOBAL_TIME_FORMAT == 1 ) {
						av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u",
												  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000,
												  GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon],
												  tm.tm_mday, tm.tm_year + 1900);
					} else {
						av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d",
												  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
												  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec,
												  tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600);
					}

					if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
						goto err;
					} 
					if ( GLOBAL_DEBUG ) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value);
					}
				} else if ( strncmp( var, "h323-disconnect-time", 20) == 0 ) {
					switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel);
					switch_time_t time = profile->times->hungup;
					switch_time_exp_t tm;

					if ( !time ) {
						if ( variable_secondary != NULL && strncmp(variable_secondary, "now", 3) == 0 ) {
							time = switch_time_now();
						} else {
							goto end_loop;
						}
					}
					
					switch_time_exp_lt(&tm, time);

					if ( GLOBAL_TIME_FORMAT == 1 ) {
						av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u",
												  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000,
												  GLOBAL_TIME_FORMAT, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon],
												  tm.tm_mday, tm.tm_year + 1900);
					} else {
						av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d",
												  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
												  tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec,
												  tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600);
					}

					if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
						goto err;
					} 
					if ( GLOBAL_DEBUG ) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value);
					}
				} else if ( strncmp( var, "h323-disconnect-cause", 21) == 0 ) {
					switch_call_cause_t cause = switch_channel_get_cause(channel);
					av_value = switch_mprintf("h323-disconnect-cause=%x", cause);
					if (rc_avpair_add(handle, send, 30, av_value, -1, 9) == NULL) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add disconnect cause \n");
						goto err;
					}			
					
				} else {
					if ( format == NULL ) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing format attribute for %s variable\n", variable);
						goto err;
					}

					if ( attribute->type == 0 ) {
						const char *val = NULL;
						
						if ( other_leg ) {
							val = switch_channel_get_variable_partner(channel, variable);
							if ( val == NULL && variable_secondary != NULL) {
								val = switch_channel_get_variable_partner(channel, variable_secondary);
							}
						} else {
							val = switch_channel_get_variable(channel, variable);
							if ( val == NULL && variable_secondary != NULL) {
								val = switch_channel_get_variable(channel, variable_secondary);
							}
						}
						
						if ( val == NULL && val_default != NULL) {
							av_value = switch_mprintf(format, val_default);							
						} else {
							av_value = switch_mprintf(format, val);
						}
						
						if ( GLOBAL_DEBUG ) {
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value);
						}
				
						if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) {
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
											  "mod_xml_radius: failed to add option with val '%s' to handle\n", (char *) av_value);
							goto err;
						}			
					} else if ( attribute->type == 1 ) {
						int number = atoi(switch_channel_get_variable(channel, variable));
						
						if (rc_avpair_add(handle, send, attr_num, &number, -1, vend_num) == NULL) {
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
											  "mod_xml_radius: failed to add option with value '%d' to handle\n", number);
							goto err;
						}						
					}
				}			
			} else if ( params ) {
				/* Auth only */
				char *tmp = switch_event_get_header(params, variable);

				if ( GLOBAL_DEBUG ) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: param var '%s' val: %s\n", variable, tmp);
				}
				
				if ( tmp == NULL ) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Unable to locate '%s' on the event\n", variable);
					goto err;					
				}
				
				av_value = switch_mprintf(format, tmp);
				if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
					goto err;
				}				
			} else {
				goto err;
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: all params must have a name attribute\n");
			goto err;
		}

	end_loop:
		if ( av_value != NULL ) {
			free(av_value);
			av_value  = NULL;
		}
	}
	
	return SWITCH_STATUS_SUCCESS;
 err:
	if ( av_value != NULL ) {
		free(av_value);
		av_value  = NULL;
	}
	return SWITCH_STATUS_GENERR;
	
}
Esempio n. 16
0
static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int noat, char *separator)
{
    switch_status_t sstatus = SWITCH_STATUS_SUCCESS;
    char *sql = NULL;
    route_callback_t pdata;

    if (!switch_odbc_available()) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
                          "mod_easyroute requires core ODBC support. Please refer to the documentation on how to enable this\n");
        return sstatus;
    }

    memset(&pdata, 0, sizeof(pdata));
    if (!globals.custom_query) {
        sql = switch_mprintf(SQL_LOOKUP, dn);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing static Query\n[%s]\n", sql);
    } else {
        sql = switch_mprintf(globals.custom_query, dn);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing custom Query\n[%s]\n", sql);
    }

    if (globals.mutex) {
        switch_mutex_lock(globals.mutex);
    }
    /* Do the Query */
    if (globals.master_odbc && switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS) {
        char tmp_profile[129];
        char tmp_gateway[129];

        if (zstr(pdata.limit)) {
            switch_set_string(results->limit, "9999");
        } else {
            switch_set_string(results->limit, pdata.limit);
        }

        if (zstr(pdata.techprofile)) {
            switch_set_string(tmp_profile, globals.default_techprofile);
        } else {
            switch_set_string(tmp_profile, pdata.techprofile);
        }

        if (zstr(pdata.gateway)) {
            switch_set_string(tmp_gateway, globals.default_gateway);
        } else {
            switch_set_string(tmp_gateway, pdata.gateway);
        }

        if (zstr(pdata.translated)) {
            switch_set_string(results->translated, dn);
        } else {
            switch_set_string(results->translated, pdata.translated);
        }
        if (noat) {
            switch_snprintf(results->dialstring, 256, "%s/%s%s", tmp_profile, results->translated, tmp_gateway);
        } else if (separator) {
            switch_snprintf(results->dialstring, 256, "%s/%s%s%s", tmp_profile, results->translated, separator, tmp_gateway);
        } else {
            switch_snprintf(results->dialstring, 256, "%s/%s@%s", tmp_profile, results->translated, tmp_gateway);
        }
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "THE ROUTE [%s]\n", results->dialstring);

        if (zstr(pdata.group)) {
            switch_set_string(results->group, "");
        } else {
            switch_set_string(results->group, pdata.group);
        }

        if (zstr(pdata.acctcode)) {
            switch_set_string(results->acctcode, "");
        } else {
            switch_set_string(results->acctcode, pdata.acctcode);
        }
    } else {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DB Error Setting Default Route!\n");
        switch_set_string(results->limit, "9999");
        if (noat) {
            switch_snprintf(results->dialstring, 256, "%s/%s%s", globals.default_techprofile, dn, globals.default_gateway);
        } else if (separator) {
            switch_snprintf(results->dialstring, 256, "%s/%s%s%s", globals.default_techprofile, dn, separator, globals.default_gateway);
        } else {
            switch_snprintf(results->dialstring, 256, "%s/%s@%s", globals.default_techprofile, dn, globals.default_gateway);
        }
        switch_set_string(results->group, "");
        switch_set_string(results->acctcode, "");
    }

    switch_safe_free(sql);

    if (globals.mutex) {
        switch_mutex_unlock(globals.mutex);
    }
    return sstatus;
}
Esempio n. 17
0
/**
 * Encode log as GELF
 */
static char *to_gelf(const switch_log_node_t *node, switch_log_level_t log_level)
{
	char *gelf_text = NULL;
	cJSON *gelf = cJSON_CreateObject();
	char *hostname;
	char timestamp[32];
	char *full_message = node->content;
	char short_message[151];
	char *short_message_end = NULL;
	char *parsed_full_message = NULL;
	char *field_name = NULL;
	switch_event_t *log_fields = NULL;
	switch_core_session_t *session = NULL;

	cJSON_AddItemToObject(gelf, "version", cJSON_CreateString("1.1"));
	if ((hostname = switch_core_get_variable("hostname")) && !zstr(hostname)) {
		cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname));
	} else if ((hostname = switch_core_get_variable("local_ip_v4")) && !zstr(hostname)) {
		cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname));
	}
	switch_snprintf(timestamp, 32, "%"SWITCH_UINT64_T_FMT".%d", (uint64_t)(node->timestamp / 1000000), (node->timestamp % 1000000) / 1000);
	cJSON_AddItemToObject(gelf, "timestamp", cJSON_CreateString(timestamp));
	cJSON_AddItemToObject(gelf, "_microtimestamp", cJSON_CreateNumber(node->timestamp));
	cJSON_AddItemToObject(gelf, "level", cJSON_CreateNumber(to_graylog2_level(log_level)));
	cJSON_AddItemToObject(gelf, "_ident", cJSON_CreateString("freeswitch"));
	cJSON_AddItemToObject(gelf, "_pid", cJSON_CreateNumber((int)getpid()));
	if (!zstr(node->userdata)) {
		cJSON_AddItemToObject(gelf, "_uuid", cJSON_CreateString(node->userdata));
	}
	if (!zstr_buf(node->file)) {
		cJSON_AddItemToObject(gelf, "_file", cJSON_CreateString(node->file));
		cJSON_AddItemToObject(gelf, "_line", cJSON_CreateNumber(node->line));
	}
	if (!zstr_buf(node->func)) {
		cJSON_AddItemToObject(gelf, "_function", cJSON_CreateString(node->func));
	}

	/* skip initial space and new line */
	if (*full_message == ' ') {
		full_message++;
	}
	if (*full_message == '\n') {
		full_message++;
	}

	/* get fields from channel data, if configured */
	if (!zstr(node->userdata) && (session = switch_core_session_locate(node->userdata))) {
		switch_channel_t *channel = switch_core_session_get_channel(session);
		switch_event_header_t *hp;
		/* session_fields name mapped to variable name */
		for (hp = globals.session_fields->headers; hp; hp = hp->next) {
			if (!zstr(hp->name) && !zstr(hp->value)) {
				const char *val = switch_channel_get_variable(channel, hp->value);
				if (!zstr(val)) {
					if (!log_fields) {
						switch_event_create_plain(&log_fields, SWITCH_EVENT_CHANNEL_DATA);
					}
					switch_event_add_header_string(log_fields, SWITCH_STACK_BOTTOM, hp->name, val);
				}
			}
		}
		switch_core_session_rwunlock(session);
	}

	/* parse list of fields from message text, if any */
	if (strncmp(full_message, "LOG_FIELDS", 10) == 0) {
		switch_event_create_brackets(full_message+10, '[', ']', ',', &log_fields, &parsed_full_message, SWITCH_TRUE);
		full_message = parsed_full_message;
	}

	/* add additional fields */
	if (log_fields) {
		switch_event_header_t *hp;
		for (hp = log_fields->headers; hp; hp = hp->next) {
			if (!zstr(hp->name) && !zstr(hp->value)) {
				if (strncmp(hp->name, "@#", 2) == 0) {
					field_name = switch_mprintf("_%s", hp->name + 2);
					cJSON_AddItemToObject(gelf, field_name, cJSON_CreateNumber(strtod(hp->value, NULL)));
				} else {
					field_name = switch_mprintf("_%s", hp->name);
					cJSON_AddItemToObject(gelf, field_name, cJSON_CreateString(hp->value));
				}
				free(field_name);
			}
		}
		switch_event_destroy(&log_fields);
	}

	cJSON_AddItemToObject(gelf, "full_message", cJSON_CreateString(full_message));

	switch_snprintf(short_message, sizeof(short_message) - 1, "%s", full_message);
	if ((short_message_end = strchr(short_message, '\n'))) {
		*short_message_end = '\0';
	}
	cJSON_AddItemToObject(gelf, "short_message", cJSON_CreateString(short_message));

	gelf_text = cJSON_PrintUnformatted(gelf);
	cJSON_Delete(gelf);
	
	switch_safe_free(parsed_full_message);
	
	return gelf_text;
}
Esempio n. 18
0
switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params)
{
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	char *sql = NULL;
	char entry_count[80] = "";
	callback_t cbt = { 0 };
	int result_count;
	char macro[256] = "";
	listing_callback_t listing_cbt;
	int cur_entry = 0;
	cbt.buf = entry_count;
	cbt.len = sizeof(entry_count);

	sql =
		switch_mprintf("select count(*) from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%'",
					   globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name ? "last_name_digit" : "first_name_digit"),
					   params->digits);

	directory_execute_sql_callback(profile->mutex, sql, sql2str_callback, &cbt);
	switch_safe_free(sql);

	result_count = atoi(entry_count);

	if (result_count == 0) {
		switch_snprintf(macro, sizeof(macro), "%d", result_count);
		switch_ivr_phrase_macro(session, DIR_RESULT_COUNT, macro, NULL, NULL);
		params->try_again = 1;
		return SWITCH_STATUS_BREAK;
	} else if (profile->max_result != 0 && result_count > profile->max_result) {
		switch_ivr_phrase_macro(session, DIR_RESULT_COUNT_TOO_LARGE, NULL, NULL, NULL);
		params->try_again = 1;
		return SWITCH_STATUS_BREAK;
	} else {
		switch_snprintf(macro, sizeof(macro), "%d", result_count);
		switch_ivr_phrase_macro(session, DIR_RESULT_COUNT, macro, NULL, NULL);
	}

	memset(&listing_cbt, 0, sizeof(listing_cbt));
	listing_cbt.params = params;

	sql =
		switch_mprintf
		("select extension, full_name, last_name, first_name, name_visible, exten_visible from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%' order by last_name, first_name",
		 globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name ? "last_name_digit" : "first_name_digit"), params->digits);

	for (cur_entry = 0; cur_entry < result_count; cur_entry++) {
		listing_cbt.index = 0;
		listing_cbt.want = cur_entry;
		listing_cbt.move = ENTRY_MOVE_NEXT;
		directory_execute_sql_callback(profile->mutex, sql, listing_callback, &listing_cbt);
		status = listen_entry(session, profile, &listing_cbt);
		if (!zstr(listing_cbt.transfer_to)) {
			switch_copy_string(params->transfer_to, listing_cbt.transfer_to, 255);
			break;
		}
		if (listing_cbt.new_search) {
			params->try_again = 1;
			goto end;

		}
		if (listing_cbt.move == ENTRY_MOVE_NEXT) {
			if (cur_entry == result_count - 1) {
				switch_snprintf(macro, sizeof(macro), "%d", result_count);
				switch_ivr_phrase_macro(session, DIR_RESULT_LAST, macro, NULL, NULL);
				cur_entry -= 1;
			}
		}
		if (listing_cbt.move == ENTRY_MOVE_PREV) {
			if (cur_entry <= 0) {
				cur_entry = -1;
			} else {
				cur_entry -= 2;
			}
		}
		if (status == SWITCH_STATUS_TIMEOUT) {
			goto end;
		}
		if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
			goto end;
		}
	}

  end:
	switch_safe_free(sql);
	return status;

}
Esempio n. 19
0
static int lua_parse_and_execute(lua_State * L, char *input_code)
{
    int error = 0;

    if (zstr(input_code)) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No code to execute!\n");
        return 1;
    }

    while(input_code && (*input_code == ' ' || *input_code == '\n' || *input_code == '\r')) input_code++;

    if (*input_code == '~') {
        char *buff = input_code + 1;
        error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0, 1);	//lua_pcall(L, 0, 0, 0);
    } else if (!strncasecmp(input_code, "#!/lua", 6)) {
        char *buff = input_code + 6;
        error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0, 1);	//lua_pcall(L, 0, 0, 0);
    } else {
        char *args = strchr(input_code, ' ');
        if (args) {
            char *code = NULL;
            int x, argc;
            char *argv[128] = { 0 };
            *args++ = '\0';

            if ((argc = switch_separate_string(args, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
                switch_stream_handle_t stream = { 0 };
                SWITCH_STANDARD_STREAM(stream);

                stream.write_function(&stream, " argv = {[0]='%y', ", input_code);
                for (x = 0; x < argc; x++) {
                    stream.write_function(&stream, "'%y'%s", argv[x], x == argc - 1 ? "" : ", ");
                }
                stream.write_function(&stream, " };");
                code = (char *) stream.data;
            } else {
                code = switch_mprintf("argv = {[0]='%s'};", input_code);
            }

            if (code) {
                error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0, 1);
                switch_safe_free(code);
            }
        } else {
            // Force empty argv table
            char *code = NULL;
            code = switch_mprintf("argv = {[0]='%s'};", input_code);
            error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0, 1);
            switch_safe_free(code);
        }

        if (!error) {
            char *file = input_code, *fdup = NULL;

            if (!switch_is_file_path(file)) {
                fdup = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.script_dir, file);
                switch_assert(fdup);
                file = fdup;
            }
            error = luaL_loadfile(L, file) || docall(L, 0, 0, 0, 1);
            switch_safe_free(fdup);
        }
    }

    if (error) {
        const char *err = lua_tostring(L, -1);
        if (!zstr(err)) {
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err);
        }
        lua_pop(L, 1);			/* pop error message from the stack */
    }

    return error;
}
Esempio n. 20
0
/*call呼叫状态通知
*/
int cari_net_callstatus_change(int notifyCode,
							   switch_event_t *event)
{
	inner_ResultResponse_Frame	*inner_respFrame = NULL;
	char						*result			 = NULL;
	char						*mobCaller		 = NULL;
	char						*mobCallee	     = NULL;
	char						*mobCallState	 = NULL;
	char						*mobCallType	 = NULL;

	mobCaller = switch_event_get_header(event, CARICCP_MOBCALLER);	     //主叫号
	mobCallee = switch_event_get_header(event, CARICCP_MOBCALLEE);       //被叫号
	mobCallState = switch_event_get_header(event, CARICCP_MOBCALLSTATE); //呼叫状态
	mobCallType = switch_event_get_header(event, CARICCP_MOBCALLTYPE);	 //呼叫类型

	if (isNullStr(mobCallType)){//默认为p2p类型
		mobCallType = "P2P";
	}
	if (isNullStr(mobCallState)){
		string str = intToString(/*CARICCP_MOB_USER_HANGUP*/5);//默认为:挂机
		mobCallState = (char*)str.c_str();
	}

	//new响应帧
	inner_respFrame = CARI_CCP_VOS_NEW(inner_ResultResponse_Frame);

	//初始化"内部响应帧"结构体
	memset(inner_respFrame, 0, sizeof(inner_ResultResponse_Frame));

	//初始化赋值,设置了"通知类型的标识"和"通知码"
	initInnerResponseFrame(inner_respFrame, event);

	//根据"通知码"进行详细的区分
	switch(notifyCode){
	case CARICCP_NOTIFY_MOBUSER_REALTIME_CALL:
		{
			if (NULL == mobCaller || NULL == mobCallee){
				break;
			}
			//组装结果集,规定的格式为 type:状态:主叫号码〒被叫号码1,被叫号码2,type不填写默认为点呼叫
			result = switch_mprintf("%s%s%s%s%s%s%s", mobCallType,CARICCP_COLON_MARK,
				mobCallState,CARICCP_COLON_MARK,
				mobCaller, CARICCP_SPECIAL_SPLIT_FLAG, 
				mobCallee);

			break;
		}
	default:
		goto end;
	}

	if (NULL != result) {
		//存放记录
		inner_respFrame->m_vectTableValue.push_back(result);

		//将通知类型的事件发送给所有客户端
		CMsgProcess::getInstance()->notifyResult(inner_respFrame);
		//释放内存
		switch_safe_free(result);
	}

end:

	//销毁"响应帧"
	CARI_CCP_VOS_DEL(inner_respFrame);
	return CARICCP_SUCCESS_STATE_CODE;
}
Esempio n. 21
0
static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
{
	switch_bool_t r = SWITCH_TRUE;
	struct api_command_struct *acs = (struct api_command_struct *) obj;
	switch_stream_handle_t stream = { 0 };
	char *reply, *freply = NULL;
	switch_status_t status;

	if (!acs) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal error.\n");
		return NULL;
	}

	if (!acs->listener || !acs->listener->rwlock || switch_thread_rwlock_tryrdlock(acs->listener->rwlock) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! cannot get read lock.\n");
		goto done;
	}

	SWITCH_STANDARD_STREAM(stream);

	if ((status = switch_api_execute(acs->api_cmd, acs->arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) {
		reply = stream.data;
	} else {
		freply = switch_mprintf("%s: Command not found!\n", acs->api_cmd);
		reply = freply;
		r = SWITCH_FALSE;
	}

	if (!reply) {
		reply = "Command returned no output!";
		r = SWITCH_FALSE;
	}

	if (*reply == '-')
		r = SWITCH_FALSE;

	if (acs->bg) {
		switch_event_t *event;

		if (switch_event_create(&event, SWITCH_EVENT_BACKGROUND_JOB) == SWITCH_STATUS_SUCCESS) {
			ei_x_buff ebuf;

			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", acs->uuid_str);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command", acs->api_cmd);

			ei_x_new_with_version(&ebuf);

			if (acs->arg) {
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command-Arg", acs->arg);
			}

			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Successful", r ? "true" : "false");
			switch_event_add_body(event, "%s", reply);

			switch_event_fire(&event);

			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending bgapi reply to %s\n", acs->pid.node);

			ei_x_encode_tuple_header(&ebuf, 3);

			if (r)
				ei_x_encode_atom(&ebuf, "bgok");
			else
				ei_x_encode_atom(&ebuf, "bgerror");

			_ei_x_encode_string(&ebuf, acs->uuid_str);
			_ei_x_encode_string(&ebuf, reply);

			switch_mutex_lock(acs->listener->sock_mutex);
			ei_send(acs->listener->sockfd, &acs->pid, ebuf.buff, ebuf.index);
			switch_mutex_unlock(acs->listener->sock_mutex);
#ifdef EI_DEBUG
			ei_x_print_msg(&ebuf, &acs->pid, 1);
#endif

			ei_x_free(&ebuf);
		}
	} else {
		ei_x_buff rbuf;
		ei_x_new_with_version(&rbuf);
		ei_x_encode_tuple_header(&rbuf, 2);

		if (!strlen(reply)) {
			reply = "Command returned no output!";
			r = SWITCH_FALSE;
		}

		if (r) {
			ei_x_encode_atom(&rbuf, "ok");
		} else {
			ei_x_encode_atom(&rbuf, "error");
		}

		_ei_x_encode_string(&rbuf, reply);


		switch_mutex_lock(acs->listener->sock_mutex);
		ei_send(acs->listener->sockfd, &acs->pid, rbuf.buff, rbuf.index);
		switch_mutex_unlock(acs->listener->sock_mutex);
#ifdef EI_DEBUG
		ei_x_print_msg(&rbuf, &acs->pid, 1);
#endif

		ei_x_free(&rbuf);
	}

	switch_safe_free(stream.data);
	switch_safe_free(freply);

	if (acs->listener->rwlock) {
		switch_thread_rwlock_unlock(acs->listener->rwlock);
	}

  done:
	if (acs->bg) {
		switch_memory_pool_t *pool = acs->pool;
		acs = NULL;
		switch_core_destroy_memory_pool(&pool);
		pool = NULL;
	}
	return NULL;

}
Esempio n. 22
0
/*mob user的在线状态的变更通知/增加,删除用户的通知等通知类型的消息处理
*/
int cari_net_mobuserstatus_change(int notifyCode,			//通知码
								  switch_event_t *event)	//事件
{
	inner_ResultResponse_Frame	*inner_respFrame = NULL;
	char						*result			 = NULL;
	char						*mobUserId		 = NULL;
	char						*mobUserState	 = NULL;
	char						*mobUserInfo	 = NULL;

	mobUserId = switch_event_get_header(event, CARICCP_MOBUSERNAME);	//用户号
	mobUserState = switch_event_get_header(event, CARICCP_MOBUSERSTATE);//用户的状态
	mobUserInfo = switch_event_get_header(event, CARICCP_MOBUSERINFO);	//用户的其他关键信息

	//new响应帧
	inner_respFrame = CARI_CCP_VOS_NEW(inner_ResultResponse_Frame);

	//初始化"内部响应帧"结构体
	memset(inner_respFrame, 0, sizeof(inner_ResultResponse_Frame));

	//初始化赋值,设置了"通知类型的标识"和"通知码"
	initInnerResponseFrame(inner_respFrame, event);

	//根据"通知码"进行详细的区分
	switch(notifyCode){
	case CARICCP_NOTIFY_MOBUSER_STATE_CHANGED:
		{
			if (NULL == mobUserId || NULL == mobUserState){
				break;
			}
			//组装结果集,单个记录"多值",使用CARICCP_COLON_MARK(:)分割
			if (NULL == mobUserInfo || 0 == strlen(mobUserInfo)) {
				result = switch_mprintf("%s %s %s", mobUserId, CARICCP_COLON_MARK, mobUserState);
			} else {
				result = switch_mprintf("%s %s %s %s %s", mobUserId, CARICCP_COLON_MARK, mobUserState, CARICCP_COLON_MARK, mobUserInfo);
			}

			break;
		}
	case CARICCP_NOTIFY_ADD_MOBUSER:
	case CARICCP_NOTIFY_DEL_MOBUSER:
	case CARICCP_NOTIFY_MOD_MOBUSER:
		{
			//用户名设置为结果集
			result = switch_mprintf("%s", mobUserId);
			break;
		}

	default:
		goto end;
	}

	if (NULL != result) {
		//查看有几条记录存在,记录之间使用\r\n换行标识,值和值之间应该使用特殊符"〒"分开
		splitString(result, CARICCP_SPECIAL_SPLIT_FLAG, inner_respFrame->m_vectTableValue);

		//将通知类型的事件发送给所有客户端
		CMsgProcess::getInstance()->notifyResult(inner_respFrame);

		//释放内存
		switch_safe_free(result);
	}

/**/
end:
	//销毁"响应帧"
	CARI_CCP_VOS_DEL(inner_respFrame);
	return CARICCP_SUCCESS_STATE_CODE;
}
Esempio n. 23
0
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	const char *log_dir = NULL, *accountcode = NULL, *a_template_str = NULL, *g_template_str = NULL;
	char *log_line, *path = NULL,*file = NULL;
	const char *start_stamp = NULL;

	char *lbuf = NULL;
	char *argv[4] = { 0 };
	int argc = 0;

	char *start_day=NULL;
	char *dargv[8] = {0};
	int dargc = 0;
	char *Y,*M,*D;

	if (globals.shutdown) {
		return SWITCH_STATUS_SUCCESS;
	}

	if (!((globals.legs & CDR_LEG_A) && (globals.legs & CDR_LEG_B))) {
		if ((globals.legs & CDR_LEG_A)) {
			if (switch_channel_get_originator_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		} else {
			if (switch_channel_get_originatee_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		}
	}

	get_var(start_stamp);
	if(!start_stamp){
		return SWITCH_STATUS_SUCCESS;
	}
	fire_cdr_event(channel);

	if(!(lbuf = strdup(start_stamp))){
		return SWITCH_STATUS_SUCCESS;
	}
	argc = switch_separate_string(lbuf,' ',argv,(sizeof(argv)/sizeof(argv[0])));
	if(argc < 1){
		goto done;
	}
	if(!(start_day = strdup(argv[0]))){
		goto done;
	}
	dargc = switch_separate_string(start_day,'-',dargv,(sizeof(dargv)/sizeof(dargv[0])));
	if(dargc < 3){
		goto done;
	}
	Y = dargv[0];
	M = dargv[1];
	D = dargv[2];

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

	if (switch_dir_make_recursive(log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", log_dir);
		//return SWITCH_STATUS_FALSE;
		goto done;
	}

	/*if (globals.debug) {
		switch_event_t *event;
		if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
			char *buf;
			switch_channel_event_set_data(channel, event);
			switch_event_serialize(event, &buf, SWITCH_FALSE);
			switch_assert(buf);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf);
			switch_event_destroy(&event);
			free(buf);
		}
	}*/

	g_template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template);

	if (!(accountcode = switch_channel_get_variable(channel, "ACCOUNTCODE"))) {
		accountcode = switch_channel_get_variable(channel,"dialed_extension");
	}
	if(accountcode){
		a_template_str = (const char *) switch_core_hash_find(globals.template_hash, accountcode);
	}
	if (!g_template_str) {
		g_template_str = "\"${accountcode}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${caller_id}\",\"${channel_name}\",\"${bridge_channel}\",\"${last_app}\",\"${last_arg}\",\"${start_stamp}\",\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${amaflags}\",\"${uuid}\",\"${userfield}\";";
	}

	if (!a_template_str) {
		a_template_str = g_template_str;
	}

	
	if ((accountcode) && (!globals.masterfileonly)) {

		log_line = switch_channel_expand_variables(channel, a_template_str);
		if (!log_line) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating cdr\n");
			//return SWITCH_STATUS_FALSE;
			goto done;
		}

		path = switch_mprintf("%s%s%s%s%s-%s",log_dir,SWITCH_PATH_SEPARATOR,accountcode,SWITCH_PATH_SEPARATOR,Y,M);
		assert(path);
		if (switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS| SWITCH_FPROT_WREAD | SWITCH_FPROT_WEXECUTE, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", path);
			//return SWITCH_STATUS_FALSE;
			free(path);
			goto done;
		}
		
		//free(path);
		
		file = switch_mprintf("%s%s%s.csv", path, SWITCH_PATH_SEPARATOR, D);
		assert(file);
		write_cdr(file, log_line);
		free(file);
		free(path);

		if (log_line != a_template_str) {
			free(log_line);
		}
		
	}
	else{
		log_line = switch_channel_expand_variables(channel, g_template_str);

		if (!log_line) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating cdr\n");
			//return SWITCH_STATUS_FALSE;
			goto done;
		}

		path = switch_mprintf("%s%sMaster.csv", log_dir, SWITCH_PATH_SEPARATOR);
		assert(path);
		write_cdr(path, log_line);
		free(path);
		
		if (log_line != g_template_str) {
			free(log_line);
		}
	}

 done:
	switch_safe_free(start_day);
	switch_safe_free(lbuf);
	return status;

}