Ejemplo n.º 1
0
static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_reg_leg, sngtc_codec_reply_leg_t* codec_reply_leg, void **rtp_fd)
{
	switch_rtp_t *rtp_session = NULL;
	switch_port_t rtp_port;
	char codec_ip[255];
	char local_ip[255];
	switch_rtp_flag_t flags = 0;
	int iana = 0;
	const char *err = NULL;
	struct sangoma_transcoding_session *sess = usr_priv;
	struct in_addr local_ip_addr = { 0 };

	local_ip_addr.s_addr = htonl(codec_reply_leg->host_ip);
	
	switch_inet_ntop(AF_INET, &local_ip_addr, local_ip, sizeof(local_ip));

	/* request a port */
	if (!(rtp_port = switch_rtp_request_port(local_ip))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate RTP port for IP %s\n", local_ip);
		return -1;
	}
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocated port %d for IP %s\n", rtp_port, local_ip);

	codec_reg_leg->host_udp_port = rtp_port;

	sngtc_codec_ipv4_hex_to_str(codec_reply_leg->codec_ip, codec_ip);

	iana = codec_id_to_iana(codec_reg_leg->codec_id);
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Creating RTP session for host (%s/%d)  vocallo(%s/%d) Iana=%d ms=%d idx=%lu\n",
					  local_ip, rtp_port, codec_ip, codec_reply_leg->codec_udp_port, iana, 
					  codec_reg_leg->ms*1000, sess->sessid);

	/* create the RTP socket, dont use the session pool since the session may go away while the RTP socket should linger around 
	 * until sangoma_transcode decides to kill it (possibly because the same RTP session is used for a different call) */
	rtp_session = switch_rtp_new(local_ip, rtp_port, 
			codec_ip, codec_reply_leg->codec_udp_port, 
			iana,
			sess->impl->samples_per_packet,
			codec_reg_leg->ms*1000, /* microseconds per packet */
			flags, NULL, &err, g_pool);

	if (!rtp_session) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create switch rtp session: %s\n", err);
		return -1;
	}

	*rtp_fd = rtp_session;

	return 0;
}
Ejemplo n.º 2
0
static int sangoma_create_rtp_port(void *usr_priv, uint32_t host_ip, uint32_t *p_rtp_port, void **rtp_fd)
{
	struct in_addr local_ip_addr = { 0 };
	char local_ip[255];
	switch_port_t rtp_port;

	local_ip_addr.s_addr = htonl(host_ip);
	
	switch_inet_ntop(AF_INET, &local_ip_addr, local_ip, sizeof(local_ip));

	/* request a port */
	if (!(rtp_port = switch_rtp_request_port(local_ip))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate RTP port for IP %s\n", local_ip);
		return -1;
	}
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "New allocated port %d for IP %s/%d.%d.%d.%d\n", rtp_port, local_ip,
			SNGTC_NIPV4(host_ip));
	*p_rtp_port = rtp_port;
	*rtp_fd = (void *)(long)rtp_port;
	return 0;
}
Ejemplo n.º 3
0
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;
}