static int launch_streams(const char *name)
{
	switch_xml_t cfg, xml, directory;
	int x = 0;

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

	if (zstr(name)) {
		for (directory = switch_xml_child(cfg, "directory"); directory; directory = directory->next) {
			char *name = (char *) switch_xml_attr(directory, "name");
			char *path = (char *) switch_xml_attr(directory, "path");
			launch_thread(name, path, directory);
			x++;
		}
	} else if ((directory = switch_xml_find_child(cfg, "directory", "name", name))) {
		char *path = (char *) switch_xml_attr(directory, "path");
		launch_thread(name, path, directory);
		x++;
	}
	switch_xml_free(xml);

	return x;
}
switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switch_xml_t conditions) {
	switch_xml_t condition, param;
	char *channel_var = NULL;
	const char *channel_val = NULL;
	char *regex = NULL;
	char *anti = NULL;
	int all_matched = 1;
	int result = 0;
	
	if ( (condition = switch_xml_child(conditions, "condition")) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a condition under the conditions section\n");
		return SWITCH_STATUS_FALSE;
	}
	
	for (; condition; condition = condition->next) {
		
		if ( (param = switch_xml_child(condition, "param")) == NULL) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under this condition\n");
			return SWITCH_STATUS_FALSE;
		}
		
		all_matched = 1;
		for (; param && all_matched; param = param->next) {
			channel_var = (char *) switch_xml_attr(param, "var");
			regex = (char *) switch_xml_attr(param, "regex");
			anti = (char *) switch_xml_attr(param, "anti");
			
			if ( channel_var == NULL || regex == NULL ) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improperly constructed mod_radius condition: %s %s\n", channel_var, regex);
				continue;
			}
			
			if ( ( channel_val = switch_channel_get_variable(channel, channel_var) ) == NULL ) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
								  "Improperly constructed mod_radius condition, no such channel variable: %s %s\n", channel_var, regex);
				continue;
			}

			result = ( switch_regex_match( channel_val, regex) != SWITCH_STATUS_SUCCESS);
			if (( anti == NULL && result ) || ( anti != NULL && !result ) ){
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Didn't match: %s == %s \n", switch_channel_get_variable(channel, channel_var), regex);
				all_matched = 0;
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Result of %s match: %s == %s \n", 
								  anti, switch_channel_get_variable(channel, channel_var), regex);
			}
		}

		if ( all_matched ) {
			return SWITCH_STATUS_SUCCESS;
		}
	}
	
	return SWITCH_STATUS_FALSE;
}
Exemple #3
0
/*login是否成功
*/
bool CBaseModule::isLoginSuc(string username,
							 string userpwd)
{
	//临时方案:目前根据文件读取
	bool bRes = false;
	switch_xml_t x_NEs,x_ne;
	const char *errmsg[1]={ 0 };

	const char *name=NULL;
	const char *pwd=NULL;
	char *nefile = switch_mprintf("%s%s%s", 
		SWITCH_GLOBAL_dirs.conf_dir, 
		SWITCH_PATH_SEPARATOR, 
		CARI_CCP_OPUSER_XML_FILE
		);

	if (!cari_common_isExistedFile(nefile)){
		goto end;
	}

	//将内容转换成xml的结构(注意:中文字符问题)
	x_NEs = cari_common_parseXmlFromFile(nefile);
	if (!x_NEs){
		goto end;
	}

	//遍历查找
	x_ne = switch_xml_child(x_NEs, "opuser");
	for (; x_ne; x_ne = x_ne->next) {
		name = switch_xml_attr(x_ne, "name");
		pwd = switch_xml_attr(x_ne, "pwd");
		if (isEqualStr(username.c_str(),name)
			&& isEqualStr(userpwd.c_str(),pwd)){

				bRes = true;
				break;
		}	
	}

end:
	switch_safe_free(nefile);
	return bRes;
}
Exemple #4
0
void switch_load_timezones(switch_bool_t reload)
{
	switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
	unsigned total = 0;

	if (TIMEZONES_LIST.hash) {
		switch_core_hash_destroy(&TIMEZONES_LIST.hash);
	}

	if (TIMEZONES_LIST.pool) {
		switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool);
	}

	memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST));
	switch_core_new_memory_pool(&TIMEZONES_LIST.pool);
	switch_core_hash_init(&TIMEZONES_LIST.hash, TIMEZONES_LIST.pool);

	if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) {
		if ((x_lists = switch_xml_child(cfg, "timezones"))) {
			for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) {
				const char *name = switch_xml_attr(x_list, "name");
				const char *value = switch_xml_attr(x_list, "value");

				if (zstr(name)) {
					continue;
				}

				if (zstr(value)) {
					continue;
				}

				switch_core_hash_insert(TIMEZONES_LIST.hash, name, switch_core_strdup(TIMEZONES_LIST.pool, value));
				total++;
			}
		}

		switch_xml_free(xml);
	}

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total);
}
Exemple #5
0
switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switch_xml_t conditions) {
	switch_xml_t condition, param;
	char *channel_var = NULL;
	char *regex = NULL;
	int all_matched = 1;
	
	if ( (condition = switch_xml_child(conditions, "condition")) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a condition under the conditions section\n");
		return SWITCH_STATUS_FALSE;
	}
	
	for (; condition; condition = condition->next) {
		
		if ( (param = switch_xml_child(condition, "param")) == NULL) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under this condition\n");
			return SWITCH_STATUS_FALSE;
		}
		
		all_matched = 1;
		for (; param && all_matched; param = param->next) {
			channel_var = (char *) switch_xml_attr(param, "var");
			regex = (char *) switch_xml_attr(param, "regex");
			
			if ( channel_var == NULL || regex == NULL ) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improperly constructed mod_radius condition: %s %s\n", channel_var, regex);
			}
			
			if ( switch_regex_match( switch_channel_get_variable(channel, channel_var), regex) != SWITCH_STATUS_SUCCESS) {
				all_matched = 0;
			}
		}

		if ( all_matched ) {
			return SWITCH_STATUS_SUCCESS;
		}
	}
	
	return SWITCH_STATUS_FALSE;
}
static void do_config(switch_bool_t reload)
{
	switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
	if ((xml = switch_xml_open_cfg("hash.conf", &cfg, NULL))) {
		if ((x_lists = switch_xml_child(cfg, "remotes"))) {
			for (x_list = switch_xml_child(x_lists, "remote"); x_list; x_list = x_list->next) {
				const char *name = switch_xml_attr(x_list, "name");
				const char *host = switch_xml_attr(x_list, "host");
				const char *szport = switch_xml_attr(x_list, "port");
				const char *username = switch_xml_attr(x_list, "username");
				const char *password = switch_xml_attr(x_list, "password");
				const char *szinterval = switch_xml_attr(x_list, "interval");
				uint16_t port = 0;
				int	interval = 0;
				limit_remote_t *remote;
				switch_threadattr_t *thd_attr = NULL;
				
				if (reload) {
					switch_thread_rwlock_rdlock(globals.remote_hash_rwlock);
					if (switch_core_hash_find(globals.remote_hash, name)) {
						switch_thread_rwlock_unlock(globals.remote_hash_rwlock);
						continue;
					}
					switch_thread_rwlock_unlock(globals.remote_hash_rwlock);
				}

				if (!zstr(szport)) {
					port = (uint16_t)atoi(szport);
				}
				
				if (!zstr(szinterval)) {
					interval = atoi(szinterval);
				}
				
				remote = limit_remote_create(name, host, port, username, password, interval);
				
				remote->state = REMOTE_DOWN;	
				
				switch_threadattr_create(&thd_attr, remote->pool);
				switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
				switch_thread_create(&remote->thread, thd_attr, limit_remote_thread, remote, remote->pool);
			}
		}
		switch_xml_free(xml);
	}
}
static switch_status_t load_config(switch_memory_pool_t *pool)
{
	char *cf = "cdr_csv.conf";
	switch_xml_t cfg, xml, settings, param;
	switch_status_t status = SWITCH_STATUS_SUCCESS;

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

	globals.pool = pool;

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

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

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

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

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

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

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


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

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

	return status;
}
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;
}
static int sangoma_parse_config(void)
{
	switch_xml_t cfg, settings, param, vocallos, xml, vocallo;
	struct in_addr vocallo_base_ip;
	char ipbuff[50];
	char netbuff[50];
	int host_ipaddr = 0;
	int host_netmaskaddr = 0;
	int vidx = 0;
	int baseudp = 0;

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reading sangoma codec configuration\n");
	if (!(xml = switch_xml_open_cfg(SANGOMA_TRANSCODE_CONFIG, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to open sangoma codec configuration %s\n", SANGOMA_TRANSCODE_CONFIG);
		return -1;
	}

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

	if ((settings = switch_xml_child(cfg, "settings"))) {
		/* nothing here yet */
		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");

				/* this parameter overrides the default list of codecs to load */
				if (!strcasecmp(var, "register")) {
					strncpy(g_codec_register_list, val, sizeof(g_codec_register_list)-1);
					g_codec_register_list[sizeof(g_codec_register_list)-1] = 0;
				} else if (!strcasecmp(var, "noregister")) {
					strncpy(g_codec_noregister_list, val, sizeof(g_codec_noregister_list)-1);
					g_codec_noregister_list[sizeof(g_codec_noregister_list)-1] = 0;
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored unknown Sangoma codec setting %s\n", var);
				}
		}
	}

	if ((vocallos = switch_xml_child(cfg, "vocallos"))) {
		for (vocallo = switch_xml_child(vocallos, "vocallo"); vocallo; vocallo = vocallo->next) {
			const char *name = switch_xml_attr(vocallo, "name");
			if (!name) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Sangoma vocallo found with no name= attribute, ignoring!\n");
				continue;
			}

			if (load_nic_network_information(name, &g_init_cfg.host_nic_vocallo_cfg[vidx])) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
						"Ignoring vocallo %s, failed to retrieve its network configuration\n", name);
				continue;
			}

			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Configuring vocallo %s\n", name);

			g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_base_udp_port = SANGOMA_DEFAULT_UDP_PORT;
			g_init_cfg.host_nic_vocallo_cfg[vidx].silence_suppression = 0;
			for (param = switch_xml_child(vocallo, "param"); param; param = param->next) {
				char *var = (char *)switch_xml_attr_soft(param, "name");
				char *val = (char *)switch_xml_attr_soft(param, "value");

				/* starting UDP port to be used by the vocallo modules */
				if (!strcasecmp(var, "baseudp")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec base udp port %s\n", val);
					baseudp = atoi(val);
					if (baseudp < SANGOMA_MIN_UDP_PORT || baseudp > SANGOMA_MAX_UDP_PORT) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
								"Invalid Sangoma codec base udp port %s, using default %d\n", 
								val, SANGOMA_DEFAULT_UDP_PORT);
						break;
					}
					g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_base_udp_port = baseudp;
				}
				else if (!strcasecmp(var, "vocalloaddr")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec vocallo addr %s\n", val);
					if (switch_inet_pton(AF_INET, val, &vocallo_base_ip) <= 0) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Sangoma codec vocallo addr %s\n", val);
						break;
					}
					g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_ip = ntohl(vocallo_base_ip.s_addr);
				} else if (!strcasecmp(var, "silence")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec silence setting %s\n", val);
					g_init_cfg.host_nic_vocallo_cfg[vidx].silence_suppression = switch_true(val) ? 1 : 0;
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored unknown Sangoma vocallo setting %s\n", var);
				}
			}

			if (!g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_ip) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring vocallo %s, no valid address was configured\n", name);
				continue;
			}
			host_ipaddr = htonl(g_init_cfg.host_nic_vocallo_cfg[vidx].host_ip);
			host_netmaskaddr = htonl(g_init_cfg.host_nic_vocallo_cfg[vidx].host_ip_netmask);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, 
					"Configured Sangoma transcoding interface %s, IP address %s, netmask %s\n", 
					name, 
					switch_inet_ntop(AF_INET, &host_ipaddr, ipbuff, sizeof(ipbuff)),
					switch_inet_ntop(AF_INET, &host_netmaskaddr, netbuff, sizeof(netbuff)));
			strncpy(g_vocallo_names[vidx], name, sizeof(g_vocallo_names[vidx])-1);
			g_vocallo_names[vidx][sizeof(g_vocallo_names[vidx])-1] = 0;
			vidx++;
		}
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No <vocallos> section found in configuration file %s\n", SANGOMA_TRANSCODE_CONFIG);
	}

	switch_xml_free(xml);

	if (!vidx) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
		"No vocallos were configured, make sure there is at least one <vocallo> in %s.\n", SANGOMA_TRANSCODE_CONFIG);
	}

	g_init_cfg.host_nic_vocallo_sz = vidx;

	return 0;
}
static void launch_threads(void)
{
	char *cf = "local_stream.conf";
	switch_xml_t cfg, xml, directory, param;
	switch_memory_pool_t *pool;
	local_stream_source_t *source;
	switch_thread_t *thread;
	switch_threadattr_t *thd_attr = NULL;

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

	for (directory = switch_xml_child(cfg, "directory"); directory; directory = directory->next) {
		char *path = (char *) switch_xml_attr(directory, "path");
		char *name = (char *) switch_xml_attr(directory, "name");

		if (!(name && path)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid config!\n");
			continue;
		}

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

		source = switch_core_alloc(pool, sizeof(*source));
		assert(source != NULL);
		source->pool = pool;

		source->name = switch_core_strdup(source->pool, name);
		source->location = switch_core_strdup(source->pool, path);
		source->rate = 8000;
		source->interval = 20;
		source->channels = 1;
		source->timer_name = "soft";
		source->prebuf = DEFAULT_PREBUFFER_SIZE;
		source->stopped = 0;
		source->chime_freq = 30;

		for (param = switch_xml_child(directory, "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, "rate")) {
				int tmp = atoi(val);
				if (tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 || tmp == 32000 || tmp == 48000) {
					source->rate = tmp;
				}
			} else if (!strcasecmp(var, "shuffle")) {
				source->shuffle = switch_true(val);
			} else if (!strcasecmp(var, "prebuf")) {
				int tmp = atoi(val);
				if (tmp > 0) {
					source->prebuf = (uint32_t) tmp;
				}
			} else if (!strcasecmp(var, "channels")) {
				int tmp = atoi(val);
				if (tmp == 1 || tmp == 2) {
					source->channels = (uint8_t) tmp;
				}
			} else if (!strcasecmp(var, "chime-freq")) {
				int tmp = atoi(val);
				if (tmp > 1) {
					source->chime_freq = tmp;
				}
			} else if (!strcasecmp(var, "chime-max")) {
				int tmp = atoi(val);
				if (tmp > 1) {
					source->chime_max = tmp;
				}
			} else if (!strcasecmp(var, "chime-list")) {
				char *list_dup = switch_core_strdup(source->pool, val);
				source->chime_total =
					switch_separate_string(list_dup, ',', source->chime_list, (sizeof(source->chime_list) / sizeof(source->chime_list[0])));
			} else if (!strcasecmp(var, "interval")) {
				int tmp = atoi(val);
				if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) {
					source->interval = tmp;
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
									  "Interval must be multiple of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL);
				}
			} else if (!strcasecmp(var, "timer-name")) {
				source->timer_name = switch_core_strdup(source->pool, val);
			}
		}

		if (source->chime_max) {
			source->chime_max *= source->rate;
		}

		if (source->chime_total) {
			source->chime_counter = source->rate * source->chime_freq;
		}

		source->samples = switch_samples_per_packet(source->rate, source->interval);

		switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool);

		switch_threadattr_create(&thd_attr, source->pool);
		switch_threadattr_detach_set(thd_attr, 1);
		switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
		switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool);
	}

	switch_xml_free(xml);
}
Exemple #11
0
static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, switch_caller_extension_t **extension)
{
	switch_xml_t xcond, xaction, xexpression;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	char *exten_name = (char *) switch_xml_attr(xexten, "name");
	int proceed = 0;
	char *expression_expanded = NULL, *field_expanded = NULL;
	switch_regex_t *re = NULL;

	if (!exten_name) {
		exten_name = "_anon_";
	}

	for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
		char *field = NULL;
		char *do_break_a = NULL;
		char *expression = NULL;
		const char *field_data = NULL;
		int ovector[30];
		switch_bool_t anti_action = SWITCH_TRUE;
		break_t do_break_i = BREAK_ON_FALSE;

		int time_match = switch_xml_std_datetime_check(xcond);

		switch_safe_free(field_expanded);
		switch_safe_free(expression_expanded);

		if (switch_xml_child(xcond, "condition")) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Nested conditions are not allowed!\n");
			proceed = 1;
			goto done;
		}

		field = (char *) switch_xml_attr(xcond, "field");

		if ((xexpression = switch_xml_child(xcond, "expression"))) {
			expression = switch_str_nil(xexpression->txt);
		} else {
			expression = (char *) switch_xml_attr_soft(xcond, "expression");
		}

		if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) {
			expression_expanded = NULL;
		} else {
			expression = expression_expanded;
		}

		if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) {
			if (!strcasecmp(do_break_a, "on-true")) {
				do_break_i = BREAK_ON_TRUE;
			} else if (!strcasecmp(do_break_a, "on-false")) {
				do_break_i = BREAK_ON_FALSE;
			} else if (!strcasecmp(do_break_a, "always")) {
				do_break_i = BREAK_ALWAYS;
			} else if (!strcasecmp(do_break_a, "never")) {
				do_break_i = BREAK_NEVER;
			} else {
				do_break_a = NULL;
			}
		}

		if (time_match == 1) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
							  "Dialplan: %s Date/Time Match (PASS) [%s] break=%s\n",
							  switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
			anti_action = SWITCH_FALSE;
		} else if (time_match == 0) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
							  "Dialplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
							  switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
		}

		if (field) {
			if (strchr(field, '$')) {
				if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) {
					field_expanded = NULL;
					field_data = field;
				} else {
					field_data = field_expanded;
				}
			} else {
				field_data = switch_caller_get_field_by_name(caller_profile, field);
			}
			if (!field_data) {
				field_data = "";
			}

			if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
								  "Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
								  switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
				anti_action = SWITCH_FALSE;
			} else {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
								  "Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
								  switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
			}
		} else if (time_match == -1) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
							  "Dialplan: %s Absolute Condition [%s]\n", switch_channel_get_name(channel), exten_name);
			anti_action = SWITCH_FALSE;
		}

		if (anti_action) {
			for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) {
				const char *application = switch_xml_attr_soft(xaction, "application");
				const char *loop = switch_xml_attr(xaction, "loop");
				const char *data;
				const char *inline_ = switch_xml_attr_soft(xaction, "inline");
				int xinline = switch_true(inline_);
				int loop_count = 1;

				if (!zstr(xaction->txt)) {
					data = xaction->txt;
				} else {
					data = (char *) switch_xml_attr_soft(xaction, "data");
				}

				if (!*extension) {
					if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n");
						proceed = 0;
						goto done;
					}
				}

				if (loop) {
					loop_count = atoi(loop);
				}

				for (;loop_count > 0; loop_count--) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
							"Dialplan: %s ANTI-Action %s(%s) %s\n", switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");

					if (xinline) {
						exec_app(session, application, data);
					} else {
						switch_caller_extension_add_application(session, *extension, application, data);
					}
				}
				proceed = 1;
			}
		} else {
			for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) {
				char *application = (char *) switch_xml_attr_soft(xaction, "application");
				const char *loop = switch_xml_attr(xaction, "loop");
				char *data = NULL;
				char *substituted = NULL;
				uint32_t len = 0;
				char *app_data = NULL;
				const char *inline_ = switch_xml_attr_soft(xaction, "inline");
				int xinline = switch_true(inline_);
				int loop_count = 1;

				if (!zstr(xaction->txt)) {
					data = xaction->txt;
				} else {
					data = (char *) switch_xml_attr_soft(xaction, "data");
				}

				if (field && strchr(expression, '(')) {
					len = (uint32_t) (strlen(data) + strlen(field_data) + 10) * proceed;
					if (!(substituted = malloc(len))) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n");
						proceed = 0;
						goto done;
					}
					memset(substituted, 0, len);
					switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);
					app_data = substituted;
				} else {
					app_data = data;
				}

				if (!*extension) {
					if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n");
						proceed = 0;
						goto done;
					}
				}

				if (loop) {
					loop_count = atoi(loop);
				}
				for (;loop_count > 0; loop_count--) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
							"Dialplan: %s Action %s(%s) %s\n", switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");

					if (xinline) {
						exec_app(session, application, app_data);
					} else {
						switch_caller_extension_add_application(session, *extension, application, app_data);
					}
				}
				switch_safe_free(substituted);
			}
		}
		switch_regex_safe_free(re);

		if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
			 (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {
			break;
		}
	}

  done:
	switch_regex_safe_free(re);
	switch_safe_free(field_expanded);
	switch_safe_free(expression_expanded);
	return proceed;
}
Exemple #12
0
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_build(switch_ivr_menu_xml_ctx_t *xml_menu_ctx,
																switch_ivr_menu_t ** menu_stack, switch_xml_t xml_menus, switch_xml_t xml_menu)
{
	switch_status_t status = SWITCH_STATUS_FALSE;

	if (xml_menu_ctx != NULL && menu_stack != NULL && xml_menu != NULL) {
		const char *menu_name = switch_xml_attr_soft(xml_menu, "name");	/* if the attr doesn't exist, return "" */
		const char *greet_long = switch_xml_attr(xml_menu, "greet-long");	/* if the attr doesn't exist, return NULL */
		const char *greet_short = switch_xml_attr(xml_menu, "greet-short");	/* if the attr doesn't exist, return NULL */
		const char *invalid_sound = switch_xml_attr(xml_menu, "invalid-sound");	/* if the attr doesn't exist, return NULL */
		const char *exit_sound = switch_xml_attr(xml_menu, "exit-sound");	/* if the attr doesn't exist, return NULL */
		const char *timeout = switch_xml_attr_soft(xml_menu, "timeout");	/* if the attr doesn't exist, return "" */
		const char *max_failures = switch_xml_attr_soft(xml_menu, "max-failures");	/* if the attr doesn't exist, return "" */
		const char *max_timeouts = switch_xml_attr_soft(xml_menu, "max-timeouts");
		const char *confirm_macro = switch_xml_attr(xml_menu, "confirm-macro");
		const char *confirm_key = switch_xml_attr(xml_menu, "confirm-key");
		const char *tts_engine = switch_xml_attr(xml_menu, "tts-engine");
		const char *tts_voice = switch_xml_attr(xml_menu, "tts-voice");
		const char *confirm_attempts = switch_xml_attr_soft(xml_menu, "confirm-attempts");
		const char *digit_len = switch_xml_attr_soft(xml_menu, "digit-len");
		const char *inter_timeout = switch_xml_attr_soft(xml_menu, "inter-digit-timeout");

		switch_ivr_menu_t *menu = NULL;

		if (zstr(max_timeouts)) {
			max_timeouts = max_failures;
		}

		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "building menu '%s'\n", menu_name);

		status = switch_ivr_menu_init(&menu,
									  *menu_stack,
									  menu_name,
									  greet_long,
									  greet_short,
									  invalid_sound,
									  exit_sound,
									  confirm_macro,
									  confirm_key,
									  tts_engine,
									  tts_voice,
									  atoi(confirm_attempts),
									  atoi(inter_timeout),
									  atoi(digit_len),
									  atoi(timeout),
									  strlen(max_failures) ? atoi(max_failures) : 0, strlen(max_timeouts) ? atoi(max_timeouts) : 0, xml_menu_ctx->pool);
		/* set the menu_stack for the caller */
		if (status == SWITCH_STATUS_SUCCESS && *menu_stack == NULL) {
			*menu_stack = menu;

			if (xml_menu_ctx->autocreated) {
				switch_set_flag(menu, SWITCH_IVR_MENU_FLAG_FREEPOOL);
			}
		}

		if (status == SWITCH_STATUS_SUCCESS && menu != NULL) {
			switch_xml_t xml_kvp;

			/* build menu entries */
			for (xml_kvp = switch_xml_child(xml_menu, "entry"); xml_kvp != NULL && status == SWITCH_STATUS_SUCCESS; xml_kvp = xml_kvp->next) {
				const char *action = switch_xml_attr(xml_kvp, "action");
				const char *digits = switch_xml_attr(xml_kvp, "digits");
				const char *param = switch_xml_attr_soft(xml_kvp, "param");

				if (is_valid_action(action) && !zstr(digits)) {
					switch_ivr_menu_xml_map_t *xml_map = xml_menu_ctx->map;
					int found = 0;

					/* find and appropriate xml handler */
					while (xml_map != NULL && !found) {
						if (!(found = (strcasecmp(xml_map->name, action) == 0))) {
							xml_map = xml_map->next;
						}
					}

					if (found && xml_map != NULL) {
						/* do we need to build a new sub-menu ? */
						if (xml_map->action == SWITCH_IVR_ACTION_EXECMENU && switch_ivr_menu_find(*menu_stack, param) == NULL) {
							if ((xml_menu = switch_xml_find_child(xml_menus, "menu", "name", param)) != NULL) {
								status = switch_ivr_menu_stack_xml_build(xml_menu_ctx, menu_stack, xml_menus, xml_menu);
							}
						}
						/* finally bind the menu entry */
						if (status == SWITCH_STATUS_SUCCESS) {
							if (xml_map->function != NULL) {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
												  "binding menu caller control '%s'/'%s' to '%s'\n", xml_map->name, param, digits);
								status = switch_ivr_menu_bind_function(menu, xml_map->function, param, digits);
							} else {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "binding menu action '%s' to '%s'\n", xml_map->name, digits);
								status = switch_ivr_menu_bind_action(menu, xml_map->action, param, digits);
							}
						}
					}
				} else {
					status = SWITCH_STATUS_FALSE;
				}
			}
		}
	}

	if (status != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to build xml menu\n");
	}

	return status;
}
Exemple #13
0
static int load_config(int reloading)
{
	struct dist_list *main_list = NULL, *new_list, *old_list = NULL, *lp = NULL;
	switch_status_t status = SWITCH_STATUS_FALSE;
	char *cf = "distributor.conf";
	switch_xml_t cfg, xml, lists, list, param;


	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 (!(lists = switch_xml_child(cfg, "lists"))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find any lists!\n");
		return status;
	}

	switch_mutex_lock(globals.mod_lock);

	for (list = switch_xml_child(lists, "list"); list; list = list->next) {
		const char *name = switch_xml_attr(list, "name");
		const char *tweight = switch_xml_attr(list, "total-weight");
		struct dist_node *node, *np = NULL;

		if (zstr(name)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing NAME!\n");
			continue;
		}

		if (!zstr(tweight)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "The total-weight attribute is no longer necessary.\n");
		}

		switch_zmalloc(new_list, sizeof(*new_list));

		new_list->name = strdup(name);
		new_list->last = -1;

		if (lp) {
			lp->next = new_list;
		} else {
			main_list = new_list;
		}

		lp = new_list;

		for (param = switch_xml_child(list, "node"); param; param = param->next) {
			char *name_attr = (char *) switch_xml_attr_soft(param, "name");
			char *weight_val = (char *) switch_xml_attr_soft(param, "weight");
			int tmp;

			if ((tmp = atoi(weight_val)) < 1) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be > 0\n", tmp);
				continue;
			}

			switch_zmalloc(node, sizeof(*node));
			node->name = strdup(name_attr);
			node->wval = tmp;
			
			if (np) {
				np->next = node;
			} else {
				lp->nodes = node;
			}

			np = node;
			lp->node_count++;
		}

		calc_weight(lp);

	}

	if (main_list) {
		old_list = globals.list;
		globals.list = main_list;
		status = SWITCH_STATUS_SUCCESS;
	}

	switch_mutex_unlock(globals.mod_lock);

	if (old_list) {
		destroy_list(old_list);
	}


	if (xml) {
		switch_xml_free(xml);
	}

	return status;
}
switch_status_t load_agent(const char *agent_name)
{
	switch_xml_t x_agents, x_agent, cfg, xml;

	if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
		return SWITCH_STATUS_FALSE;
	}
	if (!(x_agents = switch_xml_child(cfg, "agents"))) {
		goto end;
	}

	if ((x_agent = switch_xml_find_child(x_agents, "agent", "name", agent_name))) {
		const char *type = switch_xml_attr(x_agent, "type");
		const char *contact = switch_xml_attr(x_agent, "contact"); 
		const char *status = switch_xml_attr(x_agent, "status");
		const char *max_no_answer = switch_xml_attr(x_agent, "max-no-answer");
		const char *wrap_up_time = switch_xml_attr(x_agent, "wrap-up-time");
		const char *reject_delay_time = switch_xml_attr(x_agent, "reject-delay-time");
		const char *busy_delay_time = switch_xml_attr(x_agent, "busy-delay-time");
		const char *no_answer_delay_time = switch_xml_attr(x_agent, "no-answer-delay-time");

		if (type) {
			cc_status_t res = cc_agent_add(agent_name, type);
			
            // For HA, only add new agent, DO NOT update or DELETE.
            if (res == CC_STATUS_AGENT_ALREADY_EXIST) {
                goto end;
            }
            
            if (res == CC_STATUS_SUCCESS) {
				if (contact) {
					cc_agent_update("contact", contact, agent_name);
				}
				if (status) {
					cc_agent_update("status", status, agent_name);
				}
				if (wrap_up_time) {
					cc_agent_update("wrap_up_time", wrap_up_time, agent_name);
				}
				if (max_no_answer) {
					cc_agent_update("max_no_answer", max_no_answer, agent_name);
				}
				if (reject_delay_time) {
					cc_agent_update("reject_delay_time", reject_delay_time, agent_name);
				}
				if (busy_delay_time) {
					cc_agent_update("busy_delay_time", busy_delay_time, agent_name);
				}
				if (no_answer_delay_time) {
					cc_agent_update("no_answer_delay_time", no_answer_delay_time, agent_name);
				}
				/*
                if (type && res == CC_STATUS_AGENT_ALREADY_EXIST) {
					cc_agent_update("type", type, agent_name);
				}*/

			}
		}
	}

end:

	if (xml) {
		switch_xml_free(xml);
	}

	return SWITCH_STATUS_SUCCESS;
}
/**
 * read default settings from speex.conf
 */
static void load_configuration()
{
	switch_xml_t xml = NULL, cfg = NULL;

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

				if (zstr(value)) {
					continue;
				}

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

				if (!strcasecmp("quality", name)) {
					/* compression quality, integer 0-10 */
					int tmp = atoi(value);
					if (switch_is_number(value) && tmp >= 0 && tmp <= 10) {
						default_codec_settings.quality = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid quality value: %s\n", value);
					}
				} else if (!strcasecmp("complexity", name)) {
					/* compression complexity, integer 1-10 */
					int tmp = atoi(value);
					if (switch_is_number(value) && tmp >= 1 && tmp <= 10) {
						default_codec_settings.complexity = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid complexity value: %s\n", value);
					}
				} else if (!strcasecmp("enhancement", name)) {
					/* enable perceptual enhancement, boolean */
					default_codec_settings.enhancement = switch_true(value);
				} else if (!strcasecmp("vad", name)) {
					/* enable voice activity detection, boolean */
					default_codec_settings.vad = switch_true(value);
				} else if (!strcasecmp("vbr", name)) {
					/* enable variable bit rate, boolean */
					default_codec_settings.vbr = switch_true(value);
				} else if (!strcasecmp("vbr-quality", name)) {
					/* variable bit rate quality, float 0-10 */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0 && tmp <= 10) {
						default_codec_settings.vbr_quality = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid vbr-quality value: %s\n", value);
					}
				} else if (!strcasecmp("abr", name)) {
					/* average bit rate, integer bits per sec */
					int tmp = atoi(value);
					if (switch_is_number(value) && tmp >= 0) {
						default_codec_settings.abr = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid abr value: %s\n", value);
					}
				} else if (!strcasecmp("dtx", name)) {
					/* discontinuous transmit, boolean */
					default_codec_settings.dtx = switch_true(value);
				} else if (!strcasecmp("preproc", name)) {
					/* enable preprocessor, boolean */
					default_codec_settings.preproc = switch_true(value);
				} else if (!strcasecmp("pp-vad", name)) {
					/* enable preprocessor VAD, boolean */
					default_codec_settings.pp_vad = switch_true(value);
				} else if (!strcasecmp("pp-agc", name)) {
					/* enable preprocessor automatic gain control, boolean */
					default_codec_settings.pp_agc = switch_true(value);
				} else if (!strcasecmp("pp-agc-level", name)) {
					/* agc level, float */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0.0f) {
						default_codec_settings.pp_agc_level = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-agc-level value: %s\n", value);
					}
				} else if (!strcasecmp("pp-denoise", name)) {
					/* enable preprocessor denoiser, boolean */
					default_codec_settings.pp_denoise = switch_true(value);
				} else if (!strcasecmp("pp-dereverb", name)) {
					/* enable preprocessor reverberation removal, boolean */
					default_codec_settings.pp_dereverb = switch_true(value);
				} else if (!strcasecmp("pp-dereverb-decay", name)) {
					/* reverberation removal decay, float */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0.0f) {
						default_codec_settings.pp_dereverb_decay = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-decay value: %s\n", value);
					}
				} else if (!strcasecmp("pp-dereverb-level", name)) {
					/* reverberation removal level, float */
					float tmp = atof(value);
					if (switch_is_number(value) && tmp >= 0.0f) {
						default_codec_settings.pp_dereverb_level = tmp;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-level value: %s\n", value);
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid unknown param: %s = %s\n", name, value);
				}
			}
		}
		switch_xml_free(xml);
	}
}
static switch_status_t load_config(switch_memory_pool_t *pool)
{
    switch_status_t status = SWITCH_STATUS_SUCCESS;
    char *cf = "cdr_pg_csv.conf", *ptr;
    switch_xml_t cfg, xml, schema, field;
    const char *attr;
    int num_fields = 0;
    switch_size_t len = 0;
    cdr_field_t *cdr_field;

    if (globals.db_online) {
        PQfinish(globals.db_connection);
        switch_mutex_destroy(globals.db_mutex);
        globals.db_online = 0;
    }

    memset(&globals, 0, sizeof(globals));
    switch_core_hash_init(&globals.fd_hash, pool);
    switch_mutex_init(&globals.db_mutex, SWITCH_MUTEX_NESTED, pool);

    globals.pool = pool;

    if (switch_xml_config_parse_module_settings(cf, SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {
        return SWITCH_STATUS_FALSE;
    }

    if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
        if ((schema = switch_xml_child(cfg, "schema"))) {
            /* Count fields in schema so we can calculate required buffer size */
            for (field = switch_xml_child(schema, "field"); field; field = field->next) {
                if (switch_xml_attr(field, "var")) {
                    num_fields++;
                }
            }

            globals.db_schema = switch_core_alloc(pool, (num_fields + 1) * sizeof(cdr_field_t));
            cdr_field = globals.db_schema->fields;

            for (field = switch_xml_child(schema, "field"); field; field = field->next) {
                if ((attr = switch_xml_attr(field, "var"))) {
                    cdr_field->var_name = switch_core_strdup(pool, attr);

                    /* Assume SQL column name is the same as FreeSWITCH channel var name, unless specified otherwise */
                    if ((attr = switch_xml_attr(field, "column"))) {
                        cdr_field->col_name = switch_core_strdup(pool, attr);
                    } else {
                        cdr_field->col_name = switch_core_strdup(pool, cdr_field->var_name);
                    }

                    /* Assume all fields should be quoted (treated as strings), unless specified otherwise */
                    if ((attr = switch_xml_attr(field, "quote")) && !strncmp(attr, "false", 5)) {
                        cdr_field->quote = SWITCH_FALSE;
                    } else {
                        cdr_field->quote = SWITCH_TRUE;
                    }

                    /* Assume all fields allow SQL nulls, unless specified otherwise */
                    if ((attr = switch_xml_attr(field, "not-null")) && !strncmp(attr, "true", 4)) {
                        cdr_field->not_null = SWITCH_TRUE;
                    } else {
                        cdr_field->not_null = SWITCH_FALSE;
                    }

                    len += strlen(cdr_field->col_name) + 1;
                    cdr_field++;
                }
            }
            cdr_field->var_name = 0;

            globals.db_schema->columns = switch_core_alloc(pool, len);
            ptr = globals.db_schema->columns;
            for (cdr_field = globals.db_schema->fields; cdr_field->col_name; cdr_field++) {
                len = strlen(cdr_field->col_name);
                memcpy(ptr, cdr_field->col_name, len);
                ptr += len;
                *ptr = ',';
                ptr++;
            }
            *--ptr = '\0';
        }

        switch_xml_free(xml);
    }

    return status;
}
Exemple #17
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;
	
}
static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, 
					   switch_caller_extension_t **extension, const char *exten_name, int recur)
{
	switch_xml_t xcond, xaction, xexpression, xregex;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	int proceed = 0, save_proceed = 0;
	char *expression_expanded = NULL, *field_expanded = NULL;
	switch_regex_t *re = NULL, *save_re = NULL;
	int offset = 0;
	const char *tmp, *tzoff = NULL, *tzname = NULL, *req_nesta = NULL;
	char nbuf[128] = "";
	int req_nest = 1;
	char space[MAX_RECUR_SPACE] = "";
	const char *orig_exten_name = exten_name;

	check_tz();

	if (!exten_name) {
		exten_name = "_anon_";
	}

	if (!orig_exten_name) {
		orig_exten_name = "_anon_";
	}


	if (recur) {
		int i, j = 0, k = 0;

		if (recur > MAX_RECUR) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Recursion LIMIT!\n");
			return 0;
		}

		switch_snprintf(nbuf, sizeof(nbuf), "%s_recur_%d", exten_name, recur);
		exten_name = nbuf;
		
		space[j++] = '|';

		for (i = 0; i < recur; i++) {
			for (k = 0; k < RECUR_SPACE; k++) {
				if (i == recur-1 && k == RECUR_SPACE-1) {
					space[j++] = ' ';
				} else {
					space[j++] = '-';
				}
			}
		}
		
		if ((req_nesta = switch_xml_attr(xexten, "require-nested"))) {
			req_nest = switch_true(req_nesta);
		}

		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, 
						  "%sDialplan: Processing recursive conditions level:%d [%s] require-nested=%s\n", space,
						  recur, exten_name, req_nest ? "TRUE" : "FALSE");

	} else {
		if ((tmp = switch_xml_attr(xexten, "name"))) {
			exten_name = tmp;
		}
	}


	for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
		char *field = NULL;
		char *do_break_a = NULL;
		char *expression = NULL, *save_expression = NULL, *save_field_data = NULL;
		char *regex_rule = NULL;
		const char *field_data = NULL;
		int ovector[30];
		switch_bool_t anti_action = SWITCH_TRUE;
		break_t do_break_i = BREAK_ON_FALSE;
		int time_match;

		check_tz();
		time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL, tzname);

		switch_safe_free(field_expanded);
		switch_safe_free(expression_expanded);

		field = (char *) switch_xml_attr(xcond, "field");


		if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) {
			if (!strcasecmp(do_break_a, "on-true")) {
				do_break_i = BREAK_ON_TRUE;
			} else if (!strcasecmp(do_break_a, "on-false")) {
				do_break_i = BREAK_ON_FALSE;
			} else if (!strcasecmp(do_break_a, "always")) {
				do_break_i = BREAK_ALWAYS;
			} else if (!strcasecmp(do_break_a, "never")) {
				do_break_i = BREAK_NEVER;
			} else {
				do_break_a = NULL;
			}
		}


		if (switch_xml_child(xcond, "condition")) {
			if (!(proceed = parse_exten(session, caller_profile, xcond, extension, orig_exten_name, recur + 1))) {
				if (do_break_i == BREAK_NEVER) {
					continue;
				}
				goto done;
			}
		}
		
		if (time_match == 1) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
							  "%sDialplan: %s Date/Time Match (PASS) [%s] break=%s\n", space,
							  switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
			anti_action = SWITCH_FALSE;
			proceed = 1;
		} else if (time_match == 0) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
							  "%sDialplan: %s Date/TimeMatch (FAIL) [%s] break=%s\n", space,
							  switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
		}
		
		
		if ((regex_rule = (char *) switch_xml_attr(xcond, "regex"))) {
			int all = !strcasecmp(regex_rule, "all");
			int xor = !strcasecmp(regex_rule, "xor");
			int pass = 0;
			int fail = 0;
			int total = 0;

			switch_channel_del_variable_prefix(channel, "DP_REGEX_MATCH");

			for (xregex = switch_xml_child(xcond, "regex"); xregex; xregex = xregex->next) {
				check_tz();
				time_match = switch_xml_std_datetime_check(xregex, tzoff ? &offset : NULL, tzname);
				
				if (time_match == 1) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
									  "%sDialplan: %s Date/Time Match (PASS) [%s]\n", space,
									  switch_channel_get_name(channel), exten_name);
					anti_action = SWITCH_FALSE;
				} else if (time_match == 0) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
									  "%sDialplan: %s Date/TimeMatch (FAIL) [%s]\n", space,
									  switch_channel_get_name(channel), exten_name);
				}


				if ((xexpression = switch_xml_child(xregex, "expression"))) {
					expression = switch_str_nil(xexpression->txt);
				} else {
					expression = (char *) switch_xml_attr_soft(xregex, "expression");
				}
				
				if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) {
					expression_expanded = NULL;
				} else {
					expression = expression_expanded;
				}
				
				total++;
				
				field = (char *) switch_xml_attr(xregex, "field");
				
				if (field) {
					if (strchr(field, '$')) {
						if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) {
							field_expanded = NULL;
							field_data = field;
						} else {
							field_data = field_expanded;
						}
					} else {
						field_data = switch_caller_get_field_by_name(caller_profile, field);
					}
					if (!field_data) {
						field_data = "";
					}
					
					if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
										  "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ match=%s\n", space,
										  switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any");
						pass++;
						if (!all && !xor) break;
					} else {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
										  "%sDialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ match=%s\n", space,
										  switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any");
						fail++;
						if (all && !xor) break;
					}
				} else if (time_match == -1) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
									  "%sDialplan: %s Absolute Condition [%s] match=%s\n", space,
									  switch_channel_get_name(channel), exten_name, all ? "all" : "any");
					pass++;
					proceed = 1;
					if (!all && !xor) break;
				} else if (time_match == 1) {
					pass++;
					proceed = 1;
					if (!all && !xor) break;
				}
				
				if (field && strchr(expression, '(')) {
					char var[256];
					switch_snprintf(var, sizeof(var), "DP_REGEX_MATCH_%d", total);

					switch_channel_set_variable(channel, var, NULL);
					switch_capture_regex(re, proceed, field_data, ovector, var, switch_regex_set_var_callback, session);
					
					switch_safe_free(save_expression);
					switch_safe_free(save_field_data);
					switch_regex_safe_free(save_re);
					
					
					save_expression = strdup(expression);
					save_field_data = strdup(field_data);
					save_re = re;
					save_proceed = proceed;
					
					re = NULL;
				}

				switch_regex_safe_free(re);

				switch_safe_free(field_expanded);
				switch_safe_free(expression_expanded);
				
			}

			if (xor) {
				if (pass == 1) {
					anti_action = SWITCH_FALSE;
				}
			} else {
				if ((all && !fail) || (!all && pass)) {
					anti_action = SWITCH_FALSE; 
				}
			}

			switch_safe_free(field_expanded);
			switch_safe_free(expression_expanded);
			
		} else {
			if ((xexpression = switch_xml_child(xcond, "expression"))) {
				expression = switch_str_nil(xexpression->txt);
			} else {
				expression = (char *) switch_xml_attr_soft(xcond, "expression");
			}

			if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) {
				expression_expanded = NULL;
			} else {
				expression = expression_expanded;
			}
			
			if (field) {
				if (strchr(field, '$')) {
					if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) {
						field_expanded = NULL;
						field_data = field;
					} else {
						field_data = field_expanded;
					}
				} else {
					field_data = switch_caller_get_field_by_name(caller_profile, field);
				}
				if (!field_data) {
					field_data = "";
				}

				if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
									  "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n", space,
									  switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
					anti_action = SWITCH_FALSE;
				} else {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
									  "%sDialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n", space,
									  switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
				}
			} else if (time_match == -1) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
								  "%sDialplan: %s Absolute Condition [%s]\n", space,
								  switch_channel_get_name(channel), exten_name);
				anti_action = SWITCH_FALSE;
				proceed = 1;
			}

		}

		if (save_re) {
			re = save_re;
			save_re = NULL;
			
			expression = expression_expanded = save_expression;
			save_expression = NULL;
			field_data = field_expanded = save_field_data;
			field = (char *) field_data;
			save_field_data = NULL;
			proceed = save_proceed;
		}


		if (anti_action) {
			for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) {
				const char *application = switch_xml_attr_soft(xaction, "application");
				const char *loop = switch_xml_attr(xaction, "loop");
				const char *data;
				const char *inline_ = switch_xml_attr_soft(xaction, "inline");
				int xinline = switch_true(inline_);
				int loop_count = 1;

				if (!zstr(xaction->txt)) {
					data = xaction->txt;
				} else {
					data = (char *) switch_xml_attr_soft(xaction, "data");
				}

				if (!*extension) {
					if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n");
						proceed = 0;
						goto done;
					}
				}

				if (loop) {
					loop_count = atoi(loop);
				}

				for (;loop_count > 0; loop_count--) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
									  "%sDialplan: %s ANTI-Action %s(%s) %s\n", space,
									  switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");

					if (xinline) {
						exec_app(session, application, data);
					} else {
						switch_caller_extension_add_application(session, *extension, application, data);
					}
				}
				proceed = 1;
			}
		} else {
			if (field && strchr(expression, '(')) {
				switch_channel_set_variable(channel, "DP_MATCH", NULL);
				switch_capture_regex(re, proceed, field_data, ovector, "DP_MATCH", switch_regex_set_var_callback, session);
			}

			for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) {
				char *application = (char *) switch_xml_attr_soft(xaction, "application");
				const char *loop = switch_xml_attr(xaction, "loop");
				char *data = NULL;
				char *substituted = NULL;
				uint32_t len = 0;
				char *app_data = NULL;
				const char *inline_ = switch_xml_attr_soft(xaction, "inline");
				int xinline = switch_true(inline_);
				int loop_count = 1;

				if (!zstr(xaction->txt)) {
					data = xaction->txt;
				} else {
					data = (char *) switch_xml_attr_soft(xaction, "data");
				}

				if (field && strchr(expression, '(')) {
					len = (uint32_t) (strlen(data) + strlen(field_data) + 10) * proceed;
					if (!(substituted = malloc(len))) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n");
						proceed = 0;
						goto done;
					}
					memset(substituted, 0, len);
					switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);
					app_data = substituted;
				} else {
					app_data = data;
				}

				if (!*extension) {
					if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n");
						proceed = 0;
						goto done;
					}
				}

				if (loop) {
					loop_count = atoi(loop);
				}
				for (;loop_count > 0; loop_count--) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
									  "%sDialplan: %s Action %s(%s) %s\n", space,
									  switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");

					if (xinline) {
						exec_app(session, application, app_data);
					} else {
						switch_caller_extension_add_application(session, *extension, application, app_data);
					}
				}
				switch_safe_free(substituted);
			}
		}
		switch_regex_safe_free(re);

		if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
			 (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {
			break;
		}
	}

  done:
	switch_regex_safe_free(re);
	switch_safe_free(field_expanded);
	switch_safe_free(expression_expanded);

	if (!req_nest) proceed = 1;

	return proceed;
}
Exemple #19
0
static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_t **extension)
{
	switch_xml_t xcond, xaction, xexpression;
	char *exten_name = (char *) switch_xml_attr(xexten, "name");
	int proceed = 0;
	char *expression_expanded = NULL, *field_expanded = NULL;
	switch_regex_t *re = NULL;
	const char *to = switch_event_get_header(event, "to");
	const char *tzoff = NULL, *tzname = NULL;
	int offset = 0;

	check_tz();

	if (!to) {
		to = "nobody";
	}

	if (!exten_name) {
		exten_name = "_anon_";
	}

	for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
		char *field = NULL;
		char *do_break_a = NULL;
		char *expression = NULL;
		const char *field_data = NULL;
		int ovector[30];
		switch_bool_t anti_action = SWITCH_TRUE;
		break_t do_break_i = BREAK_ON_FALSE;
		int time_match;

		check_tz();
		time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL, tzname);

		switch_safe_free(field_expanded);
		switch_safe_free(expression_expanded);

		if (switch_xml_child(xcond, "condition")) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Nested conditions are not allowed!\n");
			proceed = 1;
			goto done;
		}

		field = (char *) switch_xml_attr(xcond, "field");

		if ((xexpression = switch_xml_child(xcond, "expression"))) {
			expression = switch_str_nil(xexpression->txt);
		} else {
			expression = (char *) switch_xml_attr_soft(xcond, "expression");
		}

		if ((expression_expanded = switch_event_expand_headers(event, expression)) == expression) {
			expression_expanded = NULL;
		} else {
			expression = expression_expanded;
		}

		if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) {
			if (!strcasecmp(do_break_a, "on-true")) {
				do_break_i = BREAK_ON_TRUE;
			} else if (!strcasecmp(do_break_a, "on-false")) {
				do_break_i = BREAK_ON_FALSE;
			} else if (!strcasecmp(do_break_a, "always")) {
				do_break_i = BREAK_ALWAYS;
			} else if (!strcasecmp(do_break_a, "never")) {
				do_break_i = BREAK_NEVER;
			} else {
				do_break_a = NULL;
			}
		}

		if (time_match == 1) {
			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
							  "Chatplan: %s Date/Time Match (PASS) [%s] break=%s\n",
							  to, exten_name, do_break_a ? do_break_a : "on-false");
			anti_action = SWITCH_FALSE;
		} else if (time_match == 0) {
			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
							  "Chatplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
							  to, exten_name, do_break_a ? do_break_a : "on-false");
		}

		if (field) {
			if (strchr(field, '$')) {
				if ((field_expanded = switch_event_expand_headers(event, field)) == field) {
					field_expanded = NULL;
					field_data = field;
				} else {
					field_data = field_expanded;
				}
			} else {
				field_data = switch_event_get_header(event, field);
			}
			if (!field_data) {
				field_data = "";
			}

			if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
				switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
								  "Chatplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
								  to, exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
				anti_action = SWITCH_FALSE;
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
								  "Chatplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
								  to, exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
			}
		} else if (time_match == -1) {
			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
							  "Chatplan: %s Absolute Condition [%s]\n", to, exten_name);
			anti_action = SWITCH_FALSE;
		}

		if (anti_action) {
			for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) {
				const char *application = switch_xml_attr_soft(xaction, "application");
				const char *loop = switch_xml_attr(xaction, "loop");
				const char *data;
				const char *inline_ = switch_xml_attr_soft(xaction, "inline");
				int xinline = switch_true(inline_);
				int loop_count = 1;

				if (!zstr(xaction->txt)) {
					data = xaction->txt;
				} else {
					data = (char *) switch_xml_attr_soft(xaction, "data");
				}

				if (!*extension) {
					if ((switch_event_create(extension, SWITCH_EVENT_CLONE)) != SWITCH_STATUS_SUCCESS) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
						abort();
					}
				}

				if (loop) {
					loop_count = atoi(loop);
				}

				for (;loop_count > 0; loop_count--) {
					switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
							"Chatplan: %s ANTI-Action %s(%s) %s\n", to, application, data, xinline ? "INLINE" : "");

					if (xinline) {
						switch_core_execute_chat_app(event, application, data);
					} else {
						switch_event_add_header_string(*extension, SWITCH_STACK_BOTTOM, application, zstr(data) ? "__undef" : data);
					}
				}
				proceed = 1;
			}
		} else {
			if (field && strchr(expression, '(')) {
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DP_MATCH", NULL);
				switch_capture_regex(re, proceed, field_data, ovector, "DP_MATCH", switch_regex_set_event_header_callback, event);
			}

			for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) {
				char *application = (char *) switch_xml_attr_soft(xaction, "application");
				const char *loop = switch_xml_attr(xaction, "loop");
				char *data = NULL;
				char *substituted = NULL;
				uint32_t len = 0;
				char *app_data = NULL;
				const char *inline_ = switch_xml_attr_soft(xaction, "inline");
				int xinline = switch_true(inline_);
				int loop_count = 1;

				if (!zstr(xaction->txt)) {
					data = xaction->txt;
				} else {
					data = (char *) switch_xml_attr_soft(xaction, "data");
				}

				if (field && strchr(expression, '(')) {
					len = (uint32_t) (strlen(data) + strlen(field_data) + 10) * proceed;
					if (!(substituted = (char *) malloc(len))) {
						abort();
					}
					memset(substituted, 0, len);
					switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);
					app_data = substituted;
				} else {
					app_data = data;
				}

				if (!*extension) {
					if ((switch_event_create(extension, SWITCH_EVENT_CLONE)) != SWITCH_STATUS_SUCCESS) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
						abort();
					}
				}

				if (loop) {
					loop_count = atoi(loop);
				}
				for (;loop_count > 0; loop_count--) {
					switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
							"Chatplan: %s Action %s(%s) %s\n", to, application, app_data, xinline ? "INLINE" : "");

					if (xinline) {
						switch_core_execute_chat_app(event, application, app_data);
					} else {
						switch_event_add_header_string(*extension, SWITCH_STACK_BOTTOM, application, zstr(app_data) ? "__undef" : app_data);
					}
				}
				switch_safe_free(substituted);
			}
		}
		switch_regex_safe_free(re);

		if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
			 (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {
			break;
		}
	}

  done:
	switch_regex_safe_free(re);
	switch_safe_free(field_expanded);
	switch_safe_free(expression_expanded);
	return proceed;
}
Exemple #20
0
static switch_event_t *chatplan_hunt(switch_event_t *event)
{
	switch_event_t *extension = NULL;
	switch_xml_t alt_root = NULL, cfg, xml = NULL, xcontext, xexten = NULL;
	const char *alt_path;
	const char *context;
	const char *from;
	const char *to;

	if (!(context = switch_event_get_header(event, "context"))) {
		context = "default";
	}

	if (!(from = switch_event_get_header(event, "from_user"))) {
		from = switch_event_get_header(event, "from");
	}

	if (!(to = switch_event_get_header(event, "to_user"))) {
		to = switch_event_get_header(event, "to");
	}

	alt_path = switch_event_get_header(event, "alt_path");

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Processing text message %s->%s in context %s\n", from, to, context);

	/* get our handle to the "chatplan" section of the config */

	if (!zstr(alt_path)) {
		switch_xml_t conf = NULL, tag = NULL;
		if (!(alt_root = switch_xml_parse_file_simple(alt_path))) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of [%s] failed\n", alt_path);
			goto done;
		}

		if ((conf = switch_xml_find_child(alt_root, "section", "name", "chatplan")) && (tag = switch_xml_find_child(conf, "chatplan", NULL, NULL))) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Getting chatplan from alternate path: %s\n", alt_path);
			xml = alt_root;
			cfg = tag;
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of chatplan failed\n");
			goto done;
		}
	} else {
		if (switch_xml_locate("chatplan", NULL, NULL, NULL, &xml, &cfg, event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of chatplan failed\n");
			goto done;
		}
	}

	/* get a handle to the context tag */
	if (!(xcontext = switch_xml_find_child(cfg, "context", "name", context))) {
		if (!(xcontext = switch_xml_find_child(cfg, "context", "name", "global"))) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Context %s not found\n", context);
			goto done;
		}
	}

	xexten = switch_xml_child(xcontext, "extension");
	
	while (xexten) {
		int proceed = 0;
		const char *cont = switch_xml_attr(xexten, "continue");
		const char *exten_name = switch_xml_attr(xexten, "name");

		if (!exten_name) {
			exten_name = "UNKNOWN";
		}

		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
						  "Chatplan: %s parsing [%s->%s] continue=%s\n",
						  to, context, exten_name, cont ? cont : "false");

		proceed = parse_exten(event, xexten, &extension);
		
		if (proceed && !switch_true(cont)) {
			break;
		}

		xexten = xexten->next;
	}

	switch_xml_free(xml);
	xml = NULL;

  done:
	switch_xml_free(xml);
	return extension;
}
Exemple #21
0
static abyss_bool user_attributes(const char *user, const char *domain_name,
								  const char **ppasswd, const char **pvm_passwd, const char **palias, const char **pallowed_commands)
{
	const char *passwd;
	const char *vm_passwd;
	const char *alias;
	const char *allowed_commands;
	switch_event_t *params;
	switch_xml_t x_user, x_params, x_param;

	passwd = NULL;
	vm_passwd = NULL;
	alias = NULL;
	allowed_commands = NULL;

	if (ppasswd) *ppasswd = NULL;
	if (pvm_passwd) *pvm_passwd = NULL;
	if (palias) *palias = NULL;
	if (pallowed_commands) *pallowed_commands = NULL;

	params = NULL;

	switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
	switch_assert(params);
	switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "number_alias", "check");


	if (switch_xml_locate_user_merged("id", user, domain_name, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) {
		switch_event_destroy(&params);
		return FALSE;
	}

	switch_event_destroy(&params);
	alias = switch_xml_attr(x_user, "number-alias");

	if ((x_params = switch_xml_child(x_user, "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, "password")) {
				passwd = val;
			} else if (!strcasecmp(var, "vm-password")) {
				vm_passwd = val;
			} else if (!strcasecmp(var, "http-allowed-api")) {
				allowed_commands = val;
			}
		}
	}

	if (ppasswd && passwd) {
		*ppasswd = strdup(passwd);
	}

	if (pvm_passwd && vm_passwd) {
		*pvm_passwd = strdup(vm_passwd);
	}

	if (palias && alias) {
		*palias = strdup(alias);
	}

	if (pallowed_commands && allowed_commands) {
		*pallowed_commands = strdup(allowed_commands);
	}

	if (x_user) {
		switch_xml_free(x_user);
	}

	return TRUE;
}