Index: src/switch_rtp.c
===================================================================
--- src/switch_rtp.c	(revision 10177)
+++ src/switch_rtp.c	(working copy)
@@ -30,6 +30,7 @@
  * switch_rtp.c -- RTP
  *
  */
+#define USE_NETCHANNEL 1
 
 #include <switch.h>
 #include <switch_stun.h>
@@ -44,6 +45,10 @@
 #include <datatypes.h>
 #include <srtp.h>
 
+#ifdef USE_NETCHANNEL
+#include <unetstack.h>
+#endif
+
 #define READ_INC(rtp_session) switch_mutex_lock(rtp_session->read_mutex); rtp_session->reading++
 #define READ_DEC(rtp_session)  switch_mutex_unlock(rtp_session->read_mutex); rtp_session->reading--
 #define WRITE_INC(rtp_session)  switch_mutex_lock(rtp_session->write_mutex); rtp_session->writing++
@@ -127,7 +132,12 @@
 	 * families are equal, sock_input == sock_output and only one socket is
 	 * used.
 	 */
+#ifdef USE_NETCHANNEL
+	struct netchannel *nc_input, *nc_output;
+	struct netchannel_control nc_ctl;
+#else
 	switch_socket_t *sock_input, *sock_output;
+#endif
 
 	switch_sockaddr_t *local_addr;
 	rtp_msg_t send_msg;
@@ -250,8 +260,16 @@
 		bytes += 4;
 	}
 
-
+#ifdef USE_NETCHANNEL
+	bytes = netchannel_send(rtp_session->nc_output, (void *)packet, bytes);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Netchannel_send() retval = %d\n", (int)bytes);
+	if (bytes <= 0) {
+		status = SWITCH_STATUS_FALSE;
+		goto end;
+	}
+#else
 	switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_stun_addr, 0, (void *) packet, &bytes);
+#endif
 	rtp_session->stuncount = rtp_session->default_stuncount;
 	
   end:
@@ -291,7 +309,17 @@
 	packet = switch_stun_packet_build_header(SWITCH_STUN_BINDING_REQUEST, NULL, buf);
 	switch_stun_packet_attribute_add_username(packet, rtp_session->ice_user, 32);
 	bytes = switch_stun_packet_length(packet);
+
+#ifdef USE_NETCHANNEL
+	bytes = netchannel_send(rtp_session->nc_input, (void *)packet, bytes);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Netchannel_send() retval = %d\n", (int)bytes);
+	if (bytes <= 0) {
+		status = SWITCH_STATUS_FALSE;
+		goto end;
+	}
+#else
 	switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) packet, &bytes);
+#endif
 	rtp_session->stuncount = rtp_session->default_stuncount;
 
   end:
@@ -377,7 +405,12 @@
 		remote_ip = switch_get_addr(ipbuf, sizeof(ipbuf), rtp_session->from_addr);
 		switch_stun_packet_attribute_add_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(rtp_session->from_addr));
 		bytes = switch_stun_packet_length(rpacket);
+#ifdef USE_NETCHANNEL
+		bytes = netchannel_send(rtp_session->nc_input, (void *)rpacket, bytes);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Netchannel_send() retval = %d\n", (int)bytes);
+#else
 		switch_socket_sendto(rtp_session->sock_output, rtp_session->from_addr, 0, (void *) rpacket, &bytes);
+#endif
 	}
 
   end:
@@ -487,9 +520,11 @@
 
 SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err)
 {
+#ifndef USE_NETCHANNEL
 	switch_socket_t *new_sock = NULL, *old_sock = NULL;
+#endif
 	switch_status_t status = SWITCH_STATUS_FALSE;
-#ifndef WIN32
+#if !defined(WIN32) && !defined(USE_NETCHANNEL)
 	char o[5] = "TEST", i[5] = "";
 	switch_size_t len, ilen = 0;
 	int x;
@@ -521,6 +556,28 @@
 		goto done;
 	}
 
+#ifdef USE_NETCHANNEL
+	if (netchannel_addr_init(&rtp_session->nc_ctl.saddr, (char *)host, port, IPPROTO_UDP)) {
+		*err = "Netchannel local addr error!";
+		goto done;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Netchannel saddr host:port = %s:%d\n", host, port);
+
+	if (rtp_session->nc_input) {
+		/*
+		 * Remove already existing netchannel
+		 */
+		netchannel_remove(rtp_session->nc_input);
+		rtp_session->nc_input = NULL;
+
+		rtp_session->nc_input = netchannel_create(&rtp_session->nc_ctl, NETCHANNEL_ATCP_CONNECT);
+		if (!rtp_session->nc_input) {
+			*err = "Netchannel allocation error!";
+			goto done;
+		}
+	}
+#else
 	if (rtp_session->sock_input) {
 		switch_rtp_kill_socket(rtp_session);
 	}
@@ -567,9 +624,12 @@
 	old_sock = rtp_session->sock_input;
 	rtp_session->sock_input = new_sock;
 	new_sock = NULL;
+#endif
 
 	if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK)) {
+#ifndef USE_NETCHANNEL
 		switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, TRUE);
+#endif
 		switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
 	}
 
@@ -579,6 +639,7 @@
 
   done:
 
+#ifndef USE_NETCHANNEL
 	if (new_sock) {
 		switch_socket_close(new_sock);
 	}
@@ -586,6 +647,7 @@
 	if (old_sock) {
 		switch_socket_close(old_sock);
 	}
+#endif
 
 	if (rtp_session->ready != 1) {
 		WRITE_DEC(rtp_session);
@@ -632,6 +694,29 @@
 		rtp_session->remote_port = port;
 	}
 
+#ifdef USE_NETCHANNEL
+	if (netchannel_addr_init(&rtp_session->nc_ctl.daddr, (char *)host, port, IPPROTO_UDP)) {
+		*err = "Netchannel remote addr error!";
+		goto done;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Netchannel daddr host:port = %s:%d\n", host, port);
+
+	if (rtp_session->nc_input) {
+		/*
+		 * Remove already existing netchannel
+		 */
+		netchannel_remove(rtp_session->nc_input);
+		rtp_session->nc_input = NULL;
+
+		rtp_session->nc_input = netchannel_create(&rtp_session->nc_ctl, NETCHANNEL_ATCP_CONNECT);
+		if (!rtp_session->nc_input) {
+			*err = "Netchannel allocation error!";
+			goto done;
+		}
+	}
+done:
+#else
 	if (rtp_session->sock_input &&
 		switch_sockaddr_get_family(rtp_session->remote_addr) ==
 		switch_sockaddr_get_family(rtp_session->local_addr)) {
@@ -650,7 +735,7 @@
 			*err = "Socket Error!";
 		}
 	}
-
+#endif
 	switch_mutex_unlock(rtp_session->write_mutex);
 
 	return status;
@@ -790,7 +875,14 @@
 	/* for from address on recvfrom calls */
 	switch_sockaddr_info_get(&rtp_session->from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
 
+#ifdef USE_NETCHANNEL
+	memset(&rtp_session->nc_ctl, 0, sizeof(struct netchannel_control));
 
+	rtp_session->nc_input  = NULL;
+	rtp_session->nc_output = NULL;
+	rtp_session->nc_ctl.packet_limit = 1024;
+#endif
+
 	rtp_session->seq = (uint16_t) rand();
 	rtp_session->ssrc = (uint32_t) ((intptr_t) &rtp_session + (uint32_t) switch_timestamp(NULL));
 	rtp_session->send_msg.header.ssrc = htonl(rtp_session->ssrc);
@@ -897,6 +989,17 @@
 		goto end;
 	}
 
+#ifdef USE_NETCHANNEL
+	rtp_session->nc_input = netchannel_create(&rtp_session->nc_ctl, NETCHANNEL_ATCP_CONNECT);
+	if (!rtp_session->nc_input) {
+		switch_mutex_unlock(rtp_session->flag_mutex);
+		rtp_session = NULL;
+
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Netchannel allocation error!\n");
+		goto end;
+	}
+#endif
+
   end:
 
 	if (rtp_session) {
@@ -979,12 +1082,14 @@
 	switch_mutex_lock(rtp_session->flag_mutex);
 	switch_set_flag(rtp_session, SWITCH_RTP_FLAG_BREAK);
 
+#ifndef USE_NETCHANNEL
 	if (rtp_session->sock_input) {
 		char o[4] = "DOH";
 		switch_size_t len = sizeof(o);
 		
 		switch_socket_sendto(rtp_session->sock_input, rtp_session->local_addr, 0, (void *) o, &len);
 	}
+#endif
 	switch_mutex_unlock(rtp_session->flag_mutex);
 }
 
@@ -994,12 +1099,19 @@
 	switch_mutex_lock(rtp_session->flag_mutex);
 	if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) {
 		switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_IO);
+#ifdef USE_NETCHANNEL
+		if (rtp_session->nc_input) {
+			netchannel_remove(rtp_session->nc_input);
+			rtp_session->nc_input = NULL;
+		}
+#else
 		if (rtp_session->sock_input) {
 			switch_socket_shutdown(rtp_session->sock_input, SWITCH_SHUTDOWN_READWRITE);
 		}
 		if (rtp_session->sock_output && rtp_session->sock_output != rtp_session->sock_input) {
 			switch_socket_shutdown(rtp_session->sock_output, SWITCH_SHUTDOWN_READWRITE);
 		}
+#endif
 	}
 	switch_mutex_unlock(rtp_session->flag_mutex);
 }
@@ -1013,7 +1125,11 @@
 	}
 
 	switch_mutex_lock(rtp_session->flag_mutex);
+#ifdef USE_NETCHANNEL
+	ret = (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO) && rtp_session->nc_input && rtp_session->remote_addr && rtp_session->ready == 2) ? 1 : 0;
+#else
 	ret = (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO) && rtp_session->sock_input && rtp_session->sock_output && rtp_session->remote_addr && rtp_session->ready == 2) ? 1 : 0;
+#endif
 	switch_mutex_unlock(rtp_session->flag_mutex);
 
 	return ret;
@@ -1022,7 +1138,9 @@
 SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
 {
 	void *pop;
+#ifndef USE_NETCHANNEL
 	switch_socket_t *sock;
+#endif
 
 	if (!rtp_session || !*rtp_session || !(*rtp_session)->ready) {
 		return;
@@ -1054,6 +1172,9 @@
 		stfu_n_destroy(&(*rtp_session)->jb);
 	}
 
+#ifdef USE_NETCHANNEL
+	(*rtp_session)->nc_input = NULL;
+#else
 	sock = (*rtp_session)->sock_input;
 	(*rtp_session)->sock_input = NULL;
 	switch_socket_close(sock);
@@ -1063,6 +1184,7 @@
 		(*rtp_session)->sock_output = NULL;
 		switch_socket_close(sock);
 	}
+#endif
 
 	if (switch_test_flag((*rtp_session), SWITCH_RTP_FLAG_VAD)) {
 		switch_rtp_disable_vad(*rtp_session);
@@ -1092,7 +1214,12 @@
 
 SWITCH_DECLARE(switch_socket_t *) switch_rtp_get_rtp_socket(switch_rtp_t *rtp_session)
 {
+#ifdef USE_NETCHANNEL
+//	return netchannel_get_fd(rtp_session->nc_input);
+	return NULL;
+#else
 	return rtp_session->sock_input;
+#endif
 }
 
 SWITCH_DECLARE(void) switch_rtp_set_default_samples_per_interval(switch_rtp_t *rtp_session, uint16_t samples_per_interval)
@@ -1261,7 +1388,17 @@
 		int do_cng = 0;
 
 		bytes = sizeof(rtp_msg_t);
+#ifdef USE_NETCHANNEL
+		bytes = netchannel_recv(rtp_session->nc_input, (void *)&rtp_session->recv_msg, bytes);
+		if (bytes <= 0) {
+			status = SWITCH_STATUS_FALSE;
+		} else {
+			status = SWITCH_STATUS_SUCCESS;
+		}
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Netchannel_recv() retval = %d\n", (int)bytes);
+#else
 		status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes);
+#endif
 
 		if (bytes < 0) {
 			ret = (int) bytes;
@@ -1365,10 +1502,13 @@
 				}
 			}
 
+#ifndef USE_NETCHANNEL
 			if (rtp_session->invalid_handler) {
 				rtp_session->invalid_handler(rtp_session, rtp_session->sock_input, (void *) &rtp_session->recv_msg, bytes, rtp_session->from_addr);
 			}
-
+#else
+	/* TODO: port this */
+#endif
 			memset(data, 0, 2);
 			data[0] = 65;
 
@@ -1955,12 +2095,21 @@
 			bytes = sbytes;
 		}
 
+#ifdef USE_NETCHANNEL
+		bytes = netchannel_send(rtp_session->nc_input, (void *) send_msg, bytes);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Netchannel_send() retval = %d\n", (int)bytes);
+		if (bytes <= 0) {
+			rtp_session->seq--;
+			ret = -1;
+			goto end;
+		}
+#else
 		if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) send_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
 			rtp_session->seq--;
 			ret = -1;
 			goto end;
 		}
-
+#endif
 		if (rtp_session->timer.interval) {
 			rtp_session->last_write_samplecount = rtp_session->timer.samplecount;
 		}
@@ -2065,9 +2214,17 @@
 			return 0;
 		}
 		bytes = frame->packetlen;
+#ifdef USE_NETCHANNEL
+		bytes = netchannel_send(rtp_session->nc_input, frame->packet, bytes);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Netchannel_send() retval = %d\n", (int)bytes);
+		if (bytes <= 0) {
+			return -1;
+		}
+#else
 		if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, frame->packet, &bytes) != SWITCH_STATUS_SUCCESS) {
 			return -1;
 		}
+#endif
 		return (int) bytes;
 	}
 
@@ -2147,12 +2304,21 @@
 		bytes = sbytes;
 	}
 
+#ifdef USE_NETCHANNEL
+	bytes = netchannel_send(rtp_session->nc_input, (void *)&rtp_session->write_msg, bytes);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Netchannel_send() retval = %d\n", (int)bytes);
+	if (bytes <= 0) {
+		rtp_session->seq--;
+		ret = -1;
+		goto end;
+	}
+#else
 	if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) &rtp_session->write_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
 		rtp_session->seq--;
 		ret = -1;
 		goto end;
 	}
-
+#endif
 	rtp_session->last_write_ts = ts;
 
 	ret = (int) bytes;
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 10177)
+++ Makefile.am	(working copy)
@@ -179,6 +179,9 @@
 libfreeswitch_la_LDFLAGS     += -Wl,-lodbc
 endif
 
+libfreeswitch_la_LDFLAGS     += -Wl,-lunetstack
+freeswitch_LDFLAGS           += -Wl,-lunetstack
+
 bin_SCRIPTS = scripts/gentls_cert scripts/fsxs
 
 src/include/switch_swigable_cpp.h: src/include/switch_cpp.h
